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
Kirill Smelkov
cython
Commits
0e55d5f3
Commit
0e55d5f3
authored
Mar 09, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for parse tree transformations.
parent
3ee07211
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
339 additions
and
15 deletions
+339
-15
Cython/Compiler/CmdLine.py
Cython/Compiler/CmdLine.py
+29
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+9
-0
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+4
-1
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+5
-3
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+177
-11
Cython/Compiler/Transform.py
Cython/Compiler/Transform.py
+115
-0
No files found.
Cython/Compiler/CmdLine.py
View file @
0e55d5f3
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
import
sys
import
sys
import
Options
import
Options
import
Transform
usage
=
"""
\
usage
=
"""
\
Cython (http://cython.org) is a compiler for code written in the
Cython (http://cython.org) is a compiler for code written in the
...
@@ -36,11 +37,36 @@ Options:
...
@@ -36,11 +37,36 @@ Options:
# -+, --cplus Use C++ compiler for compiling and linking
# -+, --cplus Use C++ compiler for compiling and linking
# Additional .o files to link may be supplied when using -X."""
# Additional .o files to link may be supplied when using -X."""
#The following options are very experimental and is used for plugging in code
#into different transform stages.
# -T phase:factory At the phase given, hand off the tree to the transform returned
# when calling factory without arguments. Factory should be fully
# specified (ie Module.SubModule.factory) and the containing module
# will be imported. This option can be repeated to add more transforms,
# transforms for the same phase will be used in the order they are given.
def
bad_usage
():
def
bad_usage
():
print
>>
sys
.
stderr
,
usage
print
>>
sys
.
stderr
,
usage
sys
.
exit
(
1
)
sys
.
exit
(
1
)
def
parse_command_line
(
args
):
def
parse_command_line
(
args
):
def
parse_add_transform
(
transforms
,
param
):
def
import_symbol
(
fqn
):
modsplitpt
=
fqn
.
rfind
(
"."
)
if
modsplitpt
==
-
1
:
bad_usage
()
modulename
=
fqn
[:
modsplitpt
]
symbolname
=
fqn
[
modsplitpt
+
1
:]
module
=
__import__
(
modulename
,
fromlist
=
[
symbolname
],
level
=
0
)
return
getattr
(
module
,
symbolname
)
stagename
,
factoryname
=
param
.
split
(
":"
)
if
not
stagename
in
Transform
.
PHASES
:
bad_usage
()
factory
=
import_symbol
(
factoryname
)
transform
=
factory
()
transforms
[
stagename
].
append
(
transform
)
from
Cython.Compiler.Main
import
\
from
Cython.Compiler.Main
import
\
CompilationOptions
,
default_options
CompilationOptions
,
default_options
...
@@ -93,6 +119,9 @@ def parse_command_line(args):
...
@@ -93,6 +119,9 @@ def parse_command_line(args):
Options
.
annotate
=
True
Options
.
annotate
=
True
elif
option
==
"--convert-range"
:
elif
option
==
"--convert-range"
:
Options
.
convert_range
=
True
Options
.
convert_range
=
True
elif
option
.
startswith
(
"-T"
):
parse_add_transform
(
options
.
transforms
,
get_param
(
option
))
# Note: this can occur multiple times, each time appends
else
:
else
:
bad_usage
()
bad_usage
()
else
:
else
:
...
...
Cython/Compiler/ExprNodes.py
View file @
0e55d5f3
...
@@ -31,6 +31,7 @@ class ExprNode(Node):
...
@@ -31,6 +31,7 @@ class ExprNode(Node):
# Cached result of subexpr_nodes()
# Cached result of subexpr_nodes()
result_ctype
=
None
result_ctype
=
None
type
=
None
# The Analyse Expressions phase for expressions is split
# The Analyse Expressions phase for expressions is split
# into two sub-phases:
# into two sub-phases:
...
@@ -165,6 +166,14 @@ class ExprNode(Node):
...
@@ -165,6 +166,14 @@ class ExprNode(Node):
saved_subexpr_nodes
=
None
saved_subexpr_nodes
=
None
is_temp
=
0
is_temp
=
0
def
get_child_attrs
(
self
):
"""Automatically provide the contents of subexprs as children, unless child_attr
has been declared. See Nodes.Node.get_child_accessors."""
if
self
.
child_attrs
!=
None
:
return
self
.
child_attr
elif
self
.
subexprs
!=
None
:
return
self
.
subexprs
def
not_implemented
(
self
,
method_name
):
def
not_implemented
(
self
,
method_name
):
print_call_chain
(
method_name
,
"not implemented"
)
###
print_call_chain
(
method_name
,
"not implemented"
)
###
raise
InternalError
(
raise
InternalError
(
...
...
Cython/Compiler/Main.py
View file @
0e55d5f3
...
@@ -18,6 +18,7 @@ from Symtab import BuiltinScope, ModuleScope
...
@@ -18,6 +18,7 @@ from Symtab import BuiltinScope, ModuleScope
import
Code
import
Code
from
Cython.Utils
import
replace_suffix
from
Cython.Utils
import
replace_suffix
from
Cython
import
Utils
from
Cython
import
Utils
import
Transform
verbose
=
0
verbose
=
0
...
@@ -236,6 +237,7 @@ class CompilationOptions:
...
@@ -236,6 +237,7 @@ class CompilationOptions:
include_path [string] Directories to search for include files
include_path [string] Directories to search for include files
output_file string Name of generated .c file
output_file string Name of generated .c file
generate_pxi boolean Generate .pxi file for public declarations
generate_pxi boolean Generate .pxi file for public declarations
transforms Transform.TransformSet Transforms to use on the parse tree
Following options are experimental and only used on MacOSX:
Following options are experimental and only used on MacOSX:
...
@@ -342,7 +344,8 @@ default_options = dict(
...
@@ -342,7 +344,8 @@ default_options = dict(
obj_only
=
1
,
obj_only
=
1
,
cplus
=
0
,
cplus
=
0
,
output_file
=
None
,
output_file
=
None
,
generate_pxi
=
0
)
generate_pxi
=
0
,
transforms
=
Transform
.
TransformSet
())
if
sys
.
platform
==
"mac"
:
if
sys
.
platform
==
"mac"
:
from
Cython.Mac.MacSystem
import
c_compile
,
c_link
,
CCompilerError
from
Cython.Mac.MacSystem
import
c_compile
,
c_link
,
CCompilerError
...
...
Cython/Compiler/ModuleNode.py
View file @
0e55d5f3
...
@@ -27,6 +27,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -27,6 +27,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# module_temp_cname string
# module_temp_cname string
# full_module_name string
# full_module_name string
children_attrs
=
[
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
Options
.
embed_pos_in_docstring
:
if
Options
.
embed_pos_in_docstring
:
env
.
doc
=
'File: %s (starting at line %s)'
%
Nodes
.
relative_position
(
self
.
pos
)
env
.
doc
=
'File: %s (starting at line %s)'
%
Nodes
.
relative_position
(
self
.
pos
)
...
@@ -46,7 +48,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -46,7 +48,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
self
.
has_imported_c_functions
():
if
self
.
has_imported_c_functions
():
self
.
module_temp_cname
=
env
.
allocate_temp_pyobject
()
self
.
module_temp_cname
=
env
.
allocate_temp_pyobject
()
env
.
release_temp
(
self
.
module_temp_cname
)
env
.
release_temp
(
self
.
module_temp_cname
)
self
.
generate_c_code
(
env
,
result
)
self
.
generate_c_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_api_code
(
env
,
result
)
self
.
generate_api_code
(
env
,
result
)
...
@@ -199,7 +201,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -199,7 +201,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
i_code
.
putln
(
"pass"
)
i_code
.
putln
(
"pass"
)
i_code
.
dedent
()
i_code
.
dedent
()
def
generate_c_code
(
self
,
env
,
result
):
def
generate_c_code
(
self
,
env
,
options
,
result
):
modules
=
self
.
referenced_modules
modules
=
self
.
referenced_modules
if
Options
.
annotate
:
if
Options
.
annotate
:
code
=
Annotate
.
AnnotationCCodeWriter
(
StringIO
())
code
=
Annotate
.
AnnotationCCodeWriter
(
StringIO
())
...
@@ -216,7 +218,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -216,7 +218,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_interned_name_decls
(
env
,
code
)
self
.
generate_interned_name_decls
(
env
,
code
)
self
.
generate_py_string_decls
(
env
,
code
)
self
.
generate_py_string_decls
(
env
,
code
)
self
.
generate_cached_builtins_decls
(
env
,
code
)
self
.
generate_cached_builtins_decls
(
env
,
code
)
self
.
body
.
generate_function_definitions
(
env
,
code
)
self
.
body
.
generate_function_definitions
(
env
,
code
,
options
.
transforms
)
code
.
mark_pos
(
None
)
code
.
mark_pos
(
None
)
self
.
generate_interned_name_table
(
env
,
code
)
self
.
generate_interned_name_table
(
env
,
code
)
self
.
generate_py_string_table
(
env
,
code
)
self
.
generate_py_string_table
(
env
,
code
)
...
...
Cython/Compiler/Nodes.py
View file @
0e55d5f3
...
@@ -38,6 +38,21 @@ def relative_position(pos):
...
@@ -38,6 +38,21 @@ def relative_position(pos):
return
(
pos
[
0
][
absolute_path_length
+
1
:],
pos
[
1
])
return
(
pos
[
0
][
absolute_path_length
+
1
:],
pos
[
1
])
class
AttributeAccessor
:
"""Used as the result of the Node.get_children_accessors() generator"""
def
__init__
(
self
,
obj
,
attrname
):
self
.
obj
=
obj
self
.
attrname
=
attrname
def
get
(
self
):
try
:
return
getattr
(
self
.
obj
,
self
.
attrname
)
except
AttributeError
:
return
None
def
set
(
self
,
value
):
setattr
(
self
.
obj
,
self
.
attrname
,
value
)
def
name
(
self
):
return
self
.
attrname
class
Node
:
class
Node
:
# pos (string, int, int) Source file position
# pos (string, int, int) Source file position
# is_name boolean Is a NameNode
# is_name boolean Is a NameNode
...
@@ -46,10 +61,63 @@ class Node:
...
@@ -46,10 +61,63 @@ class Node:
is_name
=
0
is_name
=
0
is_literal
=
0
is_literal
=
0
# All descandants should set child_attrs (see get_child_accessors)
child_attrs
=
None
def
__init__
(
self
,
pos
,
**
kw
):
def
__init__
(
self
,
pos
,
**
kw
):
self
.
pos
=
pos
self
.
pos
=
pos
self
.
__dict__
.
update
(
kw
)
self
.
__dict__
.
update
(
kw
)
def
get_child_accessors
(
self
):
"""Returns an iterator over the children of the Node. Each member in the
iterated list is an object with get(), set(value), and name() methods,
which can be used to fetch and replace the child and query the name
the relation this node has with the child. For instance, for an
assignment node, this code:
for child in assignment_node.get_child_accessors():
print(child.name())
child.set(i_node)
will print "lhs", "rhs", and change the assignment statement to "i = i"
(assuming that i_node is a node able to represent the variable i in the
tree).
Any kind of objects can in principle be returned, but the typical
candidates are either Node instances or lists of node instances.
The object returned in each iteration stage can only be used until the
iterator is advanced to the next child attribute. (However, the objects
returned by the get() function can be kept).
Typically, a Node instance will have other interesting and potentially
hierarchical attributes as well. These must be explicitly accessed -- this
method only provides access to attributes that are deemed to naturally
belong in the parse tree.
Descandant classes can either specify child_attrs, override get_child_attrs,
or override this method directly in order to provide access to their
children. All descendants of Node *must* declare their children -- leaf nodes
should simply declare "child_attrs = []".
"""
attrnames
=
self
.
get_child_attrs
()
if
attrnames
is
None
:
raise
InternalError
(
"Children access not implemented for %s"
%
\
self
.
__class__
.
__name__
)
for
name
in
attrnames
:
a
=
AttributeAccessor
(
self
,
name
)
yield
a
# Not really needed, but one wants to enforce clients not to
# hold on to iterated objects, in case more advanced iteration
# is needed later
a
.
attrname
=
None
def
get_child_attrs
(
self
):
"""Utility method for more easily implementing get_child_accessors.
If you override get_child_accessors then this method is not used."""
return
self
.
child_attrs
#
#
# There are 3 phases of parse tree processing, applied in order to
# There are 3 phases of parse tree processing, applied in order to
# all the statements in a given scope-block:
# all the statements in a given scope-block:
...
@@ -145,6 +213,8 @@ class BlockNode:
...
@@ -145,6 +213,8 @@ class BlockNode:
class
StatListNode
(
Node
):
class
StatListNode
(
Node
):
# stats a list of StatNode
# stats a list of StatNode
child_attrs
=
[
"stats"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
#print "StatListNode.analyse_declarations" ###
#print "StatListNode.analyse_declarations" ###
for
stat
in
self
.
stats
:
for
stat
in
self
.
stats
:
...
@@ -155,10 +225,10 @@ class StatListNode(Node):
...
@@ -155,10 +225,10 @@ class StatListNode(Node):
for
stat
in
self
.
stats
:
for
stat
in
self
.
stats
:
stat
.
analyse_expressions
(
env
)
stat
.
analyse_expressions
(
env
)
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
#print "StatListNode.generate_function_definitions" ###
#print "StatListNode.generate_function_definitions" ###
for
stat
in
self
.
stats
:
for
stat
in
self
.
stats
:
stat
.
generate_function_definitions
(
env
,
code
)
stat
.
generate_function_definitions
(
env
,
code
,
transforms
)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
#print "StatListNode.generate_execution_code" ###
#print "StatListNode.generate_execution_code" ###
...
@@ -184,7 +254,7 @@ class StatNode(Node):
...
@@ -184,7 +254,7 @@ class StatNode(Node):
# Emit C code for executable statements.
# Emit C code for executable statements.
#
#
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
pass
pass
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
...
@@ -196,6 +266,8 @@ class CDefExternNode(StatNode):
...
@@ -196,6 +266,8 @@ class CDefExternNode(StatNode):
# include_file string or None
# include_file string or None
# body StatNode
# body StatNode
child_attrs
=
[
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
include_file
:
if
self
.
include_file
:
env
.
add_include_file
(
self
.
include_file
)
env
.
add_include_file
(
self
.
include_file
)
...
@@ -227,6 +299,8 @@ class CDeclaratorNode(Node):
...
@@ -227,6 +299,8 @@ class CDeclaratorNode(Node):
# calling_convention string Calling convention of CFuncDeclaratorNode
# calling_convention string Calling convention of CFuncDeclaratorNode
# for which this is a base
# for which this is a base
child_attrs
=
[]
calling_convention
=
""
calling_convention
=
""
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
...
@@ -240,6 +314,8 @@ class CNameDeclaratorNode(CDeclaratorNode):
...
@@ -240,6 +314,8 @@ class CNameDeclaratorNode(CDeclaratorNode):
# name string The Pyrex name being declared
# name string The Pyrex name being declared
# cname string or None C name, if specified
# cname string or None C name, if specified
child_attrs
=
[]
def
analyse
(
self
,
base_type
,
env
):
def
analyse
(
self
,
base_type
,
env
):
self
.
type
=
base_type
self
.
type
=
base_type
return
self
,
base_type
return
self
,
base_type
...
@@ -268,6 +344,8 @@ class CNameDeclaratorNode(CDeclaratorNode):
...
@@ -268,6 +344,8 @@ class CNameDeclaratorNode(CDeclaratorNode):
class
CPtrDeclaratorNode
(
CDeclaratorNode
):
class
CPtrDeclaratorNode
(
CDeclaratorNode
):
# base CDeclaratorNode
# base CDeclaratorNode
child_attrs
=
[
"base"
]
def
analyse
(
self
,
base_type
,
env
):
def
analyse
(
self
,
base_type
,
env
):
if
base_type
.
is_pyobject
:
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
error
(
self
.
pos
,
...
@@ -285,6 +363,8 @@ class CArrayDeclaratorNode(CDeclaratorNode):
...
@@ -285,6 +363,8 @@ class CArrayDeclaratorNode(CDeclaratorNode):
# base CDeclaratorNode
# base CDeclaratorNode
# dimension ExprNode
# dimension ExprNode
child_attrs
=
[
"base"
,
"dimension"
]
def
analyse
(
self
,
base_type
,
env
):
def
analyse
(
self
,
base_type
,
env
):
if
self
.
dimension
:
if
self
.
dimension
:
self
.
dimension
.
analyse_const_expression
(
env
)
self
.
dimension
.
analyse_const_expression
(
env
)
...
@@ -315,6 +395,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
...
@@ -315,6 +395,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
# nogil boolean Can be called without gil
# nogil boolean Can be called without gil
# with_gil boolean Acquire gil around function body
# with_gil boolean Acquire gil around function body
child_attrs
=
[
"base"
,
"args"
,
"exception_value"
]
overridable
=
0
overridable
=
0
optional_arg_count
=
0
optional_arg_count
=
0
...
@@ -403,6 +485,8 @@ class CArgDeclNode(Node):
...
@@ -403,6 +485,8 @@ class CArgDeclNode(Node):
# is_self_arg boolean Is the "self" arg of an extension type method
# is_self_arg boolean Is the "self" arg of an extension type method
# is_kw_only boolean Is a keyword-only argument
# is_kw_only boolean Is a keyword-only argument
child_attrs
=
[
"base_type"
,
"declarator"
,
"default"
]
is_self_arg
=
0
is_self_arg
=
0
is_generic
=
1
is_generic
=
1
...
@@ -435,6 +519,8 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
...
@@ -435,6 +519,8 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
# longness integer
# longness integer
# is_self_arg boolean Is self argument of C method
# is_self_arg boolean Is self argument of C method
child_attrs
=
[]
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
):
# Return type descriptor.
# Return type descriptor.
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
...
@@ -480,6 +566,8 @@ class CComplexBaseTypeNode(CBaseTypeNode):
...
@@ -480,6 +566,8 @@ class CComplexBaseTypeNode(CBaseTypeNode):
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# declarator CDeclaratorNode
child_attrs
=
[
"base_type"
,
"declarator"
]
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
):
base
=
self
.
base_type
.
analyse
(
env
)
base
=
self
.
base_type
.
analyse
(
env
)
_
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
_
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
...
@@ -495,6 +583,8 @@ class CVarDefNode(StatNode):
...
@@ -495,6 +583,8 @@ class CVarDefNode(StatNode):
# in_pxd boolean
# in_pxd boolean
# api boolean
# api boolean
child_attrs
=
[
"base_type"
,
"declarators"
]
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
if
not
dest_scope
:
if
not
dest_scope
:
dest_scope
=
env
dest_scope
=
env
...
@@ -543,6 +633,8 @@ class CStructOrUnionDefNode(StatNode):
...
@@ -543,6 +633,8 @@ class CStructOrUnionDefNode(StatNode):
# attributes [CVarDefNode] or None
# attributes [CVarDefNode] or None
# entry Entry
# entry Entry
child_attrs
=
[
"attributes"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
scope
=
None
scope
=
None
if
self
.
attributes
is
not
None
:
if
self
.
attributes
is
not
None
:
...
@@ -572,6 +664,8 @@ class CEnumDefNode(StatNode):
...
@@ -572,6 +664,8 @@ class CEnumDefNode(StatNode):
# in_pxd boolean
# in_pxd boolean
# entry Entry
# entry Entry
child_attrs
=
[
"items"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
...
@@ -594,6 +688,8 @@ class CEnumDefItemNode(StatNode):
...
@@ -594,6 +688,8 @@ class CEnumDefItemNode(StatNode):
# cname string or None
# cname string or None
# value ExprNode or None
# value ExprNode or None
child_attrs
=
[
"value"
]
def
analyse_declarations
(
self
,
env
,
enum_entry
):
def
analyse_declarations
(
self
,
env
,
enum_entry
):
if
self
.
value
:
if
self
.
value
:
self
.
value
.
analyse_const_expression
(
env
)
self
.
value
.
analyse_const_expression
(
env
)
...
@@ -611,6 +707,8 @@ class CTypeDefNode(StatNode):
...
@@ -611,6 +707,8 @@ class CTypeDefNode(StatNode):
# visibility "public" or "private"
# visibility "public" or "private"
# in_pxd boolean
# in_pxd boolean
child_attrs
=
[
"base_type"
,
"declarator"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
base
=
self
.
base_type
.
analyse
(
env
)
base
=
self
.
base_type
.
analyse
(
env
)
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
...
@@ -663,7 +761,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -663,7 +761,7 @@ class FuncDefNode(StatNode, BlockNode):
def
need_gil_acquisition
(
self
,
lenv
):
def
need_gil_acquisition
(
self
,
lenv
):
return
0
return
0
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
code
.
mark_pos
(
self
.
pos
)
code
.
mark_pos
(
self
.
pos
)
# Generate C code for header and body of function
# Generate C code for header and body of function
genv
=
env
.
global_scope
()
genv
=
env
.
global_scope
()
...
@@ -671,8 +769,10 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -671,8 +769,10 @@ class FuncDefNode(StatNode, BlockNode):
lenv
.
return_type
=
self
.
return_type
lenv
.
return_type
=
self
.
return_type
code
.
init_labels
()
code
.
init_labels
()
self
.
declare_arguments
(
lenv
)
self
.
declare_arguments
(
lenv
)
transforms
.
run
(
'before_analyse_function'
,
self
,
env
=
env
,
lenv
=
lenv
,
genv
=
genv
)
self
.
body
.
analyse_declarations
(
lenv
)
self
.
body
.
analyse_declarations
(
lenv
)
self
.
body
.
analyse_expressions
(
lenv
)
self
.
body
.
analyse_expressions
(
lenv
)
transforms
.
run
(
'after_analyse_function'
,
self
,
env
=
env
,
lenv
=
lenv
,
genv
=
genv
)
# Code for nested function definitions would go here
# Code for nested function definitions would go here
# if we supported them, which we probably won't.
# if we supported them, which we probably won't.
# ----- Top-level constants used by this function
# ----- Top-level constants used by this function
...
@@ -775,7 +875,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -775,7 +875,7 @@ class FuncDefNode(StatNode, BlockNode):
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
# ----- Python version
# ----- Python version
if
self
.
py_func
:
if
self
.
py_func
:
self
.
py_func
.
generate_function_definitions
(
env
,
code
)
self
.
py_func
.
generate_function_definitions
(
env
,
code
,
transforms
)
self
.
generate_optarg_wrapper_function
(
env
,
code
)
self
.
generate_optarg_wrapper_function
(
env
,
code
)
def
put_stararg_decrefs
(
self
,
code
):
def
put_stararg_decrefs
(
self
,
code
):
...
@@ -834,6 +934,8 @@ class CFuncDefNode(FuncDefNode):
...
@@ -834,6 +934,8 @@ class CFuncDefNode(FuncDefNode):
# with_gil boolean Acquire GIL around body
# with_gil boolean Acquire GIL around body
# type CFuncType
# type CFuncType
child_attrs
=
[
"base_type"
,
"declarator"
,
"body"
]
def
unqualified_name
(
self
):
def
unqualified_name
(
self
):
return
self
.
entry
.
name
return
self
.
entry
.
name
...
@@ -1032,6 +1134,7 @@ class PyArgDeclNode(Node):
...
@@ -1032,6 +1134,7 @@ class PyArgDeclNode(Node):
#
#
# name string
# name string
# entry Symtab.Entry
# entry Symtab.Entry
child_attrs
=
[]
pass
pass
...
@@ -1051,6 +1154,8 @@ class DefNode(FuncDefNode):
...
@@ -1051,6 +1154,8 @@ class DefNode(FuncDefNode):
#
#
# assmt AssignmentNode Function construction/assignment
# assmt AssignmentNode Function construction/assignment
child_attrs
=
[
"args"
,
"star_arg"
,
"starstar_arg"
,
"body"
]
assmt
=
None
assmt
=
None
num_kwonly_args
=
0
num_kwonly_args
=
0
num_required_kw_args
=
0
num_required_kw_args
=
0
...
@@ -1740,6 +1845,8 @@ class PyClassDefNode(StatNode, BlockNode):
...
@@ -1740,6 +1845,8 @@ class PyClassDefNode(StatNode, BlockNode):
# classobj ClassNode Class object
# classobj ClassNode Class object
# target NameNode Variable to assign class object to
# target NameNode Variable to assign class object to
child_attrs
=
[
"body"
,
"dict"
,
"classobj"
,
"target"
]
def
__init__
(
self
,
pos
,
name
,
bases
,
doc
,
body
):
def
__init__
(
self
,
pos
,
name
,
bases
,
doc
,
body
):
StatNode
.
__init__
(
self
,
pos
)
StatNode
.
__init__
(
self
,
pos
)
self
.
name
=
name
self
.
name
=
name
...
@@ -1777,10 +1884,10 @@ class PyClassDefNode(StatNode, BlockNode):
...
@@ -1777,10 +1884,10 @@ class PyClassDefNode(StatNode, BlockNode):
#self.classobj.release_temp(env)
#self.classobj.release_temp(env)
#self.target.release_target_temp(env)
#self.target.release_target_temp(env)
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
self
.
generate_py_string_decls
(
self
.
scope
,
code
)
self
.
generate_py_string_decls
(
self
.
scope
,
code
)
self
.
body
.
generate_function_definitions
(
self
.
body
.
generate_function_definitions
(
self
.
scope
,
code
)
self
.
scope
,
code
,
transforms
)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
self
.
dict
.
generate_evaluation_code
(
code
)
self
.
dict
.
generate_evaluation_code
(
code
)
...
@@ -1809,6 +1916,8 @@ class CClassDefNode(StatNode):
...
@@ -1809,6 +1916,8 @@ class CClassDefNode(StatNode):
# entry Symtab.Entry
# entry Symtab.Entry
# base_type PyExtensionType or None
# base_type PyExtensionType or None
child_attrs
=
[
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
#print "CClassDefNode.analyse_declarations:", self.class_name
#print "CClassDefNode.analyse_declarations:", self.class_name
#print "...visibility =", self.visibility
#print "...visibility =", self.visibility
...
@@ -1880,10 +1989,10 @@ class CClassDefNode(StatNode):
...
@@ -1880,10 +1989,10 @@ class CClassDefNode(StatNode):
scope
=
self
.
entry
.
type
.
scope
scope
=
self
.
entry
.
type
.
scope
self
.
body
.
analyse_expressions
(
scope
)
self
.
body
.
analyse_expressions
(
scope
)
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
if
self
.
body
:
if
self
.
body
:
self
.
body
.
generate_function_definitions
(
self
.
body
.
generate_function_definitions
(
self
.
entry
.
type
.
scope
,
code
)
self
.
entry
.
type
.
scope
,
code
,
transforms
)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
# This is needed to generate evaluation code for
# This is needed to generate evaluation code for
...
@@ -1903,6 +2012,8 @@ class PropertyNode(StatNode):
...
@@ -1903,6 +2012,8 @@ class PropertyNode(StatNode):
# doc string or None Doc string
# doc string or None Doc string
# body StatListNode
# body StatListNode
child_attrs
=
[
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
entry
=
env
.
declare_property
(
self
.
name
,
self
.
doc
,
self
.
pos
)
entry
=
env
.
declare_property
(
self
.
name
,
self
.
doc
,
self
.
pos
)
if
entry
:
if
entry
:
...
@@ -1914,8 +2025,8 @@ class PropertyNode(StatNode):
...
@@ -1914,8 +2025,8 @@ class PropertyNode(StatNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
body
.
analyse_expressions
(
env
)
self
.
body
.
analyse_expressions
(
env
)
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
,
transforms
):
self
.
body
.
generate_function_definitions
(
env
,
code
)
self
.
body
.
generate_function_definitions
(
env
,
code
,
transforms
)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
pass
pass
...
@@ -1929,6 +2040,8 @@ class GlobalNode(StatNode):
...
@@ -1929,6 +2040,8 @@ class GlobalNode(StatNode):
#
#
# names [string]
# names [string]
child_attrs
=
[]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
name
in
self
.
names
:
for
name
in
self
.
names
:
env
.
declare_global
(
name
,
self
.
pos
)
env
.
declare_global
(
name
,
self
.
pos
)
...
@@ -1945,6 +2058,8 @@ class ExprStatNode(StatNode):
...
@@ -1945,6 +2058,8 @@ class ExprStatNode(StatNode):
#
#
# expr ExprNode
# expr ExprNode
child_attrs
=
[
"expr"
]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
expr
.
analyse_expressions
(
env
)
self
.
expr
.
analyse_expressions
(
env
)
self
.
expr
.
release_temp
(
env
)
self
.
expr
.
release_temp
(
env
)
...
@@ -1990,6 +2105,8 @@ class SingleAssignmentNode(AssignmentNode):
...
@@ -1990,6 +2105,8 @@ class SingleAssignmentNode(AssignmentNode):
# lhs ExprNode Left hand side
# lhs ExprNode Left hand side
# rhs ExprNode Right hand side
# rhs ExprNode Right hand side
child_attrs
=
[
"lhs"
,
"rhs"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
lhs
.
analyse_target_declaration
(
env
)
self
.
lhs
.
analyse_target_declaration
(
env
)
...
@@ -2044,6 +2161,8 @@ class CascadedAssignmentNode(AssignmentNode):
...
@@ -2044,6 +2161,8 @@ class CascadedAssignmentNode(AssignmentNode):
#
#
# coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
# coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
child_attrs
=
[
"lhs_list"
,
"rhs"
,
"coerced_rhs_list"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
lhs
in
self
.
lhs_list
:
for
lhs
in
self
.
lhs_list
:
lhs
.
analyse_target_declaration
(
env
)
lhs
.
analyse_target_declaration
(
env
)
...
@@ -2128,6 +2247,8 @@ class ParallelAssignmentNode(AssignmentNode):
...
@@ -2128,6 +2247,8 @@ class ParallelAssignmentNode(AssignmentNode):
#
#
# stats [AssignmentNode] The constituent assignments
# stats [AssignmentNode] The constituent assignments
child_attrs
=
[
"stats"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
stat
in
self
.
stats
:
for
stat
in
self
.
stats
:
stat
.
analyse_declarations
(
env
)
stat
.
analyse_declarations
(
env
)
...
@@ -2175,6 +2296,8 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -2175,6 +2296,8 @@ class InPlaceAssignmentNode(AssignmentNode):
# Fortunately, the type of the lhs node is fairly constrained
# Fortunately, the type of the lhs node is fairly constrained
# (it must be a NameNode, AttributeNode, or IndexNode).
# (it must be a NameNode, AttributeNode, or IndexNode).
child_attrs
=
[
"lhs"
,
"rhs"
,
"dup"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
lhs
.
analyse_target_declaration
(
env
)
self
.
lhs
.
analyse_target_declaration
(
env
)
...
@@ -2272,6 +2395,8 @@ class PrintStatNode(StatNode):
...
@@ -2272,6 +2395,8 @@ class PrintStatNode(StatNode):
# args [ExprNode]
# args [ExprNode]
# ends_with_comma boolean
# ends_with_comma boolean
child_attrs
=
[
"args"
]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
for
i
in
range
(
len
(
self
.
args
)):
for
i
in
range
(
len
(
self
.
args
)):
arg
=
self
.
args
[
i
]
arg
=
self
.
args
[
i
]
...
@@ -2306,6 +2431,8 @@ class DelStatNode(StatNode):
...
@@ -2306,6 +2431,8 @@ class DelStatNode(StatNode):
#
#
# args [ExprNode]
# args [ExprNode]
child_attrs
=
[
"args"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
arg
.
analyse_target_declaration
(
env
)
arg
.
analyse_target_declaration
(
env
)
...
@@ -2331,6 +2458,8 @@ class DelStatNode(StatNode):
...
@@ -2331,6 +2458,8 @@ class DelStatNode(StatNode):
class
PassStatNode
(
StatNode
):
class
PassStatNode
(
StatNode
):
# pass statement
# pass statement
child_attrs
=
[]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
...
@@ -2340,6 +2469,8 @@ class PassStatNode(StatNode):
...
@@ -2340,6 +2469,8 @@ class PassStatNode(StatNode):
class
BreakStatNode
(
StatNode
):
class
BreakStatNode
(
StatNode
):
child_attrs
=
[]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
...
@@ -2355,6 +2486,8 @@ class BreakStatNode(StatNode):
...
@@ -2355,6 +2486,8 @@ class BreakStatNode(StatNode):
class
ContinueStatNode
(
StatNode
):
class
ContinueStatNode
(
StatNode
):
child_attrs
=
[]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
...
@@ -2377,6 +2510,8 @@ class ReturnStatNode(StatNode):
...
@@ -2377,6 +2510,8 @@ class ReturnStatNode(StatNode):
# return_type PyrexType
# return_type PyrexType
# temps_in_use [Entry] Temps in use at time of return
# temps_in_use [Entry] Temps in use at time of return
child_attrs
=
[
"value"
]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
return_type
=
env
.
return_type
return_type
=
env
.
return_type
self
.
return_type
=
return_type
self
.
return_type
=
return_type
...
@@ -2439,6 +2574,8 @@ class RaiseStatNode(StatNode):
...
@@ -2439,6 +2574,8 @@ class RaiseStatNode(StatNode):
# exc_value ExprNode or None
# exc_value ExprNode or None
# exc_tb ExprNode or None
# exc_tb ExprNode or None
child_attrs
=
[
"exc_type"
,
"exc_value"
,
"exc_tb"
]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
if
self
.
exc_type
:
if
self
.
exc_type
:
self
.
exc_type
.
analyse_types
(
env
)
self
.
exc_type
.
analyse_types
(
env
)
...
@@ -2508,6 +2645,8 @@ class RaiseStatNode(StatNode):
...
@@ -2508,6 +2645,8 @@ class RaiseStatNode(StatNode):
class
ReraiseStatNode
(
StatNode
):
class
ReraiseStatNode
(
StatNode
):
child_attrs
=
[]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
env
.
use_utility_code
(
raise_utility_code
)
env
.
use_utility_code
(
raise_utility_code
)
...
@@ -2526,6 +2665,8 @@ class AssertStatNode(StatNode):
...
@@ -2526,6 +2665,8 @@ class AssertStatNode(StatNode):
# cond ExprNode
# cond ExprNode
# value ExprNode or None
# value ExprNode or None
child_attrs
=
[
"cond"
,
"value"
]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
cond
=
self
.
cond
.
analyse_boolean_expression
(
env
)
self
.
cond
=
self
.
cond
.
analyse_boolean_expression
(
env
)
if
self
.
value
:
if
self
.
value
:
...
@@ -2571,6 +2712,8 @@ class IfStatNode(StatNode):
...
@@ -2571,6 +2712,8 @@ class IfStatNode(StatNode):
# if_clauses [IfClauseNode]
# if_clauses [IfClauseNode]
# else_clause StatNode or None
# else_clause StatNode or None
child_attrs
=
[
"if_clauses"
,
"else_clause"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
if_clause
in
self
.
if_clauses
:
for
if_clause
in
self
.
if_clauses
:
if_clause
.
analyse_declarations
(
env
)
if_clause
.
analyse_declarations
(
env
)
...
@@ -2607,6 +2750,8 @@ class IfClauseNode(Node):
...
@@ -2607,6 +2750,8 @@ class IfClauseNode(Node):
# condition ExprNode
# condition ExprNode
# body StatNode
# body StatNode
child_attrs
=
[
"condition"
,
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
condition
.
analyse_declarations
(
env
)
self
.
condition
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
...
@@ -2642,6 +2787,8 @@ class WhileStatNode(StatNode):
...
@@ -2642,6 +2787,8 @@ class WhileStatNode(StatNode):
# body StatNode
# body StatNode
# else_clause StatNode
# else_clause StatNode
child_attrs
=
[
"condition"
,
"body"
,
"else_clause"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
if
self
.
else_clause
:
if
self
.
else_clause
:
...
@@ -2697,6 +2844,8 @@ class ForInStatNode(StatNode):
...
@@ -2697,6 +2844,8 @@ class ForInStatNode(StatNode):
# else_clause StatNode
# else_clause StatNode
# item NextNode used internally
# item NextNode used internally
child_attrs
=
[
"target"
,
"iterator"
,
"body"
,
"else_clause"
,
"item"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
target
.
analyse_target_declaration
(
env
)
self
.
target
.
analyse_target_declaration
(
env
)
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
...
@@ -2811,6 +2960,7 @@ class ForFromStatNode(StatNode):
...
@@ -2811,6 +2960,7 @@ class ForFromStatNode(StatNode):
# is_py_target bool
# is_py_target bool
# loopvar_name string
# loopvar_name string
# py_loopvar_node PyTempNode or None
# py_loopvar_node PyTempNode or None
child_attrs
=
[
"target"
,
"bound1"
,
"bound2"
,
"step"
,
"body"
,
"else_clause"
,
"py_loopvar_node"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
target
.
analyse_target_declaration
(
env
)
self
.
target
.
analyse_target_declaration
(
env
)
...
@@ -2934,6 +3084,8 @@ class TryExceptStatNode(StatNode):
...
@@ -2934,6 +3084,8 @@ class TryExceptStatNode(StatNode):
# else_clause StatNode or None
# else_clause StatNode or None
# cleanup_list [Entry] temps to clean up on error
# cleanup_list [Entry] temps to clean up on error
child_attrs
=
[
"body"
,
"except_clauses"
,
"else_clause"
,
"cleanup_list"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
for
except_clause
in
self
.
except_clauses
:
for
except_clause
in
self
.
except_clauses
:
...
@@ -2999,6 +3151,8 @@ class ExceptClauseNode(Node):
...
@@ -2999,6 +3151,8 @@ class ExceptClauseNode(Node):
# function_name string qualified name of enclosing function
# function_name string qualified name of enclosing function
# exc_vars (string * 3) local exception variables
# exc_vars (string * 3) local exception variables
child_attrs
=
[
"pattern"
,
"target"
,
"body"
,
"exc_value"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
target
:
if
self
.
target
:
self
.
target
.
analyse_target_declaration
(
env
)
self
.
target
.
analyse_target_declaration
(
env
)
...
@@ -3085,6 +3239,8 @@ class TryFinallyStatNode(StatNode):
...
@@ -3085,6 +3239,8 @@ class TryFinallyStatNode(StatNode):
# exception on entry to the finally block and restore
# exception on entry to the finally block and restore
# it on exit.
# it on exit.
child_attrs
=
[
"body"
,
"finally_clause"
,
"cleanup_list"
]
preserve_exception
=
1
preserve_exception
=
1
disallow_continue_in_try_finally
=
0
disallow_continue_in_try_finally
=
0
...
@@ -3243,6 +3399,8 @@ class GILStatNode(TryFinallyStatNode):
...
@@ -3243,6 +3399,8 @@ class GILStatNode(TryFinallyStatNode):
#
#
# state string 'gil' or 'nogil'
# state string 'gil' or 'nogil'
child_attrs
=
[]
preserve_exception
=
0
preserve_exception
=
0
def
__init__
(
self
,
pos
,
state
,
body
):
def
__init__
(
self
,
pos
,
state
,
body
):
...
@@ -3280,6 +3438,8 @@ class GILExitNode(StatNode):
...
@@ -3280,6 +3438,8 @@ class GILExitNode(StatNode):
#
#
# state string 'gil' or 'nogil'
# state string 'gil' or 'nogil'
child_attrs
=
[]
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
...
@@ -3296,6 +3456,8 @@ class CImportStatNode(StatNode):
...
@@ -3296,6 +3456,8 @@ class CImportStatNode(StatNode):
# module_name string Qualified name of module being imported
# module_name string Qualified name of module being imported
# as_name string or None Name specified in "as" clause, if any
# as_name string or None Name specified in "as" clause, if any
child_attrs
=
[]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
not
env
.
is_module_scope
:
if
not
env
.
is_module_scope
:
error
(
self
.
pos
,
"cimport only allowed at module level"
)
error
(
self
.
pos
,
"cimport only allowed at module level"
)
...
@@ -3331,6 +3493,8 @@ class FromCImportStatNode(StatNode):
...
@@ -3331,6 +3493,8 @@ class FromCImportStatNode(StatNode):
# module_name string Qualified name of module
# module_name string Qualified name of module
# imported_names [(pos, name, as_name)] Names to be imported
# imported_names [(pos, name, as_name)] Names to be imported
child_attrs
=
[]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
not
env
.
is_module_scope
:
if
not
env
.
is_module_scope
:
error
(
self
.
pos
,
"cimport only allowed at module level"
)
error
(
self
.
pos
,
"cimport only allowed at module level"
)
...
@@ -3358,6 +3522,8 @@ class FromImportStatNode(StatNode):
...
@@ -3358,6 +3522,8 @@ class FromImportStatNode(StatNode):
# interned_items [(string, NameNode)]
# interned_items [(string, NameNode)]
# item PyTempNode used internally
# item PyTempNode used internally
child_attrs
=
[
"module"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
_
,
target
in
self
.
items
:
for
_
,
target
in
self
.
items
:
target
.
analyse_target_declaration
(
env
)
target
.
analyse_target_declaration
(
env
)
...
...
Cython/Compiler/Transform.py
0 → 100644
View file @
0e55d5f3
#
# Tree transform framework
#
import
Nodes
import
ExprNodes
class
Transform
(
object
):
# parent_stack [Node] A stack providing information about where in the tree
# we currently are. Nodes here should be considered
# read-only.
# Transforms for the parse tree should usually extend this class for convenience.
# The caller of a transform will only first call initialize and then process_node on
# the root node, the rest are utility functions and conventions.
# Transformations usually happens by recursively filtering through the stream.
# process_node is always expected to return a new node, however it is ok to simply
# return the input node untouched. Returning None will remove the node from the
# parent.
def
__init__
(
self
):
self
.
parent_stack
=
[]
def
initialize
(
self
,
phase
,
**
options
):
pass
def
process_children
(
self
,
node
):
"""For all children of node, either process_list (if isinstance(node, list))
or process_node (otherwise) is called."""
if
node
==
None
:
return
self
.
parent_stack
.
append
(
node
)
for
childacc
in
node
.
get_child_accessors
():
child
=
childacc
.
get
()
if
isinstance
(
child
,
list
):
newchild
=
self
.
process_list
(
child
,
childacc
.
name
())
if
not
isinstance
(
newchild
,
list
):
raise
Exception
(
"Cannot replace list with non-list!"
)
else
:
newchild
=
self
.
process_node
(
child
,
childacc
.
name
())
if
newchild
is
not
None
and
not
isinstance
(
newchild
,
Nodes
.
Node
):
raise
Exception
(
"Cannot replace Node with non-Node!"
)
childacc
.
set
(
newchild
)
self
.
parent_stack
.
pop
()
def
process_list
(
self
,
l
,
name
):
"""Calls process_node on all the items in l, using the name one gets when appending
[idx] to the name. Each item in l is transformed in-place by the item process_node
returns, then l is returned."""
# Comment: If moving to a copying strategy, it might makes sense to return a
# new list instead.
for
idx
in
xrange
(
len
(
l
)):
l
[
idx
]
=
self
.
process_node
(
l
[
idx
],
"%s[%d]"
%
(
name
,
idx
))
return
l
def
process_node
(
self
,
node
,
name
):
"""Override this method to process nodes. name specifies which kind of relation the
parent has with child. This method should always return the node which the parent
should use for this relation, which can either be the same node, None to remove
the node, or a different node."""
raise
InternalError
(
"Not implemented"
)
class
PrintTree
(
Transform
):
"""Prints a representation of the tree to standard output.
Subclass and override repr_of to provide more information
about nodes. """
def
__init__
(
self
):
Transform
.
__init__
(
self
)
self
.
_indent
=
""
def
indent
(
self
):
self
.
_indent
+=
" "
def
unindent
(
self
):
self
.
_indent
=
self
.
_indent
[:
-
2
]
def
initialize
(
self
,
phase
,
**
options
):
print
(
"Parse tree dump at phase '%s'"
%
phase
)
# Don't do anything about process_list, the defaults gives
# nice-looking name[idx] nodes which will visually appear
# under the parent-node, not displaying the list itself in
# the hierarchy.
def
process_node
(
self
,
node
,
name
):
print
(
"%s- %s: %s"
%
(
self
.
_indent
,
name
,
self
.
repr_of
(
node
)))
self
.
indent
()
self
.
process_children
(
node
)
self
.
unindent
()
return
node
def
repr_of
(
self
,
node
):
if
node
is
None
:
return
"(none)"
else
:
result
=
node
.
__class__
.
__name__
if
isinstance
(
node
,
ExprNodes
.
ExprNode
):
t
=
node
.
type
result
+=
"(type=%s)"
%
repr
(
t
)
return
result
PHASES
=
[
'before_analyse_function'
,
# run in FuncDefNode.generate_function_definitions
'after_analyse_function'
# run in FuncDefNode.generate_function_definitions
]
class
TransformSet
(
dict
):
def
__init__
(
self
):
self
.
update
([(
name
,
[])
for
name
in
PHASES
])
def
run
(
self
,
name
,
node
,
**
options
):
assert
name
in
self
for
transform
in
self
[
name
]:
transform
.
initialize
(
phase
=
name
,
**
options
)
transform
.
process_node
(
node
,
"(root)"
)
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