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
Xavier Thompson
cython
Commits
3588f4a6
Commit
3588f4a6
authored
Oct 11, 2007
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import of Pyrex 0.9.6.2
parent
5aab5520
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
2270 additions
and
791 deletions
+2270
-791
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+9
-3
Cython/Compiler/Errors.py
Cython/Compiler/Errors.py
+9
-4
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+356
-85
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+26
-8
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+475
-69
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+12
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+401
-214
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+360
-189
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+190
-95
Cython/Compiler/Scanning.py
Cython/Compiler/Scanning.py
+68
-6
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+100
-34
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+43
-10
Cython/Compiler/Version.py
Cython/Compiler/Version.py
+1
-1
Cython/Debugging.py
Cython/Debugging.py
+1
-1
Cython/Distutils/__init__.py
Cython/Distutils/__init__.py
+1
-12
Cython/Distutils/build_ext.py
Cython/Distutils/build_ext.py
+186
-56
Cython/Mac/DarwinSystem.py
Cython/Mac/DarwinSystem.py
+13
-3
Cython/Unix/LinuxSystem.py
Cython/Unix/LinuxSystem.py
+1
-1
Cython/Utils.py
Cython/Utils.py
+18
-0
No files found.
Cython/Compiler/Code.py
View file @
3588f4a6
...
@@ -19,6 +19,7 @@ class CCodeWriter:
...
@@ -19,6 +19,7 @@ class CCodeWriter:
# in_try_finally boolean inside try of try...finally
# in_try_finally boolean inside try of try...finally
# filename_table {string : int} for finding filename table indexes
# filename_table {string : int} for finding filename table indexes
# filename_list [string] filenames in filename table order
# filename_list [string] filenames in filename table order
# exc_vars (string * 3) exception variables for reraise, or None
in_try_finally
=
0
in_try_finally
=
0
...
@@ -32,6 +33,7 @@ class CCodeWriter:
...
@@ -32,6 +33,7 @@ class CCodeWriter:
self
.
error_label
=
None
self
.
error_label
=
None
self
.
filename_table
=
{}
self
.
filename_table
=
{}
self
.
filename_list
=
[]
self
.
filename_list
=
[]
self
.
exc_vars
=
None
def
putln
(
self
,
code
=
""
):
def
putln
(
self
,
code
=
""
):
if
self
.
marker
and
self
.
bol
:
if
self
.
marker
and
self
.
bol
:
...
@@ -156,11 +158,13 @@ class CCodeWriter:
...
@@ -156,11 +158,13 @@ class CCodeWriter:
def
put_var_declaration
(
self
,
entry
,
static
=
0
,
dll_linkage
=
None
,
def
put_var_declaration
(
self
,
entry
,
static
=
0
,
dll_linkage
=
None
,
definition
=
True
):
definition
=
True
):
#print "Code.put_var_declaration:", entry.name,
"definition =", definition
###
#print "Code.put_var_declaration:", entry.name,
repr(entry.type)
###
visibility
=
entry
.
visibility
visibility
=
entry
.
visibility
if
visibility
==
'private'
and
not
definition
:
if
visibility
==
'private'
and
not
definition
:
#print "...private and not definition, skipping" ###
return
return
if
not
entry
.
used
and
visibility
==
"private"
:
if
not
entry
.
used
and
visibility
==
"private"
:
#print "not used and private, skipping" ###
return
return
storage_class
=
""
storage_class
=
""
if
visibility
==
'extern'
:
if
visibility
==
'extern'
:
...
@@ -254,8 +258,6 @@ class CCodeWriter:
...
@@ -254,8 +258,6 @@ class CCodeWriter:
def
put_init_var_to_py_none
(
self
,
entry
,
template
=
"%s"
):
def
put_init_var_to_py_none
(
self
,
entry
,
template
=
"%s"
):
code
=
template
%
entry
.
cname
code
=
template
%
entry
.
cname
#if entry.type.is_extension_type:
# code = "((PyObject*)%s)" % code
self
.
put_init_to_py_none
(
code
,
entry
.
type
)
self
.
put_init_to_py_none
(
code
,
entry
.
type
)
def
put_pymethoddef
(
self
,
entry
,
term
):
def
put_pymethoddef
(
self
,
entry
,
term
):
...
@@ -270,6 +272,10 @@ class CCodeWriter:
...
@@ -270,6 +272,10 @@ class CCodeWriter:
doc_code
,
doc_code
,
term
))
term
))
def
put_h_guard
(
self
,
guard
):
self
.
putln
(
"#ifndef %s"
%
guard
)
self
.
putln
(
"#define %s"
%
guard
)
def
error_goto
(
self
,
pos
):
def
error_goto
(
self
,
pos
):
lbl
=
self
.
error_label
lbl
=
self
.
error_label
self
.
use_label
(
lbl
)
self
.
use_label
(
lbl
)
...
...
Cython/Compiler/Errors.py
View file @
3588f4a6
...
@@ -54,14 +54,19 @@ def close_listing_file():
...
@@ -54,14 +54,19 @@ def close_listing_file():
listing_file
.
close
()
listing_file
.
close
()
listing_file
=
None
listing_file
=
None
def
error
(
position
,
message
):
def
report
(
position
,
message
):
#print "Errors.error:", repr(position), repr(message) ###
global
num_errors
err
=
CompileError
(
position
,
message
)
err
=
CompileError
(
position
,
message
)
line
=
"%s
\
n
"
%
err
line
=
"%s
\
n
"
%
err
if
listing_file
:
if
listing_file
:
listing_file
.
write
(
line
)
listing_file
.
write
(
line
)
if
echo_file
:
if
echo_file
:
echo_file
.
write
(
line
)
echo_file
.
write
(
line
)
num_errors
=
num_errors
+
1
return
err
return
err
def
warning
(
position
,
message
):
return
report
(
position
,
"Warning: %s"
%
message
)
def
error
(
position
,
message
):
global
num_errors
num_errors
=
num_errors
+
1
return
report
(
position
,
message
)
Cython/Compiler/ExprNodes.py
View file @
3588f4a6
...
@@ -2,13 +2,14 @@
...
@@ -2,13 +2,14 @@
# Pyrex - Parse tree nodes for expressions
# Pyrex - Parse tree nodes for expressions
#
#
import
operator
from
string
import
join
from
string
import
join
from
Errors
import
error
,
InternalError
from
Errors
import
error
,
InternalError
import
Naming
import
Naming
from
Nodes
import
Node
from
Nodes
import
Node
import
PyrexTypes
import
PyrexTypes
from
PyrexTypes
import
py_object_type
,
c_long_type
,
typecast
from
PyrexTypes
import
py_object_type
,
c_long_type
,
typecast
,
error_type
import
Symtab
import
Symtab
import
Options
import
Options
...
@@ -208,6 +209,14 @@ class ExprNode(Node):
...
@@ -208,6 +209,14 @@ class ExprNode(Node):
# C type of the result_code expression).
# C type of the result_code expression).
return
self
.
result_ctype
or
self
.
type
return
self
.
result_ctype
or
self
.
type
def
compile_time_value
(
self
,
denv
):
# Return value of compile-time expression, or report error.
error
(
self
.
pos
,
"Invalid compile-time expression"
)
def
compile_time_value_error
(
self
,
e
):
error
(
self
.
pos
,
"Error in compile-time expression: %s: %s"
%
(
e
.
__class__
.
__name__
,
e
))
# ------------- Declaration Analysis ----------------
# ------------- Declaration Analysis ----------------
def
analyse_target_declaration
(
self
,
env
):
def
analyse_target_declaration
(
self
,
env
):
...
@@ -486,7 +495,7 @@ class ExprNode(Node):
...
@@ -486,7 +495,7 @@ class ExprNode(Node):
if
type
.
is_pyobject
or
type
.
is_ptr
or
type
.
is_float
:
if
type
.
is_pyobject
or
type
.
is_ptr
or
type
.
is_float
:
return
CoerceToBooleanNode
(
self
,
env
)
return
CoerceToBooleanNode
(
self
,
env
)
else
:
else
:
if
not
type
.
is_int
:
if
not
type
.
is_int
and
not
type
.
is_error
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Type '%s' not acceptable as a boolean"
%
type
)
"Type '%s' not acceptable as a boolean"
%
type
)
return
self
return
self
...
@@ -548,12 +557,18 @@ class NoneNode(PyConstNode):
...
@@ -548,12 +557,18 @@ class NoneNode(PyConstNode):
value
=
"Py_None"
value
=
"Py_None"
def
compile_time_value
(
self
,
denv
):
return
None
class
EllipsisNode
(
PyConstNode
):
class
EllipsisNode
(
PyConstNode
):
# '...' in a subscript list.
# '...' in a subscript list.
value
=
"Py_Ellipsis"
value
=
"Py_Ellipsis"
def
compile_time_value
(
self
,
denv
):
return
Ellipsis
class
ConstNode
(
AtomicExprNode
):
class
ConstNode
(
AtomicExprNode
):
# Abstract base type for literal constant nodes.
# Abstract base type for literal constant nodes.
...
@@ -586,6 +601,9 @@ class NullNode(ConstNode):
...
@@ -586,6 +601,9 @@ class NullNode(ConstNode):
class
CharNode
(
ConstNode
):
class
CharNode
(
ConstNode
):
type
=
PyrexTypes
.
c_char_type
type
=
PyrexTypes
.
c_char_type
def
compile_time_value
(
self
,
denv
):
return
ord
(
self
.
value
)
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
return
"'%s'"
%
self
.
value
return
"'%s'"
%
self
.
value
...
@@ -593,16 +611,25 @@ class CharNode(ConstNode):
...
@@ -593,16 +611,25 @@ class CharNode(ConstNode):
class
IntNode
(
ConstNode
):
class
IntNode
(
ConstNode
):
type
=
PyrexTypes
.
c_long_type
type
=
PyrexTypes
.
c_long_type
def
compile_time_value
(
self
,
denv
):
return
int
(
self
.
value
)
class
FloatNode
(
ConstNode
):
class
FloatNode
(
ConstNode
):
type
=
PyrexTypes
.
c_double_type
type
=
PyrexTypes
.
c_double_type
def
compile_time_value
(
self
,
denv
):
return
float
(
self
.
value
)
class
StringNode
(
ConstNode
):
class
StringNode
(
ConstNode
):
# entry Symtab.Entry
# entry Symtab.Entry
type
=
PyrexTypes
.
c_char_ptr_type
type
=
PyrexTypes
.
c_char_ptr_type
def
compile_time_value
(
self
,
denv
):
return
eval
(
'"%s"'
%
self
.
value
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
...
@@ -637,6 +664,9 @@ class LongNode(AtomicExprNode):
...
@@ -637,6 +664,9 @@ class LongNode(AtomicExprNode):
#
#
# value string
# value string
def
compile_time_value
(
self
,
denv
):
return
long
(
self
.
value
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
type
=
py_object_type
self
.
type
=
py_object_type
self
.
is_temp
=
1
self
.
is_temp
=
1
...
@@ -655,6 +685,9 @@ class ImagNode(AtomicExprNode):
...
@@ -655,6 +685,9 @@ class ImagNode(AtomicExprNode):
#
#
# value float imaginary part
# value float imaginary part
def
compile_time_value
(
self
,
denv
):
return
complex
(
0.0
,
self
.
value
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
type
=
py_object_type
self
.
type
=
py_object_type
self
.
is_temp
=
1
self
.
is_temp
=
1
...
@@ -672,10 +705,34 @@ class NameNode(AtomicExprNode):
...
@@ -672,10 +705,34 @@ class NameNode(AtomicExprNode):
# Reference to a local or global variable name.
# Reference to a local or global variable name.
#
#
# name string Python name of the variable
# name string Python name of the variable
#
# entry Entry Symbol table entry
# entry Entry Symbol table entry
# interned_cname string
is_name
=
1
is_name
=
1
def
compile_time_value
(
self
,
denv
):
try
:
return
denv
.
lookup
(
self
.
name
)
except
KeyError
:
error
(
self
.
pos
,
"Compile-time name '%s' not defined"
,
self
.
name
)
def
coerce_to
(
self
,
dst_type
,
env
):
# If coercing to a generic pyobject and this is a builtin
# C function with a Python equivalent, manufacture a NameNode
# referring to the Python builtin.
#print "NameNode.coerce_to:", self.name, dst_type ###
if
dst_type
is
py_object_type
:
entry
=
self
.
entry
if
entry
.
is_cfunction
:
var_entry
=
entry
.
as_variable
if
var_entry
:
node
=
NameNode
(
self
.
pos
,
name
=
self
.
name
)
node
.
entry
=
var_entry
node
.
analyse_rvalue_entry
(
env
)
return
node
return
AtomicExprNode
.
coerce_to
(
self
,
dst_type
,
env
)
def
analyse_as_module
(
self
,
env
):
def
analyse_as_module
(
self
,
env
):
# Try to interpret this as a reference to a cimported module.
# Try to interpret this as a reference to a cimported module.
# Returns the module scope, or None.
# Returns the module scope, or None.
...
@@ -689,50 +746,56 @@ class NameNode(AtomicExprNode):
...
@@ -689,50 +746,56 @@ class NameNode(AtomicExprNode):
# Returns the extension type, or None.
# Returns the extension type, or None.
entry
=
env
.
lookup
(
self
.
name
)
entry
=
env
.
lookup
(
self
.
name
)
if
entry
and
entry
.
is_type
and
entry
.
type
.
is_extension_type
:
if
entry
and
entry
.
is_type
and
entry
.
type
.
is_extension_type
:
return
entry
.
type
return
entry
.
type
return
None
else
:
return
None
def
analyse_target_declaration
(
self
,
env
):
def
analyse_target_declaration
(
self
,
env
):
self
.
entry
=
env
.
lookup_here
(
self
.
name
)
self
.
entry
=
env
.
lookup_here
(
self
.
name
)
if
not
self
.
entry
:
if
not
self
.
entry
:
#print "NameNode.analyse_target_declaration:", self.name ###
#print "...declaring as py_object_type" ###
self
.
entry
=
env
.
declare_var
(
self
.
name
,
py_object_type
,
self
.
pos
)
self
.
entry
=
env
.
declare_var
(
self
.
name
,
py_object_type
,
self
.
pos
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
entry
=
env
.
lookup
(
self
.
name
)
self
.
entry
=
env
.
lookup
(
self
.
name
)
if
not
self
.
entry
:
if
not
self
.
entry
:
self
.
entry
=
env
.
declare_builtin
(
self
.
name
,
self
.
pos
)
self
.
entry
=
env
.
declare_builtin
(
self
.
name
,
self
.
pos
)
self
.
analyse_rvalue_entry
(
env
)
def
analyse_target_types
(
self
,
env
):
self
.
analyse_entry
(
env
)
self
.
analyse_entry
(
env
)
if
not
self
.
is_lvalue
():
error
(
self
.
pos
,
"Assignment to non-lvalue '%s'"
%
self
.
name
)
self
.
type
=
PyrexTypes
.
error_type
def
analyse_entry
(
self
,
env
):
def
analyse_rvalue_entry
(
self
,
env
):
self
.
check_identifier_kind
()
#print "NameNode.analyse_rvalue_entry:", self.name ###
#print "Entry:", self.entry.__dict__ ###
self
.
analyse_entry
(
env
)
entry
=
self
.
entry
entry
=
self
.
entry
self
.
type
=
entry
.
type
if
entry
.
is_declared_generic
:
if
entry
.
is_declared_generic
:
self
.
result_ctype
=
py_object_type
self
.
result_ctype
=
py_object_type
## Reference to C array turns into pointer to first element.
#while self.type.is_array:
# self.type = self.type.element_ptr_type()
if
entry
.
is_pyglobal
or
entry
.
is_builtin
:
if
entry
.
is_pyglobal
or
entry
.
is_builtin
:
assert
self
.
type
.
is_pyobject
,
"Python global or builtin not a Python object"
self
.
is_temp
=
1
self
.
is_temp
=
1
if
Options
.
intern_names
:
if
Options
.
intern_names
:
env
.
use_utility_code
(
get_name_interned_utility_code
)
env
.
use_utility_code
(
get_name_interned_utility_code
)
else
:
else
:
env
.
use_utility_code
(
get_name_utility_code
)
env
.
use_utility_code
(
get_name_utility_code
)
def
analyse_target_types
(
self
,
env
):
def
analyse_entry
(
self
,
env
):
#print "NameNode.analyse_entry:", self.name ###
self
.
check_identifier_kind
()
self
.
check_identifier_kind
()
if
self
.
is_lvalue
():
entry
=
self
.
entry
self
.
type
=
self
.
entry
.
type
type
=
entry
.
type
else
:
self
.
type
=
type
error
(
self
.
pos
,
"Assignment to non-lvalue '%s'"
if
entry
.
is_pyglobal
or
entry
.
is_builtin
:
%
self
.
name
)
assert
type
.
is_pyobject
,
"Python global or builtin not a Python object"
self
.
type
=
PyrexTypes
.
error_type
if
Options
.
intern_names
:
self
.
interned_cname
=
env
.
intern
(
self
.
name
)
def
check_identifier_kind
(
self
):
def
check_identifier_kind
(
self
):
#print "NameNode.check_identifier_kind:", self.entry.name ###
#print "NameNode.check_identifier_kind:", self.entry.name ###
#print self.entry.__dict__ ###
entry
=
self
.
entry
entry
=
self
.
entry
entry
.
used
=
1
entry
.
used
=
1
if
not
(
entry
.
is_const
or
entry
.
is_variable
if
not
(
entry
.
is_const
or
entry
.
is_variable
...
@@ -776,8 +839,9 @@ class NameNode(AtomicExprNode):
...
@@ -776,8 +839,9 @@ class NameNode(AtomicExprNode):
return
self
.
entry
.
cname
return
self
.
entry
.
cname
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
if
not
hasattr
(
self
,
'entry'
):
assert
hasattr
(
self
,
'entry'
)
error
(
self
.
pos
,
"INTERNAL ERROR: NameNode has no entry attribute during code generation"
)
#if not hasattr(self, 'entry'):
# error(self.pos, "INTERNAL ERROR: NameNode has no entry attribute during code generation")
entry
=
self
.
entry
entry
=
self
.
entry
if
entry
is
None
:
if
entry
is
None
:
return
# There was an error earlier
return
# There was an error earlier
...
@@ -792,9 +856,10 @@ class NameNode(AtomicExprNode):
...
@@ -792,9 +856,10 @@ class NameNode(AtomicExprNode):
'%s = __Pyx_GetName(%s, %s); if (!%s) %s'
%
(
'%s = __Pyx_GetName(%s, %s); if (!%s) %s'
%
(
self
.
result_code
,
self
.
result_code
,
namespace
,
namespace
,
entry
.
interned_cname
,
#entry.interned_cname,
self
.
interned_cname
,
self
.
result_code
,
self
.
result_code
,
code
.
error_goto
(
self
.
pos
)))
code
.
error_goto
(
self
.
pos
)))
else
:
else
:
code
.
putln
(
code
.
putln
(
'%s = __Pyx_GetName(%s, "%s"); if (!%s) %s'
%
(
'%s = __Pyx_GetName(%s, "%s"); if (!%s) %s'
%
(
...
@@ -805,6 +870,7 @@ class NameNode(AtomicExprNode):
...
@@ -805,6 +870,7 @@ class NameNode(AtomicExprNode):
code
.
error_goto
(
self
.
pos
)))
code
.
error_goto
(
self
.
pos
)))
def
generate_assignment_code
(
self
,
rhs
,
code
):
def
generate_assignment_code
(
self
,
rhs
,
code
):
#print "NameNode.generate_assignment_code:", self.name ###
entry
=
self
.
entry
entry
=
self
.
entry
if
entry
is
None
:
if
entry
is
None
:
return
# There was an error earlier
return
# There was an error earlier
...
@@ -814,7 +880,8 @@ class NameNode(AtomicExprNode):
...
@@ -814,7 +880,8 @@ class NameNode(AtomicExprNode):
code
.
putln
(
code
.
putln
(
'if (PyObject_SetAttr(%s, %s, %s) < 0) %s'
%
(
'if (PyObject_SetAttr(%s, %s, %s) < 0) %s'
%
(
namespace
,
namespace
,
entry
.
interned_cname
,
#entry.interned_cname,
self
.
interned_cname
,
rhs
.
py_result
(),
rhs
.
py_result
(),
code
.
error_goto
(
self
.
pos
)))
code
.
error_goto
(
self
.
pos
)))
else
:
else
:
...
@@ -962,25 +1029,23 @@ class NextNode(AtomicExprNode):
...
@@ -962,25 +1029,23 @@ class NextNode(AtomicExprNode):
"break;"
)
"break;"
)
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
class
ExcValueNode
(
AtomicExprNode
):
class
ExcValueNode
(
AtomicExprNode
):
# Node created during analyse_types phase
# Node created during analyse_types phase
# of an ExceptClauseNode to fetch the current
# of an ExceptClauseNode to fetch the current
# exception value.
# exception value.
def
__init__
(
self
,
pos
,
env
):
def
__init__
(
self
,
pos
,
env
,
var
):
ExprNode
.
__init__
(
self
,
pos
)
ExprNode
.
__init__
(
self
,
pos
)
self
.
type
=
py_object_type
self
.
type
=
py_object_type
self
.
is_temp
=
1
self
.
var
=
var
env
.
use_utility_code
(
get_exception_utility_code
)
def
calculate_result_code
(
self
):
return
self
.
var
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
code
.
putln
(
pass
"%s = __Pyx_GetExcValue(); if (!%s) %s"
%
(
self
.
result_code
,
self
.
result_code
,
code
.
error_goto
(
self
.
pos
)))
class
TempNode
(
AtomicExprNode
):
class
TempNode
(
AtomicExprNode
):
...
@@ -1019,6 +1084,14 @@ class IndexNode(ExprNode):
...
@@ -1019,6 +1084,14 @@ class IndexNode(ExprNode):
subexprs
=
[
'base'
,
'index'
]
subexprs
=
[
'base'
,
'index'
]
def
compile_time_value
(
self
,
denv
):
base
=
self
.
base
.
compile_time_value
(
denv
)
index
=
self
.
index
.
compile_time_value
(
denv
)
try
:
return
base
[
index
]
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
is_ephemeral
(
self
):
def
is_ephemeral
(
self
):
return
self
.
base
.
is_ephemeral
()
return
self
.
base
.
is_ephemeral
()
...
@@ -1042,7 +1115,7 @@ class IndexNode(ExprNode):
...
@@ -1042,7 +1115,7 @@ class IndexNode(ExprNode):
self
.
type
=
PyrexTypes
.
error_type
self
.
type
=
PyrexTypes
.
error_type
if
self
.
index
.
type
.
is_pyobject
:
if
self
.
index
.
type
.
is_pyobject
:
self
.
index
=
self
.
index
.
coerce_to
(
self
.
index
=
self
.
index
.
coerce_to
(
PyrexTypes
.
c_
in
t_type
,
env
)
PyrexTypes
.
c_
py_ssize_
t_type
,
env
)
if
not
self
.
index
.
type
.
is_int
:
if
not
self
.
index
.
type
.
is_int
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Invalid index type '%s'"
%
"Invalid index type '%s'"
%
...
@@ -1104,6 +1177,15 @@ class SliceIndexNode(ExprNode):
...
@@ -1104,6 +1177,15 @@ class SliceIndexNode(ExprNode):
subexprs
=
[
'base'
,
'start'
,
'stop'
]
subexprs
=
[
'base'
,
'start'
,
'stop'
]
def
compile_time_value
(
self
,
denv
):
base
=
self
.
base
.
compile_time_value
(
denv
)
start
=
self
.
start
.
compile_time_value
(
denv
)
stop
=
self
.
stop
.
compile_time_value
(
denv
)
try
:
return
base
[
start
:
stop
]
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_target_declaration
(
self
,
env
):
def
analyse_target_declaration
(
self
,
env
):
pass
pass
...
@@ -1114,7 +1196,7 @@ class SliceIndexNode(ExprNode):
...
@@ -1114,7 +1196,7 @@ class SliceIndexNode(ExprNode):
if
self
.
stop
:
if
self
.
stop
:
self
.
stop
.
analyse_types
(
env
)
self
.
stop
.
analyse_types
(
env
)
self
.
base
=
self
.
base
.
coerce_to_pyobject
(
env
)
self
.
base
=
self
.
base
.
coerce_to_pyobject
(
env
)
c_int
=
PyrexTypes
.
c_
in
t_type
c_int
=
PyrexTypes
.
c_
py_ssize_
t_type
if
self
.
start
:
if
self
.
start
:
self
.
start
=
self
.
start
.
coerce_to
(
c_int
,
env
)
self
.
start
=
self
.
start
.
coerce_to
(
c_int
,
env
)
if
self
.
stop
:
if
self
.
stop
:
...
@@ -1164,7 +1246,7 @@ class SliceIndexNode(ExprNode):
...
@@ -1164,7 +1246,7 @@ class SliceIndexNode(ExprNode):
if
self
.
stop
:
if
self
.
stop
:
return
self
.
stop
.
result_code
return
self
.
stop
.
result_code
else
:
else
:
return
"
0x7fffffff
"
return
"
PY_SSIZE_T_MAX
"
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
# self.result_code is not used, but this method must exist
# self.result_code is not used, but this method must exist
...
@@ -1178,6 +1260,15 @@ class SliceNode(ExprNode):
...
@@ -1178,6 +1260,15 @@ class SliceNode(ExprNode):
# stop ExprNode
# stop ExprNode
# step ExprNode
# step ExprNode
def
compile_time_value
(
self
,
denv
):
start
=
self
.
start
.
compile_time_value
(
denv
)
stop
=
self
.
stop
.
compile_time_value
(
denv
)
step
=
step
.
step
.
compile_time_value
(
denv
)
try
:
return
slice
(
start
,
stop
,
step
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
subexprs
=
[
'start'
,
'stop'
,
'step'
]
subexprs
=
[
'start'
,
'stop'
,
'step'
]
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
...
@@ -1216,6 +1307,14 @@ class SimpleCallNode(ExprNode):
...
@@ -1216,6 +1307,14 @@ class SimpleCallNode(ExprNode):
coerced_self
=
None
coerced_self
=
None
arg_tuple
=
None
arg_tuple
=
None
def
compile_time_value
(
self
,
denv
):
function
=
self
.
function
.
compile_time_value
(
denv
)
args
=
[
arg
.
compile_time_value
(
denv
)
for
arg
in
self
.
args
]
try
:
return
function
(
*
args
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
function
=
self
.
function
function
=
self
.
function
function
.
is_called
=
1
function
.
is_called
=
1
...
@@ -1371,6 +1470,17 @@ class GeneralCallNode(ExprNode):
...
@@ -1371,6 +1470,17 @@ class GeneralCallNode(ExprNode):
subexprs
=
[
'function'
,
'positional_args'
,
'keyword_args'
,
'starstar_arg'
]
subexprs
=
[
'function'
,
'positional_args'
,
'keyword_args'
,
'starstar_arg'
]
def
compile_time_value
(
self
,
denv
):
function
=
self
.
function
.
compile_time_value
(
denv
)
positional_args
=
self
.
positional_args
.
compile_time_value
(
denv
)
keyword_args
=
self
.
keyword_args
.
compile_time_value
(
denv
)
starstar_arg
=
self
.
starstar_arg
.
compile_time_value
(
denv
)
try
:
keyword_args
.
update
(
starstar_arg
)
return
function
(
*
positional_args
,
**
keyword_args
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
function
.
analyse_types
(
env
)
self
.
function
.
analyse_types
(
env
)
self
.
positional_args
.
analyse_types
(
env
)
self
.
positional_args
.
analyse_types
(
env
)
...
@@ -1426,6 +1536,13 @@ class AsTupleNode(ExprNode):
...
@@ -1426,6 +1536,13 @@ class AsTupleNode(ExprNode):
subexprs
=
[
'arg'
]
subexprs
=
[
'arg'
]
def
compile_time_value
(
self
,
denv
):
arg
=
self
.
arg
.
compile_time_value
(
denv
)
try
:
return
tuple
(
arg
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
arg
.
analyse_types
(
env
)
self
.
arg
.
analyse_types
(
env
)
self
.
arg
=
self
.
arg
.
coerce_to_pyobject
(
env
)
self
.
arg
=
self
.
arg
.
coerce_to_pyobject
(
env
)
...
@@ -1463,6 +1580,18 @@ class AttributeNode(ExprNode):
...
@@ -1463,6 +1580,18 @@ class AttributeNode(ExprNode):
entry
=
None
entry
=
None
is_called
=
0
is_called
=
0
def
compile_time_value
(
self
,
denv
):
attr
=
self
.
attribute
if
attr
.
beginswith
(
"__"
)
and
attr
.
endswith
(
"__"
):
self
.
error
(
"Invalid attribute name '%s' in compile-time expression"
%
attr
)
return
None
obj
=
self
.
arg
.
compile_time_value
(
denv
)
try
:
return
getattr
(
obj
,
attr
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_target_declaration
(
self
,
env
):
def
analyse_target_declaration
(
self
,
env
):
pass
pass
...
@@ -1542,7 +1671,7 @@ class AttributeNode(ExprNode):
...
@@ -1542,7 +1671,7 @@ class AttributeNode(ExprNode):
if
target
:
if
target
:
NameNode
.
analyse_target_types
(
self
,
env
)
NameNode
.
analyse_target_types
(
self
,
env
)
else
:
else
:
NameNode
.
analyse_entry
(
self
,
env
)
NameNode
.
analyse_
rvalue_
entry
(
self
,
env
)
def
analyse_as_ordinary_attribute
(
self
,
env
,
target
):
def
analyse_as_ordinary_attribute
(
self
,
env
,
target
):
self
.
obj
.
analyse_types
(
env
)
self
.
obj
.
analyse_types
(
env
)
...
@@ -1729,6 +1858,9 @@ class SequenceNode(ExprNode):
...
@@ -1729,6 +1858,9 @@ class SequenceNode(ExprNode):
is_sequence_constructor
=
1
is_sequence_constructor
=
1
unpacked_items
=
None
unpacked_items
=
None
def
compile_time_value_list
(
self
,
denv
):
return
[
arg
.
compile_time_value
(
denv
)
for
arg
in
self
.
args
]
def
analyse_target_declaration
(
self
,
env
):
def
analyse_target_declaration
(
self
,
env
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
arg
.
analyse_target_declaration
(
env
)
arg
.
analyse_target_declaration
(
env
)
...
@@ -1809,6 +1941,13 @@ class SequenceNode(ExprNode):
...
@@ -1809,6 +1941,13 @@ class SequenceNode(ExprNode):
class
TupleNode
(
SequenceNode
):
class
TupleNode
(
SequenceNode
):
# Tuple constructor.
# Tuple constructor.
def
compile_time_value
(
self
,
denv
):
values
=
self
.
compile_time_value_list
(
denv
)
try
:
return
tuple
(
values
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
generate_operation_code
(
self
,
code
):
def
generate_operation_code
(
self
,
code
):
code
.
putln
(
code
.
putln
(
"%s = PyTuple_New(%s); if (!%s) %s"
%
(
"%s = PyTuple_New(%s); if (!%s) %s"
%
(
...
@@ -1837,6 +1976,9 @@ class TupleNode(SequenceNode):
...
@@ -1837,6 +1976,9 @@ class TupleNode(SequenceNode):
class
ListNode
(
SequenceNode
):
class
ListNode
(
SequenceNode
):
# List constructor.
# List constructor.
def
compile_time_value
(
self
,
denv
):
return
self
.
compile_time_value_list
(
denv
)
def
generate_operation_code
(
self
,
code
):
def
generate_operation_code
(
self
,
code
):
code
.
putln
(
"%s = PyList_New(%s); if (!%s) %s"
%
code
.
putln
(
"%s = PyList_New(%s); if (!%s) %s"
%
(
self
.
result_code
,
(
self
.
result_code
,
...
@@ -1866,6 +2008,14 @@ class DictNode(ExprNode):
...
@@ -1866,6 +2008,14 @@ class DictNode(ExprNode):
#
#
# key_value_pairs [(ExprNode, ExprNode)]
# key_value_pairs [(ExprNode, ExprNode)]
def
compile_time_value
(
self
,
denv
):
pairs
=
[(
key
.
compile_time_value
(
denv
),
value
.
compile_time_value
(
denv
))
for
(
key
,
value
)
in
self
.
key_value_pairs
]
try
:
return
dict
(
pairs
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
new_pairs
=
[]
new_pairs
=
[]
for
key
,
value
in
self
.
key_value_pairs
:
for
key
,
value
in
self
.
key_value_pairs
:
...
@@ -2002,6 +2152,13 @@ class PyCFunctionNode(AtomicExprNode):
...
@@ -2002,6 +2152,13 @@ class PyCFunctionNode(AtomicExprNode):
#
#
#-------------------------------------------------------------------
#-------------------------------------------------------------------
compile_time_unary_operators
=
{
'not'
:
operator
.
not_
,
'~'
:
operator
.
inv
,
'-'
:
operator
.
neg
,
'+'
:
operator
.
pos
,
}
class
UnopNode
(
ExprNode
):
class
UnopNode
(
ExprNode
):
# operator string
# operator string
# operand ExprNode
# operand ExprNode
...
@@ -2016,6 +2173,18 @@ class UnopNode(ExprNode):
...
@@ -2016,6 +2173,18 @@ class UnopNode(ExprNode):
subexprs
=
[
'operand'
]
subexprs
=
[
'operand'
]
def
compile_time_value
(
self
,
denv
):
func
=
compile_time_unary_operators
.
get
(
self
.
operator
)
if
not
func
:
error
(
self
.
pos
,
"Unary '%s' not supported in compile-time expression"
%
self
.
operator
)
operand
=
self
.
operand
.
compile_time_value
(
denv
)
try
:
return
func
(
operand
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand
.
analyse_types
(
env
)
self
.
operand
.
analyse_types
(
env
)
if
self
.
is_py_operation
():
if
self
.
is_py_operation
():
...
@@ -2063,6 +2232,13 @@ class NotNode(ExprNode):
...
@@ -2063,6 +2232,13 @@ class NotNode(ExprNode):
#
#
# operand ExprNode
# operand ExprNode
def
compile_time_value
(
self
,
denv
):
operand
=
self
.
operand
.
compile_time_value
(
denv
)
try
:
return
not
operand
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
subexprs
=
[
'operand'
]
subexprs
=
[
'operand'
]
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
...
@@ -2185,6 +2361,10 @@ class TypecastNode(ExprNode):
...
@@ -2185,6 +2361,10 @@ class TypecastNode(ExprNode):
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
base_type
=
self
.
base_type
.
analyse
(
env
)
base_type
=
self
.
base_type
.
analyse
(
env
)
_
,
self
.
type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
_
,
self
.
type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
if
self
.
type
.
is_cfunction
:
error
(
self
.
pos
,
"Cannot cast to a function type"
)
self
.
type
=
PyrexTypes
.
error_type
self
.
operand
.
analyse_types
(
env
)
self
.
operand
.
analyse_types
(
env
)
to_py
=
self
.
type
.
is_pyobject
to_py
=
self
.
type
.
is_pyobject
from_py
=
self
.
operand
.
type
.
is_pyobject
from_py
=
self
.
operand
.
type
.
is_pyobject
...
@@ -2277,6 +2457,40 @@ class SizeofVarNode(SizeofNode):
...
@@ -2277,6 +2457,40 @@ class SizeofVarNode(SizeofNode):
#
#
#-------------------------------------------------------------------
#-------------------------------------------------------------------
compile_time_binary_operators
=
{
'<'
:
operator
.
lt
,
'<='
:
operator
.
le
,
'='
:
operator
.
eq
,
'!='
:
operator
.
ne
,
'>='
:
operator
.
ge
,
'>'
:
operator
.
gt
,
'is'
:
operator
.
is_
,
'is_not'
:
operator
.
is_not
,
'+'
:
operator
.
add
,
'&'
:
operator
.
and_
,
'/'
:
operator
.
div
,
'//'
:
operator
.
floordiv
,
'<<'
:
operator
.
lshift
,
'%'
:
operator
.
mod
,
'*'
:
operator
.
mul
,
'|'
:
operator
.
or_
,
'**'
:
operator
.
pow
,
'>>'
:
operator
.
rshift
,
'-'
:
operator
.
sub
,
#'/': operator.truediv,
'^'
:
operator
.
xor
,
'in'
:
lambda
x
,
y
:
x
in
y
,
'not_in'
:
lambda
x
,
y
:
x
not
in
y
,
}
def
get_compile_time_binop
(
node
):
func
=
compile_time_binary_operators
.
get
(
node
.
operator
)
if
not
func
:
error
(
node
.
pos
,
"Binary '%s' not supported in compile-time expression"
%
self
.
operator
)
return
func
class
BinopNode
(
ExprNode
):
class
BinopNode
(
ExprNode
):
# operator string
# operator string
# operand1 ExprNode
# operand1 ExprNode
...
@@ -2292,6 +2506,15 @@ class BinopNode(ExprNode):
...
@@ -2292,6 +2506,15 @@ class BinopNode(ExprNode):
subexprs
=
[
'operand1'
,
'operand2'
]
subexprs
=
[
'operand1'
,
'operand2'
]
def
compile_time_value
(
self
,
denv
):
func
=
get_compile_time_binop
(
self
)
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
operand2
=
self
.
operand2
.
compile_time_value
(
denv
)
try
:
return
func
(
operand1
,
operand2
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand1
.
analyse_types
(
env
)
self
.
operand1
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
...
@@ -2350,6 +2573,10 @@ class NumBinopNode(BinopNode):
...
@@ -2350,6 +2573,10 @@ class NumBinopNode(BinopNode):
def
analyse_c_operation
(
self
,
env
):
def
analyse_c_operation
(
self
,
env
):
type1
=
self
.
operand1
.
type
type1
=
self
.
operand1
.
type
type2
=
self
.
operand2
.
type
type2
=
self
.
operand2
.
type
if
self
.
operator
==
"**"
and
type1
.
is_int
and
type2
.
is_int
:
error
(
self
.
pos
,
"** with two C int types is ambiguous"
)
self
.
type
=
error_type
return
self
.
type
=
self
.
compute_c_result_type
(
type1
,
type2
)
self
.
type
=
self
.
compute_c_result_type
(
type1
,
type2
)
if
not
self
.
type
:
if
not
self
.
type
:
self
.
type_error
()
self
.
type_error
()
...
@@ -2361,7 +2588,9 @@ class NumBinopNode(BinopNode):
...
@@ -2361,7 +2588,9 @@ class NumBinopNode(BinopNode):
return
None
return
None
def
c_types_okay
(
self
,
type1
,
type2
):
def
c_types_okay
(
self
,
type1
,
type2
):
return
type1
.
is_numeric
and
type2
.
is_numeric
#print "NumBinopNode.c_types_okay:", type1, type2 ###
return
(
type1
.
is_numeric
or
type1
.
is_enum
)
\
and
(
type2
.
is_numeric
or
type2
.
is_enum
)
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
return
"(%s %s %s)"
%
(
return
"(%s %s %s)"
%
(
...
@@ -2391,7 +2620,9 @@ class IntBinopNode(NumBinopNode):
...
@@ -2391,7 +2620,9 @@ class IntBinopNode(NumBinopNode):
# Binary operation taking integer arguments.
# Binary operation taking integer arguments.
def
c_types_okay
(
self
,
type1
,
type2
):
def
c_types_okay
(
self
,
type1
,
type2
):
return
type1
.
is_int
and
type2
.
is_int
#print "IntBinopNode.c_types_okay:", type1, type2 ###
return
(
type1
.
is_int
or
type1
.
is_enum
)
\
and
(
type2
.
is_int
or
type2
.
is_enum
)
class
AddNode
(
NumBinopNode
):
class
AddNode
(
NumBinopNode
):
...
@@ -2405,9 +2636,10 @@ class AddNode(NumBinopNode):
...
@@ -2405,9 +2636,10 @@ class AddNode(NumBinopNode):
return
NumBinopNode
.
is_py_operation
(
self
)
return
NumBinopNode
.
is_py_operation
(
self
)
def
compute_c_result_type
(
self
,
type1
,
type2
):
def
compute_c_result_type
(
self
,
type1
,
type2
):
if
type1
.
is_ptr
and
type2
.
is_int
:
#print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
if
(
type1
.
is_ptr
or
type1
.
is_array
)
and
(
type2
.
is_int
or
type2
.
is_enum
):
return
type1
return
type1
elif
type1
.
is_int
and
type2
.
is_ptr
:
elif
(
type2
.
is_ptr
or
type2
.
is_array
)
and
(
type1
.
is_int
or
type1
.
is_enum
)
:
return
type2
return
type2
else
:
else
:
return
NumBinopNode
.
compute_c_result_type
(
return
NumBinopNode
.
compute_c_result_type
(
...
@@ -2418,9 +2650,9 @@ class SubNode(NumBinopNode):
...
@@ -2418,9 +2650,9 @@ class SubNode(NumBinopNode):
# '-' operator.
# '-' operator.
def
compute_c_result_type
(
self
,
type1
,
type2
):
def
compute_c_result_type
(
self
,
type1
,
type2
):
if
type1
.
is_ptr
and
type2
.
is_int
:
if
(
type1
.
is_ptr
or
type1
.
is_array
)
and
(
type2
.
is_int
or
type2
.
is_enum
)
:
return
type1
return
type1
elif
type1
.
is_ptr
and
type2
.
is_ptr
:
elif
(
type1
.
is_ptr
or
type1
.
is_array
)
and
(
type2
.
is_ptr
or
type2
.
is_array
)
:
return
PyrexTypes
.
c_int_type
return
PyrexTypes
.
c_int_type
else
:
else
:
return
NumBinopNode
.
compute_c_result_type
(
return
NumBinopNode
.
compute_c_result_type
(
...
@@ -2479,6 +2711,14 @@ class BoolBinopNode(ExprNode):
...
@@ -2479,6 +2711,14 @@ class BoolBinopNode(ExprNode):
subexprs
=
[
'operand1'
,
'operand2'
,
'temp_bool'
]
subexprs
=
[
'operand1'
,
'operand2'
,
'temp_bool'
]
def
compile_time_value
(
self
,
denv
):
if
self
.
operator
==
'and'
:
return
self
.
operand1
.
compile_time_value
(
denv
)
\
and
self
.
operand2
.
compile_time_value
(
denv
)
else
:
return
self
.
operand1
.
compile_time_value
(
denv
)
\
or
self
.
operand2
.
compile_time_value
(
denv
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand1
.
analyse_types
(
env
)
self
.
operand1
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
...
@@ -2571,6 +2811,19 @@ class CmpNode:
...
@@ -2571,6 +2811,19 @@ class CmpNode:
# Mixin class containing code common to PrimaryCmpNodes
# Mixin class containing code common to PrimaryCmpNodes
# and CascadedCmpNodes.
# and CascadedCmpNodes.
def
cascaded_compile_time_value
(
self
,
operand1
,
denv
):
func
=
get_compile_time_binop
(
self
)
operand2
=
self
.
operand
.
compile_time_value
(
denv
)
try
:
result
=
func
(
operand1
,
operand2
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
if
result
:
cascade
=
self
.
cascade
if
cascade
:
result
=
result
and
cascade
.
compile_time_value
(
operand2
,
denv
)
return
result
def
is_python_comparison
(
self
):
def
is_python_comparison
(
self
):
return
(
self
.
has_python_operands
()
return
(
self
.
has_python_operands
()
or
(
self
.
cascade
and
self
.
cascade
.
is_python_comparison
())
or
(
self
.
cascade
and
self
.
cascade
.
is_python_comparison
())
...
@@ -2626,11 +2879,20 @@ class CmpNode:
...
@@ -2626,11 +2879,20 @@ class CmpNode:
"%s = %s %s 0;"
%
(
"%s = %s %s 0;"
%
(
result_code
,
result_code
,
op
))
result_code
,
result_code
,
op
))
else
:
else
:
type1
=
operand1
.
type
type2
=
operand2
.
type
if
(
type1
.
is_extension_type
or
type2
.
is_extension_type
)
\
and
not
type1
.
same_as
(
type2
):
common_type
=
py_object_type
else
:
common_type
=
type1
code1
=
operand1
.
result_as
(
common_type
)
code2
=
operand2
.
result_as
(
common_type
)
code
.
putln
(
"%s = %s %s %s;"
%
(
code
.
putln
(
"%s = %s %s %s;"
%
(
result_code
,
result_code
,
operand1
.
result_code
,
code1
,
self
.
c_operator
(
op
),
self
.
c_operator
(
op
),
operand2
.
result_code
))
code2
))
def
c_operator
(
self
,
op
):
def
c_operator
(
self
,
op
):
if
op
==
'is'
:
if
op
==
'is'
:
...
@@ -2657,6 +2919,10 @@ class PrimaryCmpNode(ExprNode, CmpNode):
...
@@ -2657,6 +2919,10 @@ class PrimaryCmpNode(ExprNode, CmpNode):
cascade
=
None
cascade
=
None
def
compile_time_value
(
self
,
denv
):
operand1
=
self
.
operand
.
compile_time_value
(
denv
)
return
self
.
cascaded_compile_time_value
(
operand1
,
denv
)
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
operand1
.
analyse_types
(
env
)
self
.
operand1
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
...
@@ -2937,9 +3203,14 @@ class CoerceFromPyTypeNode(CoercionNode):
...
@@ -2937,9 +3203,14 @@ class CoerceFromPyTypeNode(CoercionNode):
rhs
=
"%s(%s)"
%
(
function
,
operand
)
rhs
=
"%s(%s)"
%
(
function
,
operand
)
if
self
.
type
.
is_enum
:
if
self
.
type
.
is_enum
:
rhs
=
typecast
(
self
.
type
,
c_long_type
,
rhs
)
rhs
=
typecast
(
self
.
type
,
c_long_type
,
rhs
)
code
.
putln
(
'%s = %s; if (PyErr_Occurred()) %s'
%
(
if
self
.
type
.
is_string
:
err_code
=
"!%s"
%
self
.
result_code
else
:
err_code
=
"PyErr_Occurred()"
code
.
putln
(
'%s = %s; if (%s) %s'
%
(
self
.
result_code
,
self
.
result_code
,
rhs
,
rhs
,
err_code
,
code
.
error_goto
(
self
.
pos
)))
code
.
error_goto
(
self
.
pos
)))
...
@@ -3095,42 +3366,42 @@ bad:
...
@@ -3095,42 +3366,42 @@ bad:
}]
}]
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
#
get_exception_utility_code
=
[
#
get_exception_utility_code = [
"""
#
"""
static PyObject *__Pyx_GetExcValue(void); /*proto*/
#
static PyObject *__Pyx_GetExcValue(void); /*proto*/
"""
,
"""
#
""","""
static PyObject *__Pyx_GetExcValue(void) {
#
static PyObject *__Pyx_GetExcValue(void) {
PyObject *type = 0, *value = 0, *tb = 0;
#
PyObject *type = 0, *value = 0, *tb = 0;
PyObject *result = 0;
#
PyObject *result = 0;
PyThreadState *tstate = PyThreadState_Get();
#
PyThreadState *tstate = PyThreadState_Get();
PyErr_Fetch(&type, &value, &tb);
#
PyErr_Fetch(&type, &value, &tb);
PyErr_NormalizeException(&type, &value, &tb);
#
PyErr_NormalizeException(&type, &value, &tb);
if (PyErr_Occurred())
#
if (PyErr_Occurred())
goto bad;
#
goto bad;
if (!value) {
#
if (!value) {
value = Py_None;
#
value = Py_None;
Py_INCREF(value);
#
Py_INCREF(value);
}
#
}
Py_XDECREF(tstate->exc_type);
#
Py_XDECREF(tstate->exc_type);
Py_XDECREF(tstate->exc_value);
#
Py_XDECREF(tstate->exc_value);
Py_XDECREF(tstate->exc_traceback);
#
Py_XDECREF(tstate->exc_traceback);
tstate->exc_type = type;
#
tstate->exc_type = type;
tstate->exc_value = value;
#
tstate->exc_value = value;
tstate->exc_traceback = tb;
#
tstate->exc_traceback = tb;
result = value;
#
result = value;
Py_XINCREF(result);
#
Py_XINCREF(result);
type = 0;
#
type = 0;
value = 0;
#
value = 0;
tb = 0;
#
tb = 0;
bad:
#
bad:
Py_XDECREF(type);
#
Py_XDECREF(type);
Py_XDECREF(value);
#
Py_XDECREF(value);
Py_XDECREF(tb);
#
Py_XDECREF(tb);
return result;
#
return result;
}
#
}
"""
]
#
"""]
#
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
unpacking_utility_code
=
[
unpacking_utility_code
=
[
...
...
Cython/Compiler/Main.py
View file @
3588f4a6
...
@@ -17,6 +17,8 @@ import Parsing
...
@@ -17,6 +17,8 @@ import Parsing
from
Symtab
import
BuiltinScope
,
ModuleScope
from
Symtab
import
BuiltinScope
,
ModuleScope
import
Code
import
Code
from
Pyrex.Utils
import
replace_suffix
from
Pyrex.Utils
import
replace_suffix
import
Builtin
from
Pyrex
import
Utils
verbose
=
0
verbose
=
0
...
@@ -31,7 +33,8 @@ class Context:
...
@@ -31,7 +33,8 @@ class Context:
# include_directories [string]
# include_directories [string]
def
__init__
(
self
,
include_directories
):
def
__init__
(
self
,
include_directories
):
self
.
modules
=
{
"__builtin__"
:
BuiltinScope
()}
#self.modules = {"__builtin__" : BuiltinScope()}
self
.
modules
=
{
"__builtin__"
:
Builtin
.
builtin_scope
}
self
.
include_directories
=
include_directories
self
.
include_directories
=
include_directories
def
find_module
(
self
,
module_name
,
def
find_module
(
self
,
module_name
,
...
@@ -171,22 +174,29 @@ class Context:
...
@@ -171,22 +174,29 @@ class Context:
else
:
else
:
c_suffix
=
".c"
c_suffix
=
".c"
result
.
c_file
=
replace_suffix
(
source
,
c_suffix
)
result
.
c_file
=
replace_suffix
(
source
,
c_suffix
)
c_stat
=
None
if
result
.
c_file
:
try
:
c_stat
=
os
.
stat
(
result
.
c_file
)
except
EnvironmentError
:
pass
module_name
=
self
.
extract_module_name
(
source
)
module_name
=
self
.
extract_module_name
(
source
)
initial_pos
=
(
source
,
1
,
0
)
initial_pos
=
(
source
,
1
,
0
)
scope
=
self
.
find_module
(
module_name
,
pos
=
initial_pos
,
need_pxd
=
0
)
scope
=
self
.
find_module
(
module_name
,
pos
=
initial_pos
,
need_pxd
=
0
)
errors_occurred
=
False
errors_occurred
=
False
try
:
try
:
tree
=
self
.
parse
(
source
,
scope
.
type_names
,
pxd
=
0
)
tree
=
self
.
parse
(
source
,
scope
.
type_names
,
pxd
=
0
)
tree
.
process_implementation
(
scope
,
result
)
tree
.
process_implementation
(
scope
,
options
,
result
)
except
CompileError
:
except
CompileError
:
errors_occurred
=
True
errors_occurred
=
True
Errors
.
close_listing_file
()
Errors
.
close_listing_file
()
result
.
num_errors
=
Errors
.
num_errors
result
.
num_errors
=
Errors
.
num_errors
if
result
.
num_errors
>
0
:
if
result
.
num_errors
>
0
:
errors_occurred
=
True
errors_occurred
=
True
if
errors_occurred
:
if
errors_occurred
and
result
.
c_file
:
try
:
try
:
os
.
unlink
(
result
.
c_file
)
#os.unlink(result.c_file)
Utils
.
castrate_file
(
result
.
c_file
,
c_stat
)
except
EnvironmentError
:
except
EnvironmentError
:
pass
pass
result
.
c_file
=
None
result
.
c_file
=
None
...
@@ -216,6 +226,7 @@ class CompilationOptions:
...
@@ -216,6 +226,7 @@ class CompilationOptions:
errors_to_stderr boolean Echo errors to stderr when using .lis
errors_to_stderr boolean Echo errors to stderr when using .lis
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
Following options are experimental and only used on MacOSX:
Following options are experimental and only used on MacOSX:
...
@@ -229,7 +240,11 @@ class CompilationOptions:
...
@@ -229,7 +240,11 @@ class CompilationOptions:
self
.
include_path
=
[]
self
.
include_path
=
[]
self
.
objects
=
[]
self
.
objects
=
[]
if
defaults
:
if
defaults
:
self
.
__dict__
.
update
(
defaults
.
__dict__
)
if
isinstance
(
defaults
,
CompilationOptions
):
defaults
=
defaults
.
__dict__
else
:
defaults
=
default_options
self
.
__dict__
.
update
(
defaults
)
self
.
__dict__
.
update
(
kw
)
self
.
__dict__
.
update
(
kw
)
...
@@ -240,6 +255,7 @@ class CompilationResult:
...
@@ -240,6 +255,7 @@ class CompilationResult:
c_file string or None The generated C source file
c_file string or None The generated C source file
h_file string or None The generated C header file
h_file string or None The generated C header file
i_file string or None The generated .pxi file
i_file string or None The generated .pxi file
api_file string or None The generated C API .h file
listing_file string or None File of error messages
listing_file string or None File of error messages
object_file string or None Result of compiling the C file
object_file string or None Result of compiling the C file
extension_file string or None Result of linking the object file
extension_file string or None Result of linking the object file
...
@@ -250,6 +266,7 @@ class CompilationResult:
...
@@ -250,6 +266,7 @@ class CompilationResult:
self
.
c_file
=
None
self
.
c_file
=
None
self
.
h_file
=
None
self
.
h_file
=
None
self
.
i_file
=
None
self
.
i_file
=
None
self
.
api_file
=
None
self
.
listing_file
=
None
self
.
listing_file
=
None
self
.
object_file
=
None
self
.
object_file
=
None
self
.
extension_file
=
None
self
.
extension_file
=
None
...
@@ -307,18 +324,19 @@ def main(command_line = 0):
...
@@ -307,18 +324,19 @@ def main(command_line = 0):
#
#
#------------------------------------------------------------------------
#------------------------------------------------------------------------
default_options
=
CompilationOptions
(
default_options
=
dict
(
show_version
=
0
,
show_version
=
0
,
use_listing_file
=
0
,
use_listing_file
=
0
,
errors_to_stderr
=
1
,
errors_to_stderr
=
1
,
c_only
=
1
,
c_only
=
1
,
obj_only
=
1
,
obj_only
=
1
,
cplus
=
0
,
cplus
=
0
,
output_file
=
None
)
output_file
=
None
,
generate_pxi
=
0
)
if
sys
.
platform
==
"mac"
:
if
sys
.
platform
==
"mac"
:
from
Pyrex.Mac.MacSystem
import
c_compile
,
c_link
,
CCompilerError
from
Pyrex.Mac.MacSystem
import
c_compile
,
c_link
,
CCompilerError
default_options
.
use_listing_file
=
1
default_options
[
'use_listing_file'
]
=
1
elif
sys
.
platform
==
"darwin"
:
elif
sys
.
platform
==
"darwin"
:
from
Pyrex.Mac.DarwinSystem
import
c_compile
,
c_link
,
CCompilerError
from
Pyrex.Mac.DarwinSystem
import
c_compile
,
c_link
,
CCompilerError
else
:
else
:
...
...
Cython/Compiler/ModuleNode.py
View file @
3588f4a6
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
import
os
,
time
import
os
,
time
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
from
PyrexTypes
import
CPtrType
import
Code
import
Code
import
Naming
import
Naming
...
@@ -20,55 +21,169 @@ from Pyrex.Utils import open_new_file, replace_suffix
...
@@ -20,55 +21,169 @@ from Pyrex.Utils import open_new_file, replace_suffix
class
ModuleNode
(
Nodes
.
Node
,
Nodes
.
BlockNode
):
class
ModuleNode
(
Nodes
.
Node
,
Nodes
.
BlockNode
):
# doc string or None
# doc string or None
# body StatListNode
# body StatListNode
#
# referenced_modules [ModuleScope]
# module_temp_cname string
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
env
.
doc
=
self
.
doc
env
.
doc
=
self
.
doc
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
def
process_implementation
(
self
,
env
,
result
):
def
process_implementation
(
self
,
env
,
options
,
result
):
self
.
analyse_declarations
(
env
)
self
.
analyse_declarations
(
env
)
env
.
check_c_classes
()
env
.
check_c_classes
()
self
.
body
.
analyse_expressions
(
env
)
self
.
body
.
analyse_expressions
(
env
)
env
.
return_type
=
PyrexTypes
.
c_void_type
env
.
return_type
=
PyrexTypes
.
c_void_type
self
.
referenced_modules
=
[]
self
.
find_referenced_modules
(
env
,
self
.
referenced_modules
,
{})
if
self
.
has_imported_c_functions
():
self
.
module_temp_cname
=
env
.
allocate_temp_pyobject
()
env
.
release_temp
(
self
.
module_temp_cname
)
self
.
generate_c_code
(
env
,
result
)
self
.
generate_c_code
(
env
,
result
)
self
.
generate_h_code
(
env
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_api_code
(
env
,
result
)
def
generate_h_code
(
self
,
env
,
result
):
def
has_imported_c_functions
(
self
):
public_vars_and_funcs
=
[]
for
module
in
self
.
referenced_modules
:
for
entry
in
module
.
cfunc_entries
:
if
entry
.
defined_in_pxd
:
return
1
return
0
def
generate_h_code
(
self
,
env
,
options
,
result
):
public_vars
=
[]
public_funcs
=
[]
public_extension_types
=
[]
public_extension_types
=
[]
for
entry
in
env
.
var_entries
:
for
entry
in
env
.
var_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_vars
_and_funcs
.
append
(
entry
)
public_vars
.
append
(
entry
)
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_
vars_and_
funcs
.
append
(
entry
)
public_funcs
.
append
(
entry
)
for
entry
in
env
.
c_class_entries
:
for
entry
in
env
.
c_class_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_extension_types
.
append
(
entry
)
public_extension_types
.
append
(
entry
)
if
public_vars
_and
_funcs
or
public_extension_types
:
if
public_vars
or
public
_funcs
or
public_extension_types
:
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
result
.
i_file
=
replace_suffix
(
result
.
c_file
,
".pxi"
)
h_code
=
Code
.
CCodeWriter
(
open_new_file
(
result
.
h_file
))
h_code
=
Code
.
CCodeWriter
(
open_new_file
(
result
.
h_file
))
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
if
options
.
generate_pxi
:
result
.
i_file
=
replace_suffix
(
result
.
c_file
,
".pxi"
)
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
else
:
i_code
=
None
guard
=
Naming
.
h_guard_prefix
+
env
.
qualified_name
.
replace
(
"."
,
"__"
)
h_code
.
put_h_guard
(
guard
)
self
.
generate_extern_c_macro_definition
(
h_code
)
self
.
generate_extern_c_macro_definition
(
h_code
)
for
entry
in
public_vars_and_funcs
:
self
.
generate_type_header_code
(
env
,
h_code
)
h_code
.
putln
(
"%s %s;"
%
(
h_code
.
putln
(
""
)
Naming
.
extern_c_macro
,
h_code
.
putln
(
"#ifndef %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
entry
.
type
.
declaration_code
(
if
public_vars
:
entry
.
cname
,
dll_linkage
=
"DL_IMPORT"
)))
h_code
.
putln
(
""
)
i_code
.
putln
(
"cdef extern %s"
%
for
entry
in
public_vars
:
entry
.
type
.
declaration_code
(
entry
.
cname
,
pyrex
=
1
))
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
for
entry
in
public_extension_types
:
if
public_funcs
:
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
h_code
.
putln
(
""
)
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
for
entry
in
public_funcs
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
public_extension_types
:
h_code
.
putln
(
""
)
for
entry
in
public_extension_types
:
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
if
i_code
:
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
def
generate_public_declaration
(
self
,
entry
,
h_code
,
i_code
):
h_code
.
putln
(
"%s %s;"
%
(
Naming
.
extern_c_macro
,
entry
.
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
"DL_IMPORT"
)))
if
i_code
:
i_code
.
putln
(
"cdef extern %s"
%
entry
.
type
.
declaration_code
(
entry
.
cname
,
pyrex
=
1
))
def
api_name
(
self
,
env
):
return
env
.
qualified_name
.
replace
(
"."
,
"__"
)
def
generate_api_code
(
self
,
env
,
result
):
api_funcs
=
[]
for
entry
in
env
.
cfunc_entries
:
if
entry
.
api
:
api_funcs
.
append
(
entry
)
public_extension_types
=
[]
for
entry
in
env
.
c_class_entries
:
if
entry
.
visibility
==
'public'
:
public_extension_types
.
append
(
entry
)
if
api_funcs
or
public_extension_types
:
result
.
api_file
=
replace_suffix
(
result
.
c_file
,
"_api.h"
)
h_code
=
Code
.
CCodeWriter
(
open_new_file
(
result
.
api_file
))
name
=
self
.
api_name
(
env
)
guard
=
Naming
.
api_guard_prefix
+
name
h_code
.
put_h_guard
(
guard
)
h_code
.
putln
(
'#include "Python.h"'
)
if
result
.
h_file
:
h_code
.
putln
(
'#include "%s"'
%
os
.
path
.
basename
(
result
.
h_file
))
for
entry
in
public_extension_types
:
type
=
entry
.
type
h_code
.
putln
(
""
)
h_code
.
putln
(
"static PyTypeObject *%s;"
%
type
.
typeptr_cname
)
h_code
.
putln
(
"#define %s (*%s)"
%
(
type
.
typeobj_cname
,
type
.
typeptr_cname
))
if
api_funcs
:
h_code
.
putln
(
""
)
for
entry
in
api_funcs
:
type
=
CPtrType
(
entry
.
type
)
h_code
.
putln
(
"static %s;"
%
type
.
declaration_code
(
entry
.
cname
))
h_code
.
putln
(
""
)
h_code
.
put_h_guard
(
Naming
.
api_func_guard
+
"import_module"
)
h_code
.
put
(
import_module_utility_code
[
1
])
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
if
api_funcs
:
h_code
.
putln
(
""
)
h_code
.
put_h_guard
(
Naming
.
api_func_guard
+
"import_function"
)
h_code
.
put
(
function_import_utility_code
[
1
])
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
if
public_extension_types
:
h_code
.
putln
(
""
)
h_code
.
put_h_guard
(
Naming
.
api_func_guard
+
"import_type"
)
h_code
.
put
(
type_import_utility_code
[
1
])
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"static int import_%s(void) {"
%
name
)
h_code
.
putln
(
"PyObject *module = 0;"
)
h_code
.
putln
(
'module = __Pyx_ImportModule("%s");'
%
env
.
qualified_name
)
h_code
.
putln
(
"if (!module) goto bad;"
)
for
entry
in
api_funcs
:
sig
=
entry
.
type
.
signature_string
()
h_code
.
putln
(
'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
entry
.
cname
,
sig
))
h_code
.
putln
(
"Py_DECREF(module);"
)
for
entry
in
public_extension_types
:
self
.
generate_type_import_call
(
entry
.
type
,
h_code
,
"goto bad"
)
h_code
.
putln
(
"return 0;"
)
h_code
.
putln
(
"bad:"
)
h_code
.
putln
(
"Py_XDECREF(module);"
)
h_code
.
putln
(
"return -1;"
)
h_code
.
putln
(
"}"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif"
)
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
#h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
h_code
.
putln
(
"%s DL_IMPORT(PyTypeObject) %s;"
%
(
h_code
.
putln
(
"%s DL_IMPORT(PyTypeObject) %s;"
%
(
Naming
.
extern_c_macro
,
Naming
.
extern_c_macro
,
type
.
typeobj_cname
))
type
.
typeobj_cname
))
self
.
generate_obj_struct_definition
(
type
,
h_code
)
#
self.generate_obj_struct_definition(type, h_code)
def
generate_cclass_include_code
(
self
,
type
,
i_code
):
def
generate_cclass_include_code
(
self
,
type
,
i_code
):
i_code
.
putln
(
"cdef extern class %s.%s:"
%
(
i_code
.
putln
(
"cdef extern class %s.%s:"
%
(
...
@@ -84,9 +199,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -84,9 +199,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
i_code
.
dedent
()
i_code
.
dedent
()
def
generate_c_code
(
self
,
env
,
result
):
def
generate_c_code
(
self
,
env
,
result
):
modules
=
[]
#
modules = []
self
.
find_referenced_modules
(
env
,
modules
,
{})
#
self.find_referenced_modules(env, modules, {})
#code = Code.CCodeWriter(result.c_file)
modules
=
self
.
referenced_modules
code
=
Code
.
CCodeWriter
(
StringIO
())
code
=
Code
.
CCodeWriter
(
StringIO
())
code
.
h
=
Code
.
CCodeWriter
(
StringIO
())
code
.
h
=
Code
.
CCodeWriter
(
StringIO
())
code
.
init_labels
()
code
.
init_labels
()
...
@@ -129,22 +244,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -129,22 +244,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
'/* Generated by Pyrex %s on %s */'
%
(
code
.
putln
(
'/* Generated by Pyrex %s on %s */'
%
(
Version
.
version
,
time
.
asctime
()))
Version
.
version
,
time
.
asctime
()))
code
.
putln
(
''
)
code
.
putln
(
''
)
code
.
putln
(
'#define PY_SSIZE_T_CLEAN'
)
for
filename
in
env
.
python_include_files
:
for
filename
in
env
.
python_include_files
:
code
.
putln
(
'#include "%s"'
%
filename
)
code
.
putln
(
'#include "%s"'
%
filename
)
code
.
putln
(
"#ifndef PY_LONG_LONG"
)
code
.
putln
(
"#ifndef PY_LONG_LONG"
)
code
.
putln
(
" #define PY_LONG_LONG LONG_LONG"
)
code
.
putln
(
" #define PY_LONG_LONG LONG_LONG"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#if PY_VERSION_HEX < 0x02050000"
)
code
.
putln
(
" typedef int Py_ssize_t;"
)
code
.
putln
(
" #define PY_SSIZE_T_MAX INT_MAX"
)
code
.
putln
(
" #define PY_SSIZE_T_MIN INT_MIN"
)
code
.
putln
(
" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)"
)
code
.
putln
(
" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#ifndef WIN32"
)
code
.
putln
(
" #define __stdcall"
)
code
.
putln
(
" #define __cdecl"
)
code
.
putln
(
"#endif"
)
self
.
generate_extern_c_macro_definition
(
code
)
self
.
generate_extern_c_macro_definition
(
code
)
code
.
putln
(
"
%s double pow(double, double);"
%
Naming
.
extern_c_macro
)
code
.
putln
(
"
#include <math.h>"
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
#for filename in env.include_files:
# code.putln('#include "%s"' % filename)
code
.
putln
(
''
)
code
.
putln
(
''
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
#if Options.intern_names:
# code.putln(Nodes.get_name_interned_predeclaration)
#else:
# code.putln(get_name_predeclaration)
code
.
putln
(
''
)
code
.
putln
(
''
)
code
.
putln
(
'static PyObject *%s;'
%
env
.
module_cname
)
code
.
putln
(
'static PyObject *%s;'
%
env
.
module_cname
)
code
.
putln
(
'static PyObject *%s;'
%
Naming
.
builtins_cname
)
code
.
putln
(
'static PyObject *%s;'
%
Naming
.
builtins_cname
)
...
@@ -192,28 +313,65 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -192,28 +313,65 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_type_predeclarations
(
env
,
code
)
self
.
generate_type_predeclarations
(
env
,
code
)
self
.
generate_type_definitions
(
env
,
code
)
self
.
generate_type_definitions
(
env
,
code
)
self
.
generate_global_declarations
(
env
,
code
,
definition
)
self
.
generate_global_declarations
(
env
,
code
,
definition
)
self
.
generate_cfunction_predeclarations
(
env
,
code
)
self
.
generate_cfunction_predeclarations
(
env
,
code
,
definition
)
def
generate_type_predeclarations
(
self
,
env
,
code
):
def
generate_type_predeclarations
(
self
,
env
,
code
):
pass
pass
def
generate_type_definitions
(
self
,
env
,
code
):
def
generate_type_header_code
(
self
,
env
,
code
):
# Generate definitions of structs/unions/enums.
# Generate definitions of structs/unions/enums/typedefs/objstructs.
for
entry
in
env
.
sue_entries
:
#self.generate_gcc33_hack(env, code) # Is this still needed?
for
entry
in
env
.
type_entries
:
if
not
entry
.
in_cinclude
:
if
not
entry
.
in_cinclude
:
#print "generate_type_header_code:", entry.name, repr(entry.type) ###
type
=
entry
.
type
type
=
entry
.
type
if
type
.
is_struct_or_union
:
if
type
.
is_typedef
:
# Must test this first!
self
.
generate_typedef
(
entry
,
code
)
elif
type
.
is_struct_or_union
:
self
.
generate_struct_union_definition
(
entry
,
code
)
self
.
generate_struct_union_definition
(
entry
,
code
)
el
se
:
el
if
type
.
is_enum
:
self
.
generate_enum_definition
(
entry
,
code
)
self
.
generate_enum_definition
(
entry
,
code
)
elif
type
.
is_extension_type
:
self
.
generate_obj_struct_definition
(
type
,
code
)
def
generate_type_definitions
(
self
,
env
,
code
):
# Generate definitions of structs/unions/enums.
# self.generate_gcc33_hack(env, code)
# for entry in env.sue_entries:
# if not entry.in_cinclude:
# type = entry.type
# if type.is_struct_or_union:
# self.generate_struct_union_definition(entry, code)
# else:
# self.generate_enum_definition(entry, code)
self
.
generate_type_header_code
(
env
,
code
)
# Generate extension type object struct definitions.
# Generate extension type object struct definitions.
for
entry
in
env
.
c_class_entries
:
for
entry
in
env
.
c_class_entries
:
if
not
entry
.
in_cinclude
:
if
not
entry
.
in_cinclude
:
self
.
generate_typeobject_predeclaration
(
entry
,
code
)
self
.
generate_typeobject_predeclaration
(
entry
,
code
)
self
.
generate_obj_struct_definition
(
entry
.
type
,
code
)
#
self.generate_obj_struct_definition(entry.type, code)
self
.
generate_exttype_vtable_struct
(
entry
,
code
)
self
.
generate_exttype_vtable_struct
(
entry
,
code
)
self
.
generate_exttype_vtabptr_declaration
(
entry
,
code
)
self
.
generate_exttype_vtabptr_declaration
(
entry
,
code
)
def
generate_gcc33_hack
(
self
,
env
,
code
):
# Workaround for spurious warning generation in gcc 3.3
code
.
putln
(
""
)
for
entry
in
env
.
c_class_entries
:
type
=
entry
.
type
if
not
type
.
typedef_flag
:
name
=
type
.
objstruct_cname
if
name
.
startswith
(
"__pyx_"
):
tail
=
name
[
6
:]
else
:
tail
=
name
code
.
putln
(
"typedef struct %s __pyx_gcc33_%s;"
%
(
name
,
tail
))
def
generate_typedef
(
self
,
entry
,
code
):
base_type
=
entry
.
type
.
typedef_base_type
code
.
putln
(
""
)
code
.
putln
(
"typedef %s;"
%
base_type
.
declaration_code
(
entry
.
cname
))
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
if
type
.
typedef_flag
:
if
type
.
typedef_flag
:
header
=
"typedef %s {"
%
kind
header
=
"typedef %s {"
%
kind
...
@@ -342,7 +500,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -342,7 +500,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"%s;"
%
"%s;"
%
attr
.
type
.
declaration_code
(
attr
.
cname
))
attr
.
type
.
declaration_code
(
attr
.
cname
))
code
.
putln
(
footer
)
code
.
putln
(
footer
)
def
generate_global_declarations
(
self
,
env
,
code
,
definition
):
def
generate_global_declarations
(
self
,
env
,
code
,
definition
):
code
.
putln
(
""
)
code
.
putln
(
""
)
for
entry
in
env
.
c_class_entries
:
for
entry
in
env
.
c_class_entries
:
...
@@ -352,14 +510,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -352,14 +510,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
dll_linkage
=
"DL_EXPORT"
,
definition
=
definition
)
dll_linkage
=
"DL_EXPORT"
,
definition
=
definition
)
code
.
put_var_declarations
(
env
.
default_entries
,
static
=
1
)
code
.
put_var_declarations
(
env
.
default_entries
,
static
=
1
)
def
generate_cfunction_predeclarations
(
self
,
env
,
code
):
def
generate_cfunction_predeclarations
(
self
,
env
,
code
,
definition
):
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
if
not
entry
.
in_cinclude
:
if
not
entry
.
in_cinclude
and
(
definition
if
entry
.
visibility
==
'public'
:
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
):
if
entry
.
visibility
in
(
'public'
,
'extern'
):
dll_linkage
=
"DL_EXPORT"
dll_linkage
=
"DL_EXPORT"
else
:
else
:
dll_linkage
=
None
dll_linkage
=
None
header
=
entry
.
type
.
declaration_code
(
entry
.
cname
,
type
=
entry
.
type
if
not
definition
and
entry
.
defined_in_pxd
:
type
=
CPtrType
(
type
)
header
=
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
)
dll_linkage
=
dll_linkage
)
if
entry
.
visibility
<>
'private'
:
if
entry
.
visibility
<>
'private'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
storage_class
=
"%s "
%
Naming
.
extern_c_macro
...
@@ -419,11 +581,21 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -419,11 +581,21 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type
.
declaration_code
(
""
)))
type
.
declaration_code
(
""
)))
def
generate_new_function
(
self
,
scope
,
code
):
def
generate_new_function
(
self
,
scope
,
code
):
base_type
=
scope
.
parent_type
.
base_type
type
=
scope
.
parent_type
base_type
=
type
.
base_type
py_attrs
=
[]
for
entry
in
scope
.
var_entries
:
if
entry
.
type
.
is_pyobject
:
py_attrs
.
append
(
entry
)
need_self_cast
=
type
.
vtabslot_cname
or
py_attrs
code
.
putln
(
""
)
code
.
putln
(
""
)
code
.
putln
(
code
.
putln
(
"static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
"static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
%
scope
.
mangle_internal
(
"tp_new"
))
%
scope
.
mangle_internal
(
"tp_new"
))
if
need_self_cast
:
code
.
putln
(
"%s;"
%
scope
.
parent_type
.
declaration_code
(
"p"
))
if
base_type
:
if
base_type
:
code
.
putln
(
code
.
putln
(
"PyObject *o = %s->tp_new(t, a, k);"
%
"PyObject *o = %s->tp_new(t, a, k);"
%
...
@@ -431,13 +603,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -431,13 +603,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else
:
else
:
code
.
putln
(
code
.
putln
(
"PyObject *o = (*t->tp_alloc)(t, 0);"
)
"PyObject *o = (*t->tp_alloc)(t, 0);"
)
type
=
scope
.
parent_type
code
.
putln
(
py_attrs
=
[]
"if (!o) return 0;"
)
for
entry
in
scope
.
var_entries
:
if
need_self_cast
:
if
entry
.
type
.
is_pyobject
:
code
.
putln
(
py_attrs
.
append
(
entry
)
"p = %s;"
if
type
.
vtabslot_cname
or
py_attrs
:
%
type
.
cast_code
(
"o"
))
self
.
generate_self_cast
(
scope
,
code
)
#if need_self_cast:
# self.generate_self_cast(scope, code)
if
type
.
vtabslot_cname
:
if
type
.
vtabslot_cname
:
code
.
putln
(
"*(struct %s **)&p->%s = %s;"
%
(
code
.
putln
(
"*(struct %s **)&p->%s = %s;"
%
(
type
.
vtabstruct_cname
,
type
.
vtabstruct_cname
,
...
@@ -519,7 +692,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -519,7 +692,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
%
scope
.
mangle_internal
(
"tp_traverse"
))
%
scope
.
mangle_internal
(
"tp_traverse"
))
py_attrs
=
[]
py_attrs
=
[]
for
entry
in
scope
.
var_entries
:
for
entry
in
scope
.
var_entries
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
and
entry
.
name
<>
"__weakref__"
:
py_attrs
.
append
(
entry
)
py_attrs
.
append
(
entry
)
if
base_type
or
py_attrs
:
if
base_type
or
py_attrs
:
code
.
putln
(
code
.
putln
(
...
@@ -555,7 +728,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -555,7 +728,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
%
scope
.
mangle_internal
(
"tp_clear"
))
%
scope
.
mangle_internal
(
"tp_clear"
))
py_attrs
=
[]
py_attrs
=
[]
for
entry
in
scope
.
var_entries
:
for
entry
in
scope
.
var_entries
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
and
entry
.
name
<>
"__weakref__"
:
py_attrs
.
append
(
entry
)
py_attrs
.
append
(
entry
)
if
py_attrs
:
if
py_attrs
:
self
.
generate_self_cast
(
scope
,
code
)
self
.
generate_self_cast
(
scope
,
code
)
...
@@ -577,12 +750,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -577,12 +750,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# a __getitem__ method is present. It converts its
# a __getitem__ method is present. It converts its
# argument to a Python integer and calls mp_subscript.
# argument to a Python integer and calls mp_subscript.
code
.
putln
(
code
.
putln
(
"static PyObject *%s(PyObject *o,
in
t i) {"
%
"static PyObject *%s(PyObject *o,
Py_ssize_
t i) {"
%
scope
.
mangle_internal
(
"sq_item"
))
scope
.
mangle_internal
(
"sq_item"
))
code
.
putln
(
code
.
putln
(
"PyObject *r;"
)
"PyObject *r;"
)
code
.
putln
(
code
.
putln
(
"PyObject *x = PyInt_From
Long
(i); if(!x) return 0;"
)
"PyObject *x = PyInt_From
Ssize_t
(i); if(!x) return 0;"
)
code
.
putln
(
code
.
putln
(
"r = o->ob_type->tp_as_mapping->mp_subscript(o, x);"
)
"r = o->ob_type->tp_as_mapping->mp_subscript(o, x);"
)
code
.
putln
(
code
.
putln
(
...
@@ -668,7 +841,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -668,7 +841,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
del_entry
=
scope
.
lookup_here
(
"__delslice__"
)
del_entry
=
scope
.
lookup_here
(
"__delslice__"
)
code
.
putln
(
""
)
code
.
putln
(
""
)
code
.
putln
(
code
.
putln
(
"static int %s(PyObject *o,
int i, in
t j, PyObject *v) {"
%
"static int %s(PyObject *o,
Py_ssize_t i, Py_ssize_
t j, PyObject *v) {"
%
scope
.
mangle_internal
(
"sq_ass_slice"
))
scope
.
mangle_internal
(
"sq_ass_slice"
))
code
.
putln
(
code
.
putln
(
"if (v) {"
)
"if (v) {"
)
...
@@ -1045,17 +1218,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1045,17 +1218,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"%s; /*proto*/"
%
header
)
code
.
putln
(
"%s; /*proto*/"
%
header
)
code
.
putln
(
"%s {"
%
header
)
code
.
putln
(
"%s {"
%
header
)
code
.
put_var_declarations
(
env
.
temp_entries
)
code
.
put_var_declarations
(
env
.
temp_entries
)
#code.putln("/*--- Libary function declarations ---*/")
#code.putln("/*--- Libary function declarations ---*/")
env
.
generate_library_function_declarations
(
code
)
env
.
generate_library_function_declarations
(
code
)
self
.
generate_filename_init_call
(
code
)
self
.
generate_filename_init_call
(
code
)
#code.putln("/*--- Module creation code ---*/")
#code.putln("/*--- Module creation code ---*/")
self
.
generate_module_creation_code
(
env
,
code
)
self
.
generate_module_creation_code
(
env
,
code
)
#code.putln("/*--- Intern code ---*/")
#code.putln("/*--- Intern code ---*/")
self
.
generate_intern_code
(
env
,
code
)
self
.
generate_intern_code
(
env
,
code
)
#code.putln("/*--- String init code ---*/")
#code.putln("/*--- String init code ---*/")
self
.
generate_string_init_code
(
env
,
code
)
self
.
generate_string_init_code
(
env
,
code
)
#code.putln("/*--- Global init code ---*/")
#code.putln("/*--- Global init code ---*/")
self
.
generate_global_init_code
(
env
,
code
)
self
.
generate_global_init_code
(
env
,
code
)
#code.putln("/*--- Function export code ---*/")
self
.
generate_c_function_export_code
(
env
,
code
)
#code.putln("/*--- Function import code ---*/")
for
module
in
imported_modules
:
self
.
generate_c_function_import_code_for_module
(
module
,
env
,
code
)
#code.putln("/*--- Type init code ---*/")
#code.putln("/*--- Type init code ---*/")
self
.
generate_type_init_code
(
env
,
code
)
self
.
generate_type_init_code
(
env
,
code
)
...
@@ -1129,14 +1314,53 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1129,14 +1314,53 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
entry
.
visibility
<>
'extern'
:
if
entry
.
visibility
<>
'extern'
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
:
code
.
put_init_var_to_py_none
(
entry
)
code
.
put_init_var_to_py_none
(
entry
)
def
generate_c_function_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
for
entry
in
env
.
cfunc_entries
:
if
entry
.
api
or
entry
.
defined_in_pxd
:
env
.
use_utility_code
(
function_export_utility_code
)
signature
=
entry
.
type
.
signature_string
()
code
.
putln
(
'if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s'
%
(
entry
.
name
,
entry
.
cname
,
signature
,
code
.
error_goto
(
self
.
pos
)))
def
generate_type_import_code_for_module
(
self
,
module
,
env
,
code
):
def
generate_type_import_code_for_module
(
self
,
module
,
env
,
code
):
# Generate type import code for all extension types in
# Generate type import code for all ex
ported ex
tension types in
# an imported module.
# an imported module.
if
module
.
c_class_entries
:
#if module.c_class_entries:
for
entry
in
module
.
c_class_entries
:
for
entry
in
module
.
c_class_entries
:
if
entry
.
defined_in_pxd
:
self
.
generate_type_import_code
(
env
,
entry
.
type
,
entry
.
pos
,
code
)
self
.
generate_type_import_code
(
env
,
entry
.
type
,
entry
.
pos
,
code
)
def
generate_c_function_import_code_for_module
(
self
,
module
,
env
,
code
):
# Generate import code for all exported C functions in a cimported module.
entries
=
[]
for
entry
in
module
.
cfunc_entries
:
if
entry
.
defined_in_pxd
:
entries
.
append
(
entry
)
if
entries
:
env
.
use_utility_code
(
import_module_utility_code
)
env
.
use_utility_code
(
function_import_utility_code
)
temp
=
self
.
module_temp_cname
code
.
putln
(
'%s = __Pyx_ImportModule("%s"); if (!%s) %s'
%
(
temp
,
module
.
qualified_name
,
temp
,
code
.
error_goto
(
self
.
pos
)))
for
entry
in
entries
:
code
.
putln
(
'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s'
%
(
temp
,
entry
.
name
,
entry
.
cname
,
entry
.
type
.
signature_string
(),
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
"Py_DECREF(%s); %s = 0;"
%
(
temp
,
temp
))
def
generate_type_init_code
(
self
,
env
,
code
):
def
generate_type_init_code
(
self
,
env
,
code
):
# Generate type import code for extern extension types
# Generate type import code for extern extension types
# and type ready code for non-extern ones.
# and type ready code for non-extern ones.
...
@@ -1156,8 +1380,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1156,8 +1380,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
use_type_import_utility_code
(
self
,
env
):
def
use_type_import_utility_code
(
self
,
env
):
import
ExprNodes
import
ExprNodes
env
.
use_utility_code
(
Nodes
.
type_import_utility_code
)
env
.
use_utility_code
(
type_import_utility_code
)
env
.
use_utility_code
(
ExprNodes
.
import
_utility_code
)
env
.
use_utility_code
(
import_module
_utility_code
)
def
generate_type_import_code
(
self
,
env
,
type
,
pos
,
code
):
def
generate_type_import_code
(
self
,
env
,
type
,
pos
,
code
):
# If not already done, generate code to import the typeobject of an
# If not already done, generate code to import the typeobject of an
...
@@ -1169,13 +1393,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1169,13 +1393,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
objstruct
=
type
.
objstruct_cname
objstruct
=
type
.
objstruct_cname
else
:
else
:
objstruct
=
"struct %s"
%
type
.
objstruct_cname
objstruct
=
"struct %s"
%
type
.
objstruct_cname
code
.
putln
(
'%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s'
%
(
# code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
type
.
typeptr_cname
,
# type.typeptr_cname,
type
.
module_name
,
# type.module_name,
type
.
name
,
# type.name,
objstruct
,
# objstruct,
type
.
typeptr_cname
,
# type.typeptr_cname,
code
.
error_goto
(
pos
)))
# code.error_goto(pos)))
self
.
generate_type_import_call
(
type
,
code
,
code
.
error_goto
(
pos
))
self
.
use_type_import_utility_code
(
env
)
self
.
use_type_import_utility_code
(
env
)
if
type
.
vtabptr_cname
:
if
type
.
vtabptr_cname
:
code
.
putln
(
code
.
putln
(
...
@@ -1186,6 +1411,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1186,6 +1411,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env
.
use_utility_code
(
Nodes
.
get_vtable_utility_code
)
env
.
use_utility_code
(
Nodes
.
get_vtable_utility_code
)
env
.
types_imported
[
type
]
=
1
env
.
types_imported
[
type
]
=
1
def
generate_type_import_call
(
self
,
type
,
code
,
error_code
):
if
type
.
typedef_flag
:
objstruct
=
type
.
objstruct_cname
else
:
objstruct
=
"struct %s"
%
type
.
objstruct_cname
code
.
putln
(
'%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s'
%
(
type
.
typeptr_cname
,
type
.
module_name
,
type
.
name
,
objstruct
,
type
.
typeptr_cname
,
error_code
))
def
generate_type_ready_code
(
self
,
env
,
entry
,
code
):
def
generate_type_ready_code
(
self
,
env
,
entry
,
code
):
# Generate a call to PyType_Ready for an extension
# Generate a call to PyType_Ready for an extension
# type defined in this module.
# type defined in this module.
...
@@ -1243,7 +1481,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1243,7 +1481,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
meth_entry
in
type
.
scope
.
cfunc_entries
:
for
meth_entry
in
type
.
scope
.
cfunc_entries
:
if
meth_entry
.
func_cname
:
if
meth_entry
.
func_cname
:
code
.
putln
(
code
.
putln
(
"*(void(**)(
))&%s.%s = (void(*)(
))%s;"
%
(
"*(void(**)(
void))&%s.%s = (void(*)(void
))%s;"
%
(
type
.
vtable_cname
,
type
.
vtable_cname
,
meth_entry
.
cname
,
meth_entry
.
cname
,
meth_entry
.
func_cname
))
meth_entry
.
func_cname
))
...
@@ -1268,3 +1506,171 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1268,3 +1506,171 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
utility_code
in
env
.
utility_code_used
:
for
utility_code
in
env
.
utility_code_used
:
code
.
h
.
put
(
utility_code
[
0
])
code
.
h
.
put
(
utility_code
[
0
])
code
.
put
(
utility_code
[
1
])
code
.
put
(
utility_code
[
1
])
#------------------------------------------------------------------------------------
#type_import_utility_code = [
#"""
#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
#""","""
#static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
# long size)
#{
# PyObject *py_module_name = 0;
# PyObject *py_class_name = 0;
# PyObject *py_name_list = 0;
# PyObject *py_module = 0;
# PyObject *result = 0;
#
# py_module_name = PyString_FromString(module_name);
# if (!py_module_name)
# goto bad;
# py_class_name = PyString_FromString(class_name);
# if (!py_class_name)
# goto bad;
# py_name_list = PyList_New(1);
# if (!py_name_list)
# goto bad;
# Py_INCREF(py_class_name);
# if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
# goto bad;
# py_module = __Pyx_Import(py_module_name, py_name_list);
# if (!py_module)
# goto bad;
# result = PyObject_GetAttr(py_module, py_class_name);
# if (!result)
# goto bad;
# if (!PyType_Check(result)) {
# PyErr_Format(PyExc_TypeError,
# "%s.%s is not a type object",
# module_name, class_name);
# goto bad;
# }
# if (((PyTypeObject *)result)->tp_basicsize != size) {
# PyErr_Format(PyExc_ValueError,
# "%s.%s does not appear to be the correct type object",
# module_name, class_name);
# goto bad;
# }
# goto done;
#bad:
# Py_XDECREF(result);
# result = 0;
#done:
# Py_XDECREF(py_module_name);
# Py_XDECREF(py_class_name);
# Py_XDECREF(py_name_list);
# return (PyTypeObject *)result;
#}
#"""]
#------------------------------------------------------------------------------------
import_module_utility_code
=
[
"""
static PyObject *__Pyx_ImportModule(char *name); /*proto*/
"""
,
"""
static PyObject *__Pyx_ImportModule(char *name) {
PyObject *py_name = 0;
py_name = PyString_FromString(name);
if (!py_name)
goto bad;
return PyImport_Import(py_name);
bad:
Py_XDECREF(py_name);
return 0;
}
"""
]
#------------------------------------------------------------------------------------
type_import_utility_code
=
[
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
"""
,
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
long size)
{
PyObject *py_module = 0;
PyObject *result = 0;
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
goto bad;
result = PyObject_GetAttrString(py_module, class_name);
if (!result)
goto bad;
if (!PyType_Check(result)) {
PyErr_Format(PyExc_TypeError,
"%s.%s is not a type object",
module_name, class_name);
goto bad;
}
if (((PyTypeObject *)result)->tp_basicsize != size) {
PyErr_Format(PyExc_ValueError,
"%s.%s does not appear to be the correct type object",
module_name, class_name);
goto bad;
}
return (PyTypeObject *)result;
bad:
Py_XDECREF(result);
return 0;
}
"""
]
#------------------------------------------------------------------------------------
function_export_utility_code
=
[
"""
static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
"""
,
r"""
static int __Pyx_ExportFunction(char *n, void *f, char *s) {
PyObject *p = 0;
p = PyCObject_FromVoidPtrAndDesc(f, s, 0);
if (!p)
goto bad;
if (PyModule_AddObject(%(MODULE)s, n, p) < 0)
goto bad;
return 0;
bad:
Py_XDECREF(p);
return -1;
}
"""
%
{
'MODULE'
:
Naming
.
module_cname
}]
#------------------------------------------------------------------------------------
function_import_utility_code
=
[
"""
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
"""
,
"""
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
PyObject *cobj = 0;
char *desc;
cobj = PyObject_GetAttrString(module, funcname);
if (!cobj) {
PyErr_Format(PyExc_ImportError,
"%s does not export expected C function %s",
PyModule_GetName(module), funcname);
goto bad;
}
desc = (char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
if (strcmp(desc, sig) != 0) {
PyErr_Format(PyExc_TypeError,
"C function %s.%s has wrong signature (expected %s, got %s)",
PyModule_GetName(module), funcname, sig, desc);
goto bad;
}
*f = PyCObject_AsVoidPtr(cobj);
Py_DECREF(cobj);
return 0;
bad:
Py_XDECREF(cobj);
return -1;
}
"""
]
Cython/Compiler/Naming.py
View file @
3588f4a6
...
@@ -47,8 +47,20 @@ module_cname = pyrex_prefix + "m"
...
@@ -47,8 +47,20 @@ module_cname = pyrex_prefix + "m"
moddoc_cname
=
pyrex_prefix
+
"mdoc"
moddoc_cname
=
pyrex_prefix
+
"mdoc"
methtable_cname
=
pyrex_prefix
+
"methods"
methtable_cname
=
pyrex_prefix
+
"methods"
retval_cname
=
pyrex_prefix
+
"r"
retval_cname
=
pyrex_prefix
+
"r"
reqd_kwds_cname
=
pyrex_prefix
+
"reqd_kwds"
self_cname
=
pyrex_prefix
+
"self"
self_cname
=
pyrex_prefix
+
"self"
stringtab_cname
=
pyrex_prefix
+
"string_tab"
stringtab_cname
=
pyrex_prefix
+
"string_tab"
vtabslot_cname
=
pyrex_prefix
+
"vtab"
vtabslot_cname
=
pyrex_prefix
+
"vtab"
extern_c_macro
=
pyrex_prefix
.
upper
()
+
"EXTERN_C"
extern_c_macro
=
pyrex_prefix
.
upper
()
+
"EXTERN_C"
exc_type_name
=
pyrex_prefix
+
"exc_type"
exc_value_name
=
pyrex_prefix
+
"exc_value"
exc_tb_name
=
pyrex_prefix
+
"exc_tb"
exc_lineno_name
=
pyrex_prefix
+
"exc_lineno"
exc_vars
=
(
exc_type_name
,
exc_value_name
,
exc_tb_name
)
h_guard_prefix
=
"__PYX_HAVE__"
api_guard_prefix
=
"__PYX_HAVE_API__"
api_func_guard
=
"__PYX_HAVE_API_FUNC_"
Cython/Compiler/Nodes.py
View file @
3588f4a6
...
@@ -8,7 +8,7 @@ import Code
...
@@ -8,7 +8,7 @@ import Code
from
Errors
import
error
,
InternalError
from
Errors
import
error
,
InternalError
import
Naming
import
Naming
import
PyrexTypes
import
PyrexTypes
from
PyrexTypes
import
py_object_type
,
error_type
,
CTypedefType
from
PyrexTypes
import
py_object_type
,
error_type
,
CTypedefType
,
CFuncType
from
Symtab
import
ModuleScope
,
LocalScope
,
\
from
Symtab
import
ModuleScope
,
LocalScope
,
\
StructOrUnionScope
,
PyClassScope
,
CClassScope
StructOrUnionScope
,
PyClassScope
,
CClassScope
from
Pyrex.Utils
import
open_new_file
,
replace_suffix
from
Pyrex.Utils
import
open_new_file
,
replace_suffix
...
@@ -170,7 +170,10 @@ class CDeclaratorNode(Node):
...
@@ -170,7 +170,10 @@ class CDeclaratorNode(Node):
# CNameDeclaratorNode of the name being declared
# CNameDeclaratorNode of the name being declared
# and type is the type it is being declared as.
# and type is the type it is being declared as.
#
#
pass
# calling_convention string Calling convention of CFuncDeclaratorNode
# for which this is a base
calling_convention
=
""
class
CNameDeclaratorNode
(
CDeclaratorNode
):
class
CNameDeclaratorNode
(
CDeclaratorNode
):
...
@@ -201,7 +204,6 @@ class CArrayDeclaratorNode(CDeclaratorNode):
...
@@ -201,7 +204,6 @@ class CArrayDeclaratorNode(CDeclaratorNode):
self
.
dimension
.
analyse_const_expression
(
env
)
self
.
dimension
.
analyse_const_expression
(
env
)
if
not
self
.
dimension
.
type
.
is_int
:
if
not
self
.
dimension
.
type
.
is_int
:
error
(
self
.
dimension
.
pos
,
"Array dimension not integer"
)
error
(
self
.
dimension
.
pos
,
"Array dimension not integer"
)
#size = self.dimension.value
size
=
self
.
dimension
.
result_code
size
=
self
.
dimension
.
result_code
else
:
else
:
size
=
None
size
=
None
...
@@ -211,6 +213,9 @@ class CArrayDeclaratorNode(CDeclaratorNode):
...
@@ -211,6 +213,9 @@ class CArrayDeclaratorNode(CDeclaratorNode):
if
base_type
.
is_pyobject
:
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Array element cannot be a Python object"
)
"Array element cannot be a Python object"
)
if
base_type
.
is_cfunction
:
error
(
self
.
pos
,
"Array element cannot be a function"
)
array_type
=
PyrexTypes
.
c_array_type
(
base_type
,
size
)
array_type
=
PyrexTypes
.
c_array_type
(
base_type
,
size
)
return
self
.
base
.
analyse
(
array_type
,
env
)
return
self
.
base
.
analyse
(
array_type
,
env
)
...
@@ -221,6 +226,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
...
@@ -221,6 +226,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
# has_varargs boolean
# has_varargs boolean
# exception_value ConstNode
# exception_value ConstNode
# exception_check boolean True if PyErr_Occurred check needed
# exception_check boolean True if PyErr_Occurred check needed
# nogil boolean Can be called without gil
# with_gil boolean Acquire gil around function body
def
analyse
(
self
,
return_type
,
env
):
def
analyse
(
self
,
return_type
,
env
):
func_type_args
=
[]
func_type_args
=
[]
...
@@ -236,6 +243,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
...
@@ -236,6 +243,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
# Catch attempted C-style func(void) decl
# Catch attempted C-style func(void) decl
if
type
.
is_void
:
if
type
.
is_void
:
error
(
arg_node
.
pos
,
"Function argument cannot be void"
)
error
(
arg_node
.
pos
,
"Function argument cannot be void"
)
if
type
.
is_pyobject
and
self
.
nogil
:
error
(
self
.
pos
,
"Function with Python argument cannot be declared nogil"
)
func_type_args
.
append
(
func_type_args
.
append
(
PyrexTypes
.
CFuncTypeArg
(
name
,
type
,
arg_node
.
pos
))
PyrexTypes
.
CFuncTypeArg
(
name
,
type
,
arg_node
.
pos
))
if
arg_node
.
default
:
if
arg_node
.
default
:
...
@@ -254,9 +264,20 @@ class CFuncDeclaratorNode(CDeclaratorNode):
...
@@ -254,9 +264,20 @@ class CFuncDeclaratorNode(CDeclaratorNode):
error
(
self
.
exception_value
.
pos
,
error
(
self
.
exception_value
.
pos
,
"Exception value incompatible with function return type"
)
"Exception value incompatible with function return type"
)
exc_check
=
self
.
exception_check
exc_check
=
self
.
exception_check
if
return_type
.
is_pyobject
and
self
.
nogil
:
error
(
self
.
pos
,
"Function with Python return type cannot be declared nogil"
)
if
return_type
.
is_array
:
error
(
self
.
pos
,
"Function cannot return an array"
)
if
return_type
.
is_cfunction
:
error
(
self
.
pos
,
"Function cannot return a function"
)
func_type
=
PyrexTypes
.
CFuncType
(
func_type
=
PyrexTypes
.
CFuncType
(
return_type
,
func_type_args
,
self
.
has_varargs
,
return_type
,
func_type_args
,
self
.
has_varargs
,
exception_value
=
exc_val
,
exception_check
=
exc_check
)
exception_value
=
exc_val
,
exception_check
=
exc_check
,
calling_convention
=
self
.
base
.
calling_convention
,
nogil
=
self
.
nogil
,
with_gil
=
self
.
with_gil
)
return
self
.
base
.
analyse
(
func_type
,
env
)
return
self
.
base
.
analyse
(
func_type
,
env
)
...
@@ -269,10 +290,12 @@ class CArgDeclNode(Node):
...
@@ -269,10 +290,12 @@ class CArgDeclNode(Node):
# default ExprNode or None
# default ExprNode or None
# default_entry Symtab.Entry Entry for the variable holding the default value
# default_entry Symtab.Entry Entry for the variable holding the default value
# 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_self_arg
=
0
is_self_arg
=
0
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
):
#print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
base_type
=
self
.
base_type
.
analyse
(
env
)
base_type
=
self
.
base_type
.
analyse
(
env
)
return
self
.
declarator
.
analyse
(
base_type
,
env
)
return
self
.
declarator
.
analyse
(
base_type
,
env
)
...
@@ -298,6 +321,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
...
@@ -298,6 +321,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
):
# Return type descriptor.
# Return type descriptor.
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
type
=
None
type
=
None
if
self
.
is_basic_c_type
:
if
self
.
is_basic_c_type
:
type
=
PyrexTypes
.
simple_c_type
(
self
.
signed
,
self
.
longness
,
self
.
name
)
type
=
PyrexTypes
.
simple_c_type
(
self
.
signed
,
self
.
longness
,
self
.
name
)
...
@@ -307,6 +331,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
...
@@ -307,6 +331,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
type
=
py_object_type
type
=
py_object_type
elif
self
.
name
is
None
:
elif
self
.
name
is
None
:
if
self
.
is_self_arg
and
env
.
is_c_class_scope
:
if
self
.
is_self_arg
and
env
.
is_c_class_scope
:
#print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
type
=
env
.
parent_type
type
=
env
.
parent_type
else
:
else
:
type
=
py_object_type
type
=
py_object_type
...
@@ -349,6 +374,7 @@ class CVarDefNode(StatNode):
...
@@ -349,6 +374,7 @@ class CVarDefNode(StatNode):
# visibility 'private' or 'public' or 'extern'
# visibility 'private' or 'public' or 'extern'
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# declarators [CDeclaratorNode]
# declarators [CDeclaratorNode]
# in_pxd boolean
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
if
not
dest_scope
:
if
not
dest_scope
:
...
@@ -366,9 +392,18 @@ class CVarDefNode(StatNode):
...
@@ -366,9 +392,18 @@ class CVarDefNode(StatNode):
name
=
name_declarator
.
name
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
cname
=
name_declarator
.
cname
if
type
.
is_cfunction
:
if
type
.
is_cfunction
:
dest_scope
.
declare_cfunction
(
name
,
type
,
declarator
.
pos
,
entry
=
dest_scope
.
declare_cfunction
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
)
cname
=
cname
,
visibility
=
self
.
visibility
,
in_pxd
=
self
.
in_pxd
)
#if self.visibility <> 'extern':
# if self.in_pxd:
# entry.defined_in_pxd = 1
# else:
# error(declarator.pos,
# "Non-extern C function declared but not defined")
else
:
else
:
if
self
.
in_pxd
and
self
.
visibility
<>
'extern'
:
error
(
self
.
pos
,
"Only 'extern' C variable declaration allowed in .pxd file"
)
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
is_cdef
=
1
)
cname
=
cname
,
visibility
=
self
.
visibility
,
is_cdef
=
1
)
...
@@ -384,6 +419,7 @@ class CStructOrUnionDefNode(StatNode):
...
@@ -384,6 +419,7 @@ class CStructOrUnionDefNode(StatNode):
# cname string or None
# cname string or None
# kind "struct" or "union"
# kind "struct" or "union"
# typedef_flag boolean
# typedef_flag boolean
# visibility "public" or "private"
# attributes [CVarDefNode] or None
# attributes [CVarDefNode] or None
# entry Entry
# entry Entry
...
@@ -393,7 +429,7 @@ class CStructOrUnionDefNode(StatNode):
...
@@ -393,7 +429,7 @@ class CStructOrUnionDefNode(StatNode):
scope
=
StructOrUnionScope
()
scope
=
StructOrUnionScope
()
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
cname
)
self
.
cname
,
visibility
=
self
.
visibility
)
if
self
.
attributes
is
not
None
:
if
self
.
attributes
is
not
None
:
for
attr
in
self
.
attributes
:
for
attr
in
self
.
attributes
:
attr
.
analyse_declarations
(
env
,
scope
)
attr
.
analyse_declarations
(
env
,
scope
)
...
@@ -410,11 +446,13 @@ class CEnumDefNode(StatNode):
...
@@ -410,11 +446,13 @@ class CEnumDefNode(StatNode):
# cname string or None
# cname string or None
# items [CEnumDefItemNode]
# items [CEnumDefItemNode]
# typedef_flag boolean
# typedef_flag boolean
# visibility "public" or "private"
# entry Entry
# entry Entry
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
,
visibility
=
self
.
visibility
)
for
item
in
self
.
items
:
for
item
in
self
.
items
:
item
.
analyse_declarations
(
env
,
self
.
entry
)
item
.
analyse_declarations
(
env
,
self
.
entry
)
...
@@ -444,15 +482,17 @@ class CEnumDefItemNode(StatNode):
...
@@ -444,15 +482,17 @@ class CEnumDefItemNode(StatNode):
class
CTypeDefNode
(
StatNode
):
class
CTypeDefNode
(
StatNode
):
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# declarator CDeclaratorNode
# visibility "public" or "private"
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
)
name
=
name_declarator
.
name
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
cname
=
name_declarator
.
cname
if
env
.
in_cinclude
:
#if env.in_cinclude:
type
=
CTypedefType
(
cname
or
name
,
type
)
# type = CTypedefType(cname, type)
env
.
declare_type
(
name
,
type
,
self
.
pos
,
cname
=
cname
)
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
)
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
...
@@ -470,14 +510,15 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -470,14 +510,15 @@ class FuncDefNode(StatNode, BlockNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
def
need_gil_acquisition
(
self
,
lenv
):
return
0
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
):
# 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
()
lenv
=
LocalScope
(
name
=
self
.
entry
.
name
,
outer_scope
=
genv
)
lenv
=
LocalScope
(
name
=
self
.
entry
.
name
,
outer_scope
=
genv
)
#lenv.function_name = self.function_name()
lenv
.
return_type
=
self
.
return_type
lenv
.
return_type
=
self
.
return_type
#self.filename = lenv.get_filename_const(self.pos)
code
.
init_labels
()
code
.
init_labels
()
self
.
declare_arguments
(
lenv
)
self
.
declare_arguments
(
lenv
)
self
.
body
.
analyse_declarations
(
lenv
)
self
.
body
.
analyse_declarations
(
lenv
)
...
@@ -506,6 +547,10 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -506,6 +547,10 @@ class FuncDefNode(StatNode, BlockNode):
self
.
generate_keyword_list
(
code
)
self
.
generate_keyword_list
(
code
)
# ----- Extern library function declarations
# ----- Extern library function declarations
lenv
.
generate_library_function_declarations
(
code
)
lenv
.
generate_library_function_declarations
(
code
)
# ----- GIL acquisition
acquire_gil
=
self
.
need_gil_acquisition
(
lenv
)
if
acquire_gil
:
code
.
putln
(
"PyGILState_STATE _save = PyGILState_Ensure();"
)
# ----- Fetch arguments
# ----- Fetch arguments
self
.
generate_argument_parsing_code
(
code
)
self
.
generate_argument_parsing_code
(
code
)
self
.
generate_argument_increfs
(
lenv
,
code
)
self
.
generate_argument_increfs
(
lenv
,
code
)
...
@@ -552,18 +597,23 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -552,18 +597,23 @@ class FuncDefNode(StatNode, BlockNode):
'__Pyx_WriteUnraisable("%s");'
%
'__Pyx_WriteUnraisable("%s");'
%
self
.
entry
.
qualified_name
)
self
.
entry
.
qualified_name
)
env
.
use_utility_code
(
unraisable_exception_utility_code
)
env
.
use_utility_code
(
unraisable_exception_utility_code
)
#if not self.return_type.is_void:
default_retval
=
self
.
return_type
.
default_value
if
default_retval
:
code
.
putln
(
"%s = %s;"
%
(
Naming
.
retval_cname
,
default_retval
))
#self.return_type.default_value))
# ----- Return cleanup
# ----- Return cleanup
code
.
put_label
(
code
.
return_label
)
code
.
put_label
(
code
.
return_label
)
code
.
put_var_decrefs
(
lenv
.
var_entries
,
used_only
=
1
)
code
.
put_var_decrefs
(
lenv
.
var_entries
,
used_only
=
1
)
code
.
put_var_decrefs
(
lenv
.
arg_entries
)
code
.
put_var_decrefs
(
lenv
.
arg_entries
)
self
.
put_stararg_decrefs
(
code
)
self
.
put_stararg_decrefs
(
code
)
if
acquire_gil
:
code
.
putln
(
"PyGILState_Release(_save);"
)
if
not
self
.
return_type
.
is_void
:
if
not
self
.
return_type
.
is_void
:
retval_code
=
Naming
.
retval_cname
code
.
putln
(
"return %s;"
%
Naming
.
retval_cname
)
#if self.return_type.is_extension_type:
# retval_code = "((%s)%s) " % (
# self.return_type.declaration_code(""),
# retval_code)
code
.
putln
(
"return %s;"
%
retval_code
)
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
def
put_stararg_decrefs
(
self
,
code
):
def
put_stararg_decrefs
(
self
,
code
):
...
@@ -595,7 +645,9 @@ class CFuncDefNode(FuncDefNode):
...
@@ -595,7 +645,9 @@ class CFuncDefNode(FuncDefNode):
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# declarator CDeclaratorNode
# body StatListNode
# body StatListNode
# api boolean
#
#
# with_gil boolean Acquire GIL around body
# type CFuncType
# type CFuncType
def
unqualified_name
(
self
):
def
unqualified_name
(
self
):
...
@@ -604,20 +656,21 @@ class CFuncDefNode(FuncDefNode):
...
@@ -604,20 +656,21 @@ class CFuncDefNode(FuncDefNode):
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
base_type
=
self
.
base_type
.
analyse
(
env
)
base_type
=
self
.
base_type
.
analyse
(
env
)
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
if
not
type
.
is_cfunction
:
error
(
self
.
pos
,
"Suite attached to non-function declaration"
)
# Remember the actual type according to the function header
# Remember the actual type according to the function header
# written here, because the type in the symbol table entry
# written here, because the type in the symbol table entry
# may be different if we're overriding a C method inherited
# may be different if we're overriding a C method inherited
# from the base type of an extension type.
# from the base type of an extension type.
self
.
type
=
type
self
.
type
=
type
if
not
type
.
is_cfunction
:
error
(
self
.
pos
,
"Suite attached to non-function declaration"
)
name
=
name_declarator
.
name
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
cname
=
name_declarator
.
cname
self
.
entry
=
env
.
declare_cfunction
(
self
.
entry
=
env
.
declare_cfunction
(
name
,
type
,
self
.
pos
,
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
cname
=
cname
,
visibility
=
self
.
visibility
,
defining
=
self
.
body
is
not
None
)
defining
=
self
.
body
is
not
None
,
api
=
self
.
api
)
self
.
return_type
=
type
.
return_type
self
.
return_type
=
type
.
return_type
def
declare_arguments
(
self
,
env
):
def
declare_arguments
(
self
,
env
):
...
@@ -626,6 +679,14 @@ class CFuncDefNode(FuncDefNode):
...
@@ -626,6 +679,14 @@ class CFuncDefNode(FuncDefNode):
error
(
arg
.
pos
,
"Missing argument name"
)
error
(
arg
.
pos
,
"Missing argument name"
)
self
.
declare_argument
(
env
,
arg
)
self
.
declare_argument
(
env
,
arg
)
def
need_gil_acquisition
(
self
,
lenv
):
with_gil
=
self
.
type
.
with_gil
if
self
.
type
.
nogil
and
not
with_gil
:
for
entry
in
lenv
.
var_entries
+
lenv
.
temp_entries
:
if
entry
.
type
.
is_pyobject
:
error
(
self
.
pos
,
"Function declared nogil has Python locals or temporaries"
)
return
with_gil
def
generate_function_header
(
self
,
code
,
with_pymethdef
):
def
generate_function_header
(
self
,
code
,
with_pymethdef
):
arg_decls
=
[]
arg_decls
=
[]
type
=
self
.
type
type
=
self
.
type
...
@@ -704,6 +765,16 @@ class DefNode(FuncDefNode):
...
@@ -704,6 +765,16 @@ class DefNode(FuncDefNode):
# assmt AssignmentNode Function construction/assignment
# assmt AssignmentNode Function construction/assignment
assmt
=
None
assmt
=
None
num_kwonly_args
=
0
reqd_kw_flags_cname
=
"0"
def
__init__
(
self
,
pos
,
**
kwds
):
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
n
=
0
for
arg
in
self
.
args
:
if
arg
.
kw_only
:
n
+=
1
self
.
num_kwonly_args
=
n
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
...
@@ -781,14 +852,19 @@ class DefNode(FuncDefNode):
...
@@ -781,14 +852,19 @@ class DefNode(FuncDefNode):
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
def
declare_pyfunction
(
self
,
env
):
def
declare_pyfunction
(
self
,
env
):
self
.
entry
=
env
.
declare_pyfunction
(
self
.
name
,
self
.
pos
)
#print "DefNode.declare_pyfunction:", self.name, "in", env ###
self
.
entry
.
doc
=
self
.
doc
name
=
self
.
name
self
.
entry
.
func_cname
=
\
entry
=
env
.
declare_pyfunction
(
self
.
name
,
self
.
pos
)
Naming
.
func_prefix
+
env
.
scope_prefix
+
self
.
name
self
.
entry
=
entry
self
.
entry
.
doc_cname
=
\
prefix
=
env
.
scope_prefix
Naming
.
funcdoc_prefix
+
env
.
scope_prefix
+
self
.
name
entry
.
func_cname
=
\
self
.
entry
.
pymethdef_cname
=
\
Naming
.
func_prefix
+
prefix
+
name
Naming
.
pymethdef_prefix
+
env
.
scope_prefix
+
self
.
name
entry
.
pymethdef_cname
=
\
Naming
.
pymethdef_prefix
+
prefix
+
name
if
not
entry
.
is_special
:
entry
.
doc
=
self
.
doc
entry
.
doc_cname
=
\
Naming
.
funcdoc_prefix
+
prefix
+
name
def
declare_arguments
(
self
,
env
):
def
declare_arguments
(
self
,
env
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
...
@@ -890,6 +966,8 @@ class DefNode(FuncDefNode):
...
@@ -890,6 +966,8 @@ class DefNode(FuncDefNode):
def
generate_keyword_list
(
self
,
code
):
def
generate_keyword_list
(
self
,
code
):
if
self
.
entry
.
signature
.
has_generic_args
:
if
self
.
entry
.
signature
.
has_generic_args
:
reqd_kw_flags
=
[]
has_reqd_kwds
=
False
code
.
put
(
code
.
put
(
"static char *%s[] = {"
%
"static char *%s[] = {"
%
Naming
.
kwdlist_cname
)
Naming
.
kwdlist_cname
)
...
@@ -898,13 +976,32 @@ class DefNode(FuncDefNode):
...
@@ -898,13 +976,32 @@ class DefNode(FuncDefNode):
code
.
put
(
code
.
put
(
'"%s",'
%
'"%s",'
%
arg
.
name
)
arg
.
name
)
if
arg
.
kw_only
and
not
arg
.
default
:
has_reqd_kwds
=
1
flag
=
"1"
else
:
flag
=
"0"
reqd_kw_flags
.
append
(
flag
)
code
.
putln
(
code
.
putln
(
"0};"
)
"0};"
)
if
has_reqd_kwds
:
flags_name
=
Naming
.
reqd_kwds_cname
self
.
reqd_kw_flags_cname
=
flags_name
code
.
putln
(
"static char %s[] = {%s};"
%
(
flags_name
,
","
.
join
(
reqd_kw_flags
)))
def
generate_argument_parsing_code
(
self
,
code
):
def
generate_argument_parsing_code
(
self
,
code
):
# Generate PyArg_ParseTuple call for generic
# Generate PyArg_ParseTuple call for generic
# arguments, if any.
# arguments, if any.
if
self
.
entry
.
signature
.
has_generic_args
:
has_kwonly_args
=
self
.
num_kwonly_args
>
0
has_star_or_kw_args
=
self
.
star_arg
is
not
None
\
or
self
.
starstar_arg
is
not
None
or
has_kwonly_args
if
not
self
.
entry
.
signature
.
has_generic_args
:
if
has_star_or_kw_args
:
error
(
self
.
pos
,
"This method cannot have * or keyword arguments"
)
else
:
arg_addrs
=
[]
arg_addrs
=
[]
arg_formats
=
[]
arg_formats
=
[]
default_seen
=
0
default_seen
=
0
...
@@ -919,7 +1016,7 @@ class DefNode(FuncDefNode):
...
@@ -919,7 +1016,7 @@ class DefNode(FuncDefNode):
if
not
default_seen
:
if
not
default_seen
:
arg_formats
.
append
(
"|"
)
arg_formats
.
append
(
"|"
)
default_seen
=
1
default_seen
=
1
elif
default_seen
:
elif
default_seen
and
not
arg
.
kw_only
:
error
(
arg
.
pos
,
"Non-default argument following default argument"
)
error
(
arg
.
pos
,
"Non-default argument following default argument"
)
arg_addrs
.
append
(
"&"
+
arg_entry
.
cname
)
arg_addrs
.
append
(
"&"
+
arg_entry
.
cname
)
format
=
arg_entry
.
type
.
parsetuple_format
format
=
arg_entry
.
type
.
parsetuple_format
...
@@ -929,9 +1026,9 @@ class DefNode(FuncDefNode):
...
@@ -929,9 +1026,9 @@ class DefNode(FuncDefNode):
error
(
arg
.
pos
,
error
(
arg
.
pos
,
"Cannot convert Python object argument to type '%s'"
"Cannot convert Python object argument to type '%s'"
%
arg
.
type
)
%
arg
.
type
)
error_return_code
=
"return %s;"
%
self
.
error_value
()
argformat
=
'"%s"'
%
string
.
join
(
arg_formats
,
""
)
argformat
=
'"%s"'
%
string
.
join
(
arg_formats
,
""
)
has_starargs
=
self
.
star_arg
is
not
None
or
self
.
starstar_arg
is
not
None
if
has_star_or_kw_args
:
if
has_starargs
:
self
.
generate_stararg_getting_code
(
code
)
self
.
generate_stararg_getting_code
(
code
)
pt_arglist
=
[
Naming
.
args_cname
,
Naming
.
kwds_cname
,
argformat
,
pt_arglist
=
[
Naming
.
args_cname
,
Naming
.
kwds_cname
,
argformat
,
Naming
.
kwdlist_cname
]
+
arg_addrs
Naming
.
kwdlist_cname
]
+
arg_addrs
...
@@ -939,8 +1036,7 @@ class DefNode(FuncDefNode):
...
@@ -939,8 +1036,7 @@ class DefNode(FuncDefNode):
code
.
put
(
code
.
put
(
'if (!PyArg_ParseTupleAndKeywords(%s)) '
%
'if (!PyArg_ParseTupleAndKeywords(%s)) '
%
pt_argstring
)
pt_argstring
)
error_return_code
=
"return %s;"
%
self
.
error_value
()
if
has_star_or_kw_args
:
if
has_starargs
:
code
.
putln
(
"{"
)
code
.
putln
(
"{"
)
code
.
put_xdecref
(
Naming
.
args_cname
,
py_object_type
)
code
.
put_xdecref
(
Naming
.
args_cname
,
py_object_type
)
code
.
put_xdecref
(
Naming
.
kwds_cname
,
py_object_type
)
code
.
put_xdecref
(
Naming
.
kwds_cname
,
py_object_type
)
...
@@ -950,7 +1046,7 @@ class DefNode(FuncDefNode):
...
@@ -950,7 +1046,7 @@ class DefNode(FuncDefNode):
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
else
:
else
:
code
.
putln
(
error_return_code
)
code
.
putln
(
error_return_code
)
def
put_stararg_decrefs
(
self
,
code
):
def
put_stararg_decrefs
(
self
,
code
):
if
self
.
star_arg
or
self
.
starstar_arg
:
if
self
.
star_arg
or
self
.
starstar_arg
:
code
.
put_xdecref
(
Naming
.
args_cname
,
py_object_type
)
code
.
put_xdecref
(
Naming
.
args_cname
,
py_object_type
)
...
@@ -967,20 +1063,20 @@ class DefNode(FuncDefNode):
...
@@ -967,20 +1063,20 @@ class DefNode(FuncDefNode):
return
0
return
0
def
generate_stararg_getting_code
(
self
,
code
):
def
generate_stararg_getting_code
(
self
,
code
):
if
self
.
star_arg
or
self
.
starstar_arg
:
num_kwonly
=
self
.
num_kwonly_args
if
not
self
.
entry
.
signature
.
has_generic_args
:
nargs
=
len
(
self
.
args
)
-
num_kwonly
-
self
.
entry
.
signature
.
num_fixed_args
()
error
(
self
.
pos
,
"This method cannot have * or ** arguments"
)
star_arg_addr
=
self
.
arg_address
(
self
.
star_arg
)
star_arg_addr
=
self
.
arg_address
(
self
.
star_arg
)
starstar_arg_addr
=
self
.
arg_address
(
self
.
star
star_arg
)
starstar_arg_addr
=
self
.
arg_address
(
self
.
starstar_arg
)
code
.
putln
(
code
.
putln
(
"if (__Pyx_GetStarArgs(&%s, &%s, %s, %s, %s, %s, %s) < 0) return %s;"
%
(
"if (__Pyx_GetStarArgs(&%s, &%s, %s, %s, %s, %s) < 0) return %s;"
%
(
Naming
.
args_cname
,
Naming
.
arg
s_cname
,
Naming
.
kwd
s_cname
,
Naming
.
kwds
_cname
,
Naming
.
kwdlist
_cname
,
Naming
.
kwdlist_cname
,
nargs
,
len
(
self
.
args
)
-
self
.
entry
.
signature
.
num_fixed_args
()
,
star_arg_addr
,
star_arg_addr
,
star
star_arg_addr
,
starstar_arg_addr
,
self
.
reqd_kw_flags_cname
,
self
.
error_value
()))
self
.
error_value
()))
def
generate_argument_conversion_code
(
self
,
code
):
def
generate_argument_conversion_code
(
self
,
code
):
# Generate code to convert arguments from
# Generate code to convert arguments from
...
@@ -1646,11 +1742,10 @@ class RaiseStatNode(StatNode):
...
@@ -1646,11 +1742,10 @@ class RaiseStatNode(StatNode):
self
.
exc_value
.
release_temp
(
env
)
self
.
exc_value
.
release_temp
(
env
)
if
self
.
exc_tb
:
if
self
.
exc_tb
:
self
.
exc_tb
.
release_temp
(
env
)
self
.
exc_tb
.
release_temp
(
env
)
#env.recycle_pending_temps() # TEMPORARY
# if not (self.exc_type or self.exc_value or self.exc_tb):
if
not
(
self
.
exc_type
or
self
.
exc_value
or
self
.
exc_tb
):
# env.use_utility_code(reraise_utility_code)
env
.
use_utility_code
(
reraise_utility_code
)
# else:
else
:
env
.
use_utility_code
(
raise_utility_code
)
env
.
use_utility_code
(
raise_utility_code
)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
if
self
.
exc_type
:
if
self
.
exc_type
:
...
@@ -1687,6 +1782,20 @@ class RaiseStatNode(StatNode):
...
@@ -1687,6 +1782,20 @@ class RaiseStatNode(StatNode):
code
.
error_goto
(
self
.
pos
))
code
.
error_goto
(
self
.
pos
))
class
ReraiseStatNode
(
StatNode
):
def
analyse_expressions
(
self
,
env
):
env
.
use_utility_code
(
raise_utility_code
)
def
generate_execution_code
(
self
,
code
):
vars
=
code
.
exc_vars
if
vars
:
code
.
putln
(
"__Pyx_Raise(%s, %s, %s);"
%
tuple
(
vars
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
else
:
error
(
self
.
pos
,
"Reraise not inside except clause"
)
class
AssertStatNode
(
StatNode
):
class
AssertStatNode
(
StatNode
):
# assert statement
# assert statement
#
#
...
@@ -1705,6 +1814,7 @@ class AssertStatNode(StatNode):
...
@@ -1705,6 +1814,7 @@ class AssertStatNode(StatNode):
#env.recycle_pending_temps() # TEMPORARY
#env.recycle_pending_temps() # TEMPORARY
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
code
.
putln
(
"#ifndef PYREX_WITHOUT_ASSERTIONS"
)
self
.
cond
.
generate_evaluation_code
(
code
)
self
.
cond
.
generate_evaluation_code
(
code
)
if
self
.
value
:
if
self
.
value
:
self
.
value
.
generate_evaluation_code
(
code
)
self
.
value
.
generate_evaluation_code
(
code
)
...
@@ -1725,7 +1835,7 @@ class AssertStatNode(StatNode):
...
@@ -1725,7 +1835,7 @@ class AssertStatNode(StatNode):
self
.
cond
.
generate_disposal_code
(
code
)
self
.
cond
.
generate_disposal_code
(
code
)
if
self
.
value
:
if
self
.
value
:
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
code
.
putln
(
"#endif"
)
class
IfStatNode
(
StatNode
):
class
IfStatNode
(
StatNode
):
# if statement
# if statement
...
@@ -2020,9 +2130,6 @@ class TryExceptStatNode(StatNode):
...
@@ -2020,9 +2130,6 @@ class TryExceptStatNode(StatNode):
self
.
else_clause
.
generate_execution_code
(
code
)
self
.
else_clause
.
generate_execution_code
(
code
)
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
#code.putln(
# "goto %s;" %
# end_label)
code
.
put_goto
(
end_label
)
code
.
put_goto
(
end_label
)
code
.
put_label
(
our_error_label
)
code
.
put_label
(
our_error_label
)
code
.
put_var_xdecrefs_clear
(
self
.
cleanup_list
)
code
.
put_var_xdecrefs_clear
(
self
.
cleanup_list
)
...
@@ -2035,9 +2142,6 @@ class TryExceptStatNode(StatNode):
...
@@ -2035,9 +2142,6 @@ class TryExceptStatNode(StatNode):
error
(
except_clause
.
pos
,
"Default except clause not last"
)
error
(
except_clause
.
pos
,
"Default except clause not last"
)
except_clause
.
generate_handling_code
(
code
,
end_label
)
except_clause
.
generate_handling_code
(
code
,
end_label
)
if
not
default_clause_seen
:
if
not
default_clause_seen
:
#code.putln(
# "goto %s;" %
# code.error_label)
code
.
put_goto
(
code
.
error_label
)
code
.
put_goto
(
code
.
error_label
)
code
.
put_label
(
end_label
)
code
.
put_label
(
end_label
)
...
@@ -2051,6 +2155,7 @@ class ExceptClauseNode(Node):
...
@@ -2051,6 +2155,7 @@ class ExceptClauseNode(Node):
# match_flag string result of exception match
# match_flag string result of exception match
# exc_value ExcValueNode used internally
# exc_value ExcValueNode used internally
# function_name string qualified name of enclosing function
# function_name string qualified name of enclosing function
# exc_vars (string * 3) local exception variables
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
target
:
if
self
.
target
:
...
@@ -2067,15 +2172,15 @@ class ExceptClauseNode(Node):
...
@@ -2067,15 +2172,15 @@ class ExceptClauseNode(Node):
self
.
match_flag
=
env
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
self
.
match_flag
=
env
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
self
.
pattern
.
release_temp
(
env
)
self
.
pattern
.
release_temp
(
env
)
env
.
release_temp
(
self
.
match_flag
)
env
.
release_temp
(
self
.
match_flag
)
self
.
exc_value
=
ExprNodes
.
ExcValueNode
(
self
.
pos
,
env
)
self
.
exc_vars
=
[
env
.
allocate_temp
(
py_object_type
)
for
i
in
xrange
(
3
)]
self
.
exc_value
.
allocate_temps
(
env
)
if
self
.
target
:
if
self
.
target
:
self
.
exc_value
=
ExprNodes
.
ExcValueNode
(
self
.
pos
,
env
,
self
.
exc_vars
[
1
])
self
.
exc_value
.
allocate_temps
(
env
)
self
.
target
.
analyse_target_expression
(
env
,
self
.
exc_value
)
self
.
target
.
analyse_target_expression
(
env
,
self
.
exc_value
)
else
:
self
.
exc_value
.
release_temp
(
env
)
#if self.target:
# self.target.release_target_temp(env)
self
.
body
.
analyse_expressions
(
env
)
self
.
body
.
analyse_expressions
(
env
)
for
var
in
self
.
exc_vars
:
env
.
release_temp
(
var
)
env
.
use_utility_code
(
get_exception_utility_code
)
def
generate_handling_code
(
self
,
code
,
end_label
):
def
generate_handling_code
(
self
,
code
,
end_label
):
code
.
mark_pos
(
self
.
pos
)
code
.
mark_pos
(
self
.
pos
)
...
@@ -2097,15 +2202,18 @@ class ExceptClauseNode(Node):
...
@@ -2097,15 +2202,18 @@ class ExceptClauseNode(Node):
# We always have to fetch the exception value even if
# We always have to fetch the exception value even if
# there is no target, because this also normalises the
# there is no target, because this also normalises the
# exception and stores it in the thread state.
# exception and stores it in the thread state.
self
.
exc_value
.
generate_evaluation_code
(
code
)
exc_args
=
"&%s, &%s, &%s"
%
tuple
(
self
.
exc_vars
)
code
.
putln
(
"if (__Pyx_GetException(%s) < 0) %s"
%
(
exc_args
,
code
.
error_goto
(
self
.
pos
)))
if
self
.
target
:
if
self
.
target
:
self
.
exc_value
.
generate_evaluation_code
(
code
)
self
.
target
.
generate_assignment_code
(
self
.
exc_value
,
code
)
self
.
target
.
generate_assignment_code
(
self
.
exc_value
,
code
)
else
:
old_exc_vars
=
code
.
exc_vars
self
.
exc_value
.
generate_disposal_code
(
code
)
code
.
exc_vars
=
self
.
exc_vars
self
.
body
.
generate_execution_code
(
code
)
self
.
body
.
generate_execution_code
(
code
)
#code.putln(
code
.
exc_vars
=
old_exc_vars
# "goto %s;"
for
var
in
self
.
exc_vars
:
# % end_label
)
code
.
putln
(
"Py_DECREF(%s);"
%
var
)
code
.
put_goto
(
end_label
)
code
.
put_goto
(
end_label
)
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
...
@@ -2116,8 +2224,8 @@ class TryFinallyStatNode(StatNode):
...
@@ -2116,8 +2224,8 @@ class TryFinallyStatNode(StatNode):
#
#
# body StatNode
# body StatNode
# finally_clause StatNode
# finally_clause StatNode
#
# cleanup_list [Entry] temps to clean up on error
# cleanup_list [Entry] temps to clean up on error
# exc_vars 3*(string,) temps to hold saved exception
#
#
# The plan is that we funnel all continue, break
# The plan is that we funnel all continue, break
# return and error gotos into the beginning of the
# return and error gotos into the beginning of the
...
@@ -2128,6 +2236,8 @@ class TryFinallyStatNode(StatNode):
...
@@ -2128,6 +2236,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.
preserve_exception
=
1
disallow_continue_in_try_finally
=
0
disallow_continue_in_try_finally
=
0
# There doesn't seem to be any point in disallowing
# There doesn't seem to be any point in disallowing
# continue in the try block, since we have no problem
# continue in the try block, since we have no problem
...
@@ -2140,15 +2250,15 @@ class TryFinallyStatNode(StatNode):
...
@@ -2140,15 +2250,15 @@ class TryFinallyStatNode(StatNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
body
.
analyse_expressions
(
env
)
self
.
body
.
analyse_expressions
(
env
)
self
.
cleanup_list
=
env
.
free_temp_entries
[:]
self
.
cleanup_list
=
env
.
free_temp_entries
[:]
self
.
exc_vars
=
(
#
self.exc_vars = (
env
.
allocate_temp
(
PyrexTypes
.
py_object_type
),
#
env.allocate_temp(PyrexTypes.py_object_type),
env
.
allocate_temp
(
PyrexTypes
.
py_object_type
),
#
env.allocate_temp(PyrexTypes.py_object_type),
env
.
allocate_temp
(
PyrexTypes
.
py_object_type
))
#
env.allocate_temp(PyrexTypes.py_object_type))
self
.
lineno_var
=
\
#
self.lineno_var = \
env
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
#
env.allocate_temp(PyrexTypes.c_int_type)
self
.
finally_clause
.
analyse_expressions
(
env
)
self
.
finally_clause
.
analyse_expressions
(
env
)
for
var
in
self
.
exc_vars
:
#
for var in self.exc_vars:
env
.
release_temp
(
var
)
#
env.release_temp(var)
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
old_error_label
=
code
.
error_label
old_error_label
=
code
.
error_label
...
@@ -2168,47 +2278,69 @@ class TryFinallyStatNode(StatNode):
...
@@ -2168,47 +2278,69 @@ class TryFinallyStatNode(StatNode):
"}"
)
"}"
)
code
.
putln
(
code
.
putln
(
"/*finally:*/ {"
)
"/*finally:*/ {"
)
code
.
putln
(
cases_used
=
[]
"int __pyx_why;"
)
error_label_used
=
0
#code.putln(
for
i
,
new_label
in
enumerate
(
new_labels
):
# "PyObject *%s, *%s, *%s;" %
if
new_label
in
code
.
labels_used
:
# self.exc_vars)
cases_used
.
append
(
i
)
#code.putln(
if
new_label
==
new_error_label
:
# "int %s;" %
error_label_used
=
1
# self.lineno_var)
error_label_case
=
i
code
.
use_label
(
catch_label
)
if
cases_used
:
code
.
putln
(
code
.
putln
(
"__pyx_why = 0; goto %s;"
%
"int __pyx_why;"
)
catch_label
)
if
error_label_used
and
self
.
preserve_exception
:
for
i
in
range
(
len
(
new_labels
)):
code
.
putln
(
new_label
=
new_labels
[
i
]
"PyObject *%s, *%s, *%s;"
%
Naming
.
exc_vars
)
if
new_label
and
new_label
<>
"<try>"
:
code
.
putln
(
if
new_label
in
code
.
labels_used
:
"int %s;"
%
Naming
.
exc_lineno_name
)
if
new_label
==
new_error_label
:
code
.
use_label
(
catch_label
)
self
.
put_error_catcher
(
code
,
code
.
putln
(
new_error_label
,
i
+
1
,
catch_label
)
"__pyx_why = 0; goto %s;"
%
catch_label
)
else
:
for
i
in
cases_used
:
code
.
putln
(
new_label
=
new_labels
[
i
]
"%s: __pyx_why = %s; goto %s;"
%
(
#if new_label and new_label <> "<try>":
new_label
,
if
new_label
==
new_error_label
and
self
.
preserve_exception
:
i
+
1
,
self
.
put_error_catcher
(
code
,
catch_label
))
new_error_label
,
i
+
1
,
catch_label
)
code
.
put_label
(
catch_label
)
else
:
code
.
putln
(
"%s: __pyx_why = %s; goto %s;"
%
(
new_label
,
i
+
1
,
catch_label
))
code
.
put_label
(
catch_label
)
code
.
set_all_labels
(
old_labels
)
code
.
set_all_labels
(
old_labels
)
if
error_label_used
:
code
.
new_error_label
()
finally_error_label
=
code
.
error_label
self
.
finally_clause
.
generate_execution_code
(
code
)
self
.
finally_clause
.
generate_execution_code
(
code
)
code
.
putln
(
if
error_label_used
:
if
finally_error_label
in
code
.
labels_used
and
self
.
preserve_exception
:
over_label
=
code
.
new_label
()
code
.
put_goto
(
over_label
);
code
.
put_label
(
finally_error_label
)
code
.
putln
(
"if (__pyx_why == %d) {"
%
(
error_label_case
+
1
))
for
var
in
Naming
.
exc_vars
:
code
.
putln
(
"Py_XDECREF(%s);"
%
var
)
code
.
putln
(
"}"
)
code
.
put_goto
(
old_error_label
)
code
.
put_label
(
over_label
)
code
.
error_label
=
old_error_label
if
cases_used
:
code
.
putln
(
"switch (__pyx_why) {"
)
"switch (__pyx_why) {"
)
for
i
in
range
(
len
(
old_labels
))
:
for
i
in
cases_used
:
if
old_labels
[
i
]:
old_label
=
old_labels
[
i
]
if
old_label
s
[
i
]
==
old_error_label
:
if
old_label
==
old_error_label
and
self
.
preserve_exception
:
self
.
put_error_uncatcher
(
code
,
i
+
1
,
old_error_label
)
self
.
put_error_uncatcher
(
code
,
i
+
1
,
old_error_label
)
else
:
else
:
code
.
use_label
(
old_label
s
[
i
]
)
code
.
use_label
(
old_label
)
code
.
putln
(
code
.
putln
(
"case %s: goto %s;"
%
(
"case %s: goto %s;"
%
(
i
+
1
,
i
+
1
,
old_label
s
[
i
]
))
old_label
))
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
...
@@ -2223,10 +2355,10 @@ class TryFinallyStatNode(StatNode):
...
@@ -2223,10 +2355,10 @@ class TryFinallyStatNode(StatNode):
code
.
put_var_xdecrefs_clear
(
self
.
cleanup_list
)
code
.
put_var_xdecrefs_clear
(
self
.
cleanup_list
)
code
.
putln
(
code
.
putln
(
"PyErr_Fetch(&%s, &%s, &%s);"
%
"PyErr_Fetch(&%s, &%s, &%s);"
%
self
.
exc_vars
)
Naming
.
exc_vars
)
code
.
putln
(
code
.
putln
(
"%s = %s;"
%
(
"%s = %s;"
%
(
self
.
lineno_var
,
Naming
.
lineno_cname
))
Naming
.
exc_lineno_name
,
Naming
.
lineno_cname
))
#code.putln(
#code.putln(
# "goto %s;" %
# "goto %s;" %
# catch_label)
# catch_label)
...
@@ -2240,22 +2372,71 @@ class TryFinallyStatNode(StatNode):
...
@@ -2240,22 +2372,71 @@ class TryFinallyStatNode(StatNode):
i
)
i
)
code
.
putln
(
code
.
putln
(
"PyErr_Restore(%s, %s, %s);"
%
"PyErr_Restore(%s, %s, %s);"
%
self
.
exc_vars
)
Naming
.
exc_vars
)
code
.
putln
(
code
.
putln
(
"%s = %s;"
%
(
"%s = %s;"
%
(
Naming
.
lineno_cname
,
self
.
lineno_var
))
Naming
.
lineno_cname
,
Naming
.
exc_lineno_name
))
for
var
in
self
.
exc_vars
:
for
var
in
Naming
.
exc_vars
:
code
.
putln
(
code
.
putln
(
"%s = 0;"
%
"%s = 0;"
%
var
)
var
)
#code.putln(
# "goto %s;" %
# error_label)
code
.
put_goto
(
error_label
)
code
.
put_goto
(
error_label
)
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
class
GILStatNode
(
TryFinallyStatNode
):
# 'with gil' or 'with nogil' statement
#
# state string 'gil' or 'nogil'
preserve_exception
=
0
def
__init__
(
self
,
pos
,
state
,
body
):
self
.
state
=
state
TryFinallyStatNode
.
__init__
(
self
,
pos
,
body
=
body
,
finally_clause
=
GILExitNode
(
pos
,
state
=
state
))
def
generate_execution_code
(
self
,
code
):
code
.
putln
(
"/*with %s:*/ {"
%
self
.
state
)
if
self
.
state
==
'gil'
:
code
.
putln
(
"PyGILState_STATE _save = PyGILState_Ensure();"
)
else
:
code
.
putln
(
"PyThreadState *_save;"
)
code
.
putln
(
"Py_UNBLOCK_THREADS"
)
TryFinallyStatNode
.
generate_execution_code
(
self
,
code
)
code
.
putln
(
"}"
)
#class GILEntryNode(StatNode):
# # state string 'gil' or 'nogil'
#
# def analyse_expressions(self, env):
# pass
#
# def generate_execution_code(self, code):
# if self.state == 'gil':
# code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
# else:
# code.putln("PyThreadState *_save;")
# code.putln("Py_UNBLOCK_THREADS")
class
GILExitNode
(
StatNode
):
# Used as the 'finally' block in a GILStatNode
#
# state string 'gil' or 'nogil'
def
analyse_expressions
(
self
,
env
):
pass
def
generate_execution_code
(
self
,
code
):
if
self
.
state
==
'gil'
:
code
.
putln
(
"PyGILState_Release();"
)
else
:
code
.
putln
(
"Py_BLOCK_THREADS"
)
class
CImportStatNode
(
StatNode
):
class
CImportStatNode
(
StatNode
):
# cimport statement
# cimport statement
#
#
...
@@ -2406,7 +2587,7 @@ static int __Pyx_PrintItem(PyObject *v) {
...
@@ -2406,7 +2587,7 @@ static int __Pyx_PrintItem(PyObject *v) {
return -1;
return -1;
if (PyString_Check(v)) {
if (PyString_Check(v)) {
char *s = PyString_AsString(v);
char *s = PyString_AsString(v);
in
t len = PyString_Size(v);
Py_ssize_
t len = PyString_Size(v);
if (len > 0 &&
if (len > 0 &&
isspace(Py_CHARMASK(s[len-1])) &&
isspace(Py_CHARMASK(s[len-1])) &&
s[len-1] != ' ')
s[len-1] != ' ')
...
@@ -2454,21 +2635,12 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
...
@@ -2454,21 +2635,12 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
value = Py_None;
value = Py_None;
Py_INCREF(value);
Py_INCREF(value);
}
}
/* Next, repeatedly, replace a tuple exception with its first item */
#if PY_VERSION_HEX < 0x02050000
while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
if (!PyClass_Check(type))
PyObject *tmp = type;
#else
type = PyTuple_GET_ITEM(type, 0);
if (!PyType_Check(type))
Py_INCREF(type);
#endif
Py_DECREF(tmp);
{
}
if (PyString_Check(type)) {
if (PyErr_Warn(PyExc_DeprecationWarning,
"raising a string exception is deprecated"))
goto raise_error;
}
else if (PyType_Check(type) || PyClass_Check(type))
; /*PyErr_NormalizeException(&type, &value, &tb);*/
else {
/* Raising an instance. The value should be a dummy. */
/* Raising an instance. The value should be a dummy. */
if (value != Py_None) {
if (value != Py_None) {
PyErr_SetString(PyExc_TypeError,
PyErr_SetString(PyExc_TypeError,
...
@@ -2478,11 +2650,25 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
...
@@ -2478,11 +2650,25 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
/* Normalize to raise <class>, <instance> */
/* Normalize to raise <class>, <instance> */
Py_DECREF(value);
Py_DECREF(value);
value = type;
value = type;
if (PyInstance_Check(type))
#if PY_VERSION_HEX < 0x02050000
type = (PyObject*) ((PyInstanceObject*)type)->in_class;
if (PyInstance_Check(type)) {
else
type = (PyObject*) ((PyInstanceObject*)type)->in_class;
Py_INCREF(type);
}
else {
PyErr_SetString(PyExc_TypeError,
"raise: exception must be an old-style class or instance");
goto raise_error;
}
#else
type = (PyObject*) type->ob_type;
type = (PyObject*) type->ob_type;
Py_INCREF(type);
Py_INCREF(type);
if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
PyErr_SetString(PyExc_TypeError,
"raise: exception class must be a subclass of BaseException");
goto raise_error;
}
#endif
}
}
PyErr_Restore(type, value, tb);
PyErr_Restore(type, value, tb);
return;
return;
...
@@ -2545,21 +2731,28 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
...
@@ -2545,21 +2731,28 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
# *kwds == 0, it is not changed. If kwds2 == 0 and *kwds != 0, a new
# *kwds == 0, it is not changed. If kwds2 == 0 and *kwds != 0, a new
# reference to the same dictionary is passed back in *kwds.
# reference to the same dictionary is passed back in *kwds.
#
#
# If rqd_kwds is not 0, it is an array of booleans corresponding to the
# names in kwd_list, indicating required keyword arguments. If any of
# these are not present in kwds, an exception is raised.
#
get_starargs_utility_code
=
[
get_starargs_utility_code
=
[
"""
"""
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,
\
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,
char *kwd_list[],
\
char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2
); /*proto*/
Py_ssize_t nargs, PyObject **args2, PyObject **kwds2, char rqd_kwds[]
); /*proto*/
"""
,
"""
"""
,
"""
static int __Pyx_GetStarArgs(
static int __Pyx_GetStarArgs(
PyObject **args,
PyObject **args,
PyObject **kwds,
PyObject **kwds,
char *kwd_list[],
char *kwd_list[],
in
t nargs,
Py_ssize_
t nargs,
PyObject **args2,
PyObject **args2,
PyObject **kwds2)
PyObject **kwds2,
char rqd_kwds[])
{
{
PyObject *x = 0, *args1 = 0, *kwds1 = 0;
PyObject *x = 0, *args1 = 0, *kwds1 = 0;
int i;
char **p;
if (args2)
if (args2)
*args2 = 0;
*args2 = 0;
...
@@ -2570,25 +2763,37 @@ static int __Pyx_GetStarArgs(
...
@@ -2570,25 +2763,37 @@ static int __Pyx_GetStarArgs(
args1 = PyTuple_GetSlice(*args, 0, nargs);
args1 = PyTuple_GetSlice(*args, 0, nargs);
if (!args1)
if (!args1)
goto bad;
goto bad;
*args2 = PyTuple_GetSlice(*args, nargs, PyTuple_
Size
(*args));
*args2 = PyTuple_GetSlice(*args, nargs, PyTuple_
GET_SIZE
(*args));
if (!*args2)
if (!*args2)
goto bad;
goto bad;
}
}
else if (PyTuple_GET_SIZE(*args) > nargs) {
int m = nargs;
int n = PyTuple_GET_SIZE(*args);
PyErr_Format(PyExc_TypeError,
"function takes at most %d positional arguments (%d given)",
m, n);
goto bad;
}
else {
else {
args1 = *args;
args1 = *args;
Py_INCREF(args1);
Py_INCREF(args1);
}
}
if (rqd_kwds && !*kwds)
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i])
goto missing_kwarg;
if (kwds2) {
if (kwds2) {
if (*kwds) {
if (*kwds) {
char **p;
kwds1 = PyDict_New();
kwds1 = PyDict_New();
if (!kwds)
if (!kwds
1
)
goto bad;
goto bad;
*kwds2 = PyDict_Copy(*kwds);
*kwds2 = PyDict_Copy(*kwds);
if (!*kwds2)
if (!*kwds2)
goto bad;
goto bad;
for (
p = kwd_list; *p;
p++) {
for (
i = 0, p = kwd_list; *p; i++,
p++) {
x = PyDict_GetItemString(*kwds, *p);
x = PyDict_GetItemString(*kwds, *p);
if (x) {
if (x) {
if (PyDict_SetItemString(kwds1, *p, x) < 0)
if (PyDict_SetItemString(kwds1, *p, x) < 0)
...
@@ -2596,6 +2801,8 @@ static int __Pyx_GetStarArgs(
...
@@ -2596,6 +2801,8 @@ static int __Pyx_GetStarArgs(
if (PyDict_DelItemString(*kwds2, *p) < 0)
if (PyDict_DelItemString(*kwds2, *p) < 0)
goto bad;
goto bad;
}
}
else if (rqd_kwds && rqd_kwds[i])
goto missing_kwarg;
}
}
}
}
else {
else {
...
@@ -2607,18 +2814,25 @@ static int __Pyx_GetStarArgs(
...
@@ -2607,18 +2814,25 @@ static int __Pyx_GetStarArgs(
else {
else {
kwds1 = *kwds;
kwds1 = *kwds;
Py_XINCREF(kwds1);
Py_XINCREF(kwds1);
if (rqd_kwds && *kwds)
for (i = 0, p = kwd_list; *p; i++, p++)
if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p))
goto missing_kwarg;
}
}
*args = args1;
*args = args1;
*kwds = kwds1;
*kwds = kwds1;
return 0;
return 0;
missing_kwarg:
PyErr_Format(PyExc_TypeError,
"required keyword argument '%s' is missing", *p);
bad:
bad:
Py_XDECREF(args1);
Py_XDECREF(args1);
Py_XDECREF(kwds1);
Py_XDECREF(kwds1);
if (
*
args2) {
if (args2) {
Py_XDECREF(*args2);
Py_XDECREF(*args2);
}
}
if (
*
kwds2) {
if (kwds2) {
Py_XDECREF(*kwds2);
Py_XDECREF(*kwds2);
}
}
return -1;
return -1;
...
@@ -2714,63 +2928,6 @@ bad:
...
@@ -2714,63 +2928,6 @@ bad:
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
type_import_utility_code
=
[
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
"""
,
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
long size)
{
PyObject *py_module_name = 0;
PyObject *py_class_name = 0;
PyObject *py_name_list = 0;
PyObject *py_module = 0;
PyObject *result = 0;
py_module_name = PyString_FromString(module_name);
if (!py_module_name)
goto bad;
py_class_name = PyString_FromString(class_name);
if (!py_class_name)
goto bad;
py_name_list = PyList_New(1);
if (!py_name_list)
goto bad;
Py_INCREF(py_class_name);
if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
goto bad;
py_module = __Pyx_Import(py_module_name, py_name_list);
if (!py_module)
goto bad;
result = PyObject_GetAttr(py_module, py_class_name);
if (!result)
goto bad;
if (!PyType_Check(result)) {
PyErr_Format(PyExc_TypeError,
"%s.%s is not a type object",
module_name, class_name);
goto bad;
}
if (((PyTypeObject *)result)->tp_basicsize != size) {
PyErr_Format(PyExc_ValueError,
"%s.%s does not appear to be the correct type object",
module_name, class_name);
goto bad;
}
goto done;
bad:
Py_XDECREF(result);
result = 0;
done:
Py_XDECREF(py_module_name);
Py_XDECREF(py_class_name);
Py_XDECREF(py_name_list);
return (PyTypeObject *)result;
}
"""
]
#------------------------------------------------------------------------------------
set_vtable_utility_code
=
[
set_vtable_utility_code
=
[
"""
"""
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
...
@@ -2857,3 +3014,33 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
...
@@ -2857,3 +3014,33 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
"""
]
"""
]
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
get_exception_utility_code
=
[
"""
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
"""
,
"""
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
PyThreadState *tstate = PyThreadState_Get();
PyErr_Fetch(type, value, tb);
PyErr_NormalizeException(type, value, tb);
if (PyErr_Occurred())
goto bad;
Py_INCREF(*type);
Py_INCREF(*value);
Py_INCREF(*tb);
Py_XDECREF(tstate->exc_type);
Py_XDECREF(tstate->exc_value);
Py_XDECREF(tstate->exc_traceback);
tstate->exc_type = *type;
tstate->exc_value = *value;
tstate->exc_traceback = *tb;
return 0;
bad:
Py_XDECREF(*type);
Py_XDECREF(*value);
Py_XDECREF(*tb);
return -1;
}
"""
]
#------------------------------------------------------------------------------------
Cython/Compiler/Parsing.py
View file @
3588f4a6
...
@@ -441,13 +441,35 @@ def p_atom(s):
...
@@ -441,13 +441,35 @@ def p_atom(s):
if
name
==
"None"
:
if
name
==
"None"
:
return
ExprNodes
.
NoneNode
(
pos
)
return
ExprNodes
.
NoneNode
(
pos
)
else
:
else
:
return
ExprNodes
.
NameNode
(
pos
,
name
=
name
)
return
p_name
(
s
,
name
)
elif
sy
==
'NULL'
:
elif
sy
==
'NULL'
:
s
.
next
()
s
.
next
()
return
ExprNodes
.
NullNode
(
pos
)
return
ExprNodes
.
NullNode
(
pos
)
else
:
else
:
s
.
error
(
"Expected an identifier or literal"
)
s
.
error
(
"Expected an identifier or literal"
)
def
p_name
(
s
,
name
):
pos
=
s
.
position
()
if
not
s
.
compile_time_expr
:
try
:
value
=
s
.
compile_time_env
.
lookup_here
(
name
)
except
KeyError
:
pass
else
:
rep
=
repr
(
value
)
if
isinstance
(
value
,
int
):
return
ExprNodes
.
IntNode
(
pos
,
value
=
rep
)
elif
isinstance
(
value
,
long
):
return
ExprNodes
.
LongNode
(
pos
,
value
=
rep
)
elif
isinstance
(
value
,
float
):
return
ExprNodes
.
FloatNode
(
pos
,
value
=
rep
)
elif
isinstance
(
value
,
str
):
return
ExprNodes
.
StringNode
(
pos
,
value
=
rep
[
1
:
-
1
])
else
:
error
(
pos
,
"Invalid type for compile-time constant: %s"
%
value
.
__class__
.
__name__
)
return
ExprNodes
.
NameNode
(
pos
,
name
=
name
)
def
p_cat_string_literal
(
s
):
def
p_cat_string_literal
(
s
):
# A sequence of one or more adjacent string literals.
# A sequence of one or more adjacent string literals.
# Returns (kind, value) where kind in ('', 'c', 'r')
# Returns (kind, value) where kind in ('', 'c', 'r')
...
@@ -645,7 +667,10 @@ def p_expression_or_assignment(s):
...
@@ -645,7 +667,10 @@ def p_expression_or_assignment(s):
expr_list
.
append
(
p_expr
(
s
))
expr_list
.
append
(
p_expr
(
s
))
if
len
(
expr_list
)
==
1
:
if
len
(
expr_list
)
==
1
:
expr
=
expr_list
[
0
]
expr
=
expr_list
[
0
]
return
Nodes
.
ExprStatNode
(
expr
.
pos
,
expr
=
expr
)
if
isinstance
(
expr
,
ExprNodes
.
StringNode
):
return
Nodes
.
PassStatNode
(
expr
.
pos
)
else
:
return
Nodes
.
ExprStatNode
(
expr
.
pos
,
expr
=
expr
)
else
:
else
:
expr_list_list
=
[]
expr_list_list
=
[]
flatten_parallel_assignments
(
expr_list
,
expr_list_list
)
flatten_parallel_assignments
(
expr_list
,
expr_list_list
)
...
@@ -769,10 +794,13 @@ def p_raise_statement(s):
...
@@ -769,10 +794,13 @@ def p_raise_statement(s):
if
s
.
sy
==
','
:
if
s
.
sy
==
','
:
s
.
next
()
s
.
next
()
exc_tb
=
p_simple_expr
(
s
)
exc_tb
=
p_simple_expr
(
s
)
return
Nodes
.
RaiseStatNode
(
pos
,
if
exc_type
or
exc_value
or
exc_tb
:
exc_type
=
exc_type
,
return
Nodes
.
RaiseStatNode
(
pos
,
exc_value
=
exc_value
,
exc_type
=
exc_type
,
exc_tb
=
exc_tb
)
exc_value
=
exc_value
,
exc_tb
=
exc_tb
)
else
:
return
Nodes
.
ReraiseStatNode
(
pos
)
def
p_import_statement
(
s
):
def
p_import_statement
(
s
):
# s.sy in ('import', 'cimport')
# s.sy in ('import', 'cimport')
...
@@ -790,13 +818,18 @@ def p_import_statement(s):
...
@@ -790,13 +818,18 @@ def p_import_statement(s):
module_name
=
dotted_name
,
module_name
=
dotted_name
,
as_name
=
as_name
)
as_name
=
as_name
)
else
:
else
:
if
as_name
and
"."
in
dotted_name
:
name_list
=
ExprNodes
.
ListNode
(
pos
,
args
=
[
ExprNodes
.
StringNode
(
pos
,
value
=
"*"
)])
else
:
name_list
=
None
stat
=
Nodes
.
SingleAssignmentNode
(
pos
,
stat
=
Nodes
.
SingleAssignmentNode
(
pos
,
lhs
=
ExprNodes
.
NameNode
(
pos
,
lhs
=
ExprNodes
.
NameNode
(
pos
,
name
=
as_name
or
target_name
),
name
=
as_name
or
target_name
),
rhs
=
ExprNodes
.
ImportNode
(
pos
,
rhs
=
ExprNodes
.
ImportNode
(
pos
,
module_name
=
ExprNodes
.
StringNode
(
pos
,
module_name
=
ExprNodes
.
StringNode
(
pos
,
value
=
dotted_name
),
value
=
dotted_name
),
name_list
=
None
))
name_list
=
name_list
))
stats
.
append
(
stat
)
stats
.
append
(
stat
)
return
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
return
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
...
@@ -859,8 +892,6 @@ def p_dotted_name(s, as_allowed):
...
@@ -859,8 +892,6 @@ def p_dotted_name(s, as_allowed):
names
.
append
(
p_ident
(
s
))
names
.
append
(
p_ident
(
s
))
if
as_allowed
:
if
as_allowed
:
as_name
=
p_as_name
(
s
)
as_name
=
p_as_name
(
s
)
else
:
as_name
=
None
return
(
pos
,
target_name
,
join
(
names
,
"."
),
as_name
)
return
(
pos
,
target_name
,
join
(
names
,
"."
),
as_name
)
def
p_as_name
(
s
):
def
p_as_name
(
s
):
...
@@ -1039,17 +1070,32 @@ def p_include_statement(s, level):
...
@@ -1039,17 +1070,32 @@ def p_include_statement(s, level):
s
.
next
()
# 'include'
s
.
next
()
# 'include'
_
,
include_file_name
=
p_string_literal
(
s
)
_
,
include_file_name
=
p_string_literal
(
s
)
s
.
expect_newline
(
"Syntax error in include statement"
)
s
.
expect_newline
(
"Syntax error in include statement"
)
include_file_path
=
s
.
context
.
find_include_file
(
include_file_name
,
pos
)
if
s
.
compile_time_eval
:
if
include_file_path
:
include_file_path
=
s
.
context
.
find_include_file
(
include_file_name
,
pos
)
f
=
open
(
include_file_path
,
"rU"
)
if
include_file_path
:
s2
=
PyrexScanner
(
f
,
include_file_path
,
s
)
f
=
open
(
include_file_path
,
"rU"
)
try
:
s2
=
PyrexScanner
(
f
,
include_file_path
,
s
)
tree
=
p_statement_list
(
s2
,
level
)
try
:
finally
:
tree
=
p_statement_list
(
s2
,
level
)
f
.
close
()
finally
:
return
tree
f
.
close
()
return
tree
else
:
return
None
else
:
else
:
return
None
return
Nodes
.
PassStatNode
(
pos
)
def
p_with_statement
(
s
):
pos
=
s
.
position
()
s
.
next
()
# 'with'
# if s.sy == 'IDENT' and s.systring in ('gil', 'nogil'):
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'nogil'
:
state
=
s
.
systring
s
.
next
()
body
=
p_suite
(
s
)
return
Nodes
.
GILStatNode
(
pos
,
state
=
state
,
body
=
body
)
else
:
s
.
error
(
pos
,
"Only 'with gil' and 'with nogil' implemented"
)
def
p_simple_statement
(
s
):
def
p_simple_statement
(
s
):
#print "p_simple_statement:", s.sy, s.systring ###
#print "p_simple_statement:", s.sy, s.systring ###
...
@@ -1095,63 +1141,122 @@ def p_simple_statement_list(s):
...
@@ -1095,63 +1141,122 @@ def p_simple_statement_list(s):
s
.
expect_newline
(
"Syntax error in simple statement list"
)
s
.
expect_newline
(
"Syntax error in simple statement list"
)
return
stat
return
stat
def
p_statement
(
s
,
level
,
cdef_flag
=
0
,
visibility
=
'private'
):
def
p_compile_time_expr
(
s
):
#print "p_statement:", s.sy, s.systring ###
old
=
s
.
compile_time_expr
s
.
compile_time_expr
=
1
expr
=
p_expr
(
s
)
s
.
compile_time_expr
=
old
return
expr
def
p_DEF_statement
(
s
):
pos
=
s
.
position
()
denv
=
s
.
compile_time_env
s
.
next
()
# 'DEF'
name
=
p_ident
(
s
)
s
.
expect
(
'='
)
expr
=
p_compile_time_expr
(
s
)
value
=
expr
.
compile_time_value
(
denv
)
#print "p_DEF_statement: %s = %r" % (name, value) ###
denv
.
declare
(
name
,
value
)
s
.
expect_newline
()
return
Nodes
.
PassStatNode
(
pos
)
def
p_IF_statement
(
s
,
level
,
cdef_flag
,
visibility
,
api
):
pos
=
s
.
position
saved_eval
=
s
.
compile_time_eval
current_eval
=
saved_eval
denv
=
s
.
compile_time_env
result
=
None
while
1
:
s
.
next
()
# 'IF' or 'ELIF'
expr
=
p_compile_time_expr
(
s
)
s
.
compile_time_eval
=
current_eval
and
bool
(
expr
.
compile_time_value
(
denv
))
body
=
p_suite
(
s
,
level
,
cdef_flag
,
visibility
,
api
=
api
)
if
s
.
compile_time_eval
:
result
=
body
current_eval
=
0
if
s
.
sy
<>
'ELIF'
:
break
if
s
.
sy
==
'ELSE'
:
s
.
next
()
s
.
compile_time_eval
=
current_eval
body
=
p_suite
(
s
,
level
,
cdef_flag
,
visibility
,
api
=
api
)
if
current_eval
:
result
=
body
if
not
result
:
result
=
PassStatNode
(
pos
)
s
.
compile_time_eval
=
saved_eval
return
result
def
p_statement
(
s
,
level
,
cdef_flag
=
0
,
visibility
=
'private'
,
api
=
0
):
if
s
.
sy
==
'ctypedef'
:
if
s
.
sy
==
'ctypedef'
:
if
level
not
in
(
'module'
,
'module_pxd'
):
if
level
not
in
(
'module'
,
'module_pxd'
):
s
.
error
(
"ctypedef statement not allowed here"
)
s
.
error
(
"ctypedef statement not allowed here"
)
if
api
:
error
(
s
.
pos
,
"'api' not allowed with 'ctypedef'"
)
return
p_ctypedef_statement
(
s
,
level
,
visibility
)
return
p_ctypedef_statement
(
s
,
level
,
visibility
)
if
s
.
sy
==
'cdef'
:
elif
s
.
sy
==
'DEF'
:
cdef_flag
=
1
return
p_DEF_statement
(
s
)
s
.
next
()
elif
s
.
sy
==
'IF'
:
if
cdef_flag
:
return
p_IF_statement
(
s
,
level
,
cdef_flag
,
visibility
,
api
)
if
level
not
in
(
'module'
,
'module_pxd'
,
'function'
,
'c_class'
,
'c_class_pxd'
):
s
.
error
(
'cdef statement not allowed here'
)
return
p_cdef_statement
(
s
,
level
,
visibility
)
elif
s
.
sy
==
'def'
:
if
level
not
in
(
'module'
,
'class'
,
'c_class'
,
'property'
):
s
.
error
(
'def statement not allowed here'
)
return
p_def_statement
(
s
)
elif
s
.
sy
==
'class'
:
if
level
<>
'module'
:
s
.
error
(
"class definition not allowed here"
)
return
p_class_statement
(
s
)
elif
s
.
sy
==
'include'
:
if
level
not
in
(
'module'
,
'module_pxd'
):
s
.
error
(
"include statement not allowed here"
)
return
p_include_statement
(
s
,
level
)
elif
level
==
'c_class'
and
s
.
sy
==
'IDENT'
and
s
.
systring
==
'property'
:
return
p_property_decl
(
s
)
else
:
else
:
if
level
in
(
'c_class'
,
'c_class_pxd'
):
if
s
.
sy
==
'cdef'
:
if
s
.
sy
==
'pass'
:
cdef_flag
=
1
s
.
next
()
if
cdef_flag
:
if
level
not
in
(
'module'
,
'module_pxd'
,
'function'
,
'c_class'
,
'c_class_pxd'
):
s
.
error
(
'cdef statement not allowed here'
)
return
p_cdef_statement
(
s
,
level
,
visibility
,
api
)
else
:
if
api
:
error
(
s
.
pos
,
"'api' not allowed with this statement"
)
if
s
.
sy
==
'def'
:
if
level
not
in
(
'module'
,
'class'
,
'c_class'
,
'property'
):
s
.
error
(
'def statement not allowed here'
)
return
p_def_statement
(
s
)
elif
s
.
sy
==
'class'
:
if
level
<>
'module'
:
s
.
error
(
"class definition not allowed here"
)
return
p_class_statement
(
s
)
elif
s
.
sy
==
'include'
:
#if level not in ('module', 'module_pxd'):
# s.error("include statement not allowed here")
return
p_include_statement
(
s
,
level
)
elif
level
==
'c_class'
and
s
.
sy
==
'IDENT'
and
s
.
systring
==
'property'
:
return
p_property_decl
(
s
)
elif
s
.
sy
==
'pass'
and
level
<>
'property'
:
return
p_pass_statement
(
s
,
with_newline
=
1
)
return
p_pass_statement
(
s
,
with_newline
=
1
)
else
:
else
:
s
.
error
(
"Executable statement not allowed here"
)
if
level
in
(
'c_class'
,
'c_class_pxd'
,
'property'
):
if
s
.
sy
==
'if'
:
s
.
error
(
"Executable statement not allowed here"
)
return
p_if_statement
(
s
)
if
s
.
sy
==
'if'
:
elif
s
.
sy
==
'while'
:
return
p_if_statement
(
s
)
return
p_while_statement
(
s
)
elif
s
.
sy
==
'while'
:
elif
s
.
sy
==
'for'
:
return
p_while_statement
(
s
)
return
p_for_statement
(
s
)
elif
s
.
sy
==
'for'
:
elif
s
.
sy
==
'try'
:
return
p_for_statement
(
s
)
return
p_try_statement
(
s
)
elif
s
.
sy
==
'try'
:
else
:
return
p_try_statement
(
s
)
return
p_simple_statement_list
(
s
)
elif
s
.
sy
==
'with'
:
return
p_with_statement
(
s
)
else
:
return
p_simple_statement_list
(
s
)
def
p_statement_list
(
s
,
level
,
def
p_statement_list
(
s
,
level
,
cdef_flag
=
0
,
visibility
=
'private'
):
cdef_flag
=
0
,
visibility
=
'private'
,
api
=
0
):
# Parse a series of statements separated by newlines.
# Parse a series of statements separated by newlines.
#print "p_statement_list:", s.sy, s.systring ###
pos
=
s
.
position
()
pos
=
s
.
position
()
stats
=
[]
stats
=
[]
while
s
.
sy
not
in
(
'DEDENT'
,
'EOF'
):
while
s
.
sy
not
in
(
'DEDENT'
,
'EOF'
):
stats
.
append
(
p_statement
(
s
,
level
,
stats
.
append
(
p_statement
(
s
,
level
,
cdef_flag
=
cdef_flag
,
visibility
=
visibility
))
cdef_flag
=
cdef_flag
,
visibility
=
visibility
,
api
=
api
))
return
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
if
len
(
stats
)
==
1
:
return
stats
[
0
]
else
:
return
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
def
p_suite
(
s
,
level
=
'other'
,
cdef_flag
=
0
,
def
p_suite
(
s
,
level
=
'other'
,
cdef_flag
=
0
,
visibility
=
'private'
,
with_doc
=
0
):
visibility
=
'private'
,
with_doc
=
0
,
with_pseudo_doc
=
0
,
api
=
0
):
pos
=
s
.
position
()
pos
=
s
.
position
()
s
.
expect
(
':'
)
s
.
expect
(
':'
)
doc
=
None
doc
=
None
...
@@ -1159,14 +1264,17 @@ def p_suite(s, level = 'other', cdef_flag = 0,
...
@@ -1159,14 +1264,17 @@ def p_suite(s, level = 'other', cdef_flag = 0,
if
s
.
sy
==
'NEWLINE'
:
if
s
.
sy
==
'NEWLINE'
:
s
.
next
()
s
.
next
()
s
.
expect_indent
()
s
.
expect_indent
()
if
with_doc
:
if
with_doc
or
with_pseudo_doc
:
doc
=
p_doc_string
(
s
)
doc
=
p_doc_string
(
s
)
body
=
p_statement_list
(
s
,
body
=
p_statement_list
(
s
,
level
=
level
,
level
=
level
,
cdef_flag
=
cdef_flag
,
cdef_flag
=
cdef_flag
,
visibility
=
visibility
)
visibility
=
visibility
,
api
=
api
)
s
.
expect_dedent
()
s
.
expect_dedent
()
else
:
else
:
if
api
:
error
(
s
.
pos
,
"'api' not allowed with this statement"
)
if
level
in
(
'module'
,
'class'
,
'function'
,
'other'
):
if
level
in
(
'module'
,
'class'
,
'function'
,
'other'
):
body
=
p_simple_statement_list
(
s
)
body
=
p_simple_statement_list
(
s
)
else
:
else
:
...
@@ -1185,6 +1293,16 @@ def p_c_base_type(s, self_flag = 0):
...
@@ -1185,6 +1293,16 @@ def p_c_base_type(s, self_flag = 0):
else
:
else
:
return
p_c_simple_base_type
(
s
,
self_flag
)
return
p_c_simple_base_type
(
s
,
self_flag
)
def
p_calling_convention
(
s
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
calling_convention_words
:
result
=
s
.
systring
s
.
next
()
return
result
else
:
return
""
calling_convention_words
=
(
"__stdcall"
,
"__cdecl"
)
def
p_c_complex_base_type
(
s
):
def
p_c_complex_base_type
(
s
):
# s.sy == '('
# s.sy == '('
pos
=
s
.
position
()
pos
=
s
.
position
()
...
@@ -1200,13 +1318,11 @@ def p_c_simple_base_type(s, self_flag):
...
@@ -1200,13 +1318,11 @@ def p_c_simple_base_type(s, self_flag):
is_basic
=
0
is_basic
=
0
signed
=
1
signed
=
1
longness
=
0
longness
=
0
pos
=
s
.
position
()
module_path
=
[]
module_path
=
[]
pos
=
s
.
position
()
if
looking_at_base_type
(
s
):
if
looking_at_base_type
(
s
):
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
is_basic
=
1
is_basic
=
1
#signed = p_signed_or_unsigned(s)
#longness = p_short_or_long(s)
signed
,
longness
=
p_sign_and_longness
(
s
)
signed
,
longness
=
p_sign_and_longness
(
s
)
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
basic_c_type_names
:
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
basic_c_type_names
:
name
=
s
.
systring
name
=
s
.
systring
...
@@ -1246,16 +1362,12 @@ def looking_at_dotted_name(s):
...
@@ -1246,16 +1362,12 @@ def looking_at_dotted_name(s):
else
:
else
:
return
0
return
0
#base_type_start_words = (
basic_c_type_names
=
(
"void"
,
"char"
,
"int"
,
"float"
,
"double"
,
"Py_ssize_t"
)
# "char", "short", "int", "long", "float", "double",
# "void", "signed", "unsigned"
#)
basic_c_type_names
=
(
"void"
,
"char"
,
"int"
,
"float"
,
"double"
)
sign_and_longness_words
=
(
"short"
,
"long"
,
"signed"
,
"unsigned"
)
sign_and_longness_words
=
(
"short"
,
"long"
,
"signed"
,
"unsigned"
)
base_type_start_words
=
basic_c_type_names
+
sign_and_longness_words
base_type_start_words
=
\
basic_c_type_names
+
sign_and_longness_words
def
p_sign_and_longness
(
s
):
def
p_sign_and_longness
(
s
):
signed
=
1
signed
=
1
...
@@ -1263,6 +1375,8 @@ def p_sign_and_longness(s):
...
@@ -1263,6 +1375,8 @@ def p_sign_and_longness(s):
while
s
.
sy
==
'IDENT'
and
s
.
systring
in
sign_and_longness_words
:
while
s
.
sy
==
'IDENT'
and
s
.
systring
in
sign_and_longness_words
:
if
s
.
systring
==
'unsigned'
:
if
s
.
systring
==
'unsigned'
:
signed
=
0
signed
=
0
elif
s
.
systring
==
'signed'
:
signed
=
2
elif
s
.
systring
==
'short'
:
elif
s
.
systring
==
'short'
:
longness
=
-
1
longness
=
-
1
elif
s
.
systring
==
'long'
:
elif
s
.
systring
==
'long'
:
...
@@ -1270,27 +1384,6 @@ def p_sign_and_longness(s):
...
@@ -1270,27 +1384,6 @@ def p_sign_and_longness(s):
s
.
next
()
s
.
next
()
return
signed
,
longness
return
signed
,
longness
#def p_signed_or_unsigned(s):
# signed = 1
# if s.sy == 'IDENT':
# if s.systring == 'signed':
# s.next()
# elif s.systring == 'unsigned':
# signed = 0
# s.next()
# return signed
#
#def p_short_or_long(s):
# longness = 0
# if s.sy == 'IDENT' and s.systring == 'short':
# longness = -1
# s.next()
# else:
# while s.sy == 'IDENT' and s.systring == 'long':
# longness += 1
# s.next()
# return longness
def
p_opt_cname
(
s
):
def
p_opt_cname
(
s
):
literal
=
p_opt_string_literal
(
s
)
literal
=
p_opt_string_literal
(
s
)
if
literal
:
if
literal
:
...
@@ -1299,64 +1392,109 @@ def p_opt_cname(s):
...
@@ -1299,64 +1392,109 @@ def p_opt_cname(s):
cname
=
None
cname
=
None
return
cname
return
cname
def
p_c_declarator
(
s
,
empty
=
0
,
is_type
=
0
,
cmethod_flag
=
0
):
def
p_c_declarator
(
s
,
empty
=
0
,
is_type
=
0
,
cmethod_flag
=
0
,
nonempty
=
0
,
# If empty is true, the declarator must be
calling_convention_allowed
=
0
):
# empty, otherwise we don't care.
# If empty is true, the declarator must be empty. If nonempty is true,
# the declarator must be nonempty. Otherwise we don't care.
# If cmethod_flag is true, then if this declarator declares
# If cmethod_flag is true, then if this declarator declares
# a function, it's a C method of an extension type.
# a function, it's a C method of an extension type.
pos
=
s
.
position
()
pos
=
s
.
position
()
if
s
.
sy
==
'('
:
s
.
next
()
if
s
.
sy
==
')'
or
looking_at_type
(
s
):
base
=
Nodes
.
CNameDeclaratorNode
(
pos
,
name
=
""
,
cname
=
None
)
result
=
p_c_func_declarator
(
s
,
pos
,
base
,
cmethod_flag
)
else
:
result
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
,
nonempty
,
calling_convention_allowed
=
1
)
s
.
expect
(
')'
)
else
:
result
=
p_c_simple_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
,
nonempty
)
if
not
calling_convention_allowed
and
result
.
calling_convention
and
s
.
sy
<>
'('
:
error
(
s
.
position
(),
"%s on something that is not a function"
%
result
.
calling_convention
)
while
s
.
sy
in
(
'['
,
'('
):
pos
=
s
.
position
()
if
s
.
sy
==
'['
:
result
=
p_c_array_declarator
(
s
,
result
)
else
:
# sy == '('
s
.
next
()
result
=
p_c_func_declarator
(
s
,
pos
,
result
,
cmethod_flag
)
cmethod_flag
=
0
return
result
def
p_c_array_declarator
(
s
,
base
):
pos
=
s
.
position
()
s
.
next
()
# '['
if
s
.
sy
<>
']'
:
dim
=
p_expr
(
s
)
else
:
dim
=
None
s
.
expect
(
']'
)
return
Nodes
.
CArrayDeclaratorNode
(
pos
,
base
=
base
,
dimension
=
dim
)
def
p_c_func_declarator
(
s
,
pos
,
base
,
cmethod_flag
):
# Opening paren has already been skipped
args
=
p_c_arg_list
(
s
,
in_pyfunc
=
0
,
cmethod_flag
=
cmethod_flag
,
nonempty_declarators
=
0
)
ellipsis
=
p_optional_ellipsis
(
s
)
s
.
expect
(
')'
)
nogil
=
p_nogil
(
s
)
exc_val
,
exc_check
=
p_exception_value_clause
(
s
)
with_gil
=
p_with_gil
(
s
)
return
Nodes
.
CFuncDeclaratorNode
(
pos
,
base
=
base
,
args
=
args
,
has_varargs
=
ellipsis
,
exception_value
=
exc_val
,
exception_check
=
exc_check
,
nogil
=
nogil
or
with_gil
,
with_gil
=
with_gil
)
def
p_c_simple_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
,
nonempty
):
pos
=
s
.
position
()
calling_convention
=
p_calling_convention
(
s
)
if
s
.
sy
==
'*'
:
if
s
.
sy
==
'*'
:
s
.
next
()
s
.
next
()
base
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
)
base
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
,
nonempty
)
result
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
result
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
base
=
base
)
base
=
base
)
elif
s
.
sy
==
'**'
:
# scanner returns this as a single token
elif
s
.
sy
==
'**'
:
# scanner returns this as a single token
s
.
next
()
s
.
next
()
base
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
)
base
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
,
nonempty
)
result
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
result
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
base
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
base
=
Nodes
.
CPtrDeclaratorNode
(
pos
,
base
=
base
))
base
=
base
))
else
:
else
:
if
s
.
sy
==
'('
:
if
s
.
sy
==
'IDENT'
:
name
=
s
.
systring
if
is_type
:
s
.
add_type_name
(
name
)
if
empty
:
error
(
s
.
position
(),
"Declarator should be empty"
)
s
.
next
()
s
.
next
()
result
=
p_c_declarator
(
s
,
empty
,
is_type
,
cmethod_flag
)
cname
=
p_opt_cname
(
s
)
s
.
expect
(
')'
)
else
:
else
:
if
s
.
sy
==
'IDENT'
:
if
nonempty
:
name
=
s
.
systring
error
(
s
.
position
(),
"Empty declarator"
)
if
is_type
:
name
=
""
s
.
add_type_name
(
name
)
cname
=
None
if
empty
:
result
=
Nodes
.
CNameDeclaratorNode
(
pos
,
error
(
s
.
position
(),
"Declarator should be empty"
)
name
=
name
,
cname
=
cname
)
s
.
next
()
result
.
calling_convention
=
calling_convention
cname
=
p_opt_cname
(
s
)
else
:
name
=
""
cname
=
None
result
=
Nodes
.
CNameDeclaratorNode
(
pos
,
name
=
name
,
cname
=
cname
)
while
s
.
sy
in
(
'['
,
'('
):
if
s
.
sy
==
'['
:
s
.
next
()
if
s
.
sy
<>
']'
:
dim
=
p_expr
(
s
)
else
:
dim
=
None
s
.
expect
(
']'
)
result
=
Nodes
.
CArrayDeclaratorNode
(
pos
,
base
=
result
,
dimension
=
dim
)
else
:
# sy == '('
s
.
next
()
args
=
p_c_arg_list
(
s
,
in_pyfunc
=
0
,
cmethod_flag
=
cmethod_flag
)
ellipsis
=
p_optional_ellipsis
(
s
)
s
.
expect
(
')'
)
exc_val
,
exc_check
=
p_exception_value_clause
(
s
)
result
=
Nodes
.
CFuncDeclaratorNode
(
pos
,
base
=
result
,
args
=
args
,
has_varargs
=
ellipsis
,
exception_value
=
exc_val
,
exception_check
=
exc_check
)
cmethod_flag
=
0
return
result
return
result
def
p_nogil
(
s
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'nogil'
:
s
.
next
()
return
1
else
:
return
0
def
p_with_gil
(
s
):
if
s
.
sy
==
'with'
:
s
.
next
()
s
.
expect_keyword
(
'gil'
)
return
1
else
:
return
0
def
p_exception_value_clause
(
s
):
def
p_exception_value_clause
(
s
):
exc_val
=
None
exc_val
=
None
exc_check
=
0
exc_check
=
0
...
@@ -1369,32 +1507,38 @@ def p_exception_value_clause(s):
...
@@ -1369,32 +1507,38 @@ def p_exception_value_clause(s):
if
s
.
sy
==
'?'
:
if
s
.
sy
==
'?'
:
exc_check
=
1
exc_check
=
1
s
.
next
()
s
.
next
()
exc_val
=
p_simple_expr
(
s
)
#p_exception_value(s)
exc_val
=
p_simple_expr
(
s
)
return
exc_val
,
exc_check
return
exc_val
,
exc_check
#def p_exception_value(s):
# sign = ""
# if s.sy == "-":
# sign = "-"
# s.next()
# if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
# s.systring = sign + s.systring
# return p_atom(s)
# else:
# s.error("Exception value must be an int or float literal or NULL")
c_arg_list_terminators
=
(
'*'
,
'**'
,
'.'
,
')'
)
c_arg_list_terminators
=
(
'*'
,
'**'
,
'.'
,
')'
)
c_arg_list_trailers
=
(
'.'
,
'*'
,
'**'
)
def
p_c_arg_list
(
s
,
in_pyfunc
,
cmethod_flag
=
0
):
#def p_c_arg_list(s, in_pyfunc, cmethod_flag = 0, nonempty_declarators = 0,
# kw_only = 0):
# args = []
# if s.sy not in c_arg_list_terminators:
# args.append(p_c_arg_decl(s, in_pyfunc, cmethod_flag,
# nonempty = nonempty_declarators, kw_only = kw_only))
# while s.sy == ',':
# s.next()
# if s.sy in c_arg_list_terminators:
# break
# args.append(p_c_arg_decl(s, in_pyfunc), nonempty = nonempty_declarators,
# kw_only = kw_only)
# return args
def
p_c_arg_list
(
s
,
in_pyfunc
,
cmethod_flag
=
0
,
nonempty_declarators
=
0
,
kw_only
=
0
):
# Comma-separated list of C argument declarations, possibly empty.
# May have a trailing comma.
args
=
[]
args
=
[]
if
s
.
sy
not
in
c_arg_list_terminators
:
is_self_arg
=
cmethod_flag
args
.
append
(
p_c_arg_decl
(
s
,
in_pyfunc
,
cmethod_flag
))
while
s
.
sy
not
in
c_arg_list_terminators
:
while
s
.
sy
==
','
:
args
.
append
(
p_c_arg_decl
(
s
,
in_pyfunc
,
is_self_arg
,
s
.
next
()
nonempty
=
nonempty_declarators
,
kw_only
=
kw_only
))
if
s
.
sy
in
c_arg_list_trailers
:
if
s
.
sy
<>
','
:
break
break
args
.
append
(
p_c_arg_decl
(
s
,
in_pyfunc
))
s
.
next
()
is_self_arg
=
0
return
args
return
args
def
p_optional_ellipsis
(
s
):
def
p_optional_ellipsis
(
s
):
...
@@ -1404,12 +1548,12 @@ def p_optional_ellipsis(s):
...
@@ -1404,12 +1548,12 @@ def p_optional_ellipsis(s):
else
:
else
:
return
0
return
0
def
p_c_arg_decl
(
s
,
in_pyfunc
,
cmethod_flag
=
0
):
def
p_c_arg_decl
(
s
,
in_pyfunc
,
cmethod_flag
=
0
,
nonempty
=
0
,
kw_only
=
0
):
pos
=
s
.
position
()
pos
=
s
.
position
()
not_none
=
0
not_none
=
0
default
=
None
default
=
None
base_type
=
p_c_base_type
(
s
,
cmethod_flag
)
base_type
=
p_c_base_type
(
s
,
cmethod_flag
)
declarator
=
p_c_declarator
(
s
)
declarator
=
p_c_declarator
(
s
,
nonempty
=
nonempty
)
if
s
.
sy
==
'not'
:
if
s
.
sy
==
'not'
:
s
.
next
()
s
.
next
()
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'None'
:
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'None'
:
...
@@ -1426,32 +1570,54 @@ def p_c_arg_decl(s, in_pyfunc, cmethod_flag = 0):
...
@@ -1426,32 +1570,54 @@ def p_c_arg_decl(s, in_pyfunc, cmethod_flag = 0):
base_type
=
base_type
,
base_type
=
base_type
,
declarator
=
declarator
,
declarator
=
declarator
,
not_none
=
not_none
,
not_none
=
not_none
,
default
=
default
)
default
=
default
,
kw_only
=
kw_only
)
def
p_api
(
s
):
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'api'
:
s
.
next
()
return
1
else
:
return
0
def
p_cdef_statement
(
s
,
level
,
visibility
=
'private'
):
def
p_cdef_statement
(
s
,
level
,
visibility
=
'private'
,
api
=
0
):
pos
=
s
.
position
()
pos
=
s
.
position
()
visibility
=
p_visibility
(
s
,
visibility
)
visibility
=
p_visibility
(
s
,
visibility
)
if
visibility
==
'extern'
and
s
.
sy
in
(
'from'
,
':'
):
api
=
api
or
p_api
(
s
)
if
api
:
if
visibility
not
in
(
'private'
,
'public'
):
error
(
pos
,
"Cannot combine 'api' with '%s'"
%
visibility
)
if
visibility
==
'extern'
and
s
.
sy
==
'from'
:
return
p_cdef_extern_block
(
s
,
level
,
pos
)
return
p_cdef_extern_block
(
s
,
level
,
pos
)
elif
s
.
sy
==
':'
:
p_cdef_block
(
s
,
level
,
visibility
,
api
)
elif
s
.
sy
==
'class'
:
elif
s
.
sy
==
'class'
:
if
level
not
in
(
'module'
,
'module_pxd'
):
if
level
not
in
(
'module'
,
'module_pxd'
):
error
(
pos
,
"Extension type definition not allowed here"
)
error
(
pos
,
"Extension type definition not allowed here"
)
if
api
:
error
(
pos
,
"'api' not allowed with extension class"
)
return
p_c_class_definition
(
s
,
level
,
pos
,
visibility
=
visibility
)
return
p_c_class_definition
(
s
,
level
,
pos
,
visibility
=
visibility
)
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
struct_union_or_enum
:
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
struct_union_or_enum
:
if
level
not
in
(
'module'
,
'module_pxd'
):
if
level
not
in
(
'module'
,
'module_pxd'
):
error
(
pos
,
"C struct/union/enum definition not allowed here"
)
error
(
pos
,
"C struct/union/enum definition not allowed here"
)
if
visibility
==
'public'
:
#if visibility == 'public':
error
(
pos
,
"Public struct/union/enum definition not implemented"
)
# error(pos, "Public struct/union/enum definition not implemented")
if
api
:
error
(
pos
,
"'api' not allowed with '%s'"
%
s
.
systring
)
if
s
.
systring
==
"enum"
:
if
s
.
systring
==
"enum"
:
return
p_c_enum_definition
(
s
,
pos
)
return
p_c_enum_definition
(
s
,
pos
,
visibility
)
else
:
else
:
return
p_c_struct_or_union_definition
(
s
,
pos
)
return
p_c_struct_or_union_definition
(
s
,
pos
,
visibility
)
elif
s
.
sy
==
'pass'
:
elif
s
.
sy
==
'pass'
:
node
=
p_pass_statement
(
s
)
node
=
p_pass_statement
(
s
)
s
.
expect_newline
(
'Expected a newline'
)
s
.
expect_newline
(
'Expected a newline'
)
return
node
return
node
else
:
else
:
return
p_c_func_or_var_declaration
(
s
,
level
,
pos
,
visibility
)
return
p_c_func_or_var_declaration
(
s
,
level
,
pos
,
visibility
,
api
)
def
p_cdef_block
(
s
,
level
,
visibility
,
api
):
body
=
p_suite
(
s
,
level
,
cdef_flag
=
1
,
visibility
=
'extern'
,
api
=
api
)
return
Nodes
.
StatListNode
(
pos
,
stats
=
body
)
def
p_cdef_extern_block
(
s
,
level
,
pos
):
def
p_cdef_extern_block
(
s
,
level
,
pos
):
include_file
=
None
include_file
=
None
...
@@ -1469,7 +1635,7 @@ struct_union_or_enum = (
...
@@ -1469,7 +1635,7 @@ struct_union_or_enum = (
"struct"
,
"union"
,
"enum"
"struct"
,
"union"
,
"enum"
)
)
def
p_c_enum_definition
(
s
,
pos
,
typedef_flag
=
0
):
def
p_c_enum_definition
(
s
,
pos
,
visibility
,
typedef_flag
=
0
):
# s.sy == ident 'enum'
# s.sy == ident 'enum'
s
.
next
()
s
.
next
()
if
s
.
sy
==
'IDENT'
:
if
s
.
sy
==
'IDENT'
:
...
@@ -1492,7 +1658,7 @@ def p_c_enum_definition(s, pos, typedef_flag = 0):
...
@@ -1492,7 +1658,7 @@ def p_c_enum_definition(s, pos, typedef_flag = 0):
p_c_enum_line
(
s
,
items
)
p_c_enum_line
(
s
,
items
)
s
.
expect_dedent
()
s
.
expect_dedent
()
return
Nodes
.
CEnumDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
return
Nodes
.
CEnumDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
items
=
items
,
typedef_flag
=
typedef_flag
)
items
=
items
,
typedef_flag
=
typedef_flag
,
visibility
=
visibility
)
def
p_c_enum_line
(
s
,
items
):
def
p_c_enum_line
(
s
,
items
):
if
s
.
sy
<>
'pass'
:
if
s
.
sy
<>
'pass'
:
...
@@ -1517,7 +1683,7 @@ def p_c_enum_item(s, items):
...
@@ -1517,7 +1683,7 @@ def p_c_enum_item(s, items):
items
.
append
(
Nodes
.
CEnumDefItemNode
(
pos
,
items
.
append
(
Nodes
.
CEnumDefItemNode
(
pos
,
name
=
name
,
cname
=
cname
,
value
=
value
))
name
=
name
,
cname
=
cname
,
value
=
value
))
def
p_c_struct_or_union_definition
(
s
,
pos
,
typedef_flag
=
0
):
def
p_c_struct_or_union_definition
(
s
,
pos
,
visibility
,
typedef_flag
=
0
):
# s.sy == ident 'struct' or 'union'
# s.sy == ident 'struct' or 'union'
kind
=
s
.
systring
kind
=
s
.
systring
s
.
next
()
s
.
next
()
...
@@ -1542,7 +1708,7 @@ def p_c_struct_or_union_definition(s, pos, typedef_flag = 0):
...
@@ -1542,7 +1708,7 @@ def p_c_struct_or_union_definition(s, pos, typedef_flag = 0):
s
.
expect_newline
(
"Syntax error in struct or union definition"
)
s
.
expect_newline
(
"Syntax error in struct or union definition"
)
return
Nodes
.
CStructOrUnionDefNode
(
pos
,
return
Nodes
.
CStructOrUnionDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
kind
=
kind
,
attributes
=
attributes
,
name
=
name
,
cname
=
cname
,
kind
=
kind
,
attributes
=
attributes
,
typedef_flag
=
typedef_flag
)
typedef_flag
=
typedef_flag
,
visibility
=
visibility
)
def
p_visibility
(
s
,
prev_visibility
):
def
p_visibility
(
s
,
prev_visibility
):
pos
=
s
.
position
()
pos
=
s
.
position
()
...
@@ -1555,35 +1721,36 @@ def p_visibility(s, prev_visibility):
...
@@ -1555,35 +1721,36 @@ def p_visibility(s, prev_visibility):
s
.
next
()
s
.
next
()
return
visibility
return
visibility
def
p_c_func_or_var_declaration
(
s
,
level
,
pos
,
visibility
=
'private'
):
def
p_c_func_or_var_declaration
(
s
,
level
,
pos
,
visibility
=
'private'
,
api
=
0
):
cmethod_flag
=
level
in
(
'c_class'
,
'c_class_pxd'
)
cmethod_flag
=
level
in
(
'c_class'
,
'c_class_pxd'
)
base_type
=
p_c_base_type
(
s
)
base_type
=
p_c_base_type
(
s
)
declarator
=
p_c_declarator
(
s
,
cmethod_flag
=
cmethod_flag
)
declarator
=
p_c_declarator
(
s
,
cmethod_flag
=
cmethod_flag
,
nonempty
=
1
)
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
if
level
not
in
(
'module'
,
'c_class'
):
if
level
not
in
(
'module'
,
'c_class'
):
s
.
error
(
"C function definition not allowed here"
)
s
.
error
(
"C function definition not allowed here"
)
suite
=
p_suite
(
s
,
'function'
)
suite
=
p_suite
(
s
,
'function'
,
with_pseudo_doc
=
1
)
result
=
Nodes
.
CFuncDefNode
(
pos
,
result
=
Nodes
.
CFuncDefNode
(
pos
,
visibility
=
visibility
,
visibility
=
visibility
,
base_type
=
base_type
,
base_type
=
base_type
,
declarator
=
declarator
,
declarator
=
declarator
,
body
=
suite
)
body
=
suite
,
api
=
api
)
else
:
else
:
if
level
==
'module_pxd'
and
visibility
<>
'extern'
:
if
api
:
error
(
pos
,
error
(
s
.
pos
,
"'api' not allowed with variable declaration"
)
"Only 'extern' C function or variable declaration allowed in .pxd file"
)
declarators
=
[
declarator
]
declarators
=
[
declarator
]
while
s
.
sy
==
','
:
while
s
.
sy
==
','
:
s
.
next
()
s
.
next
()
if
s
.
sy
==
'NEWLINE'
:
if
s
.
sy
==
'NEWLINE'
:
break
break
declarator
=
p_c_declarator
(
s
,
cmethod_flag
=
cmethod_flag
)
declarator
=
p_c_declarator
(
s
,
cmethod_flag
=
cmethod_flag
,
nonempty
=
1
)
declarators
.
append
(
declarator
)
declarators
.
append
(
declarator
)
s
.
expect_newline
(
"Syntax error in C variable declaration"
)
s
.
expect_newline
(
"Syntax error in C variable declaration"
)
result
=
Nodes
.
CVarDefNode
(
pos
,
result
=
Nodes
.
CVarDefNode
(
pos
,
visibility
=
visibility
,
visibility
=
visibility
,
base_type
=
base_type
,
base_type
=
base_type
,
declarators
=
declarators
)
declarators
=
declarators
,
in_pxd
=
level
==
'module_pxd'
)
return
result
return
result
def
p_ctypedef_statement
(
s
,
level
,
visibility
=
'private'
):
def
p_ctypedef_statement
(
s
,
level
,
visibility
=
'private'
):
...
@@ -1597,38 +1764,42 @@ def p_ctypedef_statement(s, level, visibility = 'private'):
...
@@ -1597,38 +1764,42 @@ def p_ctypedef_statement(s, level, visibility = 'private'):
typedef_flag
=
1
)
typedef_flag
=
1
)
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'struct'
,
'union'
,
'enum'
):
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'struct'
,
'union'
,
'enum'
):
if
s
.
systring
==
'enum'
:
if
s
.
systring
==
'enum'
:
return
p_c_enum_definition
(
s
,
pos
,
typedef_flag
=
1
)
return
p_c_enum_definition
(
s
,
pos
,
visibility
,
typedef_flag
=
1
)
else
:
else
:
return
p_c_struct_or_union_definition
(
s
,
pos
,
typedef_flag
=
1
)
return
p_c_struct_or_union_definition
(
s
,
pos
,
visibility
,
typedef_flag
=
1
)
else
:
else
:
base_type
=
p_c_base_type
(
s
)
base_type
=
p_c_base_type
(
s
)
declarator
=
p_c_declarator
(
s
,
is_type
=
1
)
declarator
=
p_c_declarator
(
s
,
is_type
=
1
,
nonempty
=
1
)
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
return
Nodes
.
CTypeDefNode
(
pos
,
return
Nodes
.
CTypeDefNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
)
base_type
=
base_type
,
declarator
=
declarator
,
visibility
=
visibility
)
def
p_def_statement
(
s
):
def
p_def_statement
(
s
):
# s.sy == 'def'
# s.sy == 'def'
pos
=
s
.
position
()
pos
=
s
.
position
()
s
.
next
()
s
.
next
()
name
=
p_ident
(
s
)
name
=
p_ident
(
s
)
args
=
[]
#
args = []
s
.
expect
(
'('
);
s
.
expect
(
'('
);
args
=
p_c_arg_list
(
s
,
in_pyfunc
=
1
)
args
=
p_c_arg_list
(
s
,
in_pyfunc
=
1
,
nonempty_declarators
=
1
)
star_arg
=
None
star_arg
=
None
starstar_arg
=
None
starstar_arg
=
None
if
s
.
sy
==
'*'
:
if
s
.
sy
==
'*'
:
s
.
next
()
s
.
next
()
star_arg
=
p_py_arg_decl
(
s
)
if
s
.
sy
==
'IDENT'
:
star_arg
=
p_py_arg_decl
(
s
)
if
s
.
sy
==
','
:
if
s
.
sy
==
','
:
s
.
next
()
s
.
next
()
if
s
.
sy
==
'**'
:
args
.
extend
(
p_c_arg_list
(
s
,
in_pyfunc
=
1
,
s
.
next
()
nonempty_declarators
=
1
,
kw_only
=
1
))
starstar_arg
=
p_py_arg_decl
(
s
)
elif
s
.
sy
<>
')'
:
elif
s
.
sy
==
'**'
:
s
.
error
(
"Syntax error in Python function argument list"
)
if
s
.
sy
==
'**'
:
s
.
next
()
s
.
next
()
starstar_arg
=
p_py_arg_decl
(
s
)
starstar_arg
=
p_py_arg_decl
(
s
)
s
.
expect
(
')'
)
s
.
expect
(
')'
)
if
p_nogil
(
s
):
error
(
s
.
pos
,
"Python function cannot be declared nogil"
)
doc
,
body
=
p_suite
(
s
,
'function'
,
with_doc
=
1
)
doc
,
body
=
p_suite
(
s
,
'function'
,
with_doc
=
1
)
return
Nodes
.
DefNode
(
pos
,
name
=
name
,
args
=
args
,
return
Nodes
.
DefNode
(
pos
,
name
=
name
,
args
=
args
,
star_arg
=
star_arg
,
starstar_arg
=
starstar_arg
,
star_arg
=
star_arg
,
starstar_arg
=
starstar_arg
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
3588f4a6
...
@@ -5,7 +5,21 @@
...
@@ -5,7 +5,21 @@
import
string
import
string
import
Naming
import
Naming
class
PyrexType
:
class
BaseType
:
#
# Base class for all Pyrex types including pseudo-types.
def
cast_code
(
self
,
expr_code
):
return
"((%s)%s)"
%
(
self
.
declaration_code
(
""
),
expr_code
)
def
base_declaration_code
(
self
,
base_code
,
entity_code
):
if
entity_code
:
return
"%s %s"
%
(
base_code
,
entity_code
)
else
:
return
base_code
class
PyrexType
(
BaseType
):
#
#
# Base class for all Pyrex types.
# Base class for all Pyrex types.
#
#
...
@@ -21,6 +35,7 @@ class PyrexType:
...
@@ -21,6 +35,7 @@ class PyrexType:
# is_cfunction boolean Is a C function type
# is_cfunction boolean Is a C function type
# is_struct_or_union boolean Is a C struct or union type
# is_struct_or_union boolean Is a C struct or union type
# is_enum boolean Is a C enum type
# is_enum boolean Is a C enum type
# is_typedef boolean Is a typedef type
# is_string boolean Is a C char * type
# is_string boolean Is a C char * type
# is_returncode boolean Is used only to signal exceptions
# is_returncode boolean Is used only to signal exceptions
# is_error boolean Is the dummy error type
# is_error boolean Is the dummy error type
...
@@ -66,6 +81,7 @@ class PyrexType:
...
@@ -66,6 +81,7 @@ class PyrexType:
is_cfunction
=
0
is_cfunction
=
0
is_struct_or_union
=
0
is_struct_or_union
=
0
is_enum
=
0
is_enum
=
0
is_typedef
=
0
is_string
=
0
is_string
=
0
is_returncode
=
0
is_returncode
=
0
is_error
=
0
is_error
=
0
...
@@ -111,17 +127,20 @@ class PyrexType:
...
@@ -111,17 +127,20 @@ class PyrexType:
# A type is incomplete if it is an unsized array,
# A type is incomplete if it is an unsized array,
# a struct whose attributes are not defined, etc.
# a struct whose attributes are not defined, etc.
return
1
return
1
def
cast_code
(
self
,
expr_code
):
return
"((%s)%s)"
%
(
self
.
declaration_code
(
""
),
expr_code
)
class
CTypedefType
:
class
CTypedefType
(
BaseType
)
:
#
#
#
T
ype defined with a ctypedef statement in a
#
Pseudo-t
ype defined with a ctypedef statement in a
# 'cdef extern from' block. Delegates most attribute
# 'cdef extern from' block. Delegates most attribute
# lookups to the base type.
# lookups to the base type. ANYTHING NOT DEFINED
# HERE IS DELEGATED!
#
#
# qualified_name string
# typedef_cname string
# typedef_base_type PyrexType
is_typedef
=
1
def
__init__
(
self
,
cname
,
base_type
):
def
__init__
(
self
,
cname
,
base_type
):
self
.
typedef_cname
=
cname
self
.
typedef_cname
=
cname
...
@@ -132,10 +151,23 @@ class CTypedefType:
...
@@ -132,10 +151,23 @@ class CTypedefType:
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
return
"%s %s"
%
(
self
.
typedef_cname
,
entity_code
)
name
=
self
.
declaration_name
(
for_display
,
pyrex
)
return
self
.
base_declaration_code
(
name
,
entity_code
)
def
declaration_name
(
self
,
for_display
=
0
,
pyrex
=
0
):
if
pyrex
or
for_display
:
return
self
.
qualified_name
else
:
return
self
.
typedef_cname
def
as_argument_type
(
self
):
return
self
def
__repr__
(
self
):
return
"<CTypedefType %s>"
%
self
.
typedef_cname
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
typedef_cname
return
self
.
declaration_name
(
for_display
=
1
)
def
__getattr__
(
self
,
name
):
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
typedef_base_type
,
name
)
return
getattr
(
self
.
typedef_base_type
,
name
)
...
@@ -155,15 +187,15 @@ class PyObjectType(PyrexType):
...
@@ -155,15 +187,15 @@ class PyObjectType(PyrexType):
return
"Python object"
return
"Python object"
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
PyObjectType
"
return
"
<PyObjectType>
"
def
assignable_from
(
self
,
src_type
):
def
assignable_from
(
self
,
src_type
):
return
1
# Conversion will be attempted
return
1
# Conversion will be attempted
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
pyrex
:
if
pyrex
or
for_display
:
return
"object %s"
%
entity_code
return
self
.
base_declaration_code
(
"object"
,
entity_code
)
else
:
else
:
return
"%s *%s"
%
(
public_decl
(
"PyObject"
,
dll_linkage
),
entity_code
)
return
"%s *%s"
%
(
public_decl
(
"PyObject"
,
dll_linkage
),
entity_code
)
...
@@ -226,8 +258,8 @@ class PyExtensionType(PyObjectType):
...
@@ -226,8 +258,8 @@ class PyExtensionType(PyObjectType):
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
pyrex
:
if
pyrex
or
for_display
:
return
"%s %s"
%
(
self
.
name
,
entity_code
)
return
self
.
base_declaration_code
(
self
.
name
,
entity_code
)
else
:
else
:
if
self
.
typedef_flag
:
if
self
.
typedef_flag
:
base_format
=
"%s"
base_format
=
"%s"
...
@@ -243,8 +275,8 @@ class PyExtensionType(PyObjectType):
...
@@ -243,8 +275,8 @@ class PyExtensionType(PyObjectType):
return
self
.
name
return
self
.
name
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
PyExtensionType(%s%s)
"
%
(
self
.
scope
.
class_name
,
return
"
<PyExtensionType %s%s>
"
%
(
self
.
scope
.
class_name
,
(
""
,
"
.typedef_flag=1
"
)[
self
.
typedef_flag
])
(
""
,
"
typedef
"
)[
self
.
typedef_flag
])
class
CType
(
PyrexType
):
class
CType
(
PyrexType
):
...
@@ -259,13 +291,6 @@ class CType(PyrexType):
...
@@ -259,13 +291,6 @@ class CType(PyrexType):
from_py_function
=
None
from_py_function
=
None
#class CSimpleType(CType):
# #
# # Base class for all unstructured C types.
# #
# pass
class
CVoidType
(
CType
):
class
CVoidType
(
CType
):
is_void
=
1
is_void
=
1
...
@@ -275,7 +300,7 @@ class CVoidType(CType):
...
@@ -275,7 +300,7 @@ class CVoidType(CType):
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
base
=
public_decl
(
"void"
,
dll_linkage
)
base
=
public_decl
(
"void"
,
dll_linkage
)
return
"%s %s"
%
(
base
,
entity_code
)
return
self
.
base_declaration_code
(
base
,
entity_code
)
def
is_complete
(
self
):
def
is_complete
(
self
):
return
0
return
0
...
@@ -286,17 +311,20 @@ class CNumericType(CType):
...
@@ -286,17 +311,20 @@ class CNumericType(CType):
# Base class for all C numeric types.
# Base class for all C numeric types.
#
#
# rank integer Relative size
# rank integer Relative size
# signed
boolean
# signed
integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
#
#
is_numeric
=
1
is_numeric
=
1
default_value
=
"0"
default_value
=
"0"
parsetuple_formats
=
(
# rank -> format
parsetuple_formats
=
(
# rank -> format
"?HIkK???"
,
# unsigned
"BHIkK????"
,
# unsigned
"chilLfd?"
,
# signed
"bhilL?fd?"
,
# assumed signed
"bhilL?fd?"
,
# explicitly signed
)
)
sign_words
=
(
"unsigned "
,
""
,
"signed "
)
def
__init__
(
self
,
rank
,
signed
=
1
,
pymemberdef_typecode
=
None
):
def
__init__
(
self
,
rank
,
signed
=
1
,
pymemberdef_typecode
=
None
):
self
.
rank
=
rank
self
.
rank
=
rank
self
.
signed
=
signed
self
.
signed
=
signed
...
@@ -306,21 +334,18 @@ class CNumericType(CType):
...
@@ -306,21 +334,18 @@ class CNumericType(CType):
self
.
parsetuple_format
=
ptf
self
.
parsetuple_format
=
ptf
self
.
pymemberdef_typecode
=
pymemberdef_typecode
self
.
pymemberdef_typecode
=
pymemberdef_typecode
def
sign_and_name
(
self
):
s
=
self
.
sign_words
[
self
.
signed
]
n
=
rank_to_type_name
[
self
.
rank
]
return
s
+
n
def
__repr__
(
self
):
def
__repr__
(
self
):
if
self
.
signed
:
return
"<CNumericType %s>"
%
self
.
sign_and_name
()
u
=
""
else
:
u
=
"unsigned "
return
"<CNumericType %s%s>"
%
(
u
,
rank_to_type_name
[
self
.
rank
])
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
self
.
signed
:
base
=
public_decl
(
self
.
sign_and_name
(),
dll_linkage
)
u
=
""
return
self
.
base_declaration_code
(
base
,
entity_code
)
else
:
u
=
"unsigned "
base
=
public_decl
(
u
+
rank_to_type_name
[
self
.
rank
],
dll_linkage
)
return
"%s %s"
%
(
base
,
entity_code
)
class
CIntType
(
CNumericType
):
class
CIntType
(
CNumericType
):
...
@@ -338,6 +363,11 @@ class CIntType(CNumericType):
...
@@ -338,6 +363,11 @@ class CIntType(CNumericType):
return
src_type
.
is_int
or
src_type
.
is_enum
or
src_type
is
error_type
return
src_type
.
is_int
or
src_type
.
is_enum
or
src_type
is
error_type
class
CAnonEnumType
(
CIntType
):
is_enum
=
1
class
CUIntType
(
CIntType
):
class
CUIntType
(
CIntType
):
to_py_function
=
"PyLong_FromUnsignedLong"
to_py_function
=
"PyLong_FromUnsignedLong"
...
@@ -362,6 +392,12 @@ class CULongLongType(CIntType):
...
@@ -362,6 +392,12 @@ class CULongLongType(CIntType):
from_py_function
=
"PyInt_AsUnsignedLongLongMask"
from_py_function
=
"PyInt_AsUnsignedLongLongMask"
class
CPySSizeTType
(
CIntType
):
to_py_function
=
"PyInt_FromSsize_t"
from_py_function
=
"PyInt_AsSsize_t"
class
CFloatType
(
CNumericType
):
class
CFloatType
(
CNumericType
):
is_float
=
1
is_float
=
1
...
@@ -388,7 +424,7 @@ class CArrayType(CType):
...
@@ -388,7 +424,7 @@ class CArrayType(CType):
self
.
is_string
=
1
self
.
is_string
=
1
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
CArrayType(%s,%s)
"
%
(
self
.
size
,
repr
(
self
.
base_type
))
return
"
<CArrayType %s %s>
"
%
(
self
.
size
,
repr
(
self
.
base_type
))
def
same_as_resolved_type
(
self
,
other_type
):
def
same_as_resolved_type
(
self
,
other_type
):
return
((
other_type
.
is_array
and
return
((
other_type
.
is_array
and
...
@@ -408,8 +444,10 @@ class CArrayType(CType):
...
@@ -408,8 +444,10 @@ class CArrayType(CType):
dimension_code
=
self
.
size
dimension_code
=
self
.
size
else
:
else
:
dimension_code
=
""
dimension_code
=
""
if
entity_code
.
startswith
(
"*"
):
entity_code
=
"(%s)"
%
entity_code
return
self
.
base_type
.
declaration_code
(
return
self
.
base_type
.
declaration_code
(
"
(%s[%s])
"
%
(
entity_code
,
dimension_code
),
"
%s[%s]
"
%
(
entity_code
,
dimension_code
),
for_display
,
dll_linkage
,
pyrex
)
for_display
,
dll_linkage
,
pyrex
)
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
...
@@ -423,13 +461,13 @@ class CPtrType(CType):
...
@@ -423,13 +461,13 @@ class CPtrType(CType):
# base_type CType Referenced type
# base_type CType Referenced type
is_ptr
=
1
is_ptr
=
1
default_value
=
0
default_value
=
"0"
def
__init__
(
self
,
base_type
):
def
__init__
(
self
,
base_type
):
self
.
base_type
=
base_type
self
.
base_type
=
base_type
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
CPtrType(%s)
"
%
repr
(
self
.
base_type
)
return
"
<CPtrType %s>
"
%
repr
(
self
.
base_type
)
def
same_as_resolved_type
(
self
,
other_type
):
def
same_as_resolved_type
(
self
,
other_type
):
return
((
other_type
.
is_ptr
and
return
((
other_type
.
is_ptr
and
...
@@ -440,24 +478,20 @@ class CPtrType(CType):
...
@@ -440,24 +478,20 @@ class CPtrType(CType):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
#print "CPtrType.declaration_code: pointer to", self.base_type ###
#print "CPtrType.declaration_code: pointer to", self.base_type ###
return
self
.
base_type
.
declaration_code
(
return
self
.
base_type
.
declaration_code
(
"
(*%s)
"
%
entity_code
,
"
*%s
"
%
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
for_display
,
dll_linkage
,
pyrex
)
def
assignable_from_resolved_type
(
self
,
other_type
):
def
assignable_from_resolved_type
(
self
,
other_type
):
if
other_type
is
error_type
:
if
other_type
is
error_type
:
return
1
return
1
elif
self
.
base_type
.
is_cfunction
and
other_type
.
is_cfunction
:
return
self
.
base_type
.
same_as
(
other_type
)
elif
other_type
.
is_array
:
return
self
.
base_type
.
same_as
(
other_type
.
base_type
)
elif
not
other_type
.
is_ptr
:
return
0
elif
self
.
base_type
.
is_void
:
return
1
elif
other_type
.
is_null_ptr
:
elif
other_type
.
is_null_ptr
:
return
1
return
1
elif
self
.
base_type
.
is_cfunction
and
other_type
.
is_cfunction
:
return
self
.
base_type
.
same_as
(
other_type
)
elif
other_type
.
is_array
or
other_type
.
is_ptr
:
return
self
.
base_type
.
is_void
or
self
.
base_type
.
same_as
(
other_type
.
base_type
)
else
:
else
:
return
self
.
base_type
.
same_as
(
other_type
.
base_type
)
return
0
class
CNullPtrType
(
CPtrType
):
class
CNullPtrType
(
CPtrType
):
...
@@ -470,31 +504,48 @@ class CFuncType(CType):
...
@@ -470,31 +504,48 @@ class CFuncType(CType):
# args [CFuncTypeArg]
# args [CFuncTypeArg]
# has_varargs boolean
# has_varargs boolean
# exception_value string
# exception_value string
# exception_check boolean True if PyErr_Occurred check needed
# exception_check boolean True if PyErr_Occurred check needed
# calling_convention string Function calling convention
# nogil boolean Can be called without gil
# with_gil boolean Acquire gil around function body
is_cfunction
=
1
is_cfunction
=
1
def
__init__
(
self
,
return_type
,
args
,
has_varargs
,
def
__init__
(
self
,
return_type
,
args
,
has_varargs
=
0
,
exception_value
=
None
,
exception_check
=
0
):
exception_value
=
None
,
exception_check
=
0
,
calling_convention
=
""
,
nogil
=
0
,
with_gil
=
0
):
self
.
return_type
=
return_type
self
.
return_type
=
return_type
self
.
args
=
args
self
.
args
=
args
self
.
has_varargs
=
has_varargs
self
.
has_varargs
=
has_varargs
self
.
exception_value
=
exception_value
self
.
exception_value
=
exception_value
self
.
exception_check
=
exception_check
self
.
exception_check
=
exception_check
self
.
calling_convention
=
calling_convention
self
.
nogil
=
nogil
self
.
with_gil
=
with_gil
def
__repr__
(
self
):
def
__repr__
(
self
):
arg_reprs
=
map
(
repr
,
self
.
args
)
arg_reprs
=
map
(
repr
,
self
.
args
)
if
self
.
has_varargs
:
if
self
.
has_varargs
:
arg_reprs
.
append
(
"..."
)
arg_reprs
.
append
(
"..."
)
return
"
CFuncType(%s,[%s])
"
%
(
return
"
<CFuncType %s %s[%s]>
"
%
(
repr
(
self
.
return_type
),
repr
(
self
.
return_type
),
self
.
calling_convention_prefix
(),
string
.
join
(
arg_reprs
,
","
))
string
.
join
(
arg_reprs
,
","
))
def
calling_convention_prefix
(
self
):
cc
=
self
.
calling_convention
if
cc
:
return
cc
+
" "
else
:
return
""
def
same_c_signature_as
(
self
,
other_type
,
as_cmethod
=
0
):
def
same_c_signature_as
(
self
,
other_type
,
as_cmethod
=
0
):
return
self
.
same_c_signature_as_resolved_type
(
return
self
.
same_c_signature_as_resolved_type
(
other_type
.
resolve
(),
as_cmethod
)
other_type
.
resolve
(),
as_cmethod
)
def
same_c_signature_as_resolved_type
(
self
,
other_type
,
as_cmethod
):
def
same_c_signature_as_resolved_type
(
self
,
other_type
,
as_cmethod
):
#print "CFuncType.same_c_signature_as_resolved_type:", \
# self, other_type, "as_cmethod =", as_cmethod ###
if
other_type
is
error_type
:
if
other_type
is
error_type
:
return
1
return
1
if
not
other_type
.
is_cfunction
:
if
not
other_type
.
is_cfunction
:
...
@@ -513,8 +564,15 @@ class CFuncType(CType):
...
@@ -513,8 +564,15 @@ class CFuncType(CType):
return
0
return
0
if
not
self
.
return_type
.
same_as
(
other_type
.
return_type
):
if
not
self
.
return_type
.
same_as
(
other_type
.
return_type
):
return
0
return
0
if
not
self
.
same_calling_convention_as
(
other_type
):
return
0
return
1
return
1
def
same_calling_convention_as
(
self
,
other
):
sc1
=
self
.
calling_convention
==
'__stdcall'
sc2
=
other
.
calling_convention
==
'__stdcall'
return
sc1
==
sc2
def
same_exception_signature_as
(
self
,
other_type
):
def
same_exception_signature_as
(
self
,
other_type
):
return
self
.
same_exception_signature_as_resolved_type
(
return
self
.
same_exception_signature_as_resolved_type
(
other_type
.
resolve
())
other_type
.
resolve
())
...
@@ -539,17 +597,25 @@ class CFuncType(CType):
...
@@ -539,17 +597,25 @@ class CFuncType(CType):
if
not
arg_decl_code
and
not
pyrex
:
if
not
arg_decl_code
and
not
pyrex
:
arg_decl_code
=
"void"
arg_decl_code
=
"void"
exc_clause
=
""
exc_clause
=
""
if
pyrex
or
for_display
:
if
(
pyrex
or
for_display
)
and
not
self
.
return_type
.
is_pyobject
:
if
self
.
exception_value
and
self
.
exception_check
:
if
self
.
exception_value
and
self
.
exception_check
:
exc_clause
=
" except? %s"
%
self
.
exception_value
exc_clause
=
" except? %s"
%
self
.
exception_value
elif
self
.
exception_value
:
elif
self
.
exception_value
:
exc_clause
=
" except %s"
%
self
.
exception_value
exc_clause
=
" except %s"
%
self
.
exception_value
elif
self
.
exception_check
:
elif
self
.
exception_check
:
exc_clause
=
" except *"
exc_clause
=
" except *"
cc
=
self
.
calling_convention_prefix
()
if
(
not
entity_code
and
cc
)
or
entity_code
.
startswith
(
"*"
):
entity_code
=
"(%s%s)"
%
(
cc
,
entity_code
)
cc
=
""
return
self
.
return_type
.
declaration_code
(
return
self
.
return_type
.
declaration_code
(
"
(%s(%s)%s)"
%
(
entity_code
,
arg_decl_code
,
exc_clause
),
"
%s%s(%s)%s"
%
(
cc
,
entity_code
,
arg_decl_code
,
exc_clause
),
for_display
,
dll_linkage
,
pyrex
)
for_display
,
dll_linkage
,
pyrex
)
def
signature_string
(
self
):
s
=
self
.
declaration_code
(
""
)
return
s
class
CFuncTypeArg
:
class
CFuncTypeArg
:
# name string
# name string
...
@@ -588,13 +654,13 @@ class CStructOrUnionType(CType):
...
@@ -588,13 +654,13 @@ class CStructOrUnionType(CType):
self
.
typedef_flag
=
typedef_flag
self
.
typedef_flag
=
typedef_flag
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
CStructOrUnionType(%s,%s%s)
"
%
(
self
.
name
,
self
.
cname
,
return
"
<CStructOrUnionType %s %s%s>
"
%
(
self
.
name
,
self
.
cname
,
(
""
,
"
,typedef_flag=1
"
)[
self
.
typedef_flag
])
(
""
,
"
typedef
"
)[
self
.
typedef_flag
])
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
pyrex
:
if
pyrex
:
return
"%s %s"
%
(
self
.
name
,
entity_code
)
return
self
.
base_declaration_code
(
self
.
name
,
entity_code
)
else
:
else
:
if
for_display
:
if
for_display
:
base
=
self
.
name
base
=
self
.
name
...
@@ -602,7 +668,7 @@ class CStructOrUnionType(CType):
...
@@ -602,7 +668,7 @@ class CStructOrUnionType(CType):
base
=
self
.
cname
base
=
self
.
cname
else
:
else
:
base
=
"%s %s"
%
(
self
.
kind
,
self
.
cname
)
base
=
"%s %s"
%
(
self
.
kind
,
self
.
cname
)
return
"%s %s"
%
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
return
self
.
base_declaration_code
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
def
is_complete
(
self
):
def
is_complete
(
self
):
return
self
.
scope
is
not
None
return
self
.
scope
is
not
None
...
@@ -617,8 +683,8 @@ class CEnumType(CType):
...
@@ -617,8 +683,8 @@ class CEnumType(CType):
# typedef_flag boolean
# typedef_flag boolean
is_enum
=
1
is_enum
=
1
#
signed = 1
signed
=
1
#rank = 2
rank
=
-
1
# Ranks below any integer type
to_py_function
=
"PyInt_FromLong"
to_py_function
=
"PyInt_FromLong"
from_py_function
=
"PyInt_AsLong"
from_py_function
=
"PyInt_AsLong"
...
@@ -628,20 +694,23 @@ class CEnumType(CType):
...
@@ -628,20 +694,23 @@ class CEnumType(CType):
self
.
values
=
[]
self
.
values
=
[]
self
.
typedef_flag
=
typedef_flag
self
.
typedef_flag
=
typedef_flag
def
__str__
(
self
):
return
self
.
name
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"
CEnumType(%s,%s%s)
"
%
(
self
.
name
,
self
.
cname
,
return
"
<CEnumType %s %s%s>
"
%
(
self
.
name
,
self
.
cname
,
(
""
,
"
,typedef_flag=1
"
)[
self
.
typedef_flag
])
(
""
,
"
typedef
"
)[
self
.
typedef_flag
])
def
declaration_code
(
self
,
entity_code
,
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
pyrex
:
if
pyrex
:
return
"%s %s"
%
(
self
.
cname
,
entity_code
)
return
self
.
base_declaration_code
(
self
.
cname
,
entity_code
)
else
:
else
:
if
self
.
typedef_flag
:
if
self
.
typedef_flag
:
base
=
self
.
cname
base
=
self
.
cname
else
:
else
:
base
=
"enum %s"
%
self
.
cname
base
=
"enum %s"
%
self
.
cname
return
"%s %s"
%
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
return
self
.
base_declaration_code
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
class
CStringType
:
class
CStringType
:
...
@@ -699,21 +768,28 @@ c_void_type = CVoidType()
...
@@ -699,21 +768,28 @@ c_void_type = CVoidType()
c_void_ptr_type
=
CPtrType
(
c_void_type
)
c_void_ptr_type
=
CPtrType
(
c_void_type
)
c_void_ptr_ptr_type
=
CPtrType
(
c_void_ptr_type
)
c_void_ptr_ptr_type
=
CPtrType
(
c_void_ptr_type
)
c_char_type
=
CIntType
(
0
,
1
,
"T_CHAR"
)
c_uchar_type
=
CIntType
(
0
,
0
,
"T_UBYTE"
)
c_short_type
=
CIntType
(
1
,
1
,
"T_SHORT"
)
c_ushort_type
=
CIntType
(
1
,
0
,
"T_USHORT"
)
c_int_type
=
CIntType
(
2
,
1
,
"T_INT"
)
c_uint_type
=
CUIntType
(
2
,
0
,
"T_UINT"
)
c_long_type
=
CIntType
(
3
,
1
,
"T_LONG"
)
c_ulong_type
=
CULongType
(
3
,
0
,
"T_ULONG"
)
c_longlong_type
=
CLongLongType
(
4
,
1
,
"T_LONGLONG"
)
c_ulonglong_type
=
CULongLongType
(
4
,
0
,
"T_ULONGLONG"
)
c_uchar_type
=
CIntType
(
0
,
0
,
"T_UBYTE"
)
c_char_type
=
CIntType
(
0
,
1
,
"T_CHAR"
)
c_ushort_type
=
CIntType
(
1
,
0
,
"T_USHORT"
)
c_short_type
=
CIntType
(
1
,
1
,
"T_SHORT"
)
c_uint_type
=
CUIntType
(
2
,
0
,
"T_UINT"
)
c_int_type
=
CIntType
(
2
,
1
,
"T_INT"
)
c_ulong_type
=
CULongType
(
3
,
0
,
"T_ULONG"
)
c_long_type
=
CIntType
(
3
,
1
,
"T_LONG"
)
c_ulonglong_type
=
CULongLongType
(
4
,
0
,
"T_ULONGLONG"
)
c_longlong_type
=
CLongLongType
(
4
,
1
,
"T_LONGLONG"
)
c_py_ssize_t_type
=
CPySSizeTType
(
5
,
1
)
c_float_type
=
CFloatType
(
5
,
"T_FLOAT"
)
c_double_type
=
CFloatType
(
6
,
"T_DOUBLE"
)
c_schar_type
=
CIntType
(
0
,
2
,
"T_CHAR"
)
c_longdouble_type
=
CFloatType
(
7
)
c_sshort_type
=
CIntType
(
1
,
2
,
"T_SHORT"
)
c_sint_type
=
CIntType
(
2
,
2
,
"T_INT"
)
c_slong_type
=
CIntType
(
3
,
2
,
"T_LONG"
)
c_slonglong_type
=
CLongLongType
(
4
,
2
,
"T_LONGLONG"
)
c_float_type
=
CFloatType
(
6
,
"T_FLOAT"
)
c_double_type
=
CFloatType
(
7
,
"T_DOUBLE"
)
c_longdouble_type
=
CFloatType
(
8
)
c_null_ptr_type
=
CNullPtrType
(
c_void_type
)
c_null_ptr_type
=
CNullPtrType
(
c_void_type
)
c_char_array_type
=
CCharArrayType
(
None
)
c_char_array_type
=
CCharArrayType
(
None
)
...
@@ -723,9 +799,11 @@ c_int_ptr_type = CPtrType(c_int_type)
...
@@ -723,9 +799,11 @@ c_int_ptr_type = CPtrType(c_int_type)
c_returncode_type
=
CIntType
(
2
,
1
,
"T_INT"
,
is_returncode
=
1
)
c_returncode_type
=
CIntType
(
2
,
1
,
"T_INT"
,
is_returncode
=
1
)
c_anon_enum_type
=
CAnonEnumType
(
-
1
,
1
)
error_type
=
ErrorType
()
error_type
=
ErrorType
()
lowest_float_rank
=
5
lowest_float_rank
=
6
rank_to_type_name
=
(
rank_to_type_name
=
(
"char"
,
# 0
"char"
,
# 0
...
@@ -733,9 +811,10 @@ rank_to_type_name = (
...
@@ -733,9 +811,10 @@ rank_to_type_name = (
"int"
,
# 2
"int"
,
# 2
"long"
,
# 3
"long"
,
# 3
"PY_LONG_LONG"
,
# 4
"PY_LONG_LONG"
,
# 4
"float"
,
# 5
"Py_ssize_t"
,
# 5
"double"
,
# 6
"float"
,
# 6
"long double"
,
# 7
"double"
,
# 7
"long double"
,
# 8
)
)
sign_and_rank_to_type
=
{
sign_and_rank_to_type
=
{
...
@@ -750,9 +829,16 @@ sign_and_rank_to_type = {
...
@@ -750,9 +829,16 @@ sign_and_rank_to_type = {
(
1
,
2
):
c_int_type
,
(
1
,
2
):
c_int_type
,
(
1
,
3
):
c_long_type
,
(
1
,
3
):
c_long_type
,
(
1
,
4
):
c_longlong_type
,
(
1
,
4
):
c_longlong_type
,
(
1
,
5
):
c_float_type
,
(
1
,
5
):
c_py_ssize_t_type
,
(
1
,
6
):
c_double_type
,
(
2
,
0
):
c_schar_type
,
(
1
,
7
):
c_longdouble_type
,
(
2
,
1
):
c_sshort_type
,
(
2
,
2
):
c_sint_type
,
(
2
,
3
):
c_slong_type
,
(
2
,
4
):
c_slonglong_type
,
(
2
,
5
):
c_py_ssize_t_type
,
(
1
,
6
):
c_float_type
,
(
1
,
7
):
c_double_type
,
(
1
,
8
):
c_longdouble_type
,
}
}
modifiers_and_name_to_type
=
{
modifiers_and_name_to_type
=
{
...
@@ -768,20 +854,29 @@ modifiers_and_name_to_type = {
...
@@ -768,20 +854,29 @@ modifiers_and_name_to_type = {
(
1
,
0
,
"int"
):
c_int_type
,
(
1
,
0
,
"int"
):
c_int_type
,
(
1
,
1
,
"int"
):
c_long_type
,
(
1
,
1
,
"int"
):
c_long_type
,
(
1
,
2
,
"int"
):
c_longlong_type
,
(
1
,
2
,
"int"
):
c_longlong_type
,
(
1
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
1
,
0
,
"float"
):
c_float_type
,
(
1
,
0
,
"float"
):
c_float_type
,
(
1
,
0
,
"double"
):
c_double_type
,
(
1
,
0
,
"double"
):
c_double_type
,
(
1
,
1
,
"double"
):
c_longdouble_type
,
(
1
,
1
,
"double"
):
c_longdouble_type
,
(
1
,
0
,
"object"
):
py_object_type
,
(
1
,
0
,
"object"
):
py_object_type
,
(
2
,
0
,
"char"
):
c_schar_type
,
(
2
,
-
1
,
"int"
):
c_sshort_type
,
(
2
,
0
,
"int"
):
c_sint_type
,
(
2
,
1
,
"int"
):
c_slong_type
,
(
2
,
2
,
"int"
):
c_slonglong_type
,
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
}
}
def
widest_numeric_type
(
type1
,
type2
):
def
widest_numeric_type
(
type1
,
type2
):
# Given two numeric types, return the narrowest type
# Given two numeric types, return the narrowest type
# encompassing both of them.
# encompassing both of them.
signed
=
type1
.
signed
if
type1
.
is_enum
and
type2
.
is_enum
:
rank
=
max
(
type1
.
rank
,
type2
.
rank
)
widest_type
=
c_int_type
if
rank
>=
lowest_float_rank
:
elif
type2
.
rank
>
type1
.
rank
:
signed
=
1
widest_type
=
type2
return
sign_and_rank_to_type
[
signed
,
rank
]
else
:
widest_type
=
type1
return
widest_type
def
simple_c_type
(
signed
,
longness
,
name
):
def
simple_c_type
(
signed
,
longness
,
name
):
# Find type descriptor for simple type given name and modifiers.
# Find type descriptor for simple type given name and modifiers.
...
...
Cython/Compiler/Scanning.py
View file @
3588f4a6
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
import
cPickle
as
pickle
import
cPickle
as
pickle
import
os
import
os
import
platform
import
stat
import
stat
import
sys
import
sys
from
time
import
time
from
time
import
time
...
@@ -138,7 +139,7 @@ reserved_words = [
...
@@ -138,7 +139,7 @@ reserved_words = [
"raise"
,
"import"
,
"exec"
,
"try"
,
"except"
,
"finally"
,
"raise"
,
"import"
,
"exec"
,
"try"
,
"except"
,
"finally"
,
"while"
,
"if"
,
"elif"
,
"else"
,
"for"
,
"in"
,
"assert"
,
"while"
,
"if"
,
"elif"
,
"else"
,
"for"
,
"in"
,
"assert"
,
"and"
,
"or"
,
"not"
,
"is"
,
"in"
,
"lambda"
,
"from"
,
"and"
,
"or"
,
"not"
,
"is"
,
"in"
,
"lambda"
,
"from"
,
"NULL"
,
"cimport"
"NULL"
,
"cimport"
,
"with"
,
"DEF"
,
"IF"
,
"ELIF"
,
"ELSE"
]
]
class
Method
:
class
Method
:
...
@@ -160,7 +161,53 @@ def build_resword_dict():
...
@@ -160,7 +161,53 @@ def build_resword_dict():
#------------------------------------------------------------------
#------------------------------------------------------------------
class
CompileTimeScope
(
object
):
def
__init__
(
self
,
outer
=
None
):
self
.
entries
=
{}
self
.
outer
=
outer
def
declare
(
self
,
name
,
value
):
self
.
entries
[
name
]
=
value
def
lookup_here
(
self
,
name
):
return
self
.
entries
[
name
]
def
lookup
(
self
,
name
):
try
:
return
self
.
lookup_here
(
name
)
except
KeyError
:
outer
=
self
.
outer
if
outer
:
return
outer
.
lookup
(
name
)
else
:
raise
def
initial_compile_time_env
():
benv
=
CompileTimeScope
()
names
=
(
'UNAME_SYSNAME'
,
'UNAME_NODENAME'
,
'UNAME_RELEASE'
,
'UNAME_VERSION'
,
'UNAME_MACHINE'
)
for
name
,
value
in
zip
(
names
,
platform
.
uname
()):
benv
.
declare
(
name
,
value
)
import
__builtin__
names
=
(
'False'
,
'True'
,
'abs'
,
'bool'
,
'chr'
,
'cmp'
,
'complex'
,
'dict'
,
'divmod'
,
'enumerate'
,
'float'
,
'hash'
,
'hex'
,
'int'
,
'len'
,
'list'
,
'long'
,
'map'
,
'max'
,
'min'
,
'oct'
,
'ord'
,
'pow'
,
'range'
,
'reduce'
,
'repr'
,
'round'
,
'slice'
,
'str'
,
'sum'
,
'tuple'
,
'xrange'
,
'zip'
)
for
name
in
names
:
benv
.
declare
(
name
,
getattr
(
__builtin__
,
name
))
denv
=
CompileTimeScope
(
benv
)
return
denv
#------------------------------------------------------------------
class
PyrexScanner
(
Scanner
):
class
PyrexScanner
(
Scanner
):
# context Context Compilation context
# type_names set Identifiers to be treated as type names
# compile_time_env dict Environment for conditional compilation
# compile_time_eval boolean In a true conditional compilation context
# compile_time_expr boolean In a compile-time expression context
resword_dict
=
build_resword_dict
()
resword_dict
=
build_resword_dict
()
...
@@ -170,9 +217,15 @@ class PyrexScanner(Scanner):
...
@@ -170,9 +217,15 @@ class PyrexScanner(Scanner):
if
parent_scanner
:
if
parent_scanner
:
self
.
context
=
parent_scanner
.
context
self
.
context
=
parent_scanner
.
context
self
.
type_names
=
parent_scanner
.
type_names
self
.
type_names
=
parent_scanner
.
type_names
self
.
compile_time_env
=
parent_scanner
.
compile_time_env
self
.
compile_time_eval
=
parent_scanner
.
compile_time_eval
self
.
compile_time_expr
=
parent_scanner
.
compile_time_expr
else
:
else
:
self
.
context
=
context
self
.
context
=
context
self
.
type_names
=
type_names
self
.
type_names
=
type_names
self
.
compile_time_env
=
initial_compile_time_env
()
self
.
compile_time_eval
=
1
self
.
compile_time_expr
=
0
self
.
trace
=
trace_scanner
self
.
trace
=
trace_scanner
self
.
indentation_stack
=
[
0
]
self
.
indentation_stack
=
[
0
]
self
.
indentation_char
=
None
self
.
indentation_char
=
None
...
@@ -303,10 +356,19 @@ class PyrexScanner(Scanner):
...
@@ -303,10 +356,19 @@ class PyrexScanner(Scanner):
if
self
.
sy
==
what
:
if
self
.
sy
==
what
:
self
.
next
()
self
.
next
()
else
:
else
:
if
message
:
self
.
expected
(
what
,
message
)
self
.
error
(
message
)
else
:
def
expect_keyword
(
self
,
what
,
message
=
None
):
self
.
error
(
"Expected '%s'"
%
what
)
if
self
.
sy
==
'IDENT'
and
self
.
systring
==
what
:
self
.
next
()
else
:
self
.
expected
(
what
,
message
)
def
expected
(
self
,
what
,
message
):
if
message
:
self
.
error
(
message
)
else
:
self
.
error
(
"Expected '%s'"
%
what
)
def
expect_indent
(
self
):
def
expect_indent
(
self
):
self
.
expect
(
'INDENT'
,
self
.
expect
(
'INDENT'
,
...
@@ -316,7 +378,7 @@ class PyrexScanner(Scanner):
...
@@ -316,7 +378,7 @@ class PyrexScanner(Scanner):
self
.
expect
(
'DEDENT'
,
self
.
expect
(
'DEDENT'
,
"Expected a decrease in indentation level"
)
"Expected a decrease in indentation level"
)
def
expect_newline
(
self
,
message
):
def
expect_newline
(
self
,
message
=
"Expected a newline"
):
# Expect either a newline or end of file
# Expect either a newline or end of file
if
self
.
sy
<>
'EOF'
:
if
self
.
sy
<>
'EOF'
:
self
.
expect
(
'NEWLINE'
,
message
)
self
.
expect
(
'NEWLINE'
,
message
)
Cython/Compiler/Symtab.py
View file @
3588f4a6
...
@@ -3,9 +3,10 @@
...
@@ -3,9 +3,10 @@
#
#
import
re
import
re
from
Errors
import
error
,
InternalError
from
Errors
import
warning
,
error
,
InternalError
import
Options
import
Options
import
Naming
import
Naming
import
PyrexTypes
from
PyrexTypes
import
c_int_type
,
\
from
PyrexTypes
import
c_int_type
,
\
py_object_type
,
c_char_array_type
,
\
py_object_type
,
c_char_array_type
,
\
CEnumType
,
CStructOrUnionType
,
PyExtensionType
CEnumType
,
CStructOrUnionType
,
PyExtensionType
...
@@ -24,7 +25,7 @@ class Entry:
...
@@ -24,7 +25,7 @@ class Entry:
# doc string Doc string
# doc string Doc string
# init string Initial value
# init string Initial value
# visibility 'private' or 'public' or 'extern'
# visibility 'private' or 'public' or 'extern'
# is_builtin boolean Is a
Python builtin name
# is_builtin boolean Is a
n entry in the Python builtins dict
# is_cglobal boolean Is a C global variable
# is_cglobal boolean Is a C global variable
# is_pyglobal boolean Is a Python module-level variable
# is_pyglobal boolean Is a Python module-level variable
# or class attribute during
# or class attribute during
...
@@ -48,7 +49,7 @@ class Entry:
...
@@ -48,7 +49,7 @@ class Entry:
# signature Signature Arg & return types for Python func
# signature Signature Arg & return types for Python func
# init_to_none boolean True if initial value should be None
# init_to_none boolean True if initial value should be None
# as_variable Entry Alternative interpretation of extension
# as_variable Entry Alternative interpretation of extension
# type name as a variable
# type name
or builtin C function
as a variable
# xdecref_cleanup boolean Use Py_XDECREF for error cleanup
# xdecref_cleanup boolean Use Py_XDECREF for error cleanup
# in_cinclude boolean Suppress C declaration code
# in_cinclude boolean Suppress C declaration code
# enum_values [Entry] For enum types, list of values
# enum_values [Entry] For enum types, list of values
...
@@ -58,10 +59,14 @@ class Entry:
...
@@ -58,10 +59,14 @@ class Entry:
# type is an extension type
# type is an extension type
# as_module None Module scope, if a cimported module
# as_module None Module scope, if a cimported module
# is_inherited boolean Is an inherited attribute of an extension type
# is_inherited boolean Is an inherited attribute of an extension type
# interned_cname string C name of interned name string
#
#
interned_cname string C name of interned name string
# pystring_cname string C name of Python version of string literal
# pystring_cname string C name of Python version of string literal
# is_interned boolean For string const entries, value is interned
# is_interned boolean For string const entries, value is interned
# used boolean
# used boolean
# is_special boolean Is a special method or property accessor
# of an extension type
# defined_in_pxd boolean Is defined in a .pxd file (not just declared)
# api boolean Generate C API for C function
borrowed
=
0
borrowed
=
0
init
=
""
init
=
""
...
@@ -89,11 +94,14 @@ class Entry:
...
@@ -89,11 +94,14 @@ class Entry:
in_cinclude
=
0
in_cinclude
=
0
as_module
=
None
as_module
=
None
is_inherited
=
0
is_inherited
=
0
interned_cname
=
None
#
interned_cname = None
pystring_cname
=
None
pystring_cname
=
None
is_interned
=
0
is_interned
=
0
used
=
0
used
=
0
is_special
=
0
defined_in_pxd
=
0
api
=
0
def
__init__
(
self
,
name
,
cname
,
type
,
pos
=
None
,
init
=
None
):
def
__init__
(
self
,
name
,
cname
,
type
,
pos
=
None
,
init
=
None
):
self
.
name
=
name
self
.
name
=
name
self
.
cname
=
cname
self
.
cname
=
cname
...
@@ -107,6 +115,7 @@ class Scope:
...
@@ -107,6 +115,7 @@ class Scope:
# outer_scope Scope or None Enclosing scope
# outer_scope Scope or None Enclosing scope
# entries {string : Entry} Python name to entry, non-types
# entries {string : Entry} Python name to entry, non-types
# const_entries [Entry] Constant entries
# const_entries [Entry] Constant entries
# type_entries [Entry] Struct/union/enum/typedef/exttype entries
# sue_entries [Entry] Struct/union/enum entries
# sue_entries [Entry] Struct/union/enum entries
# arg_entries [Entry] Function argument entries
# arg_entries [Entry] Function argument entries
# var_entries [Entry] User-defined variable entries
# var_entries [Entry] User-defined variable entries
...
@@ -148,6 +157,7 @@ class Scope:
...
@@ -148,6 +157,7 @@ class Scope:
self
.
scope_prefix
=
mangled_name
self
.
scope_prefix
=
mangled_name
self
.
entries
=
{}
self
.
entries
=
{}
self
.
const_entries
=
[]
self
.
const_entries
=
[]
self
.
type_entries
=
[]
self
.
sue_entries
=
[]
self
.
sue_entries
=
[]
self
.
arg_entries
=
[]
self
.
arg_entries
=
[]
self
.
var_entries
=
[]
self
.
var_entries
=
[]
...
@@ -221,27 +231,41 @@ class Scope:
...
@@ -221,27 +231,41 @@ class Scope:
return
entry
return
entry
def
declare_type
(
self
,
name
,
type
,
pos
,
def
declare_type
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
):
cname
=
None
,
visibility
=
'private'
,
defining
=
1
):
# Add an entry for a type definition.
# Add an entry for a type definition.
if
not
cname
:
if
not
cname
:
cname
=
name
cname
=
name
entry
=
self
.
declare
(
name
,
cname
,
type
,
pos
)
entry
=
self
.
declare
(
name
,
cname
,
type
,
pos
)
entry
.
visibility
=
visibility
entry
.
visibility
=
visibility
entry
.
is_type
=
1
entry
.
is_type
=
1
if
defining
:
self
.
type_entries
.
append
(
entry
)
return
entry
return
entry
def
declare_typedef
(
self
,
name
,
base_type
,
pos
,
cname
=
None
,
visibility
=
'private'
):
if
not
cname
:
if
self
.
in_cinclude
or
visibility
==
'public'
:
cname
=
name
else
:
cname
=
self
.
mangle
(
Naming
.
type_prefix
,
name
)
type
=
PyrexTypes
.
CTypedefType
(
cname
,
base_type
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
visibility
)
type
.
qualified_name
=
entry
.
qualified_name
def
declare_struct_or_union
(
self
,
name
,
kind
,
scope
,
def
declare_struct_or_union
(
self
,
name
,
kind
,
scope
,
typedef_flag
,
pos
,
cname
=
None
):
typedef_flag
,
pos
,
cname
=
None
,
visibility
=
'private'
):
# Add an entry for a struct or union definition.
# Add an entry for a struct or union definition.
if
not
cname
:
if
not
cname
:
if
self
.
in_cinclude
:
if
self
.
in_cinclude
or
visibility
==
'public'
:
cname
=
name
cname
=
name
else
:
else
:
cname
=
self
.
mangle
(
Naming
.
type_prefix
,
name
)
cname
=
self
.
mangle
(
Naming
.
type_prefix
,
name
)
entry
=
self
.
lookup_here
(
name
)
entry
=
self
.
lookup_here
(
name
)
if
not
entry
:
if
not
entry
:
type
=
CStructOrUnionType
(
name
,
kind
,
scope
,
typedef_flag
,
cname
)
type
=
CStructOrUnionType
(
name
,
kind
,
scope
,
typedef_flag
,
cname
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
visibility
=
visibility
,
defining
=
scope
is
not
None
)
self
.
sue_entries
.
append
(
entry
)
self
.
sue_entries
.
append
(
entry
)
else
:
else
:
if
not
(
entry
.
is_type
and
entry
.
type
.
is_struct_or_union
):
if
not
(
entry
.
is_type
and
entry
.
type
.
is_struct_or_union
):
...
@@ -250,8 +274,10 @@ class Scope:
...
@@ -250,8 +274,10 @@ class Scope:
error
(
pos
,
"'%s' already defined"
%
name
)
error
(
pos
,
"'%s' already defined"
%
name
)
else
:
else
:
self
.
check_previous_typedef_flag
(
entry
,
typedef_flag
,
pos
)
self
.
check_previous_typedef_flag
(
entry
,
typedef_flag
,
pos
)
self
.
check_previous_visibility
(
entry
,
visibility
,
pos
)
if
scope
:
if
scope
:
entry
.
type
.
scope
=
scope
entry
.
type
.
scope
=
scope
self
.
type_entries
.
append
(
entry
)
if
not
scope
and
not
entry
.
type
.
scope
:
if
not
scope
and
not
entry
.
type
.
scope
:
self
.
check_for_illegal_incomplete_ctypedef
(
typedef_flag
,
pos
)
self
.
check_for_illegal_incomplete_ctypedef
(
typedef_flag
,
pos
)
return
entry
return
entry
...
@@ -261,17 +287,24 @@ class Scope:
...
@@ -261,17 +287,24 @@ class Scope:
error
(
pos
,
"'%s' previously declared using '%s'"
%
(
error
(
pos
,
"'%s' previously declared using '%s'"
%
(
entry
.
name
,
(
"cdef"
,
"ctypedef"
)[
entry
.
type
.
typedef_flag
]))
entry
.
name
,
(
"cdef"
,
"ctypedef"
)[
entry
.
type
.
typedef_flag
]))
def
declare_enum
(
self
,
name
,
pos
,
cname
,
typedef_flag
):
def
check_previous_visibility
(
self
,
entry
,
visibility
,
pos
):
if
entry
.
visibility
<>
visibility
:
error
(
pos
,
"'%s' previously declared as '%s'"
%
(
entry
.
name
,
entry
.
visibility
))
def
declare_enum
(
self
,
name
,
pos
,
cname
,
typedef_flag
,
visibility
=
'private'
):
if
name
:
if
name
:
if
not
cname
:
if
not
cname
:
if
self
.
in_cinclude
:
if
self
.
in_cinclude
or
visibility
==
'public'
:
cname
=
name
cname
=
name
else
:
else
:
cname
=
self
.
mangle
(
Naming
.
type_prefix
,
name
)
cname
=
self
.
mangle
(
Naming
.
type_prefix
,
name
)
type
=
CEnumType
(
name
,
cname
,
typedef_flag
)
type
=
CEnumType
(
name
,
cname
,
typedef_flag
)
else
:
else
:
type
=
c_int_type
type
=
PyrexTypes
.
c_anon_enum_type
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
=
cname
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
entry
.
enum_values
=
[]
entry
.
enum_values
=
[]
self
.
sue_entries
.
append
(
entry
)
self
.
sue_entries
.
append
(
entry
)
return
entry
return
entry
...
@@ -303,15 +336,26 @@ class Scope:
...
@@ -303,15 +336,26 @@ class Scope:
self
.
pyfunc_entries
.
append
(
entry
)
self
.
pyfunc_entries
.
append
(
entry
)
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
):
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
):
# Add an entry for a C function.
# Add an entry for a C function.
if
not
cname
:
entry
=
self
.
lookup_here
(
name
)
if
visibility
<>
'private'
:
if
entry
:
cname
=
name
if
not
entry
.
type
.
same_as
(
type
):
else
:
error
(
pos
,
"Function signature does not match previous declaration"
)
cname
=
self
.
mangle
(
Naming
.
func_prefix
,
name
)
else
:
entry
=
self
.
add_cfunction
(
name
,
type
,
pos
,
cname
,
visibility
)
if
not
cname
:
entry
.
func_cname
=
cname
if
api
or
visibility
<>
'private'
:
cname
=
name
else
:
cname
=
self
.
mangle
(
Naming
.
func_prefix
,
name
)
entry
=
self
.
add_cfunction
(
name
,
type
,
pos
,
cname
,
visibility
)
entry
.
func_cname
=
cname
if
in_pxd
and
visibility
<>
'extern'
:
entry
.
defined_in_pxd
=
1
if
api
:
entry
.
api
=
1
if
not
defining
and
not
in_pxd
and
visibility
<>
'extern'
:
error
(
pos
,
"Non-extern C function declared but not defined"
)
return
entry
return
entry
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
):
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
):
...
@@ -457,6 +501,15 @@ class BuiltinScope(Scope):
...
@@ -457,6 +501,15 @@ class BuiltinScope(Scope):
entry
.
is_builtin
=
1
entry
.
is_builtin
=
1
return
entry
return
entry
def
declare_builtin_cfunction
(
self
,
name
,
type
,
cname
,
with_python_equiv
=
0
):
entry
=
self
.
declare_cfunction
(
name
,
type
,
None
,
cname
)
if
with_python_equiv
:
var_entry
=
Entry
(
name
,
name
,
py_object_type
)
var_entry
.
is_variable
=
1
var_entry
.
is_builtin
=
1
entry
.
as_variable
=
var_entry
return
entry
class
ModuleScope
(
Scope
):
class
ModuleScope
(
Scope
):
# module_name string Python name of the module
# module_name string Python name of the module
...
@@ -515,7 +568,7 @@ class ModuleScope(Scope):
...
@@ -515,7 +568,7 @@ class ModuleScope(Scope):
def
declare_builtin
(
self
,
name
,
pos
):
def
declare_builtin
(
self
,
name
,
pos
):
entry
=
Scope
.
declare_builtin
(
self
,
name
,
pos
)
entry
=
Scope
.
declare_builtin
(
self
,
name
,
pos
)
entry
.
interned_cname
=
self
.
intern
(
name
)
#
entry.interned_cname = self.intern(name)
return
entry
return
entry
def
intern
(
self
,
name
):
def
intern
(
self
,
name
):
...
@@ -598,8 +651,8 @@ class ModuleScope(Scope):
...
@@ -598,8 +651,8 @@ class ModuleScope(Scope):
"Non-cdef global variable is not a generic Python object"
)
"Non-cdef global variable is not a generic Python object"
)
entry
.
is_pyglobal
=
1
entry
.
is_pyglobal
=
1
entry
.
namespace_cname
=
self
.
module_cname
entry
.
namespace_cname
=
self
.
module_cname
if
Options
.
intern_names
:
#
if Options.intern_names:
entry
.
interned_cname
=
self
.
intern
(
name
)
#
entry.interned_cname = self.intern(name)
else
:
else
:
entry
.
is_cglobal
=
1
entry
.
is_cglobal
=
1
self
.
var_entries
.
append
(
entry
)
self
.
var_entries
.
append
(
entry
)
...
@@ -636,9 +689,6 @@ class ModuleScope(Scope):
...
@@ -636,9 +689,6 @@ class ModuleScope(Scope):
module_name
,
base_type
,
objstruct_cname
,
typeobj_cname
,
module_name
,
base_type
,
objstruct_cname
,
typeobj_cname
,
visibility
,
typedef_flag
):
visibility
,
typedef_flag
):
#
#
#print "declare_c_class:", name
#print "...visibility =", visibility
#
# Look for previous declaration as a type
# Look for previous declaration as a type
#
#
entry
=
self
.
lookup_here
(
name
)
entry
=
self
.
lookup_here
(
name
)
...
@@ -660,7 +710,8 @@ class ModuleScope(Scope):
...
@@ -660,7 +710,8 @@ class ModuleScope(Scope):
else
:
else
:
type
.
module_name
=
self
.
qualified_name
type
.
module_name
=
self
.
qualified_name
type
.
typeptr_cname
=
self
.
mangle
(
Naming
.
typeptr_prefix
,
name
)
type
.
typeptr_cname
=
self
.
mangle
(
Naming
.
typeptr_prefix
,
name
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
visibility
=
visibility
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
visibility
=
visibility
,
defining
=
0
)
if
objstruct_cname
:
if
objstruct_cname
:
type
.
objstruct_cname
=
objstruct_cname
type
.
objstruct_cname
=
objstruct_cname
elif
not
entry
.
in_cinclude
:
elif
not
entry
.
in_cinclude
:
...
@@ -680,6 +731,7 @@ class ModuleScope(Scope):
...
@@ -680,6 +731,7 @@ class ModuleScope(Scope):
if
base_type
:
if
base_type
:
scope
.
declare_inherited_c_attributes
(
base_type
.
scope
)
scope
.
declare_inherited_c_attributes
(
base_type
.
scope
)
type
.
set_scope
(
scope
)
type
.
set_scope
(
scope
)
self
.
type_entries
.
append
(
entry
)
else
:
else
:
self
.
check_for_illegal_incomplete_ctypedef
(
typedef_flag
,
pos
)
self
.
check_for_illegal_incomplete_ctypedef
(
typedef_flag
,
pos
)
else
:
else
:
...
@@ -690,11 +742,13 @@ class ModuleScope(Scope):
...
@@ -690,11 +742,13 @@ class ModuleScope(Scope):
#
#
# Fill in options, checking for compatibility with any previous declaration
# Fill in options, checking for compatibility with any previous declaration
#
#
if
defining
:
entry
.
defined_in_pxd
=
1
if
implementing
:
# So that filenames in runtime exceptions refer to
if
implementing
:
# So that filenames in runtime exceptions refer to
entry
.
pos
=
pos
# the .pyx file and not the .pxd file
entry
.
pos
=
pos
# the .pyx file and not the .pxd file
if
entry
.
visibility
<>
visibility
:
if
entry
.
visibility
<>
visibility
:
error
(
pos
,
"Declaration of '%s' as '%s' conflicts with previous "
error
(
pos
,
"Declaration of '%s' as '%s' conflicts with previous "
"declaration as '%s'"
%
(
class_
name
,
visibility
,
entry
.
visibility
))
"declaration as '%s'"
%
(
name
,
visibility
,
entry
.
visibility
))
if
objstruct_cname
:
if
objstruct_cname
:
if
type
.
objstruct_cname
and
type
.
objstruct_cname
<>
objstruct_cname
:
if
type
.
objstruct_cname
and
type
.
objstruct_cname
<>
objstruct_cname
:
error
(
pos
,
"Object struct name differs from previous declaration"
)
error
(
pos
,
"Object struct name differs from previous declaration"
)
...
@@ -884,8 +938,8 @@ class PyClassScope(ClassScope):
...
@@ -884,8 +938,8 @@ class PyClassScope(ClassScope):
cname
,
visibility
,
is_cdef
)
cname
,
visibility
,
is_cdef
)
entry
.
is_pyglobal
=
1
entry
.
is_pyglobal
=
1
entry
.
namespace_cname
=
self
.
class_obj_cname
entry
.
namespace_cname
=
self
.
class_obj_cname
if
Options
.
intern_names
:
#
if Options.intern_names:
entry
.
interned_cname
=
self
.
intern
(
name
)
#
entry.interned_cname = self.intern(name)
return
entry
return
entry
def
allocate_temp
(
self
,
type
):
def
allocate_temp
(
self
,
type
):
...
@@ -976,18 +1030,28 @@ class CClassScope(ClassScope):
...
@@ -976,18 +1030,28 @@ class CClassScope(ClassScope):
def
declare_pyfunction
(
self
,
name
,
pos
):
def
declare_pyfunction
(
self
,
name
,
pos
):
# Add an entry for a method.
# Add an entry for a method.
if
name
==
"__new__"
:
warning
(
pos
,
"__new__ method of extension type will change semantics "
"in a future version of Pyrex. Use __cinit__ instead."
)
name
=
"__cinit__"
entry
=
self
.
declare
(
name
,
name
,
py_object_type
,
pos
)
entry
=
self
.
declare
(
name
,
name
,
py_object_type
,
pos
)
special_sig
=
get_special_method_signature
(
name
)
special_sig
=
get_special_method_signature
(
name
)
if
special_sig
:
if
special_sig
:
entry
.
is_special
=
1
entry
.
signature
=
special_sig
entry
.
signature
=
special_sig
# Special methods don't get put in the method table
# Special methods don't get put in the method table
else
:
else
:
entry
.
signature
=
pymethod_signature
entry
.
signature
=
pymethod_signature
self
.
pyfunc_entries
.
append
(
entry
)
self
.
pyfunc_entries
.
append
(
entry
)
return
entry
return
entry
def
lookup_here
(
self
,
name
):
if
name
==
"__new__"
:
name
=
"__cinit__"
return
ClassScope
.
lookup_here
(
self
,
name
)
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
):
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
):
if
get_special_method_signature
(
name
):
if
get_special_method_signature
(
name
):
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
args
=
type
.
args
args
=
type
.
args
...
@@ -1002,6 +1066,7 @@ class CClassScope(ClassScope):
...
@@ -1002,6 +1066,7 @@ class CClassScope(ClassScope):
else
:
else
:
if
defining
and
entry
.
func_cname
:
if
defining
and
entry
.
func_cname
:
error
(
pos
,
"'%s' already defined"
%
name
)
error
(
pos
,
"'%s' already defined"
%
name
)
#print "CClassScope.declare_cfunction: checking signature" ###
if
not
entry
.
type
.
same_as
(
type
,
as_cmethod
=
1
):
if
not
entry
.
type
.
same_as
(
type
,
as_cmethod
=
1
):
error
(
pos
,
"Signature does not match previous declaration"
)
error
(
pos
,
"Signature does not match previous declaration"
)
else
:
else
:
...
@@ -1059,6 +1124,7 @@ class PropertyScope(Scope):
...
@@ -1059,6 +1124,7 @@ class PropertyScope(Scope):
signature
=
get_property_accessor_signature
(
name
)
signature
=
get_property_accessor_signature
(
name
)
if
signature
:
if
signature
:
entry
=
self
.
declare
(
name
,
name
,
py_object_type
,
pos
)
entry
=
self
.
declare
(
name
,
name
,
py_object_type
,
pos
)
entry
.
is_special
=
1
entry
.
signature
=
signature
entry
.
signature
=
signature
return
entry
return
entry
else
:
else
:
...
...
Cython/Compiler/TypeSlots.py
View file @
3588f4a6
...
@@ -26,6 +26,7 @@ class Signature:
...
@@ -26,6 +26,7 @@ class Signature:
# 'i' int
# 'i' int
# 'I' int *
# 'I' int *
# 'l' long
# 'l' long
# 'Z' Py_ssize_t
# 's' char *
# 's' char *
# 'S' char **
# 'S' char **
# 'r' int used only to signal exception
# 'r' int used only to signal exception
...
@@ -42,6 +43,7 @@ class Signature:
...
@@ -42,6 +43,7 @@ class Signature:
'i'
:
PyrexTypes
.
c_int_type
,
'i'
:
PyrexTypes
.
c_int_type
,
'I'
:
PyrexTypes
.
c_int_ptr_type
,
'I'
:
PyrexTypes
.
c_int_ptr_type
,
'l'
:
PyrexTypes
.
c_long_type
,
'l'
:
PyrexTypes
.
c_long_type
,
'Z'
:
PyrexTypes
.
c_py_ssize_t_type
,
's'
:
PyrexTypes
.
c_char_ptr_type
,
's'
:
PyrexTypes
.
c_char_ptr_type
,
'S'
:
PyrexTypes
.
c_char_ptr_ptr_type
,
'S'
:
PyrexTypes
.
c_char_ptr_ptr_type
,
'r'
:
PyrexTypes
.
c_returncode_type
,
'r'
:
PyrexTypes
.
c_returncode_type
,
...
@@ -80,6 +82,19 @@ class Signature:
...
@@ -80,6 +82,19 @@ class Signature:
def
return_type
(
self
):
def
return_type
(
self
):
return
self
.
format_map
[
self
.
ret_format
]
return
self
.
format_map
[
self
.
ret_format
]
def
exception_value
(
self
):
return
self
.
error_value_map
.
get
(
self
.
ret_format
)
def
function_type
(
self
):
# Construct a C function type descriptor for this signature
args
=
[]
for
i
in
xrange
(
self
.
num_fixed_args
()):
arg_type
=
self
.
fixed_arg_type
(
i
)
args
.
append
(
PyrexTypes
.
CFuncTypeArg
(
""
,
arg_type
,
None
))
ret_type
=
self
.
return_type
()
exc_value
=
self
.
exception_value
()
return
PyrexTypes
.
CFuncType
(
ret_type
,
args
,
exception_value
=
exc_value
)
class
SlotDescriptor
:
class
SlotDescriptor
:
...
@@ -87,17 +102,24 @@ class SlotDescriptor:
...
@@ -87,17 +102,24 @@ class SlotDescriptor:
#
#
# slot_name string Member name of the slot in the type object
# slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function
# is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot
def
__init__
(
self
,
slot_name
,
dynamic
=
0
):
def
__init__
(
self
,
slot_name
,
dynamic
=
0
,
flag
=
None
):
self
.
slot_name
=
slot_name
self
.
slot_name
=
slot_name
self
.
is_initialised_dynamically
=
dynamic
self
.
is_initialised_dynamically
=
dynamic
self
.
flag
=
flag
def
generate
(
self
,
scope
,
code
):
def
generate
(
self
,
scope
,
code
):
if
self
.
is_initialised_dynamically
:
if
self
.
is_initialised_dynamically
:
value
=
0
value
=
0
else
:
else
:
value
=
self
.
slot_code
(
scope
)
value
=
self
.
slot_code
(
scope
)
flag
=
self
.
flag
if
flag
:
code
.
putln
(
"#if Py_TPFLAGS_DEFAULT & %s"
%
flag
)
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
if
flag
:
code
.
putln
(
"#endif"
)
# Some C implementations have trouble statically
# Some C implementations have trouble statically
# initialising a global with a pointer to an extern
# initialising a global with a pointer to an extern
...
@@ -159,8 +181,8 @@ class MethodSlot(SlotDescriptor):
...
@@ -159,8 +181,8 @@ class MethodSlot(SlotDescriptor):
# method_name string The __xxx__ name of the method
# method_name string The __xxx__ name of the method
# default string or None Default value of the slot
# default string or None Default value of the slot
def
__init__
(
self
,
signature
,
slot_name
,
method_name
,
default
=
None
):
def
__init__
(
self
,
signature
,
slot_name
,
method_name
,
default
=
None
,
flag
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
)
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
)
self
.
signature
=
signature
self
.
signature
=
signature
self
.
slot_name
=
slot_name
self
.
slot_name
=
slot_name
self
.
method_name
=
method_name
self
.
method_name
=
method_name
...
@@ -354,18 +376,28 @@ ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(P
...
@@ -354,18 +376,28 @@ ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(P
iternaryfunc
=
Signature
(
"TOO"
,
"O"
)
# typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
iternaryfunc
=
Signature
(
"TOO"
,
"O"
)
# typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
callfunc
=
Signature
(
"T*"
,
"O"
)
# typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
callfunc
=
Signature
(
"T*"
,
"O"
)
# typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
inquiry
=
Signature
(
"T"
,
"i"
)
# typedef int (*inquiry)(PyObject *);
inquiry
=
Signature
(
"T"
,
"i"
)
# typedef int (*inquiry)(PyObject *);
lenfunc
=
Signature
(
"T"
,
"Z"
)
# typedef Py_ssize_t (*lenfunc)(PyObject *);
# typedef int (*coercion)(PyObject **, PyObject **);
# typedef int (*coercion)(PyObject **, PyObject **);
intargfunc
=
Signature
(
"Ti"
,
"O"
)
# typedef PyObject *(*intargfunc)(PyObject *, int);
intargfunc
=
Signature
(
"Ti"
,
"O"
)
# typedef PyObject *(*intargfunc)(PyObject *, int);
ssizeargfunc
=
Signature
(
"TZ"
,
"O"
)
# typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
intintargfunc
=
Signature
(
"Tii"
,
"O"
)
# typedef PyObject *(*intintargfunc)(PyObject *, int, int);
intintargfunc
=
Signature
(
"Tii"
,
"O"
)
# typedef PyObject *(*intintargfunc)(PyObject *, int, int);
ssizessizeargfunc
=
Signature
(
"TZZ"
,
"O"
)
# typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
intobjargproc
=
Signature
(
"TiO"
,
'r'
)
# typedef int(*intobjargproc)(PyObject *, int, PyObject *);
intobjargproc
=
Signature
(
"TiO"
,
'r'
)
# typedef int(*intobjargproc)(PyObject *, int, PyObject *);
ssizeobjargproc
=
Signature
(
"TZO"
,
'r'
)
# typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
intintobjargproc
=
Signature
(
"TiiO"
,
'r'
)
# typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
intintobjargproc
=
Signature
(
"TiiO"
,
'r'
)
# typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
ssizessizeobjargproc
=
Signature
(
"TZZO"
,
'r'
)
# typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
intintargproc
=
Signature
(
"Tii"
,
'r'
)
intintargproc
=
Signature
(
"Tii"
,
'r'
)
ssizessizeargproc
=
Signature
(
"TZZ"
,
'r'
)
objargfunc
=
Signature
(
"TO"
,
"O"
)
objargfunc
=
Signature
(
"TO"
,
"O"
)
objobjargproc
=
Signature
(
"TOO"
,
'r'
)
# typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
objobjargproc
=
Signature
(
"TOO"
,
'r'
)
# typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
getreadbufferproc
=
Signature
(
"TiP"
,
'i'
)
# typedef int (*getreadbufferproc)(PyObject *, int, void **);
getreadbufferproc
=
Signature
(
"TiP"
,
'i'
)
# typedef int (*getreadbufferproc)(PyObject *, int, void **);
getwritebufferproc
=
Signature
(
"TiP"
,
'i'
)
# typedef int (*getwritebufferproc)(PyObject *, int, void **);
getwritebufferproc
=
Signature
(
"TiP"
,
'i'
)
# typedef int (*getwritebufferproc)(PyObject *, int, void **);
getsegcountproc
=
Signature
(
"TI"
,
'i'
)
# typedef int (*getsegcountproc)(PyObject *, int *);
getsegcountproc
=
Signature
(
"TI"
,
'i'
)
# typedef int (*getsegcountproc)(PyObject *, int *);
getcharbufferproc
=
Signature
(
"TiS"
,
'i'
)
# typedef int (*getcharbufferproc)(PyObject *, int, const char **);
getcharbufferproc
=
Signature
(
"TiS"
,
'i'
)
# typedef int (*getcharbufferproc)(PyObject *, int, const char **);
readbufferproc
=
Signature
(
"TZP"
,
"Z"
)
# typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
writebufferproc
=
Signature
(
"TZP"
,
"Z"
)
# typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
segcountproc
=
Signature
(
"TZ"
,
"Z"
)
# typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
writebufferproc
=
Signature
(
"TZS"
,
"Z"
)
# typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
objargproc
=
Signature
(
"TO"
,
'r'
)
# typedef int (*objobjproc)(PyObject *, PyObject *);
objargproc
=
Signature
(
"TO"
,
'r'
)
# typedef int (*objobjproc)(PyObject *, PyObject *);
# typedef int (*visitproc)(PyObject *, void *);
# typedef int (*visitproc)(PyObject *, void *);
# typedef int (*traverseproc)(PyObject *, visitproc, void *);
# typedef int (*traverseproc)(PyObject *, visitproc, void *);
...
@@ -454,14 +486,15 @@ PyNumberMethods = (
...
@@ -454,14 +486,15 @@ PyNumberMethods = (
MethodSlot
(
binaryfunc
,
"nb_true_divide"
,
"__truediv__"
),
MethodSlot
(
binaryfunc
,
"nb_true_divide"
,
"__truediv__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_floor_divide"
,
"__ifloordiv__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_floor_divide"
,
"__ifloordiv__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_true_divide"
,
"__itruediv__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_true_divide"
,
"__itruediv__"
),
MethodSlot
(
unaryfunc
,
"nb_index"
,
"__index__"
,
flag
=
"Py_TPFLAGS_HAVE_INDEX"
)
)
)
PySequenceMethods
=
(
PySequenceMethods
=
(
MethodSlot
(
inquiry
,
"sq_length"
,
"__len__"
),
# EmptySlot("sq_length"), # mp_length used instead
MethodSlot
(
lenfunc
,
"sq_length"
,
"__len__"
),
EmptySlot
(
"sq_concat"
),
# nb_add used instead
EmptySlot
(
"sq_concat"
),
# nb_add used instead
EmptySlot
(
"sq_repeat"
),
# nb_multiply used instead
EmptySlot
(
"sq_repeat"
),
# nb_multiply used instead
SyntheticSlot
(
"sq_item"
,
[
"__getitem__"
],
"0"
),
#EmptySlot("sq_item"), # mp_subscript used instead
SyntheticSlot
(
"sq_item"
,
[
"__getitem__"
],
"0"
),
#EmptySlot("sq_item"), # mp_subscript used instead
MethodSlot
(
intint
argfunc
,
"sq_slice"
,
"__getslice__"
),
MethodSlot
(
ssizessize
argfunc
,
"sq_slice"
,
"__getslice__"
),
EmptySlot
(
"sq_ass_item"
),
# mp_ass_subscript used instead
EmptySlot
(
"sq_ass_item"
),
# mp_ass_subscript used instead
SyntheticSlot
(
"sq_ass_slice"
,
[
"__setslice__"
,
"__delslice__"
],
"0"
),
SyntheticSlot
(
"sq_ass_slice"
,
[
"__setslice__"
,
"__delslice__"
],
"0"
),
MethodSlot
(
cmpfunc
,
"sq_contains"
,
"__contains__"
),
MethodSlot
(
cmpfunc
,
"sq_contains"
,
"__contains__"
),
...
@@ -470,7 +503,7 @@ PySequenceMethods = (
...
@@ -470,7 +503,7 @@ PySequenceMethods = (
)
)
PyMappingMethods
=
(
PyMappingMethods
=
(
MethodSlot
(
inquiry
,
"mp_length"
,
"__len__"
),
MethodSlot
(
lenfunc
,
"mp_length"
,
"__len__"
),
MethodSlot
(
objargfunc
,
"mp_subscript"
,
"__getitem__"
),
MethodSlot
(
objargfunc
,
"mp_subscript"
,
"__getitem__"
),
SyntheticSlot
(
"mp_ass_subscript"
,
[
"__setitem__"
,
"__delitem__"
],
"0"
),
SyntheticSlot
(
"mp_ass_subscript"
,
[
"__setitem__"
,
"__delitem__"
],
"0"
),
)
)
...
@@ -561,12 +594,12 @@ slot_table = (
...
@@ -561,12 +594,12 @@ slot_table = (
#
#
#------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------
MethodSlot
(
initproc
,
""
,
"__
new
__"
)
MethodSlot
(
initproc
,
""
,
"__
cinit
__"
)
MethodSlot
(
destructor
,
""
,
"__dealloc__"
)
MethodSlot
(
destructor
,
""
,
"__dealloc__"
)
MethodSlot
(
objobjargproc
,
""
,
"__setitem__"
)
MethodSlot
(
objobjargproc
,
""
,
"__setitem__"
)
MethodSlot
(
objargproc
,
""
,
"__delitem__"
)
MethodSlot
(
objargproc
,
""
,
"__delitem__"
)
MethodSlot
(
intint
objargproc
,
""
,
"__setslice__"
)
MethodSlot
(
ssizessize
objargproc
,
""
,
"__setslice__"
)
MethodSlot
(
intint
argproc
,
""
,
"__delslice__"
)
MethodSlot
(
ssizessize
argproc
,
""
,
"__delslice__"
)
MethodSlot
(
getattrofunc
,
""
,
"__getattr__"
)
MethodSlot
(
getattrofunc
,
""
,
"__getattr__"
)
MethodSlot
(
setattrofunc
,
""
,
"__setattr__"
)
MethodSlot
(
setattrofunc
,
""
,
"__setattr__"
)
MethodSlot
(
delattrofunc
,
""
,
"__delattr__"
)
MethodSlot
(
delattrofunc
,
""
,
"__delattr__"
)
...
...
Cython/Compiler/Version.py
View file @
3588f4a6
version
=
'0.9.
5.1a
'
version
=
'0.9.
6.2
'
Cython/Debugging.py
View file @
3588f4a6
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
def
print_call_chain
(
*
args
):
def
print_call_chain
(
*
args
):
import
sys
import
sys
print
" "
.
join
(
map
(
str
,
args
))
print
" "
.
join
(
map
(
str
,
args
))
f
=
sys
.
_getframe
(
2
)
f
=
sys
.
_getframe
(
1
)
while
f
:
while
f
:
name
=
f
.
f_code
.
co_name
name
=
f
.
f_code
.
co_name
s
=
f
.
f_locals
.
get
(
'self'
,
None
)
s
=
f
.
f_locals
.
get
(
'self'
,
None
)
...
...
Cython/Distutils/__init__.py
View file @
3588f4a6
# July 2002, Graham Fawcett
# July 2002, Graham Fawcett
#
#
# this hack was inspired by the way Thomas Heller got py2exe
# this hack was inspired by the way Thomas Heller got py2exe
# to appear as a distutil command
# to appear as a distutil command
#
#
# we replace distutils.command.build_ext with our own version
# we replace distutils.command.build_ext with our own version
# and keep the old one under the module name _build_ext,
# and keep the old one under the module name _build_ext,
# so that *our* build_ext can make use of it.
# so that *our* build_ext can make use of it.
from
build_ext
import
build_ext
from
build_ext
import
build_ext
from
extension
import
Extension
Cython/Distutils/build_ext.py
View file @
3588f4a6
# Subclasses disutils.command.build_ext,
"""Pyrex.Distutils.build_ext
# replacing it with a Pyrex version that compiles pyx->c
# before calling the original build_ext command.
# July 2002, Graham Fawcett
# Modified by Darrell Gallion <dgallion1@yahoo.com>
# to allow inclusion of .c files along with .pyx files.
# Pyrex is (c) Greg Ewing.
import
distutils.command.build_ext
Implements a version of the Distutils 'build_ext' command, for
#import Pyrex.Compiler.Main
building Pyrex extension modules."""
from
Pyrex.Compiler.Main
import
CompilationOptions
,
default_options
,
compile
from
Pyrex.Compiler.Errors
import
PyrexError
from
distutils.dep_util
import
newer
import
os
import
sys
def
replace_suffix
(
path
,
new_suffix
):
# This module should be kept compatible with Python 2.1.
return
os
.
path
.
splitext
(
path
)[
0
]
+
new_suffix
class
build_ext
(
distutils
.
command
.
build_ext
.
build_ext
):
__revision__
=
"$Id:$"
description
=
"compile Pyrex scripts, then build C/C++ extensions (compile/link to build directory)"
import
sys
,
os
,
string
,
re
from
types
import
*
from
distutils.core
import
Command
from
distutils.errors
import
*
from
distutils.sysconfig
import
customize_compiler
,
get_python_version
from
distutils.dep_util
import
newer_group
from
distutils
import
log
from
distutils.dir_util
import
mkpath
try
:
from
Pyrex.Compiler.Main
\
import
CompilationOptions
,
\
default_options
as
pyrex_default_options
,
\
compile
as
pyrex_compile
from
Pyrex.Compiler.Errors
import
PyrexError
except
ImportError
:
PyrexError
=
None
from
distutils.command
import
build_ext
as
_build_ext
extension_name_re
=
_build_ext
.
extension_name_re
show_compilers
=
_build_ext
.
show_compilers
class
build_ext
(
_build_ext
.
build_ext
):
description
=
"build C/C++ and Pyrex extensions (compile/link to build directory)"
sep_by
=
_build_ext
.
build_ext
.
sep_by
user_options
=
_build_ext
.
build_ext
.
user_options
boolean_options
=
_build_ext
.
build_ext
.
boolean_options
help_options
=
_build_ext
.
build_ext
.
help_options
# Add the pyrex specific data.
user_options
.
extend
([
(
'pyrex-cplus'
,
None
,
"generate C++ source files"
),
(
'pyrex-create-listing'
,
None
,
"write errors to a listing file"
),
(
'pyrex-include-dirs='
,
None
,
"path to the Pyrex include files"
+
sep_by
),
(
'pyrex-c-in-temp'
,
None
,
"put generated C files in temp directory"
),
(
'pyrex-gen-pxi'
,
None
,
"generate .pxi file for public declarations"
),
])
boolean_options
.
extend
([
'pyrex-cplus'
,
'pyrex-create-listing'
,
'pyrex-c-in-temp'
])
def
initialize_options
(
self
):
_build_ext
.
build_ext
.
initialize_options
(
self
)
self
.
pyrex_cplus
=
0
self
.
pyrex_create_listing
=
0
self
.
pyrex_include_dirs
=
None
self
.
pyrex_c_in_temp
=
0
self
.
pyrex_gen_pxi
=
0
def
finalize_options
(
self
):
def
finalize_options
(
self
):
distutils
.
command
.
build_ext
.
build_ext
.
finalize_options
(
self
)
_build_ext
.
build_ext
.
finalize_options
(
self
)
if
self
.
pyrex_include_dirs
is
None
:
# The following hack should no longer be needed.
self
.
pyrex_include_dirs
=
[]
if
0
:
elif
type
(
self
.
pyrex_include_dirs
)
is
StringType
:
# compiling with mingw32 gets an "initializer not a constant" error
self
.
pyrex_include_dirs
=
\
# doesn't appear to happen with MSVC!
string
.
split
(
self
.
pyrex_include_dirs
,
os
.
pathsep
)
# so if we are compiling with mingw32,
# finalize_options ()
# switch to C++ mode, to avoid the problem
if
self
.
compiler
==
'mingw32'
:
def
build_extensions
(
self
):
self
.
swig_cpp
=
1
# First, sanity-check the 'extensions' list
self
.
check_extensions_list
(
self
.
extensions
)
def
swig_sources
(
self
,
sources
,
extension
=
None
):
for
ext
in
self
.
extensions
:
if
not
self
.
extensions
:
ext
.
sources
=
self
.
pyrex_sources
(
ext
.
sources
,
ext
)
return
self
.
build_extension
(
ext
)
# collect the names of the source (.pyx) files
def
pyrex_sources
(
self
,
sources
,
extension
):
pyx_sources
=
[]
pyx_sources
=
[
source
for
source
in
sources
if
source
.
endswith
(
'.pyx'
)]
"""
other_sources
=
[
source
for
source
in
sources
if
not
source
.
endswith
(
'.pyx'
)]
Walk the list of source files in 'sources', looking for Pyrex
source (.pyx) files. Run Pyrex on all that are found, and return
#suffix = self.swig_cpp and '.cpp' or '.c'
a modified 'sources' list with Pyrex source files replaced by the
suffix
=
'.c'
generated C (or C++) files.
for
pyx
in
pyx_sources
:
"""
# should I raise an exception if it doesn't exist?
if
os
.
path
.
exists
(
pyx
):
if
PyrexError
==
None
:
source
=
pyx
raise
DistutilsPlatformError
,
\
target
=
replace_suffix
(
source
,
suffix
)
(
"Pyrex does not appear to be installed "
if
newer
(
source
,
target
)
or
self
.
force
:
"on platform '%s'"
)
%
os
.
name
self
.
pyrex_compile
(
source
)
new_sources
=
[]
return
[
replace_suffix
(
src
,
suffix
)
for
src
in
pyx_sources
]
+
other_sources
pyrex_sources
=
[]
pyrex_targets
=
{}
def
pyrex_compile
(
self
,
source
):
options
=
CompilationOptions
(
default_options
,
# Setup create_list and cplus from the extension options if
include_path
=
self
.
include_dirs
)
# Pyrex.Distutils.extension.Extension is used, otherwise just
result
=
compile
(
source
,
options
)
# use what was parsed from the command-line or the configuration file.
if
result
.
num_errors
<>
0
:
# cplus will also be set to true is extension.language is equal to
sys
.
exit
(
1
)
# 'C++' or 'c++'.
#try:
# create_listing = self.pyrex_create_listing or \
# extension.pyrex_create_listing
# cplus = self.pyrex_cplus or \
# extension.pyrex_cplus or \
# (extension.language != None and \
# extension.language.lower() == 'c++')
#except AttributeError:
# create_listing = self.pyrex_create_listing
# cplus = self.pyrex_cplus or \
# (extension.language != None and \
# extension.language.lower() == 'c++')
create_listing
=
self
.
pyrex_create_listing
or
\
getattr
(
extension
,
'pyrex_create_listing'
,
0
)
cplus
=
self
.
pyrex_cplus
or
getattr
(
extension
,
'pyrex_cplus'
,
0
)
or
\
(
extension
.
language
and
extension
.
language
.
lower
()
==
'c++'
)
pyrex_gen_pxi
=
self
.
pyrex_gen_pxi
or
getattr
(
extension
,
'pyrex_gen_pxi'
,
0
)
# Set up the include_path for the Pyres compiler:
# 1. Start with the command line option.
# 2. Add in any (unique) paths from the extension
# pyrex_include_dirs (if Pyrex.Distutils.extension is used).
# 3. Add in any (unique) paths from the extension include_dirs
includes
=
self
.
pyrex_include_dirs
try
:
for
i
in
extension
.
pyrex_include_dirs
:
if
not
i
in
includes
:
includes
.
append
(
i
)
except
AttributeError
:
pass
for
i
in
extension
.
include_dirs
:
if
not
i
in
includes
:
includes
.
append
(
i
)
# Set the target_ext to '.c'. Pyrex will change this to '.cpp' if
# needed.
if
cplus
:
target_ext
=
'.cpp'
else
:
target_ext
=
'.c'
# Decide whether to drop the generated C files into the temp dir
# or the source tree.
if
not
self
.
inplace
and
(
self
.
pyrex_c_in_temp
or
getattr
(
extension
,
'pyrex_c_in_temp'
,
0
)):
target_dir
=
os
.
path
.
join
(
self
.
build_temp
,
"pyrex"
)
else
:
target_dir
=
""
for
source
in
sources
:
(
base
,
ext
)
=
os
.
path
.
splitext
(
source
)
if
ext
==
".pyx"
:
# Pyrex source file
new_sources
.
append
(
os
.
path
.
join
(
target_dir
,
base
+
target_ext
))
pyrex_sources
.
append
(
source
)
pyrex_targets
[
source
]
=
new_sources
[
-
1
]
else
:
new_sources
.
append
(
source
)
if
not
pyrex_sources
:
return
new_sources
for
source
in
pyrex_sources
:
target
=
pyrex_targets
[
source
]
source_time
=
os
.
stat
(
source
).
st_mtime
try
:
target_time
=
os
.
stat
(
target
).
st_mtime
newer
=
source_time
>
target_time
except
EnvironmentError
:
newer
=
1
if
newer
:
log
.
info
(
"pyrexing %s to %s"
,
source
,
target
)
self
.
mkpath
(
os
.
path
.
dirname
(
target
))
options
=
CompilationOptions
(
pyrex_default_options
,
use_listing_file
=
create_listing
,
include_path
=
includes
,
output_file
=
target
,
cplus
=
cplus
,
generate_pxi
=
pyrex_gen_pxi
)
result
=
pyrex_compile
(
source
,
options
=
options
)
return
new_sources
# pyrex_sources ()
# class build_ext
Cython/Mac/DarwinSystem.py
View file @
3588f4a6
...
@@ -6,15 +6,20 @@ verbose = 0
...
@@ -6,15 +6,20 @@ verbose = 0
gcc_pendantic
=
True
gcc_pendantic
=
True
gcc_warnings_are_errors
=
True
gcc_warnings_are_errors
=
True
gcc_all_warnings
=
True
gcc_all_warnings
=
True
gcc_optimize
=
False
import
os
import
os
,
sys
from
Pyrex.Utils
import
replace_suffix
from
Pyrex.Utils
import
replace_suffix
from
Pyrex.Compiler.Errors
import
PyrexError
from
Pyrex.Compiler.Errors
import
PyrexError
version_string
=
"%s.%s"
%
sys
.
version_info
[:
2
]
py_include_dirs
=
[
py_include_dirs
=
[
"/Library/Frameworks/Python.framework/
Headers"
"/Library/Frameworks/Python.framework/
Versions/%s/Headers"
%
version_string
]
]
os
.
environ
[
"MACOSX_DEPLOYMENT_TARGET"
]
=
"10.3"
compilers
=
[
"gcc"
,
"g++"
]
compilers
=
[
"gcc"
,
"g++"
]
compiler_options
=
\
compiler_options
=
\
"-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp "
\
"-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp "
\
...
@@ -27,11 +32,16 @@ if gcc_warnings_are_errors:
...
@@ -27,11 +32,16 @@ if gcc_warnings_are_errors:
if
gcc_all_warnings
:
if
gcc_all_warnings
:
compiler_options
.
append
(
"-Wall"
)
compiler_options
.
append
(
"-Wall"
)
compiler_options
.
append
(
"-Wno-unused-function"
)
compiler_options
.
append
(
"-Wno-unused-function"
)
if
gcc_optimize
:
compiler_options
.
append
(
"-O"
)
linkers
=
[
"gcc"
,
"g++"
]
linkers
=
[
"gcc"
,
"g++"
]
linker_options
=
\
linker_options
=
\
"-Wl,-F.,-w -bundle -
framework Python
"
\
"-Wl,-F.,-w -bundle -
undefined dynamic_lookup
"
\
.
split
()
.
split
()
#linker_options = \
# "-Wl,-F.,-w -bundle -framework Python" \
# .split()
class
CCompilerError
(
PyrexError
):
class
CCompilerError
(
PyrexError
):
pass
pass
...
...
Cython/Unix/LinuxSystem.py
View file @
3588f4a6
...
@@ -7,7 +7,7 @@ gcc_pendantic = True
...
@@ -7,7 +7,7 @@ gcc_pendantic = True
gcc_warnings_are_errors
=
True
gcc_warnings_are_errors
=
True
gcc_all_warnings
=
True
gcc_all_warnings
=
True
import
os
import
os
,
sys
from
Pyrex.Utils
import
replace_suffix
from
Pyrex.Utils
import
replace_suffix
from
Pyrex.Compiler.Errors
import
PyrexError
from
Pyrex.Compiler.Errors
import
PyrexError
...
...
Cython/Utils.py
View file @
3588f4a6
...
@@ -14,3 +14,21 @@ def open_new_file(path):
...
@@ -14,3 +14,21 @@ def open_new_file(path):
# preserve metadata on the Mac.
# preserve metadata on the Mac.
return
open
(
path
,
"w+"
)
return
open
(
path
,
"w+"
)
def
castrate_file
(
path
,
st
):
# Remove junk contents from an output file after a
# failed compilation, but preserve metadata on Mac.
# Also sets access and modification times back to
# those specified by st (a stat struct).
try
:
f
=
open
(
path
,
"r+"
)
except
EnvironmentError
:
pass
else
:
#st = os.stat(path)
f
.
seek
(
0
,
0
)
f
.
truncate
()
f
.
write
(
"#error Do not use this file, it is the result of a failed Pyrex compilation.
\
n
"
)
f
.
close
()
if
st
:
os
.
utime
(
path
,
(
st
.
st_atime
,
st
.
st_mtime
))
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