Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
b016353f
Commit
b016353f
authored
Oct 04, 2008
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More pure cython mode stuff.
parent
3bcf8140
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
295 additions
and
37 deletions
+295
-37
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+6
-0
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+37
-6
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+60
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+26
-25
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+16
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+5
-0
Cython/Shadow.py
Cython/Shadow.py
+145
-5
No files found.
Cython/Compiler/CythonScope.py
View file @
b016353f
...
...
@@ -15,6 +15,12 @@ class CythonScope(ModuleScope):
pos
=
None
,
defining
=
1
,
cname
=
'<error>'
)
def
lookup_type
(
self
,
name
):
# This function should go away when types are all first-level objects.
type
=
parse_basic_type
(
name
)
if
type
:
return
type
def
create_cython_scope
(
context
):
return
CythonScope
(
context
)
Cython/Compiler/ExprNodes.py
View file @
b016353f
...
...
@@ -563,6 +563,9 @@ class ExprNode(Node):
# a constant, local var, C global var, struct member
# reference, or temporary.
return
self
.
result_in_temp
()
def
as_cython_attribute
(
self
):
return
None
class
AtomicExprNode
(
ExprNode
):
...
...
@@ -715,6 +718,9 @@ class StringNode(ConstNode):
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
def
analyse_as_type
(
self
,
env
):
type
=
PyrexTypes
.
parse_basic_type
(
self
.
value
)
if
type
is
not
None
:
return
type
from
TreeFragment
import
TreeFragment
pos
=
(
self
.
pos
[
0
],
self
.
pos
[
1
],
self
.
pos
[
2
]
-
7
)
declaration
=
TreeFragment
(
u"sizeof(%s)"
%
self
.
value
,
name
=
pos
[
0
].
filename
,
initial_pos
=
pos
)
...
...
@@ -849,7 +855,8 @@ class NameNode(AtomicExprNode):
# entry Entry Symbol table entry
# interned_cname string
is_name
=
1
is_name
=
True
is_cython_module
=
False
skip_assignment_decref
=
False
entry
=
None
...
...
@@ -895,8 +902,9 @@ class NameNode(AtomicExprNode):
return
None
def
analyse_as_type
(
self
,
env
):
if
self
.
name
in
PyrexTypes
.
rank_to_type_name
:
return
PyrexTypes
.
simple_c_type
(
1
,
0
,
self
.
name
)
type
=
PyrexTypes
.
parse_basic_type
(
self
.
name
)
if
type
:
return
type
entry
=
self
.
entry
if
not
entry
:
entry
=
env
.
lookup
(
self
.
name
)
...
...
@@ -1808,6 +1816,21 @@ class SimpleCallNode(CallNode):
return
function
(
*
args
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_as_type
(
self
,
env
):
attr
=
self
.
function
.
as_cython_attribute
()
if
attr
==
'pointer'
:
if
len
(
self
.
args
)
!=
1
:
error
(
self
.
args
.
pos
,
"only one type allowed."
)
else
:
type
=
self
.
args
[
0
].
analyse_as_type
(
env
)
if
not
type
:
error
(
self
.
args
[
0
].
pos
,
"Unknown type"
)
else
:
return
PyrexTypes
.
CPtrType
(
type
)
def
explicit_args_kwds
(
self
):
return
self
.
args
,
None
def
analyse_types
(
self
,
env
):
function
=
self
.
function
...
...
@@ -2037,6 +2060,12 @@ class GeneralCallNode(CallNode):
return
function
(
*
positional_args
,
**
keyword_args
)
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
explicit_args_kwds
(
self
):
if
self
.
starstar_arg
or
not
isinstance
(
self
.
positional_args
,
TupleNode
):
raise
PostParseError
(
self
.
pos
,
'Compile-time keyword arguments must be explicit.'
)
return
self
.
positional_args
.
args
,
self
.
keyword_args
def
analyse_types
(
self
,
env
):
self
.
function
.
analyse_types
(
env
)
...
...
@@ -2140,6 +2169,10 @@ class AttributeNode(ExprNode):
is_called
=
0
needs_none_check
=
True
def
as_cython_attribute
(
self
):
if
isinstance
(
self
.
obj
,
NameNode
)
and
self
.
obj
.
is_cython_module
:
return
self
.
attribute
def
coerce_to
(
self
,
dst_type
,
env
):
# If coercing to a generic pyobject and this is a cpdef function
# we can create the corresponding attribute
...
...
@@ -2217,9 +2250,7 @@ class AttributeNode(ExprNode):
def
analyse_as_type
(
self
,
env
):
module_scope
=
self
.
obj
.
analyse_as_module
(
env
)
if
module_scope
:
entry
=
module_scope
.
lookup_here
(
self
.
attribute
)
if
entry
and
entry
.
is_type
:
return
entry
.
type
return
module_scope
.
lookup_type
(
self
.
attribute
)
return
None
def
analyse_as_extension_type
(
self
,
env
):
...
...
Cython/Compiler/Nodes.py
View file @
b016353f
...
...
@@ -2597,9 +2597,68 @@ class SingleAssignmentNode(AssignmentNode):
child_attrs
=
[
"lhs"
,
"rhs"
]
first
=
False
declaration_only
=
False
def
analyse_declarations
(
self
,
env
):
self
.
lhs
.
analyse_target_declaration
(
env
)
import
ExprNodes
# handle declarations of the form x = cython.foo()
if
isinstance
(
self
.
rhs
,
ExprNodes
.
CallNode
):
func_name
=
self
.
rhs
.
function
.
as_cython_attribute
()
if
func_name
:
args
,
kwds
=
self
.
rhs
.
explicit_args_kwds
()
if
func_name
in
[
'declare'
,
'typedef'
]:
self
.
declaration_only
=
True
if
len
(
args
)
!=
1
or
kwds
is
not
None
:
error
(
rhs
.
pos
,
"Can only declare one type at a time."
)
return
type
=
args
[
0
].
analyse_as_type
(
env
)
if
type
is
None
:
error
(
args
[
0
].
pos
,
"Unknown type"
)
return
lhs
=
self
.
lhs
if
func_name
==
'declare'
:
if
isinstance
(
lhs
,
ExprNodes
.
NameNode
):
vars
=
[(
lhs
.
name
,
lhs
.
pos
)]
elif
isinstance
(
lhs
,
ExprNodes
.
TupleNode
):
vars
=
[(
var
.
name
,
var
.
pos
)
for
var
in
lhs
.
args
]
else
:
error
(
lhs
.
pos
,
"Invalid declaration"
)
return
for
var
,
pos
in
vars
:
env
.
declare_var
(
var
,
type
,
pos
,
is_cdef
=
True
)
else
:
if
not
isinstance
(
lhs
,
ExprNodes
.
NameNode
):
error
(
lhs
.
pos
,
"Invalid declaration."
)
env
.
declare_typedef
(
lhs
.
name
,
type
,
self
.
pos
,
'private'
)
elif
func_name
in
[
'struct'
,
'union'
]:
self
.
declaration_only
=
True
if
len
(
args
)
>
0
or
kwds
is
None
:
error
(
rhs
.
pos
,
"Struct or union members must be given by name."
)
return
members
=
[]
for
member
,
type_node
in
kwds
.
key_value_pairs
:
type
=
type_node
.
analyse_as_type
(
env
)
if
type
is
None
:
error
(
type_node
.
pos
,
"Unknown type"
)
else
:
members
.
append
((
member
.
value
,
type
,
member
.
pos
))
if
len
(
members
)
<
len
(
kwds
.
key_value_pairs
):
return
if
not
isinstance
(
self
.
lhs
,
ExprNodes
.
NameNode
):
error
(
self
.
lhs
.
pos
,
"Invalid declaration."
)
name
=
self
.
lhs
.
name
scope
=
StructOrUnionScope
(
name
)
env
.
declare_struct_or_union
(
name
,
func_name
,
scope
,
False
,
self
.
rhs
.
pos
)
for
member
,
type
,
pos
in
members
:
scope
.
declare_var
(
member
,
type
,
pos
)
if
self
.
declaration_only
:
return
else
:
self
.
lhs
.
analyse_target_declaration
(
env
)
def
analyse_types
(
self
,
env
,
use_temp
=
0
):
self
.
rhs
.
analyse_types
(
env
)
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
b016353f
...
...
@@ -313,10 +313,18 @@ class InterpretCompilerDirectives(CythonTransform):
def
visit_SingleAssignmentNode
(
self
,
node
):
if
(
isinstance
(
node
.
rhs
,
ImportNode
)
and
node
.
rhs
.
module_name
.
value
==
u'cython'
):
self
.
cython_module_names
.
add
(
node
.
lhs
.
name
)
node
=
CImportStatNode
(
node
.
pos
,
module_name
=
u'cython'
,
as_name
=
node
.
lhs
.
name
)
self
.
visit_CImportStatNode
(
node
)
else
:
self
.
visitchildren
(
node
)
return
node
return
node
def
visit_NameNode
(
self
,
node
):
if
node
.
name
in
self
.
cython_module_names
:
node
.
is_cython_module
=
True
return
node
def
visit_Node
(
self
,
node
):
self
.
visitchildren
(
node
)
...
...
@@ -339,15 +347,7 @@ class InterpretCompilerDirectives(CythonTransform):
if
optname
:
optiontype
=
Options
.
option_types
.
get
(
optname
)
if
optiontype
:
if
isinstance
(
node
,
SimpleCallNode
):
args
=
node
.
args
kwds
=
None
else
:
if
node
.
starstar_arg
or
not
isinstance
(
node
.
positional_args
,
TupleNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
'Compile-time keyword arguments must be explicit.'
%
optname
)
args
=
node
.
positional_args
.
args
kwds
=
node
.
keyword_args
args
,
kwds
=
node
.
explicit_args_kwds
()
if
optiontype
is
bool
:
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
...
...
@@ -516,7 +516,7 @@ property NAME:
node
.
analyse_declarations
(
self
.
env_stack
[
-
1
])
self
.
visitchildren
(
node
)
return
node
def
visit_FuncDefNode
(
self
,
node
):
lenv
=
node
.
create_local_scope
(
self
.
env_stack
[
-
1
])
node
.
body
.
analyse_control_flow
(
lenv
)
# this will be totally refactored
...
...
@@ -686,24 +686,20 @@ class EnvTransform(CythonTransform):
class
TransformBuiltinMethods
(
EnvTransform
):
def
cython_attribute
(
self
,
node
):
if
(
isinstance
(
node
,
AttributeNode
)
and
isinstance
(
node
.
obj
,
NameNode
)
and
node
.
obj
.
name
in
self
.
cython_module_names
):
return
node
.
attribute
def
visit_SingleAssignmentNode
(
self
,
node
):
if
node
.
declaration_only
:
return
None
else
:
self
.
visitchildren
(
node
)
return
node
def
visit_ModuleNode
(
self
,
node
):
self
.
cython_module_names
=
node
.
cython_module_names
self
.
visitchildren
(
node
)
return
node
def
visit_AttributeNode
(
self
,
node
):
attribute
=
self
.
cython_attribute
(
node
)
attribute
=
node
.
as_cython_attribute
(
)
if
attribute
:
if
attribute
==
u'compiled'
:
node
=
BoolNode
(
node
.
pos
,
value
=
True
)
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython attribute"
%
function
)
error
(
node
.
pos
,
u"'%s' not a valid cython attribute"
%
attribute
)
return
node
def
visit_SimpleCallNode
(
self
,
node
):
...
...
@@ -719,7 +715,7 @@ class TransformBuiltinMethods(EnvTransform):
return
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
items
)
# cython.foo
function
=
self
.
cython_attribute
(
node
.
function
)
function
=
node
.
function
.
as_cython_attribute
(
)
if
function
:
if
function
==
u'cast'
:
if
len
(
node
.
args
)
!=
2
:
...
...
@@ -739,6 +735,11 @@ class TransformBuiltinMethods(EnvTransform):
node
=
SizeofTypeNode
(
node
.
function
.
pos
,
arg_type
=
type
)
else
:
node
=
SizeofVarNode
(
node
.
function
.
pos
,
operand
=
node
.
args
[
0
])
elif
function
==
'address'
:
if
len
(
node
.
args
)
!=
1
:
error
(
node
.
function
.
pos
,
u"sizeof takes exactly one argument"
%
function
)
else
:
node
=
AmpersandNode
(
node
.
function
.
pos
,
operand
=
node
.
args
[
0
])
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython language construct"
%
function
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
b016353f
...
...
@@ -1182,6 +1182,7 @@ modifiers_and_name_to_type = {
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
1
,
0
,
"long"
):
c_long_type
,
(
1
,
0
,
"longlong"
):
c_longlong_type
,
(
1
,
0
,
"bint"
):
c_bint_type
,
}
...
...
@@ -1205,6 +1206,21 @@ def simple_c_type(signed, longness, name):
# Find type descriptor for simple type given name and modifiers.
# Returns None if arguments don't make sense.
return
modifiers_and_name_to_type
.
get
((
signed
,
longness
,
name
))
def
parse_basic_type
(
name
):
base
=
None
if
name
.
startswith
(
'p_'
):
base
=
parse_basic_type
(
name
[
2
:])
elif
name
.
startswith
(
'p'
):
base
=
parse_basic_type
(
name
[
1
:])
elif
name
.
endswith
(
'*'
):
base
=
parse_basic_type
(
name
[:
-
1
])
if
base
:
return
CPtrType
(
base
)
elif
name
.
startswith
(
'u'
):
return
simple_c_type
(
0
,
0
,
name
[
1
:])
else
:
return
simple_c_type
(
1
,
0
,
name
)
def
c_array_type
(
base_type
,
size
):
# Construct a C array type.
...
...
Cython/Compiler/Symtab.py
View file @
b016353f
...
...
@@ -502,6 +502,11 @@ class Scope:
if not entry:
entry = self.declare_var(name, py_object_type, None)
return entry
def lookup_type(self, name):
entry = self.lookup(name)
if entry and entry.is_type:
return entry.type
def add_string_const(self, value, identifier = False):
# Add an entry for a string constant.
...
...
Cython/Shadow.py
View file @
b016353f
...
...
@@ -6,17 +6,157 @@ def empty_decorator(x):
def
locals
(
**
arg_types
):
return
empty_decorator
# Emulated language constructs
def
cast
(
type
,
arg
):
# can/should we emulate anything here?
return
arg
if
callable
(
type
):
return
type
(
arg
)
else
:
return
arg
def
sizeof
(
arg
):
# can/should we emulate anything here?
return
1
def
address
(
arg
):
return
pointer
(
type
(
arg
))([
arg
])
def
declare
(
type
):
if
callable
(
type
):
return
type
()
else
:
return
None
# Emulated types
class
CythonType
(
object
):
def
_pointer
(
self
,
n
=
1
):
for
i
in
range
(
n
):
self
=
pointer
(
self
)
return
self
def
__getitem__
(
self
,
ix
):
return
array
(
self
,
ix
)
class
PointerType
(
CythonType
):
def
__init__
(
self
,
value
=
None
):
if
isinstance
(
value
,
ArrayType
):
self
.
_items
=
[
cast
(
self
.
_basetype
,
a
)
for
a
in
value
.
_items
]
elif
isinstance
(
value
,
list
):
self
.
_items
=
[
cast
(
self
.
_basetype
,
a
)
for
a
in
value
]
elif
value
is
None
:
self
.
_items
=
[]
else
:
raise
ValueError
def
__getitem__
(
self
,
ix
):
if
ix
<
0
:
raise
IndexError
,
"negative indexing not allowed in C"
return
self
.
_items
[
ix
]
def
__setitem__
(
self
,
ix
,
value
):
if
ix
<
0
:
raise
IndexError
,
"negative indexing not allowed in C"
self
.
_items
[
ix
]
=
cast
(
self
.
_basetype
,
value
)
class
ArrayType
(
PointerType
):
def
__init__
(
self
):
self
.
_items
=
[
None
]
*
self
.
_n
class
StructType
(
CythonType
):
def
__init__
(
self
,
**
data
):
for
key
,
value
in
data
.
items
():
setattr
(
self
,
key
,
value
)
def
__setattr__
(
self
,
key
,
value
):
if
key
in
self
.
_members
:
self
.
__dict__
[
key
]
=
cast
(
self
.
_members
[
key
],
value
)
else
:
raise
AttributeError
,
"Struct has no member '%s'"
%
key
class
UnionType
(
CythonType
):
def
__init__
(
self
,
**
data
):
if
len
(
data
)
>
0
:
raise
AttributeError
,
"Union can only store one field at a time."
for
key
,
value
in
data
.
items
():
setattr
(
self
,
key
,
value
)
def
__setattr__
(
self
,
key
,
value
):
if
key
in
'__dict__'
:
CythonType
.
__setattr__
(
self
,
key
,
value
)
elif
key
in
self
.
_members
:
self
.
__dict__
=
{
key
:
cast
(
self
.
_members
[
key
],
value
)}
else
:
raise
AttributeError
,
"Union has no member '%s'"
%
key
def
pointer
(
basetype
):
class
PointerInstance
(
PointerType
):
_basetype
=
basetype
return
PointerInstance
def
array
(
basetype
,
n
):
class
ArrayInstance
(
ArrayType
):
_basetype
=
basetype
_n
=
n
return
ArrayInstance
def
struct
(
**
members
):
class
StructInstance
(
StructType
):
_members
=
members
for
key
in
members
.
keys
():
setattr
(
StructInstance
,
key
,
None
)
return
StructInstance
def
union
(
**
members
):
class
UnionInstance
(
UnionType
):
_members
=
members
for
key
in
members
.
keys
():
setattr
(
UnionInstance
,
key
,
None
)
return
UnionInstance
class
typedef
(
CythonType
):
def
__init__
(
self
,
type
):
self
.
_basetype
=
type
def
__call__
(
self
,
value
=
None
):
if
value
is
not
None
:
value
=
cast
(
self
.
_basetype
,
value
)
return
value
py_int
=
int
py_long
=
long
py_float
=
float
# They just have to exist...
int
=
long
=
char
=
bint
=
uint
=
ulong
=
longlong
=
ulonglong
=
Py_ssize_t
=
float
=
double
=
None
# Predefined types
int_types
=
[
'char'
,
'short'
,
'int'
,
'long'
,
'longlong'
,
'Py_ssize_t'
]
float_types
=
[
'double'
,
'float'
]
other_types
=
[
'bint'
,
'Py_ssize_t'
,
'void'
]
gs
=
globals
()
for
name
in
int_types
:
gs
[
name
]
=
typedef
(
py_int
)
gs
[
'u'
+
name
]
=
typedef
(
py_int
)
double
=
float
=
typedef
(
py_float
)
bint
=
typedef
(
bool
)
void
=
typedef
(
int
)
for
t
in
int_types
+
float_types
+
other_types
:
for
i
in
range
(
1
,
4
):
gs
[
"%s_%s"
%
(
'p'
*
i
,
t
)]
=
globals
()[
t
].
_pointer
(
i
)
void
=
typedef
(
None
)
NULL
=
None
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment