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
dd37f81e
Commit
dd37f81e
authored
Oct 13, 2009
by
Lisandro Dalcin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Seamless C99/C++ complex numbers support (ticket #398)
parent
61e95f53
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
260 additions
and
116 deletions
+260
-116
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+0
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+12
-15
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+5
-5
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+1
-1
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+1
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+187
-75
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+1
-1
tests/run/complex_numbers_T305.pyx
tests/run/complex_numbers_T305.pyx
+27
-17
tests/run/complex_numbers_c89_T398.h
tests/run/complex_numbers_c89_T398.h
+1
-0
tests/run/complex_numbers_c89_T398.pyx
tests/run/complex_numbers_c89_T398.pyx
+2
-0
tests/run/complex_numbers_c99_T398.h
tests/run/complex_numbers_c99_T398.h
+14
-0
tests/run/complex_numbers_c99_T398.pyx
tests/run/complex_numbers_c99_T398.pyx
+2
-0
tests/run/complex_numbers_cxx_T398.h
tests/run/complex_numbers_cxx_T398.h
+5
-0
tests/run/complex_numbers_cxx_T398.pyx
tests/run/complex_numbers_cxx_T398.pyx
+2
-0
No files found.
Cython/Compiler/Code.py
View file @
dd37f81e
...
@@ -396,7 +396,6 @@ class GlobalState(object):
...
@@ -396,7 +396,6 @@ class GlobalState(object):
code_layout = [
code_layout = [
'h_code',
'h_code',
'complex_numbers_utility_code',
'utility_code_proto_before_types',
'utility_code_proto_before_types',
'type_declarations',
'type_declarations',
'utility_code_proto',
'utility_code_proto',
...
...
Cython/Compiler/ExprNodes.py
View file @
dd37f81e
...
@@ -544,9 +544,8 @@ class ExprNode(Node):
...
@@ -544,9 +544,8 @@ class ExprNode(Node):
elif
src
.
type
.
is_pyobject
:
elif
src
.
type
.
is_pyobject
:
src
=
CoerceFromPyTypeNode
(
dst_type
,
src
,
env
)
src
=
CoerceFromPyTypeNode
(
dst_type
,
src
,
env
)
elif
(
dst_type
.
is_complex
elif
(
dst_type
.
is_complex
and
src_type
!=
dst_type
and
src_type
!=
dst_type
and
dst_type
.
assignable_from
(
src_type
)
and
dst_type
.
assignable_from
(
src_type
)):
and
not
env
.
directives
[
'c99_complex'
]):
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
else
:
# neither src nor dst are py types
else
:
# neither src nor dst are py types
# Added the string comparison, since for c types that
# Added the string comparison, since for c types that
...
@@ -1007,8 +1006,6 @@ class ImagNode(AtomicExprNode):
...
@@ -1007,8 +1006,6 @@ class ImagNode(AtomicExprNode):
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
:
return
self
.
result
()
return
self
.
result
()
elif
self
.
c99_complex
:
return
"%rj"
%
float
(
self
.
value
)
else
:
else
:
return
"%s(0, %r)"
%
(
self
.
type
.
from_parts
,
float
(
self
.
value
))
return
"%s(0, %r)"
%
(
self
.
type
.
from_parts
,
float
(
self
.
value
))
...
@@ -1020,8 +1017,6 @@ class ImagNode(AtomicExprNode):
...
@@ -1020,8 +1017,6 @@ class ImagNode(AtomicExprNode):
float
(
self
.
value
),
float
(
self
.
value
),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
code
.
put_gotref
(
self
.
py_result
())
else
:
self
.
c99_complex
=
code
.
globalstate
.
directives
[
'c99_complex'
]
...
@@ -3014,7 +3009,7 @@ class AttributeNode(ExprNode):
...
@@ -3014,7 +3009,7 @@ class AttributeNode(ExprNode):
else
:
else
:
return
self
.
member
return
self
.
member
elif
obj
.
type
.
is_complex
:
elif
obj
.
type
.
is_complex
:
return
"__Pyx_
%s_PART
(%s)"
%
(
self
.
member
.
upper
(),
obj_code
)
return
"__Pyx_
C%s
(%s)"
%
(
self
.
member
.
upper
(),
obj_code
)
else
:
else
:
return
"%s%s%s"
%
(
obj_code
,
self
.
op
,
self
.
member
)
return
"%s%s%s"
%
(
obj_code
,
self
.
op
,
self
.
member
)
...
@@ -4071,7 +4066,7 @@ class UnaryMinusNode(UnopNode):
...
@@ -4071,7 +4066,7 @@ class UnaryMinusNode(UnopNode):
else
:
else
:
self
.
type_error
()
self
.
type_error
()
if
self
.
type
.
is_complex
:
if
self
.
type
.
is_complex
:
self
.
infix
=
env
.
directives
[
'c99_complex'
]
self
.
infix
=
False
def
py_operation_function
(
self
):
def
py_operation_function
(
self
):
return
"PyNumber_Negative"
return
"PyNumber_Negative"
...
@@ -4498,7 +4493,7 @@ class NumBinopNode(BinopNode):
...
@@ -4498,7 +4493,7 @@ class NumBinopNode(BinopNode):
if
not
self
.
type
:
if
not
self
.
type
:
self
.
type_error
()
self
.
type_error
()
return
return
if
self
.
type
.
is_complex
and
not
env
.
directives
[
'c99_complex'
]
:
if
self
.
type
.
is_complex
:
self
.
infix
=
False
self
.
infix
=
False
if
not
self
.
infix
:
if
not
self
.
infix
:
self
.
operand1
=
self
.
operand1
.
coerce_to
(
self
.
type
,
env
)
self
.
operand1
=
self
.
operand1
.
coerce_to
(
self
.
type
,
env
)
...
@@ -5146,9 +5141,11 @@ class CmpNode(object):
...
@@ -5146,9 +5141,11 @@ class CmpNode(object):
richcmp_constants
[
op
],
richcmp_constants
[
op
],
code
.
error_goto_if_null
(
result_code
,
self
.
pos
)))
code
.
error_goto_if_null
(
result_code
,
self
.
pos
)))
code
.
put_gotref
(
result_code
)
code
.
put_gotref
(
result_code
)
elif
operand1
.
type
.
is_complex
and
not
code
.
globalstate
.
directives
[
'c99_complex'
]:
elif
operand1
.
type
.
is_complex
:
if
op
==
"!="
:
negation
=
"!"
if
op
==
"!="
:
else
:
negation
=
""
negation
=
"!"
else
:
negation
=
""
code
.
putln
(
"%s = %s(%s%s(%s, %s));"
%
(
code
.
putln
(
"%s = %s(%s%s(%s, %s));"
%
(
result_code
,
result_code
,
coerce_result
,
coerce_result
,
...
@@ -5684,8 +5681,8 @@ class CoerceToComplexNode(CoercionNode):
...
@@ -5684,8 +5681,8 @@ class CoerceToComplexNode(CoercionNode):
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
if
self
.
arg
.
type
.
is_complex
:
if
self
.
arg
.
type
.
is_complex
:
real_part
=
"__Pyx_
REAL_PART
(%s)"
%
self
.
arg
.
result
()
real_part
=
"__Pyx_
CREAL
(%s)"
%
self
.
arg
.
result
()
imag_part
=
"__Pyx_
IMAG_PART
(%s)"
%
self
.
arg
.
result
()
imag_part
=
"__Pyx_
CIMAG
(%s)"
%
self
.
arg
.
result
()
else
:
else
:
real_part
=
self
.
arg
.
result
()
real_part
=
self
.
arg
.
result
()
imag_part
=
"0"
imag_part
=
"0"
...
...
Cython/Compiler/ModuleNode.py
View file @
dd37f81e
...
@@ -559,12 +559,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -559,12 +559,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
if
env
.
directives
[
'c99_complex'
]:
if
env
.
directives
[
'ccomplex'
]:
code
.
putln
(
"#ifndef _Complex_I"
)
code
.
putln
(
""
)
code
.
putln
(
"#include <complex.h>"
)
code
.
putln
(
"#if !defined(CYTHON_CCOMPLEX)"
)
code
.
putln
(
"#define CYTHON_CCOMPLEX 1"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#define __PYX_USE_C99_COMPLEX defined(_Complex_I)"
)
code
.
putln
(
""
)
code
.
putln
(
''
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
Nodes
.
utility_function_predeclarations
)
code
.
put
(
PyrexTypes
.
type_conversion_predeclarations
)
code
.
put
(
PyrexTypes
.
type_conversion_predeclarations
)
code
.
put
(
Nodes
.
branch_prediction_macros
)
code
.
put
(
Nodes
.
branch_prediction_macros
)
...
...
Cython/Compiler/Nodes.py
View file @
dd37f81e
...
@@ -3134,7 +3134,7 @@ class InPlaceAssignmentNode(AssignmentNode):
...
@@ -3134,7 +3134,7 @@ class InPlaceAssignmentNode(AssignmentNode):
c_op
=
"/"
c_op
=
"/"
elif
c_op
==
"**"
:
elif
c_op
==
"**"
:
error
(
self
.
pos
,
"No C inplace power operator"
)
error
(
self
.
pos
,
"No C inplace power operator"
)
elif
self
.
lhs
.
type
.
is_complex
and
not
code
.
globalstate
.
directives
[
'c99_complex'
]
:
elif
self
.
lhs
.
type
.
is_complex
:
error
(
self
.
pos
,
"Inplace operators not implemented for complex types."
)
error
(
self
.
pos
,
"Inplace operators not implemented for complex types."
)
# have to do assignment directly to avoid side-effects
# have to do assignment directly to avoid side-effects
...
...
Cython/Compiler/Options.py
View file @
dd37f81e
...
@@ -65,7 +65,7 @@ option_defaults = {
...
@@ -65,7 +65,7 @@ option_defaults = {
'cdivision_warnings'
:
False
,
'cdivision_warnings'
:
False
,
'always_allow_keywords'
:
False
,
'always_allow_keywords'
:
False
,
'wraparound'
:
True
,
'wraparound'
:
True
,
'c
99_complex'
:
False
,
# Don't use macro wrappers for complex arith, not sure what to name this...
'c
complex'
:
False
,
# use C99/C++ for complex types and arith
'callspec'
:
""
,
'callspec'
:
""
,
'profile'
:
False
,
'profile'
:
False
,
'infer_types'
:
False
,
'infer_types'
:
False
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
dd37f81e
This diff is collapsed.
Click to expand it.
Cython/Compiler/Symtab.py
View file @
dd37f81e
...
@@ -1157,7 +1157,7 @@ class StructOrUnionScope(Scope):
...
@@ -1157,7 +1157,7 @@ class StructOrUnionScope(Scope):
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, modifiers = ()):
api = 0, in_pxd = 0, modifiers = ()):
self.declare_var(name, type, pos, cname, visibility)
return
self.declare_var(name, type, pos, cname, visibility)
class ClassScope(Scope):
class ClassScope(Scope):
# Abstract base class for namespace of
# Abstract base class for namespace of
...
...
tests/run/complex_numbers_T305.pyx
View file @
dd37f81e
__doc__
=
u"""
__doc__
=
u"""
>>> test_object_conversion(2)
>>> test_object_conversion(2)
((2+0j), (2+0j))
((2+0j), (2+0j)
, (2+0j)
)
>>> test_object_conversion(2j - 0.5)
>>> test_object_conversion(2j - 0.5)
((-0.5+2j), (-0.5+2j))
((-0.5+2j), (-0.5+2j)
, (-0.5+2j)
)
>>> test_arithmetic(2j, 4j)
>>> test_arithmetic(2j, 4j)
(-2j, 6j, -2j, (-8+0j), (0.5+0j))
(
2j,
-2j, 6j, -2j, (-8+0j), (0.5+0j))
>>> test_arithmetic(6+12j, 3j)
>>> test_arithmetic(6+12j, 3j)
((-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j))
((
6+12j), (
-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j))
>>> test_arithmetic(5-10j, 3+4j)
>>> test_arithmetic(5-10j, 3+4j)
((-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
((
5-10j), (
-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
>>> test_div_by_zero(4j)
## XXX this is not working
-0.25j
## >>> test_div_by_zero(4j)
>>> test_div_by_zero(0)
## -0.25j
Traceback (most recent call last):
## >>> test_div_by_zero(0)
...
## Traceback (most recent call last):
ZeroDivisionError: float division
## ...
## ZeroDivisionError: float division
>>> test_coercion(1, 1.5, 2.5, 4+1j, 10j)
>>> test_coercion(1, 1.5, 2.5, 4+1j, 10j)
(1+0j)
(1+0j)
...
@@ -56,6 +57,10 @@ __doc__ = u"""
...
@@ -56,6 +57,10 @@ __doc__ = u"""
(1+2j)
(1+2j)
>>> test_real_imag_assignment(1.5, -3.5)
>>> test_real_imag_assignment(1.5, -3.5)
(1.5-3.5j)
(1.5-3.5j)
## XXX not implemented yet!
## >>> test_conjugate(1+2j)
## (1-2j)
"""
"""
#cdef extern from "complex.h":
#cdef extern from "complex.h":
...
@@ -65,15 +70,17 @@ cimport cython
...
@@ -65,15 +70,17 @@ cimport cython
def
test_object_conversion
(
o
):
def
test_object_conversion
(
o
):
cdef
float
complex
a
=
o
cdef
float
complex
a
=
o
cdef
double
complex
z
=
o
cdef
double
complex
b
=
o
return
(
a
,
z
)
cdef
long
double
complex
c
=
o
return
(
a
,
b
,
c
)
def
test_arithmetic
(
double
complex
z
,
double
complex
w
):
def
test_arithmetic
(
double
complex
z
,
double
complex
w
):
return
-
z
,
z
+
w
,
z
-
w
,
z
*
w
,
z
/
w
return
+
z
,
-
z
,
z
+
w
,
z
-
w
,
z
*
w
,
z
/
w
@
cython
.
cdivision
(
False
)
## XXX this is not working
def
test_div_by_zero
(
double
complex
z
):
## @cython.cdivision(False)
return
1
/
z
## def test_div_by_zero(double complex z):
## return 1/z
def
test_coercion
(
int
a
,
float
b
,
double
c
,
float
complex
d
,
double
complex
e
):
def
test_coercion
(
int
a
,
float
b
,
double
c
,
float
complex
d
,
double
complex
e
):
cdef
double
complex
z
cdef
double
complex
z
...
@@ -102,3 +109,6 @@ def test_real_imag_assignment(object a, double b):
...
@@ -102,3 +109,6 @@ def test_real_imag_assignment(object a, double b):
z
.
imag
=
b
z
.
imag
=
b
return
z
return
z
## XXX not implemented yet!
## def test_conjugate(float complex z):
## return z.conjugate()
tests/run/complex_numbers_c89_T398.h
0 → 100644
View file @
dd37f81e
#define CYTHON_CCOMPLEX 0
tests/run/complex_numbers_c89_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_c89_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
tests/run/complex_numbers_c99_T398.h
0 → 100644
View file @
dd37f81e
#if !defined(__cplusplus)
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \
|| defined(__GNUC__) \
|| defined(__INTEL_COMPILER) \
|| defined(__IBMC__) \
#include <complex.h>
#if !defined(_Complex_I)
#error The "complex.h" header does not define the '_Complex_I' macro.
#error Please report this to Cython developers <cython-dev@codespeak.net>
#endif
#endif
#endif
tests/run/complex_numbers_c99_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_c99_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
tests/run/complex_numbers_cxx_T398.h
0 → 100644
View file @
dd37f81e
#if defined(__cplusplus)
#define CYTHON_CCOMPLEX 1
#else
#define CYTHON_CCOMPLEX 0
#endif
tests/run/complex_numbers_cxx_T398.pyx
0 → 100644
View file @
dd37f81e
cdef
extern
from
"complex_numbers_cxx_T398.h"
:
pass
include
"complex_numbers_T305.pyx"
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