Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
ead141e6
Commit
ead141e6
authored
Oct 03, 2014
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CTuple type inference, unpacking.
parent
e5973b71
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
23 deletions
+96
-23
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+48
-16
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+2
-2
tests/run/ctuple.pyx
tests/run/ctuple.pyx
+46
-5
No files found.
Cython/Compiler/ExprNodes.py
View file @
ead141e6
...
...
@@ -6073,6 +6073,10 @@ class SequenceNode(ExprNode):
', '
.
join
([
arg
.
py_result
()
for
arg
in
self
.
args
]),
code
.
error_goto_if_null
(
target
,
self
.
pos
)))
code
.
put_gotref
(
target
)
elif
self
.
type
.
is_ctuple
:
for
i
,
arg
in
enumerate
(
self
.
args
):
code
.
putln
(
"%s.f%s = %s;"
%
(
target
,
i
,
arg
.
result
()))
else
:
# build the tuple/list step by step, potentially multiplying it as we go
if
self
.
type
is
Builtin
.
list_type
:
...
...
@@ -6446,27 +6450,55 @@ class TupleNode(SequenceNode):
gil_message
=
"Constructing Python tuple"
def
infer_type
(
self
,
env
):
if
self
.
mult_factor
:
return
tuple_type
arg_types
=
[
arg
.
infer_type
(
env
)
for
arg
in
self
.
args
]
if
any
(
type
.
is_pyobject
or
type
.
is_unspecified
for
type
in
arg_types
):
return
tuple_type
else
:
type
=
PyrexTypes
.
c_tuple_type
(
arg_types
)
env
.
declare_tuple_type
(
self
.
pos
,
type
)
return
type
def
analyse_types
(
self
,
env
,
skip_children
=
False
):
if
len
(
self
.
args
)
==
0
:
node
=
self
node
.
is_temp
=
Fals
e
node
.
is_literal
=
True
self
.
is_temp
=
False
self
.
is_literal
=
Tru
e
return
self
else
:
node
=
SequenceNode
.
analyse_types
(
self
,
env
,
skip_children
)
for
child
in
node
.
args
:
if
not
child
.
is_literal
:
break
if
not
skip_children
:
self
.
args
=
[
arg
.
analyse_types
(
env
)
for
arg
in
self
.
args
]
if
not
self
.
mult_factor
and
not
any
(
arg
.
type
.
is_pyobject
for
arg
in
self
.
args
):
self
.
type
=
PyrexTypes
.
c_tuple_type
(
arg
.
type
for
arg
in
self
.
args
)
env
.
declare_tuple_type
(
self
.
pos
,
self
.
type
)
self
.
is_temp
=
1
return
self
else
:
if
not
node
.
mult_factor
or
node
.
mult_factor
.
is_literal
and
\
isinstance
(
node
.
mult_factor
.
constant_result
,
(
int
,
long
))
:
node
.
is_temp
=
False
node
.
is_literal
=
True
node
=
SequenceNode
.
analyse_types
(
self
,
env
,
skip_children
=
True
)
for
child
in
node
.
args
:
if
not
child
.
is_literal
:
break
else
:
if
not
node
.
mult_factor
.
type
.
is_pyobject
:
node
.
mult_factor
=
node
.
mult_factor
.
coerce_to_pyobject
(
env
)
node
.
is_temp
=
True
node
.
is_partly_literal
=
True
return
node
if
not
node
.
mult_factor
or
node
.
mult_factor
.
is_literal
and
\
isinstance
(
node
.
mult_factor
.
constant_result
,
(
int
,
long
)):
node
.
is_temp
=
False
node
.
is_literal
=
True
else
:
if
not
node
.
mult_factor
.
type
.
is_pyobject
:
node
.
mult_factor
=
node
.
mult_factor
.
coerce_to_pyobject
(
env
)
node
.
is_temp
=
True
node
.
is_partly_literal
=
True
return
node
def
coerce_to
(
self
,
dst_type
,
env
):
if
self
.
type
.
is_ctuple
and
dst_type
.
is_ctuple
and
self
.
type
.
size
==
dst_type
.
size
:
if
self
.
type
==
dst_type
:
return
self
coerced_args
=
[
arg
.
coerce_to
(
type
,
env
)
for
arg
,
type
in
zip
(
self
.
args
,
dst_type
.
components
)]
return
TupleNode
(
self
.
pos
,
args
=
coerced_args
,
type
=
dst_type
,
is_temp
=
1
)
else
:
return
SequenceNode
.
coerce_to
(
self
,
dst_type
,
env
)
def
is_simple
(
self
):
# either temp or constant => always simple
...
...
Cython/Compiler/PyrexTypes.py
View file @
ead141e6
...
...
@@ -3393,8 +3393,8 @@ def c_tuple_type(components):
.
replace
(
'['
,
'_sbra'
)
.
replace
(
']'
,
'_sket'
)
for
c
in
components
)
c_tuple_types
[
components
]
=
tuple_type
return
CTupleType
(
cname
,
components
)
tuple_type
=
c_tuple_types
[
components
]
=
CTupleType
(
cname
,
components
)
return
tuple_type
class
UnspecifiedType
(
PyrexType
):
...
...
tests/run/ctuple.pyx
View file @
ead141e6
import
cython
def
simple_convert
(
*
o
):
"""
>>> simple_convert(1, 2)
...
...
@@ -47,6 +49,22 @@ def unpacking_with_side_effect((int, double) xy):
x
,
y
=
side_effect
(
xy
)
return
x
,
y
def
packing_tuple
(
int
x
,
double
y
):
"""
>>> packing_tuple(1, 2)
(1, 2.0)
"""
cdef
(
int
,
double
)
xy
=
(
x
,
y
)
return
xy
def
coerce_packing_tuple
(
int
x
,
int
y
):
cdef
(
int
,
double
)
xy
=
(
x
,
y
)
"""
>>> coerce_packing_tuple(1, 2)
(1, 2.0)
"""
return
xy
def
c_types
(
int
a
,
double
b
):
"""
>>> c_types(1, 2)
...
...
@@ -54,15 +72,38 @@ def c_types(int a, double b):
"""
cdef
int
*
a_ptr
cdef
double
*
b_ptr
cdef
(
int
*
,
double
*
)
ab
ab
[
0
]
=
&
a
ab
[
1
]
=
&
b
cdef
(
int
*
,
double
*
)
ab
=
(
&
a
,
&
b
)
a_ptr
,
b_ptr
=
ab
return
a_ptr
[
0
],
b_ptr
[
0
]
cpdef
(
int
,
double
)
ctuple_return_type
(
x
,
y
):
cdef
(
int
,
int
*
)
cdef
_ctuple_return_type
(
int
x
,
int
*
x_ptr
):
return
x
,
x_ptr
def
call_cdef_ctuple_return_type
(
int
x
):
"""
>>> call_cdef_ctuple_return_type(2)
(2, 2)
"""
>>> ctuple_return_type(1, 2)
cdef
(
int
,
int
*
)
res
=
cdef
_ctuple_return_type
(
x
,
&
x
)
return
res
[
0
],
res
[
1
][
0
]
cpdef
(
int
,
double
)
cpdef
_ctuple_return_type
(
int
x
,
double
y
):
"""
>>> cpdef_ctuple_return_type(1, 2)
(1, 2.0)
"""
return
x
,
y
@
cython
.
infer_types
(
True
)
def
test_type_inference
():
"""
>>> test_type_inference()
"""
cdef
int
x
=
1
cdef
double
y
=
2
cdef
object
o
=
3
xy
=
(
x
,
y
)
assert
cython
.
typeof
(
xy
)
==
"(int, double)"
,
cython
.
typeof
(
xy
)
xo
=
(
x
,
o
)
assert
cython
.
typeof
(
xo
)
==
"tuple object"
,
cython
.
typeof
(
xo
)
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