Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
2f20794c
Commit
2f20794c
authored
May 13, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support fused cpdef functions with Python indexing
parent
1472e87b
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
554 additions
and
60 deletions
+554
-60
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+7
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+385
-23
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+88
-10
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+17
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+18
-5
Cython/Shadow.py
Cython/Shadow.py
+39
-15
No files found.
Cython/Compiler/CythonScope.py
View file @
2f20794c
...
@@ -16,6 +16,13 @@ class CythonScope(ModuleScope):
...
@@ -16,6 +16,13 @@ class CythonScope(ModuleScope):
defining
=
1
,
defining
=
1
,
cname
=
'<error>'
)
cname
=
'<error>'
)
for
fused_type
in
(
cy_integral_type
,
cy_floating_type
,
cy_numeric_type
):
entry
=
self
.
declare_typedef
(
fused_type
.
name
,
fused_type
,
None
,
cname
=
'<error>'
)
entry
.
in_cinclude
=
True
def
lookup_type
(
self
,
name
):
def
lookup_type
(
self
,
name
):
# This function should go away when types are all first-level objects.
# This function should go away when types are all first-level objects.
type
=
parse_basic_type
(
name
)
type
=
parse_basic_type
(
name
)
...
...
Cython/Compiler/ExprNodes.py
View file @
2f20794c
This diff is collapsed.
Click to expand it.
Cython/Compiler/Nodes.py
View file @
2f20794c
...
@@ -1823,8 +1823,12 @@ class CFuncDefNode(FuncDefNode):
...
@@ -1823,8 +1823,12 @@ class CFuncDefNode(FuncDefNode):
# An error will be produced in the cdef function
# An error will be produced in the cdef function
self
.
overridable
=
False
self
.
overridable
=
False
self
.
declare_cpdef_wrapper
(
env
)
self
.
create_local_scope
(
env
)
def
declare_cpdef_wrapper
(
self
,
env
):
if
self
.
overridable
:
if
self
.
overridable
:
import
ExprNodes
name
=
self
.
entry
.
name
py_func_body
=
self
.
call_self_node
(
is_module_scope
=
env
.
is_module_scope
)
py_func_body
=
self
.
call_self_node
(
is_module_scope
=
env
.
is_module_scope
)
self
.
py_func
=
DefNode
(
pos
=
self
.
pos
,
self
.
py_func
=
DefNode
(
pos
=
self
.
pos
,
name
=
self
.
entry
.
name
,
name
=
self
.
entry
.
name
,
...
@@ -1842,7 +1846,6 @@ class CFuncDefNode(FuncDefNode):
...
@@ -1842,7 +1846,6 @@ class CFuncDefNode(FuncDefNode):
if
not
env
.
is_module_scope
or
Options
.
lookup_module_cpdef
:
if
not
env
.
is_module_scope
or
Options
.
lookup_module_cpdef
:
self
.
override
=
OverrideCheckNode
(
self
.
pos
,
py_func
=
self
.
py_func
)
self
.
override
=
OverrideCheckNode
(
self
.
pos
,
py_func
=
self
.
py_func
)
self
.
body
=
StatListNode
(
self
.
pos
,
stats
=
[
self
.
override
,
self
.
body
])
self
.
body
=
StatListNode
(
self
.
pos
,
stats
=
[
self
.
override
,
self
.
body
])
self
.
create_local_scope
(
env
)
def
_validate_type_visibility
(
self
,
type
,
pos
,
env
):
def
_validate_type_visibility
(
self
,
type
,
pos
,
env
):
"""
"""
...
@@ -2025,16 +2028,15 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -2025,16 +2028,15 @@ class FusedCFuncDefNode(StatListNode):
Then when a function lookup occurs (to e.g. call it), the call can be
Then when a function lookup occurs (to e.g. call it), the call can be
dispatched to the right function.
dispatched to the right function.
node FuncDefNode the original function
node FuncDefNode the original function
nodes [FuncDefNode] list of copies of node with different specific types
nodes [FuncDefNode] list of copies of node with different specific types
py_func DefNode the original python function (in case of a cpdef)
"""
"""
child_attrs
=
[
'nodes'
]
def
__init__
(
self
,
node
,
env
):
def
__init__
(
self
,
node
,
env
):
super
(
FusedCFuncDefNode
,
self
).
__init__
(
node
.
pos
)
super
(
FusedCFuncDefNode
,
self
).
__init__
(
node
.
pos
)
self
.
nodes
=
self
.
stats
=
[]
self
.
nodes
=
[]
self
.
node
=
node
self
.
node
=
node
self
.
copy_cdefs
(
env
)
self
.
copy_cdefs
(
env
)
...
@@ -2055,6 +2057,10 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -2055,6 +2057,10 @@ class FusedCFuncDefNode(StatListNode):
node
.
entry
.
fused_cfunction
=
self
node
.
entry
.
fused_cfunction
=
self
self
.
stats
=
self
.
nodes
[:]
if
self
.
py_func
:
self
.
stats
.
append
(
self
.
py_func
)
def
copy_cdefs
(
self
,
env
):
def
copy_cdefs
(
self
,
env
):
"""
"""
Gives a list of fused types and the parent environment, make copies
Gives a list of fused types and the parent environment, make copies
...
@@ -2067,7 +2073,16 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -2067,7 +2073,16 @@ class FusedCFuncDefNode(StatListNode):
# len(permutations))
# len(permutations))
# import pprint; pprint.pprint([d for cname, d in permutations])
# import pprint; pprint.pprint([d for cname, d in permutations])
env
.
cfunc_entries
.
remove
(
self
.
node
.
entry
)
if
self
.
node
.
entry
in
env
.
cfunc_entries
:
env
.
cfunc_entries
.
remove
(
self
.
node
.
entry
)
# Prevent copying of the python function
self
.
py_func
=
self
.
node
.
py_func
self
.
node
.
py_func
=
None
if
self
.
py_func
:
env
.
pyfunc_entries
.
remove
(
self
.
py_func
.
entry
)
fused_types
=
self
.
node
.
type
.
get_fused_types
()
for
cname
,
fused_to_specific
in
permutations
:
for
cname
,
fused_to_specific
in
permutations
:
copied_node
=
copy
.
deepcopy
(
self
.
node
)
copied_node
=
copy
.
deepcopy
(
self
.
node
)
...
@@ -2104,6 +2119,25 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -2104,6 +2119,25 @@ class FusedCFuncDefNode(StatListNode):
type
.
specialize_entry
(
entry
,
cname
)
type
.
specialize_entry
(
entry
,
cname
)
env
.
cfunc_entries
.
append
(
entry
)
env
.
cfunc_entries
.
append
(
entry
)
# If a cpdef, declare all specialized cpdefs
copied_node
.
declare_cpdef_wrapper
(
env
)
if
copied_node
.
py_func
:
env
.
pyfunc_entries
.
remove
(
copied_node
.
py_func
.
entry
)
type_strings
=
[
str
(
fused_to_specific
[
fused_type
])
for
fused_type
in
fused_types
]
if
len
(
type_strings
)
==
1
:
sigstring
=
type_strings
[
0
]
else
:
sigstring
=
'(%s)'
%
', '
.
join
(
type_strings
)
copied_node
.
py_func
.
specialized_signature_string
=
sigstring
copied_node
.
py_func
.
fused_py_func
=
self
.
py_func
e
=
copied_node
.
py_func
.
entry
e
.
pymethdef_cname
=
PyrexTypes
.
get_fused_cname
(
cname
,
e
.
pymethdef_cname
)
num_errors
=
Errors
.
num_errors
num_errors
=
Errors
.
num_errors
transform
=
ParseTreeTransforms
.
ReplaceFusedTypeChecks
(
transform
=
ParseTreeTransforms
.
ReplaceFusedTypeChecks
(
copied_node
.
local_scope
)
copied_node
.
local_scope
)
...
@@ -2112,6 +2146,18 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -2112,6 +2146,18 @@ class FusedCFuncDefNode(StatListNode):
if
Errors
.
num_errors
>
num_errors
:
if
Errors
.
num_errors
>
num_errors
:
break
break
if
self
.
py_func
:
self
.
py_func
.
specialized_cpdefs
=
[
n
.
py_func
for
n
in
self
.
nodes
]
self
.
py_func
.
fused_args_positions
=
[
i
for
i
,
arg
in
enumerate
(
self
.
node
.
type
.
args
)
if
arg
.
is_fused
]
from
Cython.Compiler
import
TreeFragment
fragment
=
TreeFragment
.
TreeFragment
(
u"""
raise ValueError("Index the function to get a specialized version")
"""
,
level
=
'function'
)
self
.
py_func
.
body
=
fragment
.
substitute
()
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
):
for
stat
in
self
.
stats
:
for
stat
in
self
.
stats
:
# print stat.entry, stat.entry.used
# print stat.entry, stat.entry.used
...
@@ -2167,6 +2213,12 @@ class DefNode(FuncDefNode):
...
@@ -2167,6 +2213,12 @@ class DefNode(FuncDefNode):
# when the def statement is inside a Python class definition.
# when the def statement is inside a Python class definition.
#
#
# assmt AssignmentNode Function construction/assignment
# assmt AssignmentNode Function construction/assignment
#
# fused_py_func DefNode The original fused cpdef DefNode
# (in case this is a specialization)
# specialized_cpdefs [DefNode] list of specialized cpdef DefNodes
# fused_args_positions [int] list of the positions of the
# arguments with fused types
child_attrs
=
[
"args"
,
"star_arg"
,
"starstar_arg"
,
"body"
,
"decorators"
]
child_attrs
=
[
"args"
,
"star_arg"
,
"starstar_arg"
,
"body"
,
"decorators"
]
...
@@ -2186,6 +2238,10 @@ class DefNode(FuncDefNode):
...
@@ -2186,6 +2238,10 @@ class DefNode(FuncDefNode):
starstar_arg
=
None
starstar_arg
=
None
doc
=
None
doc
=
None
fused_py_func
=
False
specialized_cpdefs
=
None
fused_args_positions
=
None
def
__init__
(
self
,
pos
,
**
kwds
):
def
__init__
(
self
,
pos
,
**
kwds
):
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
k
=
rk
=
r
=
0
k
=
rk
=
r
=
0
...
@@ -2506,11 +2562,22 @@ class DefNode(FuncDefNode):
...
@@ -2506,11 +2562,22 @@ class DefNode(FuncDefNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
local_scope
.
directives
=
env
.
directives
self
.
local_scope
.
directives
=
env
.
directives
self
.
analyse_default_values
(
env
)
self
.
analyse_default_values
(
env
)
if
self
.
specialized_cpdefs
:
for
arg
in
self
.
args
+
self
.
local_scope
.
arg_entries
:
arg
.
needs_conversion
=
False
arg
.
type
=
py_object_type
self
.
local_scope
.
entries
.
clear
()
del
self
.
local_scope
.
var_entries
[:]
if
self
.
needs_assignment_synthesis
(
env
):
if
self
.
needs_assignment_synthesis
(
env
):
# Shouldn't we be doing this at the module level too?
# Shouldn't we be doing this at the module level too?
self
.
synthesize_assignment_node
(
env
)
self
.
synthesize_assignment_node
(
env
)
def
needs_assignment_synthesis
(
self
,
env
,
code
=
None
):
def
needs_assignment_synthesis
(
self
,
env
,
code
=
None
):
if
self
.
specialized_cpdefs
:
return
True
if
self
.
no_assignment_synthesis
:
if
self
.
no_assignment_synthesis
:
return
False
return
False
# Should enable for module level as well, that will require more testing...
# Should enable for module level as well, that will require more testing...
...
@@ -2534,7 +2601,11 @@ class DefNode(FuncDefNode):
...
@@ -2534,7 +2601,11 @@ class DefNode(FuncDefNode):
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
)
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
)
else
:
else
:
rhs
=
ExprNodes
.
PyCFunctionNode
(
rhs
=
ExprNodes
.
PyCFunctionNode
(
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
,
binding
=
env
.
directives
[
'binding'
])
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
,
binding
=
env
.
directives
[
'binding'
],
specialized_cpdefs
=
self
.
specialized_cpdefs
,
fused_args_positions
=
self
.
fused_args_positions
)
if
env
.
is_py_class_scope
:
if
env
.
is_py_class_scope
:
if
not
self
.
is_staticmethod
and
not
self
.
is_classmethod
:
if
not
self
.
is_staticmethod
and
not
self
.
is_classmethod
:
...
@@ -2573,8 +2644,15 @@ class DefNode(FuncDefNode):
...
@@ -2573,8 +2644,15 @@ class DefNode(FuncDefNode):
if
mf
:
mf
+=
" "
if
mf
:
mf
+=
" "
header
=
"static %s%s(%s)"
%
(
mf
,
dc
,
arg_code
)
header
=
"static %s%s(%s)"
%
(
mf
,
dc
,
arg_code
)
code
.
putln
(
"%s; /*proto*/"
%
header
)
code
.
putln
(
"%s; /*proto*/"
%
header
)
if
proto_only
:
if
proto_only
:
if
self
.
fused_py_func
:
# If we are the specialized version of the cpdef, we still
# want the prototype for the "fused cpdef", in case we're
# checking to see if our method was overridden in Python
self
.
fused_py_func
.
generate_function_header
(
code
,
with_pymethdef
,
proto_only
=
True
)
return
return
if
(
Options
.
docstrings
and
self
.
entry
.
doc
and
if
(
Options
.
docstrings
and
self
.
entry
.
doc
and
not
self
.
entry
.
scope
.
is_property_scope
and
not
self
.
entry
.
scope
.
is_property_scope
and
(
not
self
.
entry
.
is_special
or
self
.
entry
.
wrapperbase_cname
)):
(
not
self
.
entry
.
is_special
or
self
.
entry
.
wrapperbase_cname
)):
...
@@ -2588,7 +2666,7 @@ class DefNode(FuncDefNode):
...
@@ -2588,7 +2666,7 @@ class DefNode(FuncDefNode):
if
self
.
entry
.
is_special
:
if
self
.
entry
.
is_special
:
code
.
putln
(
code
.
putln
(
"struct wrapperbase %s;"
%
self
.
entry
.
wrapperbase_cname
)
"struct wrapperbase %s;"
%
self
.
entry
.
wrapperbase_cname
)
if
with_pymethdef
:
if
with_pymethdef
or
self
.
fused_py_func
:
code
.
put
(
code
.
put
(
"static PyMethodDef %s = "
%
"static PyMethodDef %s = "
%
self
.
entry
.
pymethdef_cname
)
self
.
entry
.
pymethdef_cname
)
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
2f20794c
...
@@ -1318,20 +1318,21 @@ if VALUE is not None:
...
@@ -1318,20 +1318,21 @@ if VALUE is not None:
# ---------------------------------------
# ---------------------------------------
return
property
return
property
class
AnalyseExpressionsTransform
(
CythonTransform
):
class
AnalyseExpressionsTransform
(
EnvTransform
):
nested_index_node
=
False
def
visit_ModuleNode
(
self
,
node
):
def
visit_ModuleNode
(
self
,
node
):
self
.
env_stack
=
[
node
.
scope
]
node
.
scope
.
infer_types
()
node
.
scope
.
infer_types
()
node
.
body
.
analyse_expressions
(
node
.
scope
)
node
.
body
.
analyse_expressions
(
node
.
scope
)
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
return
node
return
node
def
visit_FuncDefNode
(
self
,
node
):
def
visit_FuncDefNode
(
self
,
node
):
self
.
env_stack
.
append
(
node
.
local_scope
)
node
.
local_scope
.
infer_types
()
node
.
local_scope
.
infer_types
()
node
.
body
.
analyse_expressions
(
node
.
local_scope
)
node
.
body
.
analyse_expressions
(
node
.
local_scope
)
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
self
.
env_stack
.
pop
()
return
node
return
node
def
visit_ScopedExprNode
(
self
,
node
):
def
visit_ScopedExprNode
(
self
,
node
):
...
@@ -1347,14 +1348,23 @@ class AnalyseExpressionsTransform(CythonTransform):
...
@@ -1347,14 +1348,23 @@ class AnalyseExpressionsTransform(CythonTransform):
argument types with the Attribute- or NameNode referring to the
argument types with the Attribute- or NameNode referring to the
function. We then need to copy over the specialization properties to
function. We then need to copy over the specialization properties to
the attribute or name node.
the attribute or name node.
Because the indexing might be a Python indexing operation on a fused
function, or (usually) a Cython indexing operation, we need to
re-analyse the types.
"""
"""
self
.
visit_Node
(
node
)
self
.
visit_Node
(
node
)
type
=
node
.
type
type
=
node
.
type
if
type
.
is_cfunction
and
node
.
base
.
type
.
is_fused
:
if
node
.
is_fused_index
:
node
.
base
.
type
=
node
.
type
if
node
.
type
is
PyrexTypes
.
error_type
:
node
.
base
.
entry
=
node
.
type
.
entry
node
.
type
=
PyrexTypes
.
error_type
node
=
node
.
base
else
:
node
.
base
.
type
=
node
.
type
node
.
base
.
entry
=
getattr
(
node
,
'entry'
,
None
)
or
node
.
type
.
entry
node
=
node
.
base
node
.
analyse_types
(
self
.
env_stack
[
-
1
])
return
node
return
node
...
...
Cython/Compiler/PyrexTypes.py
View file @
2f20794c
...
@@ -666,15 +666,15 @@ class FusedType(PyrexType):
...
@@ -666,15 +666,15 @@ class FusedType(PyrexType):
See http://wiki.cython.org/enhancements/fusedtypes
See http://wiki.cython.org/enhancements/fusedtypes
types [
CSimpleBaseTypeNode]
is the list of types to be fused
types [
PyrexType]
is the list of types to be fused
name str the name of the ctypedef
name str the name of the ctypedef
"""
"""
is_fused
=
1
is_fused
=
1
name
=
None
def
__init__
(
self
,
types
):
def
__init__
(
self
,
types
,
name
=
None
):
self
.
types
=
types
self
.
types
=
types
self
.
name
=
name
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
dll_linkage
=
None
,
pyrex
=
0
):
...
@@ -2079,7 +2079,8 @@ class CFuncType(CType):
...
@@ -2079,7 +2079,8 @@ class CFuncType(CType):
if
entry
.
is_cmethod
:
if
entry
.
is_cmethod
:
entry
.
cname
=
entry
.
name
entry
.
cname
=
entry
.
name
if
entry
.
is_inherited
:
if
entry
.
is_inherited
:
entry
.
cname
=
"%s.%s"
%
(
Naming
.
obj_base_cname
,
entry
.
cname
)
entry
.
cname
=
StringEncoding
.
EncodedString
(
"%s.%s"
%
(
Naming
.
obj_base_cname
,
entry
.
cname
))
else
:
else
:
entry
.
cname
=
get_fused_cname
(
cname
,
entry
.
cname
)
entry
.
cname
=
get_fused_cname
(
cname
,
entry
.
cname
)
...
@@ -2092,7 +2093,8 @@ def get_fused_cname(fused_cname, orig_cname):
...
@@ -2092,7 +2093,8 @@ def get_fused_cname(fused_cname, orig_cname):
Given the fused cname id and an original cname, return a specialized cname
Given the fused cname id and an original cname, return a specialized cname
"""
"""
assert
fused_cname
and
orig_cname
assert
fused_cname
and
orig_cname
return
'%s%s%s'
%
(
Naming
.
fused_func_prefix
,
fused_cname
,
orig_cname
)
return
StringEncoding
.
EncodedString
(
'%s%s%s'
%
(
Naming
.
fused_func_prefix
,
fused_cname
,
orig_cname
))
def
get_all_specific_permutations
(
fused_types
,
id
=
""
,
f2s
=
()):
def
get_all_specific_permutations
(
fused_types
,
id
=
""
,
f2s
=
()):
fused_type
=
fused_types
[
0
]
fused_type
=
fused_types
[
0
]
...
@@ -2631,6 +2633,17 @@ c_size_t_ptr_type = CPtrType(c_size_t_type)
...
@@ -2631,6 +2633,17 @@ c_size_t_ptr_type = CPtrType(c_size_t_type)
c_py_buffer_type
=
CStructOrUnionType
(
"Py_buffer"
,
"struct"
,
None
,
1
,
"Py_buffer"
)
c_py_buffer_type
=
CStructOrUnionType
(
"Py_buffer"
,
"struct"
,
None
,
1
,
"Py_buffer"
)
c_py_buffer_ptr_type
=
CPtrType
(
c_py_buffer_type
)
c_py_buffer_ptr_type
=
CPtrType
(
c_py_buffer_type
)
# Not sure whether the unsigned versions and 'long long' should be in there
# long long requires C99 and might be slow, and would always get preferred
# when specialization happens through calling and not indexing
cy_integral_type
=
FusedType
([
c_int_type
,
c_long_type
],
name
=
"integral"
)
# Omitting long double as it might be slow
cy_floating_type
=
FusedType
([
c_float_type
,
c_double_type
],
name
=
"floating"
)
cy_numeric_type
=
FusedType
([
c_long_type
,
c_double_type
,
c_double_complex_type
],
name
=
"numeric"
)
error_type
=
ErrorType
()
error_type
=
ErrorType
()
unspecified_type
=
UnspecifiedType
()
unspecified_type
=
UnspecifiedType
()
...
...
Cython/Shadow.py
View file @
2f20794c
...
@@ -135,6 +135,9 @@ class PointerType(CythonType):
...
@@ -135,6 +135,9 @@ class PointerType(CythonType):
else
:
else
:
return
not
self
.
_items
and
not
value
.
_items
return
not
self
.
_items
and
not
value
.
_items
def
__repr__
(
self
):
return
"%s *"
%
(
self
.
_basetype
,)
class
ArrayType
(
PointerType
):
class
ArrayType
(
PointerType
):
def
__init__
(
self
):
def
__init__
(
self
):
...
@@ -218,13 +221,17 @@ def union(**members):
...
@@ -218,13 +221,17 @@ def union(**members):
class
typedef
(
CythonType
):
class
typedef
(
CythonType
):
def
__init__
(
self
,
type
):
def
__init__
(
self
,
type
,
name
=
None
):
self
.
_basetype
=
type
self
.
_basetype
=
type
self
.
name
=
name
def
__call__
(
self
,
*
arg
):
def
__call__
(
self
,
*
arg
):
value
=
cast
(
self
.
_basetype
,
*
arg
)
value
=
cast
(
self
.
_basetype
,
*
arg
)
return
value
return
value
def
__repr__
(
self
):
return
self
.
name
or
str
(
self
.
_basetype
)
class
_FusedType
(
CythonType
):
class
_FusedType
(
CythonType
):
def
__call__
(
self
,
type
,
value
):
def
__call__
(
self
,
type
,
value
):
...
@@ -235,6 +242,7 @@ def fused_type(*args):
...
@@ -235,6 +242,7 @@ def fused_type(*args):
if
not
args
:
if
not
args
:
raise
TypeError
(
"Expected at least one type as argument"
)
raise
TypeError
(
"Expected at least one type as argument"
)
# Find the numeric type with biggest rank if all types are numeric
rank
=
-
1
rank
=
-
1
for
type
in
args
:
for
type
in
args
:
if
type
not
in
(
py_int
,
py_long
,
py_float
,
py_complex
):
if
type
not
in
(
py_int
,
py_long
,
py_float
,
py_complex
):
...
@@ -251,13 +259,18 @@ def fused_type(*args):
...
@@ -251,13 +259,18 @@ def fused_type(*args):
return
_FusedType
()
return
_FusedType
()
py_int
=
int
def
_specialized_from_args
(
signatures
,
args
,
kwargs
):
"Perhaps this should be implemented in a TreeFragment in Cython code"
raise
Exception
(
"yet to be implemented"
)
py_int
=
typedef
(
int
,
"int"
)
try
:
try
:
py_long
=
long
py_long
=
typedef
(
long
,
"long"
)
except
NameError
:
# Py3
except
NameError
:
# Py3
py_long
=
int
py_long
=
typedef
(
int
,
"long"
)
py_float
=
float
py_float
=
typedef
(
float
,
"float"
)
py_complex
=
complex
py_complex
=
typedef
(
complex
,
"complex"
)
try
:
try
:
...
@@ -278,28 +291,39 @@ float_types = ['longdouble', 'double', 'float']
...
@@ -278,28 +291,39 @@ float_types = ['longdouble', 'double', 'float']
complex_types
=
[
'longdoublecomplex'
,
'doublecomplex'
,
'floatcomplex'
,
'complex'
]
complex_types
=
[
'longdoublecomplex'
,
'doublecomplex'
,
'floatcomplex'
,
'complex'
]
other_types
=
[
'bint'
,
'void'
]
other_types
=
[
'bint'
,
'void'
]
to_repr
=
{
'longlong'
:
'long long'
,
'longdouble'
:
'long double'
,
'longdoublecomplex'
:
'long double complex'
,
'doublecomplex'
:
'double complex'
,
'floatcomplex'
:
'float complex'
,
}.
get
gs
=
globals
()
gs
=
globals
()
for
name
in
int_types
:
for
name
in
int_types
:
gs
[
name
]
=
typedef
(
py_int
)
reprname
=
to_repr
(
name
,
name
)
gs
[
name
]
=
typedef
(
py_int
,
reprname
)
if
name
!=
'Py_UNICODE'
and
not
name
.
endswith
(
'size_t'
):
if
name
!=
'Py_UNICODE'
and
not
name
.
endswith
(
'size_t'
):
gs
[
'u'
+
name
]
=
typedef
(
py_int
)
gs
[
'u'
+
name
]
=
typedef
(
py_int
,
"unsigned "
+
reprname
)
gs
[
's'
+
name
]
=
typedef
(
py_int
)
gs
[
's'
+
name
]
=
typedef
(
py_int
,
"signed "
+
reprname
)
for
name
in
float_types
:
for
name
in
float_types
:
gs
[
name
]
=
typedef
(
py_float
)
gs
[
name
]
=
typedef
(
py_float
,
to_repr
(
name
,
name
)
)
for
name
in
complex_types
:
for
name
in
complex_types
:
gs
[
name
]
=
typedef
(
py_complex
)
gs
[
name
]
=
typedef
(
py_complex
,
to_repr
(
name
,
name
)
)
bint
=
typedef
(
bool
)
bint
=
typedef
(
bool
,
"bint"
)
void
=
typedef
(
int
)
void
=
typedef
(
int
,
"void"
)
for
t
in
int_types
+
float_types
+
complex_types
+
other_types
:
for
t
in
int_types
+
float_types
+
complex_types
+
other_types
:
for
i
in
range
(
1
,
4
):
for
i
in
range
(
1
,
4
):
gs
[
"%s_%s"
%
(
'p'
*
i
,
t
)]
=
globals
()[
t
].
_pointer
(
i
)
gs
[
"%s_%s"
%
(
'p'
*
i
,
t
)]
=
globals
()[
t
].
_pointer
(
i
)
void
=
typedef
(
None
)
void
=
typedef
(
None
,
"void"
)
NULL
=
p_void
(
0
)
NULL
=
p_void
(
0
)
type_ordering
=
[
py_int
,
py_long
,
py_float
,
py_complex
]
integral
=
floating
=
numeric
=
_FusedType
()
\ No newline at end of file
type_ordering
=
[
py_int
,
py_long
,
py_float
,
py_complex
]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment