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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
6fff2b59
Commit
6fff2b59
authored
Oct 06, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
82f49e1e
b016353f
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
472 additions
and
57 deletions
+472
-57
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+6
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+37
-6
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+18
-4
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+168
-17
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+74
-25
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+16
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+8
-0
Cython/Shadow.py
Cython/Shadow.py
+145
-5
No files found.
Cython/Compiler/CythonScope.py
View file @
6fff2b59
...
...
@@ -16,5 +16,11 @@ class CythonScope(ModuleScope):
defining
=
1
,
cname
=
'<error>'
)
def
lookup_type
(
self
,
name
):
# This function should go away when types are all first-level objects.
type
=
parse_basic_type
(
name
)
if
type
:
return
type
def
create_cython_scope
(
context
):
return
CythonScope
(
context
)
Cython/Compiler/ExprNodes.py
View file @
6fff2b59
...
...
@@ -569,6 +569,9 @@ class ExprNode(Node):
# reference, or temporary.
return
self
.
result_in_temp
()
def
as_cython_attribute
(
self
):
return
None
class
NewTempExprNode
(
ExprNode
):
backwards_compatible_result
=
None
...
...
@@ -780,6 +783,9 @@ class StringNode(ConstNode):
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
def
analyse_as_type
(
self
,
env
):
type
=
PyrexTypes
.
parse_basic_type
(
self
.
value
)
if
type
is
not
None
:
return
type
from
TreeFragment
import
TreeFragment
pos
=
(
self
.
pos
[
0
],
self
.
pos
[
1
],
self
.
pos
[
2
]
-
7
)
declaration
=
TreeFragment
(
u"sizeof(%s)"
%
self
.
value
,
name
=
pos
[
0
].
filename
,
initial_pos
=
pos
)
...
...
@@ -914,7 +920,8 @@ class NameNode(AtomicExprNode):
# entry Entry Symbol table entry
# interned_cname string
is_name
=
1
is_name
=
True
is_cython_module
=
False
skip_assignment_decref
=
False
entry
=
None
...
...
@@ -960,8 +967,9 @@ class NameNode(AtomicExprNode):
return
None
def
analyse_as_type
(
self
,
env
):
if
self
.
name
in
PyrexTypes
.
rank_to_type_name
:
return
PyrexTypes
.
simple_c_type
(
1
,
0
,
self
.
name
)
type
=
PyrexTypes
.
parse_basic_type
(
self
.
name
)
if
type
:
return
type
entry
=
self
.
entry
if
not
entry
:
entry
=
env
.
lookup
(
self
.
name
)
...
...
@@ -1870,6 +1878,21 @@ class SimpleCallNode(CallNode):
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_as_type
(
self
,
env
):
attr
=
self
.
function
.
as_cython_attribute
()
if
attr
==
'pointer'
:
if
len
(
self
.
args
)
!=
1
:
error
(
self
.
args
.
pos
,
"only one type allowed."
)
else
:
type
=
self
.
args
[
0
].
analyse_as_type
(
env
)
if
not
type
:
error
(
self
.
args
[
0
].
pos
,
"Unknown type"
)
else
:
return
PyrexTypes
.
CPtrType
(
type
)
def
explicit_args_kwds
(
self
):
return
self
.
args
,
None
def
analyse_types
(
self
,
env
):
function
=
self
.
function
function
.
is_called
=
1
...
...
@@ -2099,6 +2122,12 @@ class GeneralCallNode(CallNode):
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
explicit_args_kwds
(
self
):
if
self
.
starstar_arg
or
not
isinstance
(
self
.
positional_args
,
TupleNode
):
raise
PostParseError
(
self
.
pos
,
'Compile-time keyword arguments must be explicit.'
)
return
self
.
positional_args
.
args
,
self
.
keyword_args
def
analyse_types
(
self
,
env
):
self
.
function
.
analyse_types
(
env
)
self
.
positional_args
.
analyse_types
(
env
)
...
...
@@ -2201,6 +2230,10 @@ class AttributeNode(ExprNode):
is_called
=
0
needs_none_check
=
True
def
as_cython_attribute
(
self
):
if
isinstance
(
self
.
obj
,
NameNode
)
and
self
.
obj
.
is_cython_module
:
return
self
.
attribute
def
coerce_to
(
self
,
dst_type
,
env
):
# If coercing to a generic pyobject and this is a cpdef function
# we can create the corresponding attribute
...
...
@@ -2278,9 +2311,7 @@ class AttributeNode(ExprNode):
def
analyse_as_type
(
self
,
env
):
module_scope
=
self
.
obj
.
analyse_as_module
(
env
)
if
module_scope
:
entry
=
module_scope
.
lookup_here
(
self
.
attribute
)
if
entry
and
entry
.
is_type
:
return
entry
.
type
return
module_scope
.
lookup_type
(
self
.
attribute
)
return
None
def
analyse_as_extension_type
(
self
,
env
):
...
...
Cython/Compiler/Main.py
View file @
6fff2b59
...
...
@@ -74,12 +74,13 @@ class Context:
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'Includes'
))
self
.
include_directories
=
include_directories
+
[
standard_include_path
]
def
create_pipeline
(
self
,
pxd
):
def
create_pipeline
(
self
,
pxd
,
py
=
False
):
from
Visitor
import
PrintTree
from
ParseTreeTransforms
import
WithTransform
,
NormalizeTree
,
PostParse
,
PxdPostParse
from
ParseTreeTransforms
import
AnalyseDeclarationsTransform
,
AnalyseExpressionsTransform
from
ParseTreeTransforms
import
CreateClosureClasses
,
MarkClosureVisitor
,
DecoratorTransform
from
ParseTreeTransforms
import
InterpretCompilerDirectives
,
TransformBuiltinMethods
from
ParseTreeTransforms
import
AlignFunctionDefinitions
from
AutoDocTransforms
import
EmbedSignature
from
Optimize
import
FlattenInListTransform
,
SwitchTransform
,
FinalOptimizePhase
from
Buffer
import
IntroduceBufferAuxiliaryVars
...
...
@@ -92,10 +93,16 @@ class Context:
_check_c_classes
=
check_c_classes
_specific_post_parse
=
None
if
py
and
not
pxd
:
_align_function_definitions
=
AlignFunctionDefinitions
(
self
)
else
:
_align_function_definitions
=
None
return
[
NormalizeTree
(
self
),
PostParse
(
self
),
_specific_post_parse
,
_align_function_definitions
,
InterpretCompilerDirectives
(
self
,
self
.
pragma_overrides
),
FlattenInListTransform
(),
WithTransform
(
self
),
...
...
@@ -112,7 +119,7 @@ class Context:
# CreateClosureClasses(context),
]
def
create_pyx_pipeline
(
self
,
options
,
result
):
def
create_pyx_pipeline
(
self
,
options
,
result
,
py
=
False
):
def
generate_pyx_code
(
module_node
):
module_node
.
process_implementation
(
options
,
result
)
result
.
compilation_source
=
module_node
.
compilation_source
...
...
@@ -134,7 +141,7 @@ class Context:
return
([
create_parse
(
self
),
]
+
self
.
create_pipeline
(
pxd
=
False
)
+
[
]
+
self
.
create_pipeline
(
pxd
=
False
,
py
=
py
)
+
[
inject_pxd_code
,
generate_pyx_code
,
])
...
...
@@ -155,6 +162,10 @@ class Context:
ExtractPxdCode
(
self
),
]
def
create_py_pipeline
(
self
,
options
,
result
):
return
self
.
create_pyx_pipeline
(
options
,
result
,
py
=
True
)
def
process_pxd
(
self
,
source_desc
,
scope
,
module_name
):
pipeline
=
self
.
create_pxd_pipeline
(
scope
,
module_name
)
result
=
self
.
run_pipeline
(
pipeline
,
source_desc
)
...
...
@@ -504,6 +515,9 @@ def run_pipeline(source, options, full_module_name = None):
result
=
create_default_resultobj
(
source
,
options
)
# Get pipeline
if
source_desc
.
filename
.
endswith
(
".py"
):
pipeline
=
context
.
create_py_pipeline
(
options
,
result
)
else
:
pipeline
=
context
.
create_pyx_pipeline
(
options
,
result
)
context
.
setup_errors
(
options
)
...
...
Cython/Compiler/Nodes.py
View file @
6fff2b59
...
...
@@ -412,7 +412,6 @@ class CNameDeclaratorNode(CDeclaratorNode):
elif
base_type
.
is_void
:
error
(
self
.
pos
,
"Use spam() rather than spam(void) to declare a function with no arguments."
)
else
:
print
"here"
self
.
name
=
base_type
.
declaration_code
(
""
,
for_display
=
1
,
pyrex
=
1
)
base_type
=
py_object_type
self
.
type
=
base_type
...
...
@@ -569,9 +568,12 @@ class CArgDeclNode(Node):
is_self_arg
=
0
is_generic
=
1
type
=
None
name_declarator
=
None
def
analyse
(
self
,
env
,
nonempty
=
0
):
#print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
if
self
.
type
is
None
:
# The parser may missinterpret names as types...
# We fix that here.
if
isinstance
(
self
.
declarator
,
CNameDeclaratorNode
)
and
self
.
declarator
.
name
==
''
:
...
...
@@ -586,6 +588,8 @@ class CArgDeclNode(Node):
if
self
.
base_type
.
arg_name
:
self
.
declarator
.
name
=
self
.
base_type
.
arg_name
return
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
nonempty
)
else
:
return
self
.
name_declarator
,
self
.
type
def
annotate
(
self
,
code
):
if
self
.
default
:
...
...
@@ -602,6 +606,14 @@ class CBaseTypeNode(Node):
pass
class
CAnalysedBaseTypeNode
(
Node
):
# type type
child_attrs
=
[]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
return
self
.
type
class
CSimpleBaseTypeNode
(
CBaseTypeNode
):
# name string
# module_path [string] Qualifying name components
...
...
@@ -1429,6 +1441,8 @@ class DefNode(FuncDefNode):
reqd_kw_flags_cname
=
"0"
is_wrapper
=
0
decorators
=
None
entry
=
None
def
__init__
(
self
,
pos
,
**
kwds
):
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
...
...
@@ -1444,7 +1458,44 @@ class DefNode(FuncDefNode):
self
.
num_required_kw_args
=
rk
self
.
num_required_args
=
r
entry
=
None
def
as_cfunction
(
self
,
cfunc
):
if
self
.
star_arg
:
error
(
self
.
star_arg
.
pos
,
"cdef function cannot have star argument"
)
if
self
.
starstar_arg
:
error
(
self
.
starstar_arg
.
pos
,
"cdef function cannot have starstar argument"
)
if
len
(
self
.
args
)
!=
len
(
cfunc
.
type
.
args
)
or
cfunc
.
type
.
has_varargs
:
error
(
self
.
pos
,
"wrong number of arguments"
)
error
(
declarator
.
pos
,
"previous declaration here"
)
for
formal_arg
,
type_arg
in
zip
(
self
.
args
,
cfunc
.
type
.
args
):
name_declarator
,
type
=
formal_arg
.
analyse
(
cfunc
.
scope
,
nonempty
=
1
)
if
type
is
PyrexTypes
.
py_object_type
or
formal_arg
.
is_self
:
formal_arg
.
type
=
type_arg
.
type
formal_arg
.
name_declarator
=
name_declarator
import
ExprNodes
if
cfunc
.
type
.
exception_value
is
None
:
exception_value
=
None
else
:
exception_value
=
ExprNodes
.
ConstNode
(
self
.
pos
,
value
=
cfunc
.
type
.
exception_value
,
type
=
cfunc
.
type
.
return_type
)
declarator
=
CFuncDeclaratorNode
(
self
.
pos
,
base
=
CNameDeclaratorNode
(
self
.
pos
,
name
=
self
.
name
,
cname
=
None
),
args
=
self
.
args
,
has_varargs
=
False
,
exception_check
=
cfunc
.
type
.
exception_check
,
exception_value
=
exception_value
,
with_gil
=
cfunc
.
type
.
with_gil
,
nogil
=
cfunc
.
type
.
nogil
)
return
CFuncDefNode
(
self
.
pos
,
modifiers
=
[],
base_type
=
CAnalysedBaseTypeNode
(
self
.
pos
,
type
=
cfunc
.
type
.
return_type
),
declarator
=
declarator
,
body
=
self
.
body
,
doc
=
self
.
doc
,
overridable
=
cfunc
.
type
.
is_overridable
,
type
=
cfunc
.
type
,
with_gil
=
cfunc
.
type
.
with_gil
,
nogil
=
cfunc
.
type
.
nogil
,
visibility
=
'private'
,
api
=
False
)
def
analyse_declarations
(
self
,
env
):
if
'locals'
in
env
.
directives
:
...
...
@@ -2235,6 +2286,43 @@ class PyClassDefNode(ClassDefNode):
bases
=
bases
,
dict
=
self
.
dict
,
doc
=
doc_node
)
self
.
target
=
ExprNodes
.
NameNode
(
pos
,
name
=
name
)
def
as_cclass
(
self
):
"""
Return this node as if it were declared as an extension class"
"""
bases
=
self
.
classobj
.
bases
.
args
if
len
(
bases
)
==
0
:
base_class_name
=
None
base_class_module
=
None
elif
len
(
bases
)
==
1
:
base
=
bases
[
0
]
path
=
[]
while
isinstance
(
base
,
ExprNodes
.
AttributeNode
):
path
.
insert
(
0
,
base
.
attribute
)
base
=
base
.
obj
if
isinstance
(
base
,
ExprNodes
.
NameNode
):
path
.
insert
(
0
,
base
.
name
)
base_class_name
=
path
[
-
1
]
if
len
(
path
)
>
1
:
base_class_module
=
u'.'
.
join
(
path
[:
-
1
])
else
:
base_class_module
=
None
else
:
error
(
self
.
classobj
.
bases
.
args
.
pos
,
"Invalid base class"
)
else
:
error
(
self
.
classobj
.
bases
.
args
.
pos
,
"C class may only have one base class"
)
return
None
return
CClassDefNode
(
self
.
pos
,
visibility
=
'private'
,
module_name
=
None
,
class_name
=
self
.
name
,
base_class_module
=
base_class_module
,
base_class_name
=
base_class_name
,
body
=
self
.
body
,
in_pxd
=
False
,
doc
=
self
.
doc
)
def
create_scope
(
self
,
env
):
genv
=
env
while
env
.
is_py_class_scope
or
env
.
is_c_class_scope
:
...
...
@@ -2297,6 +2385,10 @@ class CClassDefNode(ClassDefNode):
child_attrs
=
[
"body"
]
buffer_defaults_node
=
None
buffer_defaults_pos
=
None
typedef_flag
=
False
api
=
False
objstruct_name
=
None
typeobj_name
=
None
def
analyse_declarations
(
self
,
env
):
#print "CClassDefNode.analyse_declarations:", self.class_name
...
...
@@ -2505,8 +2597,67 @@ class SingleAssignmentNode(AssignmentNode):
child_attrs
=
[
"lhs"
,
"rhs"
]
first
=
False
declaration_only
=
False
def
analyse_declarations
(
self
,
env
):
import
ExprNodes
# handle declarations of the form x = cython.foo()
if
isinstance
(
self
.
rhs
,
ExprNodes
.
CallNode
):
func_name
=
self
.
rhs
.
function
.
as_cython_attribute
()
if
func_name
:
args
,
kwds
=
self
.
rhs
.
explicit_args_kwds
()
if
func_name
in
[
'declare'
,
'typedef'
]:
self
.
declaration_only
=
True
if
len
(
args
)
!=
1
or
kwds
is
not
None
:
error
(
rhs
.
pos
,
"Can only declare one type at a time."
)
return
type
=
args
[
0
].
analyse_as_type
(
env
)
if
type
is
None
:
error
(
args
[
0
].
pos
,
"Unknown type"
)
return
lhs
=
self
.
lhs
if
func_name
==
'declare'
:
if
isinstance
(
lhs
,
ExprNodes
.
NameNode
):
vars
=
[(
lhs
.
name
,
lhs
.
pos
)]
elif
isinstance
(
lhs
,
ExprNodes
.
TupleNode
):
vars
=
[(
var
.
name
,
var
.
pos
)
for
var
in
lhs
.
args
]
else
:
error
(
lhs
.
pos
,
"Invalid declaration"
)
return
for
var
,
pos
in
vars
:
env
.
declare_var
(
var
,
type
,
pos
,
is_cdef
=
True
)
else
:
if
not
isinstance
(
lhs
,
ExprNodes
.
NameNode
):
error
(
lhs
.
pos
,
"Invalid declaration."
)
env
.
declare_typedef
(
lhs
.
name
,
type
,
self
.
pos
,
'private'
)
elif
func_name
in
[
'struct'
,
'union'
]:
self
.
declaration_only
=
True
if
len
(
args
)
>
0
or
kwds
is
None
:
error
(
rhs
.
pos
,
"Struct or union members must be given by name."
)
return
members
=
[]
for
member
,
type_node
in
kwds
.
key_value_pairs
:
type
=
type_node
.
analyse_as_type
(
env
)
if
type
is
None
:
error
(
type_node
.
pos
,
"Unknown type"
)
else
:
members
.
append
((
member
.
value
,
type
,
member
.
pos
))
if
len
(
members
)
<
len
(
kwds
.
key_value_pairs
):
return
if
not
isinstance
(
self
.
lhs
,
ExprNodes
.
NameNode
):
error
(
self
.
lhs
.
pos
,
"Invalid declaration."
)
name
=
self
.
lhs
.
name
scope
=
StructOrUnionScope
(
name
)
env
.
declare_struct_or_union
(
name
,
func_name
,
scope
,
False
,
self
.
rhs
.
pos
)
for
member
,
type
,
pos
in
members
:
scope
.
declare_var
(
member
,
type
,
pos
)
if
self
.
declaration_only
:
return
else
:
self
.
lhs
.
analyse_target_declaration
(
env
)
def
analyse_types
(
self
,
env
,
use_temp
=
0
):
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
6fff2b59
...
...
@@ -313,11 +313,19 @@ class InterpretCompilerDirectives(CythonTransform):
def
visit_SingleAssignmentNode
(
self
,
node
):
if
(
isinstance
(
node
.
rhs
,
ImportNode
)
and
node
.
rhs
.
module_name
.
value
==
u'cython'
):
self
.
cython_module_names
.
add
(
node
.
lhs
.
name
)
node
=
CImportStatNode
(
node
.
pos
,
module_name
=
u'cython'
,
as_name
=
node
.
lhs
.
name
)
self
.
visit_CImportStatNode
(
node
)
else
:
self
.
visitchildren
(
node
)
return
node
def
visit_NameNode
(
self
,
node
):
if
node
.
name
in
self
.
cython_module_names
:
node
.
is_cython_module
=
True
return
node
def
visit_Node
(
self
,
node
):
self
.
visitchildren
(
node
)
return
node
...
...
@@ -339,15 +347,7 @@ class InterpretCompilerDirectives(CythonTransform):
if
optname
:
optiontype
=
Options
.
option_types
.
get
(
optname
)
if
optiontype
:
if
isinstance
(
node
,
SimpleCallNode
):
args
=
node
.
args
kwds
=
None
else
:
if
node
.
starstar_arg
or
not
isinstance
(
node
.
positional_args
,
TupleNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
'Compile-time keyword arguments must be explicit.'
%
optname
)
args
=
node
.
positional_args
.
args
kwds
=
node
.
keyword_args
args
,
kwds
=
node
.
explicit_args_kwds
()
if
optiontype
is
bool
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
...
...
@@ -574,6 +574,54 @@ class AnalyseExpressionsTransform(CythonTransform):
self
.
visitchildren
(
node
)
return
node
class
AlignFunctionDefinitions
(
CythonTransform
):
"""
This class takes the signatures from a .pxd file and applies them to
the def methods in a .py file.
"""
def
visit_ModuleNode
(
self
,
node
):
self
.
scope
=
node
.
scope
self
.
visitchildren
(
node
)
return
node
def
visit_PyClassDefNode
(
self
,
node
):
pxd_def
=
self
.
scope
.
lookup
(
node
.
name
)
if
pxd_def
:
if
pxd_def
.
is_cclass
:
return
self
.
visit_CClassDefNode
(
node
.
as_cclass
(),
pxd_def
)
else
:
error
(
node
.
pos
,
"'%s' redeclared"
%
node
.
name
)
error
(
pxd_def
.
pos
,
"previous declaration here"
)
return
None
self
.
visitchildren
(
node
)
return
node
def
visit_CClassDefNode
(
self
,
node
,
pxd_def
=
None
):
if
pxd_def
is
None
:
pxd_def
=
self
.
scope
.
lookup
(
node
.
class_name
)
if
pxd_def
:
outer_scope
=
self
.
scope
self
.
scope
=
pxd_def
.
type
.
scope
self
.
visitchildren
(
node
)
if
pxd_def
:
self
.
scope
=
outer_scope
return
node
def
visit_DefNode
(
self
,
node
):
pxd_def
=
self
.
scope
.
lookup
(
node
.
name
)
if
pxd_def
:
if
pxd_def
.
is_cfunction
:
node
=
node
.
as_cfunction
(
pxd_def
)
else
:
error
(
node
.
pos
,
"'%s' redeclared"
%
node
.
name
)
error
(
pxd_def
.
pos
,
"previous declaration here"
)
return
None
# Enable this when internal def functions are allowed.
# self.visitchildren(node)
return
node
class
MarkClosureVisitor
(
CythonTransform
):
needs_closure
=
False
...
...
@@ -638,24 +686,20 @@ class EnvTransform(CythonTransform):
class
TransformBuiltinMethods
(
EnvTransform
):
def
cython_attribute
(
self
,
node
):
if
(
isinstance
(
node
,
AttributeNode
)
and
isinstance
(
node
.
obj
,
NameNode
)
and
node
.
obj
.
name
in
self
.
cython_module_names
):
return
node
.
attribute
def
visit_ModuleNode
(
self
,
node
):
self
.
cython_module_names
=
node
.
cython_module_names
def
visit_SingleAssignmentNode
(
self
,
node
):
if
node
.
declaration_only
:
return
None
else
:
self
.
visitchildren
(
node
)
return
node
def
visit_AttributeNode
(
self
,
node
):
attribute
=
self
.
cython_attribute
(
node
)
attribute
=
node
.
as_cython_attribute
(
)
if
attribute
:
if
attribute
==
u'compiled'
:
node
=
BoolNode
(
node
.
pos
,
value
=
True
)
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython attribute"
%
function
)
error
(
node
.
pos
,
u"'%s' not a valid cython attribute"
%
attribute
)
return
node
def
visit_SimpleCallNode
(
self
,
node
):
...
...
@@ -671,7 +715,7 @@ class TransformBuiltinMethods(EnvTransform):
return
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
items
)
# cython.foo
function
=
self
.
cython_attribute
(
node
.
function
)
function
=
node
.
function
.
as_cython_attribute
(
)
if
function
:
if
function
==
u'cast'
:
if
len
(
node
.
args
)
!=
2
:
...
...
@@ -691,6 +735,11 @@ class TransformBuiltinMethods(EnvTransform):
node
=
SizeofTypeNode
(
node
.
function
.
pos
,
arg_type
=
type
)
else
:
node
=
SizeofVarNode
(
node
.
function
.
pos
,
operand
=
node
.
args
[
0
])
elif
function
==
'address'
:
if
len
(
node
.
args
)
!=
1
:
error
(
node
.
function
.
pos
,
u"sizeof takes exactly one argument"
%
function
)
else
:
node
=
AmpersandNode
(
node
.
function
.
pos
,
operand
=
node
.
args
[
0
])
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython language construct"
%
function
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
6fff2b59
...
...
@@ -1187,6 +1187,7 @@ modifiers_and_name_to_type = {
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
1
,
0
,
"long"
):
c_long_type
,
(
1
,
0
,
"longlong"
):
c_longlong_type
,
(
1
,
0
,
"bint"
):
c_bint_type
,
}
...
...
@@ -1211,6 +1212,21 @@ def simple_c_type(signed, longness, name):
# Returns None if arguments don't make sense.
return
modifiers_and_name_to_type
.
get
((
signed
,
longness
,
name
))
def
parse_basic_type
(
name
):
base
=
None
if
name
.
startswith
(
'p_'
):
base
=
parse_basic_type
(
name
[
2
:])
elif
name
.
startswith
(
'p'
):
base
=
parse_basic_type
(
name
[
1
:])
elif
name
.
endswith
(
'*'
):
base
=
parse_basic_type
(
name
[:
-
1
])
if
base
:
return
CPtrType
(
base
)
elif
name
.
startswith
(
'u'
):
return
simple_c_type
(
0
,
0
,
name
[
1
:])
else
:
return
simple_c_type
(
1
,
0
,
name
)
def
c_array_type
(
base_type
,
size
):
# Construct a C array type.
if
base_type
is
c_char_type
:
...
...
Cython/Compiler/Symtab.py
View file @
6fff2b59
...
...
@@ -56,6 +56,7 @@ class Entry:
# is_cmethod boolean Is a C method of an extension type
# is_unbound_cmethod boolean Is an unbound C method of an extension type
# is_type boolean Is a type definition
# is_cclass boolean Is an extension class
# is_const boolean Is a constant
# is_property boolean Is a property of an extension type:
# doc_cname string or None C const holding the docstring
...
...
@@ -108,6 +109,7 @@ class Entry:
is_cmethod = 0
is_unbound_cmethod = 0
is_type = 0
is_cclass = 0
is_const = 0
is_property = 0
doc_cname = None
...
...
@@ -501,6 +503,11 @@ class Scope:
entry = self.declare_var(name, py_object_type, None)
return entry
def lookup_type(self, name):
entry = self.lookup(name)
if entry and entry.is_type:
return entry.type
def add_string_const(self, value, identifier = False):
# Add an entry for a string constant.
if identifier:
...
...
@@ -989,6 +996,7 @@ class ModuleScope(Scope):
type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
entry = self.declare_type(name, type, pos, visibility = visibility,
defining = 0)
entry.is_cclass = True
if objstruct_cname:
type.objstruct_cname = objstruct_cname
elif not entry.in_cinclude:
...
...
Cython/Shadow.py
View file @
6fff2b59
...
...
@@ -6,17 +6,157 @@ def empty_decorator(x):
def
locals
(
**
arg_types
):
return
empty_decorator
# Emulated language constructs
def
cast
(
type
,
arg
):
# can/should we emulate anything here?
if
callable
(
type
):
return
type
(
arg
)
else
:
return
arg
def
sizeof
(
arg
):
# can/should we emulate anything here?
return
1
def
address
(
arg
):
return
pointer
(
type
(
arg
))([
arg
])
def
declare
(
type
):
if
callable
(
type
):
return
type
()
else
:
return
None
# Emulated types
class
CythonType
(
object
):
def
_pointer
(
self
,
n
=
1
):
for
i
in
range
(
n
):
self
=
pointer
(
self
)
return
self
def
__getitem__
(
self
,
ix
):
return
array
(
self
,
ix
)
class
PointerType
(
CythonType
):
def
__init__
(
self
,
value
=
None
):
if
isinstance
(
value
,
ArrayType
):
self
.
_items
=
[
cast
(
self
.
_basetype
,
a
)
for
a
in
value
.
_items
]
elif
isinstance
(
value
,
list
):
self
.
_items
=
[
cast
(
self
.
_basetype
,
a
)
for
a
in
value
]
elif
value
is
None
:
self
.
_items
=
[]
else
:
raise
ValueError
def
__getitem__
(
self
,
ix
):
if
ix
<
0
:
raise
IndexError
,
"negative indexing not allowed in C"
return
self
.
_items
[
ix
]
def
__setitem__
(
self
,
ix
,
value
):
if
ix
<
0
:
raise
IndexError
,
"negative indexing not allowed in C"
self
.
_items
[
ix
]
=
cast
(
self
.
_basetype
,
value
)
class
ArrayType
(
PointerType
):
def
__init__
(
self
):
self
.
_items
=
[
None
]
*
self
.
_n
class
StructType
(
CythonType
):
def
__init__
(
self
,
**
data
):
for
key
,
value
in
data
.
items
():
setattr
(
self
,
key
,
value
)
def
__setattr__
(
self
,
key
,
value
):
if
key
in
self
.
_members
:
self
.
__dict__
[
key
]
=
cast
(
self
.
_members
[
key
],
value
)
else
:
raise
AttributeError
,
"Struct has no member '%s'"
%
key
class
UnionType
(
CythonType
):
def
__init__
(
self
,
**
data
):
if
len
(
data
)
>
0
:
raise
AttributeError
,
"Union can only store one field at a time."
for
key
,
value
in
data
.
items
():
setattr
(
self
,
key
,
value
)
def
__setattr__
(
self
,
key
,
value
):
if
key
in
'__dict__'
:
CythonType
.
__setattr__
(
self
,
key
,
value
)
elif
key
in
self
.
_members
:
self
.
__dict__
=
{
key
:
cast
(
self
.
_members
[
key
],
value
)}
else
:
raise
AttributeError
,
"Union has no member '%s'"
%
key
def
pointer
(
basetype
):
class
PointerInstance
(
PointerType
):
_basetype
=
basetype
return
PointerInstance
def
array
(
basetype
,
n
):
class
ArrayInstance
(
ArrayType
):
_basetype
=
basetype
_n
=
n
return
ArrayInstance
def
struct
(
**
members
):
class
StructInstance
(
StructType
):
_members
=
members
for
key
in
members
.
keys
():
setattr
(
StructInstance
,
key
,
None
)
return
StructInstance
def
union
(
**
members
):
class
UnionInstance
(
UnionType
):
_members
=
members
for
key
in
members
.
keys
():
setattr
(
UnionInstance
,
key
,
None
)
return
UnionInstance
class
typedef
(
CythonType
):
def
__init__
(
self
,
type
):
self
.
_basetype
=
type
def
__call__
(
self
,
value
=
None
):
if
value
is
not
None
:
value
=
cast
(
self
.
_basetype
,
value
)
return
value
py_int
=
int
py_long
=
long
py_float
=
float
# They just have to exist...
int
=
long
=
char
=
bint
=
uint
=
ulong
=
longlong
=
ulonglong
=
Py_ssize_t
=
float
=
double
=
None
# Predefined types
int_types
=
[
'char'
,
'short'
,
'int'
,
'long'
,
'longlong'
,
'Py_ssize_t'
]
float_types
=
[
'double'
,
'float'
]
other_types
=
[
'bint'
,
'Py_ssize_t'
,
'void'
]
gs
=
globals
()
for
name
in
int_types
:
gs
[
name
]
=
typedef
(
py_int
)
gs
[
'u'
+
name
]
=
typedef
(
py_int
)
double
=
float
=
typedef
(
py_float
)
bint
=
typedef
(
bool
)
void
=
typedef
(
int
)
for
t
in
int_types
+
float_types
+
other_types
:
for
i
in
range
(
1
,
4
):
gs
[
"%s_%s"
%
(
'p'
*
i
,
t
)]
=
globals
()[
t
].
_pointer
(
i
)
void
=
typedef
(
None
)
NULL
=
None
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