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
Boxiang Sun
cython
Commits
d1a536dd
Commit
d1a536dd
authored
Sep 14, 2012
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rudimentary const support.
parent
284a2423
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
120 additions
and
6 deletions
+120
-6
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+13
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+16
-0
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+12
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+57
-5
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+18
-0
Cython/Compiler/TypeInference.py
Cython/Compiler/TypeInference.py
+4
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
d1a536dd
...
...
@@ -618,6 +618,9 @@ class ExprNode(Node):
if
dst_type
.
is_reference
and
not
src_type
.
is_reference
:
dst_type
=
dst_type
.
ref_base_type
if
src_type
.
is_const
:
src_type
=
src_type
.
const_base_type
if
src_type
.
is_fused
or
dst_type
.
is_fused
:
# See if we are coercing a fused function to a pointer to a
# specialized function
...
...
@@ -1511,6 +1514,10 @@ class NameNode(AtomicExprNode):
self
.
entry
=
self
.
entry
.
as_variable
self
.
type
=
self
.
entry
.
type
if
self
.
type
.
is_const
:
error
(
self
.
pos
,
"Assignment to const '%s'"
%
self
.
name
)
if
self
.
type
.
is_reference
:
error
(
self
.
pos
,
"Assignment to reference '%s'"
%
self
.
name
)
if
not
self
.
is_lvalue
():
error
(
self
.
pos
,
"Assignment to non-lvalue '%s'"
%
self
.
name
)
...
...
@@ -2233,6 +2240,8 @@ class NextNode(AtomicExprNode):
item_type
=
env
.
lookup_operator_for_types
(
self
.
pos
,
"*"
,
[
iterator_type
]).
type
.
return_type
if
item_type
.
is_reference
:
item_type
=
item_type
.
ref_base_type
if
item_type
.
is_const
:
item_type
=
item_type
.
const_base_type
return
item_type
else
:
# Avoid duplication of complicated logic.
...
...
@@ -2598,6 +2607,8 @@ class IndexNode(ExprNode):
def
analyse_target_types
(
self
,
env
):
self
.
analyse_base_and_index_types
(
env
,
setting
=
1
)
if
self
.
type
.
is_const
:
error
(
self
.
pos
,
"Assignment to const dereference"
)
if
not
self
.
is_lvalue
():
error
(
self
.
pos
,
"Assignment to non-lvalue of type '%s'"
%
self
.
type
)
...
...
@@ -4453,6 +4464,8 @@ class AttributeNode(ExprNode):
def
analyse_target_types
(
self
,
env
):
self
.
analyse_types
(
env
,
target
=
1
)
if
self
.
type
.
is_const
:
error
(
self
.
pos
,
"Assignment to const attribute '%s'"
%
self
.
attribute
)
if
not
self
.
is_lvalue
():
error
(
self
.
pos
,
"Assignment to non-lvalue of type '%s'"
%
self
.
type
)
...
...
Cython/Compiler/Nodes.py
View file @
d1a536dd
...
...
@@ -1048,6 +1048,19 @@ class FusedTypeNode(CBaseTypeNode):
return
PyrexTypes
.
FusedType
(
types
,
name
=
self
.
name
)
class
CConstTypeNode
(
CBaseTypeNode
):
# base_type CBaseTypeNode
child_attrs
=
[
"base_type"
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
if
base
.
is_pyobject
:
error
(
self
.
pos
,
"Const base type cannot be a Python object"
)
return
PyrexTypes
.
c_const_type
(
base
)
class
CVarDefNode
(
StatNode
):
# C variable definition or forward/extern function declaration.
#
...
...
@@ -1941,6 +1954,7 @@ class CFuncDefNode(FuncDefNode):
# overridable whether or not this is a cpdef function
# inline_in_pxd whether this is an inline function in a pxd file
# template_declaration String or None Used for c++ class methods
# is_const_method whether this is a const method
child_attrs
=
[
"base_type"
,
"declarator"
,
"body"
,
"py_func"
]
...
...
@@ -1950,6 +1964,7 @@ class CFuncDefNode(FuncDefNode):
directive_returns
=
None
override
=
None
template_declaration
=
None
is_const_method
=
False
def
unqualified_name
(
self
):
return
self
.
entry
.
name
...
...
@@ -2021,6 +2036,7 @@ class CFuncDefNode(FuncDefNode):
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
type
.
is_const_method
=
self
.
is_const_method
self
.
entry
=
env
.
declare_cfunction
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
...
...
Cython/Compiler/Parsing.py
View file @
d1a536dd
...
...
@@ -1982,6 +1982,11 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
pos
=
s
.
position
()
if
not
s
.
sy
==
'IDENT'
:
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
if
s
.
systring
==
'const'
:
s
.
next
()
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
return
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
)
if
looking_at_base_type
(
s
):
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
is_basic
=
1
...
...
@@ -2703,6 +2708,11 @@ def p_c_func_or_var_declaration(s, pos, ctx):
declarator
=
p_c_declarator
(
s
,
ctx
,
cmethod_flag
=
cmethod_flag
,
assignable
=
1
,
nonempty
=
1
)
declarator
.
overridable
=
ctx
.
overridable
if
s
.
sy
==
'IDENT'
and
s
.
systring
==
'const'
and
ctx
.
level
==
'cpp_class'
:
s
.
next
()
is_const_method
=
1
else
:
is_const_method
=
0
if
s
.
sy
==
':'
:
if
ctx
.
level
not
in
(
'module'
,
'c_class'
,
'module_pxd'
,
'c_class_pxd'
,
'cpp_class'
)
and
not
ctx
.
templates
:
s
.
error
(
"C function definition not allowed here"
)
...
...
@@ -2715,7 +2725,8 @@ def p_c_func_or_var_declaration(s, pos, ctx):
doc
=
doc
,
modifiers
=
modifiers
,
api
=
ctx
.
api
,
overridable
=
ctx
.
overridable
)
overridable
=
ctx
.
overridable
,
is_const_method
=
is_const_method
)
else
:
#if api:
# s.error("'api' not allowed with variable declaration")
...
...
Cython/Compiler/PyrexTypes.py
View file @
d1a536dd
...
...
@@ -138,6 +138,7 @@ class PyrexType(BaseType):
# is_ptr boolean Is a C pointer type
# is_null_ptr boolean Is the type of NULL
# is_reference boolean Is a C reference type
# is_const boolean Is a C const type.
# is_cfunction boolean Is a C function type
# is_struct_or_union boolean Is a C struct or union type
# is_struct boolean Is a C struct type
...
...
@@ -192,6 +193,7 @@ class PyrexType(BaseType):
is_ptr
=
0
is_null_ptr
=
0
is_reference
=
0
is_const
=
0
is_cfunction
=
0
is_struct_or_union
=
0
is_cpp_class
=
0
...
...
@@ -1151,6 +1153,42 @@ class CType(PyrexType):
return
0
class
CConstType
(
BaseType
):
is_const
=
1
def
__init__
(
self
,
const_base_type
):
self
.
const_base_type
=
const_base_type
if
const_base_type
.
has_attributes
and
const_base_type
.
scope
is
not
None
:
import
Symtab
self
.
scope
=
Symtab
.
CConstScope
(
const_base_type
.
scope
)
def
__repr__
(
self
):
return
"<CConstType %s>"
%
repr
(
self
.
const_base_type
)
def
__str__
(
self
):
return
self
.
declaration_code
(
""
,
for_display
=
1
)
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
return
self
.
const_base_type
.
declaration_code
(
"const %s"
%
entity_code
,
for_display
,
dll_linkage
,
pyrex
)
def
specialize
(
self
,
values
):
base_type
=
self
.
const_base_type
.
specialize
(
values
)
if
base_type
==
self
.
const_base_type
:
return
self
else
:
return
ConstType
(
base_type
)
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
const_base_type
.
create_to_py_utility_code
(
env
):
self
.
to_py_function
=
self
.
const_base_type
.
to_py_function
return
True
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
const_base_type
,
name
)
class
FusedType
(
CType
):
"""
Represents a Fused Type. All it needs to do is keep track of the types
...
...
@@ -2281,6 +2319,8 @@ class CPtrType(CPointerBaseType):
return
1
if
other_type
.
is_null_ptr
:
return
1
if
self
.
base_type
.
is_const
:
self
=
CPtrType
(
self
.
base_type
.
const_base_type
)
if
self
.
base_type
.
is_cfunction
:
if
other_type
.
is_ptr
:
other_type
=
other_type
.
base_type
.
resolve
()
...
...
@@ -2328,9 +2368,6 @@ class CReferenceType(BaseType):
def
__str__
(
self
):
return
"%s &"
%
self
.
ref_base_type
def
as_argument_type
(
self
):
return
self
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
#print "CReferenceType.declaration_code: pointer to", self.base_type ###
...
...
@@ -2364,11 +2401,13 @@ class CFuncType(CType):
# C function
# is_strict_signature boolean function refuses to accept coerced arguments
# (used for optimisation overrides)
# is_const_method boolean
is_cfunction
=
1
original_sig
=
None
cached_specialized_types
=
None
from_fused
=
False
is_const_method
=
False
subtypes
=
[
'return_type'
,
'args'
]
...
...
@@ -2575,13 +2614,19 @@ class CFuncType(CType):
if
(
not
entity_code
and
cc
)
or
entity_code
.
startswith
(
"*"
):
entity_code
=
"(%s%s)"
%
(
cc
,
entity_code
)
cc
=
""
if
self
.
is_const_method
:
trailer
+=
" const"
return
self
.
return_type
.
declaration_code
(
"%s%s(%s)%s"
%
(
cc
,
entity_code
,
arg_decl_code
,
trailer
),
for_display
,
dll_linkage
,
pyrex
)
def
function_header_code
(
self
,
func_name
,
arg_code
):
return
"%s%s(%s)"
%
(
self
.
calling_convention_prefix
(),
func_name
,
arg_code
)
if
self
.
is_const_method
:
trailer
=
" const"
else
:
trailer
=
""
return
"%s%s(%s)%s"
%
(
self
.
calling_convention_prefix
(),
func_name
,
arg_code
,
trailer
)
def
signature_string
(
self
):
s
=
self
.
declaration_code
(
""
)
...
...
@@ -3802,6 +3847,13 @@ def c_ref_type(base_type):
else
:
return
CReferenceType
(
base_type
)
def
c_const_type
(
base_type
):
# Construct a C const type.
if
base_type
is
error_type
:
return
error_type
else
:
return
CConstType
(
base_type
)
def
same_type
(
type1
,
type2
):
return
type1
.
same_as
(
type2
)
...
...
Cython/Compiler/Symtab.py
View file @
d1a536dd
...
...
@@ -2,6 +2,7 @@
# Symbol Table
#
import
copy
import
re
from
Errors
import
warning
,
error
,
InternalError
from
StringEncoding
import
EncodedString
...
...
@@ -2151,3 +2152,20 @@ class PropertyScope(Scope):
error
(
pos
,
"Only __get__, __set__ and __del__ methods allowed "
"in a property declaration"
)
return
None
class
CConstScope
(
Scope
):
def
__init__
(
self
,
const_base_type_scope
):
Scope
.
__init__
(
self
,
'const_'
+
const_base_type_scope
.
name
,
const_base_type_scope
.
outer_scope
,
const_base_type_scope
.
parent_scope
)
self
.
const_base_type_scope
=
const_base_type_scope
def
lookup_here
(
self
,
name
):
entry
=
self
.
const_base_type_scope
.
lookup_here
(
name
)
if
entry
is
not
None
:
entry
=
copy
.
copy
(
entry
)
entry
.
type
=
PyrexTypes
.
c_const_type
(
entry
.
type
)
return
entry
Cython/Compiler/TypeInference.py
View file @
d1a536dd
...
...
@@ -442,10 +442,14 @@ def aggressive_spanning_type(types, might_overflow):
result_type
=
reduce
(
find_spanning_type
,
types
)
if
result_type
.
is_reference
:
result_type
=
result_type
.
ref_base_type
if
result_type
.
is_const
:
result_type
=
result_type
.
const_base_type
return
result_type
def
safe_spanning_type
(
types
,
might_overflow
):
result_type
=
reduce
(
find_spanning_type
,
types
)
if
result_type
.
is_const
:
result_type
=
result_type
.
const_base_type
if
result_type
.
is_reference
:
result_type
=
result_type
.
ref_base_type
if
result_type
.
is_pyobject
:
...
...
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