Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
1ebb95b4
Commit
1ebb95b4
authored
Jan 08, 2016
by
Boxiang Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add missing attributes to complex and adjust some API
parent
2526c94e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
331 additions
and
673 deletions
+331
-673
from_cpython/Include/complexobject.h
from_cpython/Include/complexobject.h
+0
-4
from_cpython/Objects/complexobject.c
from_cpython/Objects/complexobject.c
+32
-16
src/runtime/complex.cpp
src/runtime/complex.cpp
+295
-653
src/runtime/types.h
src/runtime/types.h
+4
-0
No files found.
from_cpython/Include/complexobject.h
View file @
1ebb95b4
...
@@ -39,14 +39,10 @@ PyComplexObject represents a complex number with double-precision
...
@@ -39,14 +39,10 @@ PyComplexObject represents a complex number with double-precision
real and imaginary parts.
real and imaginary parts.
*/
*/
// Pyston change: this is not our object format
#if 0
typedef
struct
{
typedef
struct
{
PyObject_HEAD
PyObject_HEAD
Py_complex
cval
;
Py_complex
cval
;
}
PyComplexObject
;
}
PyComplexObject
;
#endif
typedef
struct
_PyComplexObject
PyComplexObject
;
// Pyston change: this is not a static object any more
// Pyston change: this is not a static object any more
// PyAPI_DATA(PyTypeObject) PyComplex_Type;
// PyAPI_DATA(PyTypeObject) PyComplex_Type;
...
...
from_cpython/Objects/complexobject.c
View file @
1ebb95b4
...
@@ -215,8 +215,6 @@ c_abs(Py_complex z)
...
@@ -215,8 +215,6 @@ c_abs(Py_complex z)
return
result
;
return
result
;
}
}
// Pyston changes: comment this out
#if 0
static
PyObject
*
static
PyObject
*
complex_subtype_from_c_complex
(
PyTypeObject
*
type
,
Py_complex
cval
)
complex_subtype_from_c_complex
(
PyTypeObject
*
type
,
Py_complex
cval
)
{
{
...
@@ -356,14 +354,18 @@ PyComplex_AsCComplex(PyObject *op)
...
@@ -356,14 +354,18 @@ PyComplex_AsCComplex(PyObject *op)
}
}
}
}
// Pyston changes: comment this out
#if 0
static void
static void
complex_dealloc(PyObject *op)
complex_dealloc(PyObject *op)
{
{
op->ob_type->tp_free(op);
op->ob_type->tp_free(op);
}
}
#endif
static PyObject *
// Pyston change: make no static
PyObject
*
complex_format
(
PyComplexObject
*
v
,
int
precision
,
char
format_code
)
complex_format
(
PyComplexObject
*
v
,
int
precision
,
char
format_code
)
{
{
PyObject
*
result
=
NULL
;
PyObject
*
result
=
NULL
;
...
@@ -426,6 +428,8 @@ complex_format(PyComplexObject *v, int precision, char format_code)
...
@@ -426,6 +428,8 @@ complex_format(PyComplexObject *v, int precision, char format_code)
return
result
;
return
result
;
}
}
// Pyston changes: comment this out
#if 0
static int
static int
complex_print(PyComplexObject *v, FILE *fp, int flags)
complex_print(PyComplexObject *v, FILE *fp, int flags)
{
{
...
@@ -788,8 +792,10 @@ complex_coerce(PyObject **pv, PyObject **pw)
...
@@ -788,8 +792,10 @@ complex_coerce(PyObject **pv, PyObject **pw)
}
}
return 1; /* Can't do it */
return 1; /* Can't do it */
}
}
#endif
static PyObject *
// Pyston change: make no static
PyObject
*
complex_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
complex_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
{
{
PyObject
*
res
;
PyObject
*
res
;
...
@@ -858,6 +864,8 @@ complex_richcompare(PyObject *v, PyObject *w, int op)
...
@@ -858,6 +864,8 @@ complex_richcompare(PyObject *v, PyObject *w, int op)
return
Py_NotImplemented
;
return
Py_NotImplemented
;
}
}
// Pyston change: comment this out
#if 0
static PyObject *
static PyObject *
complex_int(PyObject *v)
complex_int(PyObject *v)
{
{
...
@@ -907,8 +915,10 @@ PyDoc_STRVAR(complex__format__doc,
...
@@ -907,8 +915,10 @@ PyDoc_STRVAR(complex__format__doc,
"complex.__format__() -> str\n"
"complex.__format__() -> str\n"
"\n"
"\n"
"Convert to a string according to format_spec.");
"Convert to a string according to format_spec.");
#endif
static PyObject *
// Pyston changes: make no static
PyObject
*
complex__format__
(
PyObject
*
self
,
PyObject
*
args
)
complex__format__
(
PyObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
format_spec
;
PyObject
*
format_spec
;
...
@@ -952,7 +962,6 @@ PyDoc_STRVAR(complex_is_finite_doc,
...
@@ -952,7 +962,6 @@ PyDoc_STRVAR(complex_is_finite_doc,
"complex.is_finite() -> bool\n"
"complex.is_finite() -> bool\n"
"\n"
"\n"
"Returns True if the real and the imaginary part is finite.");
"Returns True if the real and the imaginary part is finite.");
#endif
static PyMethodDef complex_methods[] = {
static PyMethodDef complex_methods[] = {
{"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS,
{"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS,
...
@@ -974,6 +983,7 @@ static PyMemberDef complex_members[] = {
...
@@ -974,6 +983,7 @@ static PyMemberDef complex_members[] = {
"the imaginary part of a complex number"},
"the imaginary part of a complex number"},
{0},
{0},
};
};
#endif
static
PyObject
*
static
PyObject
*
complex_subtype_from_string
(
PyTypeObject
*
type
,
PyObject
*
v
)
complex_subtype_from_string
(
PyTypeObject
*
type
,
PyObject
*
v
)
...
@@ -1136,15 +1146,18 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
...
@@ -1136,15 +1146,18 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
return
NULL
;
return
NULL
;
}
}
static PyObject *
// Pyston changes: change the API, make it no static
complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// and let complex_new accept unpacked arguments
{
PyObject
*
PyObject *r, *i, *tmp;
complex_new
(
PyTypeObject
*
type
,
PyObject
*
r
,
PyObject
*
i
)
{
PyObject
*
tmp
;
PyNumberMethods
*
nbr
,
*
nbi
=
NULL
;
PyNumberMethods
*
nbr
,
*
nbi
=
NULL
;
Py_complex
cr
,
ci
;
Py_complex
cr
,
ci
;
int
own_r
=
0
;
int
own_r
=
0
;
int
cr_is_complex
=
0
;
int
cr_is_complex
=
0
;
int
ci_is_complex
=
0
;
int
ci_is_complex
=
0
;
/* Pyston changes: comment this out, pyston don't use tuple arg.
static char *kwlist[] = {"real", "imag", 0};
static char *kwlist[] = {"real", "imag", 0};
r = Py_False;
r = Py_False;
...
@@ -1152,6 +1165,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -1152,6 +1165,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
&r, &i))
&r, &i))
return NULL;
return NULL;
*/
/* Special-case for a single argument when type(arg) is complex. */
/* Special-case for a single argument when type(arg) is complex. */
if
(
PyComplex_CheckExact
(
r
)
&&
i
==
NULL
&&
if
(
PyComplex_CheckExact
(
r
)
&&
i
==
NULL
&&
...
@@ -1269,6 +1283,8 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -1269,6 +1283,8 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return
complex_subtype_from_doubles
(
type
,
cr
.
real
,
ci
.
real
);
return
complex_subtype_from_doubles
(
type
,
cr
.
real
,
ci
.
real
);
}
}
// Pyston changes: comment this out
#if 0
PyDoc_STRVAR(complex_doc,
PyDoc_STRVAR(complex_doc,
"complex(real[, imag]) -> complex number\n"
"complex(real[, imag]) -> complex number\n"
"\n"
"\n"
...
...
src/runtime/complex.cpp
View file @
1ebb95b4
...
@@ -22,227 +22,162 @@
...
@@ -22,227 +22,162 @@
#include "runtime/types.h"
#include "runtime/types.h"
extern
"C"
PyObject
*
complex_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
noexcept
;
extern
"C"
PyObject
*
complex_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
noexcept
;
extern
"C"
PyObject
*
complex_new
(
PyTypeObject
*
type
,
PyObject
*
r
,
PyObject
*
i
)
noexcept
;
extern
"C"
Py_complex
PyComplex_AsCComplex
(
PyObject
*
op
)
noexcept
;
extern
"C"
PyObject
*
complex_format
(
PyComplexObject
*
v
,
int
precision
,
char
format_code
)
noexcept
;
extern
"C"
PyObject
*
complex_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
noexcept
;
extern
"C"
PyObject
*
complex__format__
(
PyObject
*
self
,
PyObject
*
args
)
noexcept
;
namespace
pyston
{
namespace
pyston
{
static
inline
void
raiseDivZeroExc
()
{
static
Box
*
toComplex
(
Box
*
self
)
noexcept
{
raiseExcHelper
(
ZeroDivisionError
,
"complex divide by zero"
);
BoxedComplex
*
r
;
}
if
(
self
==
NULL
)
{
return
new
BoxedComplex
(
0.0
,
0.0
);
extern
"C"
Box
*
createPureImaginary
(
double
i
)
{
return
new
BoxedComplex
(
0.0
,
i
);
}
static
PyObject
*
try_complex_special_method
(
PyObject
*
op
)
noexcept
{
PyObject
*
f
;
static
PyObject
*
complexstr
;
if
(
complexstr
==
NULL
)
{
complexstr
=
PyString_InternFromString
(
"__complex__"
);
if
(
complexstr
==
NULL
)
return
NULL
;
}
if
(
PyInstance_Check
(
op
))
{
f
=
PyObject_GetAttr
(
op
,
complexstr
);
if
(
f
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
PyErr_Clear
();
else
return
NULL
;
}
}
else
{
f
=
_PyObject_LookupSpecial
(
op
,
"__complex__"
,
&
complexstr
);
if
(
f
==
NULL
&&
PyErr_Occurred
())
return
NULL
;
}
if
(
f
!=
NULL
)
{
PyObject
*
res
=
PyObject_CallFunctionObjArgs
(
f
,
NULL
);
Py_DECREF
(
f
);
return
res
;
}
return
NULL
;
}
extern
"C"
Py_complex
PyComplex_AsCComplex
(
PyObject
*
op
)
noexcept
{
Py_complex
cv
;
PyObject
*
newop
=
NULL
;
assert
(
op
);
/* If op is already of type PyComplex_Type, return its value */
if
(
PyComplex_Check
(
op
))
{
cv
.
real
=
((
BoxedComplex
*
)
op
)
->
real
;
cv
.
imag
=
((
BoxedComplex
*
)
op
)
->
imag
;
return
cv
;
}
/* If not, use op's __complex__ method, if it exists */
/* return -1 on failure */
cv
.
real
=
-
1.
;
cv
.
imag
=
0.
;
newop
=
try_complex_special_method
(
op
);
if
(
newop
)
{
if
(
!
PyComplex_Check
(
newop
))
{
PyErr_SetString
(
PyExc_TypeError
,
"__complex__ should return a complex object"
);
Py_DECREF
(
newop
);
return
cv
;
}
cv
.
real
=
((
BoxedComplex
*
)
newop
)
->
real
;
cv
.
imag
=
((
BoxedComplex
*
)
newop
)
->
imag
;
Py_DECREF
(
newop
);
return
cv
;
}
else
if
(
PyErr_Occurred
())
{
return
cv
;
}
/* If neither of the above works, interpret op as a float giving the
real part of the result, and fill in the imaginary part as 0. */
else
{
/* PyFloat_AsDouble will return -1 on failure */
cv
.
real
=
PyFloat_AsDouble
(
op
);
return
cv
;
}
}
extern
"C"
double
PyComplex_RealAsDouble
(
PyObject
*
op
)
noexcept
{
if
(
PyComplex_Check
(
op
))
{
return
static_cast
<
BoxedComplex
*>
(
op
)
->
real
;
}
else
{
return
PyFloat_AsDouble
(
op
);
}
}
}
extern
"C"
double
PyComplex_ImagAsDouble
(
PyObject
*
op
)
noexcept
{
if
(
PyComplex_Check
(
self
))
{
if
(
PyComplex_Check
(
op
))
{
r
=
(
BoxedComplex
*
)
self
;
return
static_cast
<
BoxedComplex
*>
(
op
)
->
imag
;
}
else
if
(
PyInt_Check
(
self
))
{
r
=
new
BoxedComplex
(
static_cast
<
BoxedInt
*>
(
self
)
->
n
,
0.0
);
}
else
if
(
PyFloat_Check
(
self
))
{
r
=
new
BoxedComplex
((
static_cast
<
BoxedFloat
*>
(
PyNumber_Float
(
self
)))
->
d
,
0.0
);
}
else
if
(
PyLong_Check
(
self
))
{
double
real
=
PyLong_AsDouble
(
self
);
if
(
real
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
r
=
new
BoxedComplex
(
real
,
0.0
);
}
else
{
}
else
{
return
0.0
;
return
NotImplemented
;
}
}
return
r
;
}
}
extern
"C"
PyObject
*
PyComplex_FromDoubles
(
double
real
,
double
imag
)
noexcept
{
static
inline
void
raiseDivZeroExc
()
{
r
eturn
new
BoxedComplex
(
real
,
imag
);
r
aiseExcHelper
(
ZeroDivisionError
,
"complex division by zero"
);
}
}
extern
"C"
PyObject
*
PyComplex_FromCComplex
(
Py_complex
val
)
noexcept
{
extern
"C"
Box
*
createPureImaginary
(
double
i
)
{
return
new
BoxedComplex
(
val
.
real
,
val
.
imag
);
return
new
BoxedComplex
(
0.0
,
i
);
}
}
// addition
// addition
extern
"C"
Box
*
complexAddComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
extern
"C"
Box
*
complexAddComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
+
rhs
->
real
,
lhs
->
imag
+
rhs
->
imag
);
return
boxComplex
(
lhs
->
real
+
rhs
->
real
,
lhs
->
imag
+
rhs
->
imag
);
}
}
extern
"C"
Box
*
complexAddFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
extern
"C"
Box
*
complexAddFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
float_cls
);
assert
(
PyFloat_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
+
rhs
->
d
,
lhs
->
imag
);
return
boxComplex
(
lhs
->
real
+
rhs
->
d
,
lhs
->
imag
);
}
}
extern
"C"
Box
*
complexAddInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
complexAddInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
PyInt_Check
(
rhs
));
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
+
(
double
)
rhs
->
n
,
lhs
->
imag
);
return
boxComplex
(
lhs
->
real
+
(
double
)
rhs
->
n
,
lhs
->
imag
);
}
}
extern
"C"
Box
*
complexAdd
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
complexAdd
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
!
PyComplex_Check
(
lhs
))
if
(
PyInt_Check
(
rhs
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__add__' requires a 'complex' object but received a '%s'"
,
return
complexAddInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
rhs
=
toComplex
(
_rhs
);
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexAddComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
if
(
rhs
==
NotImplemented
)
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexAddComplex
(
lhs
,
rhs_complex
);
}
}
// subtraction
// subtraction
extern
"C"
Box
*
complexSubComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
extern
"C"
Box
*
complexSubComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
-
rhs
->
real
,
lhs
->
imag
-
rhs
->
imag
);
return
boxComplex
(
lhs
->
real
-
rhs
->
real
,
lhs
->
imag
-
rhs
->
imag
);
}
}
extern
"C"
Box
*
complexSubFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
extern
"C"
Box
*
complexSubFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
float_cls
);
assert
(
PyFloat_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
-
rhs
->
d
,
lhs
->
imag
);
return
boxComplex
(
lhs
->
real
-
rhs
->
d
,
lhs
->
imag
);
}
}
extern
"C"
Box
*
complexSubInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
complexSubInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
PyInt_Check
(
rhs
));
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
-
(
double
)
rhs
->
n
,
lhs
->
imag
);
return
boxComplex
(
lhs
->
real
-
(
double
)
rhs
->
n
,
lhs
->
imag
);
}
}
extern
"C"
Box
*
complexSub
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
complexSub
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
!
PyComplex_Check
(
lhs
))
if
(
PyInt_Check
(
rhs
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__sub__' requires a 'complex' object but received a '%s'"
,
return
complexSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
rhs
=
toComplex
(
_rhs
);
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexSubComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
if
(
rhs
==
NotImplemented
)
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexSubComplex
(
lhs
,
rhs_complex
);
}
}
extern
"C"
Box
*
complexRSub
(
BoxedComplex
*
_
lhs
,
Box
*
_rhs
)
{
extern
"C"
Box
*
complexRSub
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
_
lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rsub__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__rsub__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_lhs
));
getTypeName
(
lhs
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
if
(
PyInt_Check
(
_rhs
))
{
Box
*
rhs
=
toComplex
(
_rhs
);
lhs
->
real
=
(
static_cast
<
BoxedInt
*>
(
_rhs
))
->
n
;
}
else
if
(
_rhs
->
cls
==
float_cls
)
{
if
(
rhs
==
NotImplemented
)
lhs
->
real
=
(
static_cast
<
BoxedFloat
*>
(
_rhs
))
->
d
;
}
else
if
(
_rhs
->
cls
==
complex_cls
)
{
lhs
=
static_cast
<
BoxedComplex
*>
(
_rhs
);
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
return
complexSubComplex
(
lhs
,
_lhs
);
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexSubComplex
(
rhs_complex
,
lhs
);
}
}
// multiplication
// multiplication
extern
"C"
Box
*
complexMulComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
extern
"C"
Box
*
complexMulComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
*
rhs
->
real
-
lhs
->
imag
*
rhs
->
imag
,
lhs
->
real
*
rhs
->
imag
+
lhs
->
imag
*
rhs
->
real
);
return
boxComplex
(
lhs
->
real
*
rhs
->
real
-
lhs
->
imag
*
rhs
->
imag
,
lhs
->
real
*
rhs
->
imag
+
lhs
->
imag
*
rhs
->
real
);
}
}
extern
"C"
Box
*
complexMulFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
extern
"C"
Box
*
complexMulFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
rhs
->
cls
==
float_cls
);
assert
(
PyFloat_Check
(
rhs
)
);
return
boxComplex
(
lhs
->
real
*
rhs
->
d
,
lhs
->
imag
*
rhs
->
d
);
return
boxComplex
(
lhs
->
real
*
rhs
->
d
,
lhs
->
imag
*
rhs
->
d
);
}
}
extern
"C"
Box
*
complexMulInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
complexMulInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
lhs
)
);
assert
(
PyInt_Check
(
rhs
));
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
*
(
double
)
rhs
->
n
,
lhs
->
imag
*
(
double
)
rhs
->
n
);
return
boxComplex
(
lhs
->
real
*
(
double
)
rhs
->
n
,
lhs
->
imag
*
(
double
)
rhs
->
n
);
}
}
extern
"C"
Box
*
complexMul
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
complexMul
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
!
PyComplex_Check
(
lhs
))
if
(
PyInt_Check
(
rhs
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__mul__' requires a 'complex' object but received a '%s'"
,
return
complexMulInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
rhs
=
toComplex
(
_rhs
);
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexMulComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
if
(
rhs
==
NotImplemented
)
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexMulComplex
(
lhs
,
rhs_complex
);
}
}
// division
// division
...
@@ -250,7 +185,7 @@ Box* complexDivComplex(BoxedComplex* lhs, BoxedComplex* rhs) {
...
@@ -250,7 +185,7 @@ Box* complexDivComplex(BoxedComplex* lhs, BoxedComplex* rhs) {
if
(
!
PyComplex_Check
(
lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
getTypeName
(
lhs
));
assert
(
rhs
->
cls
==
complex_cls
);
assert
(
PyComplex_Check
(
rhs
)
);
double
real_f
,
imag_f
;
double
real_f
,
imag_f
;
const
double
abs_breal
=
rhs
->
real
<
0
?
-
rhs
->
real
:
rhs
->
real
;
const
double
abs_breal
=
rhs
->
real
<
0
?
-
rhs
->
real
:
rhs
->
real
;
...
@@ -299,36 +234,72 @@ extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) {
...
@@ -299,36 +234,72 @@ extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) {
return
boxComplex
(
lhs
->
real
/
(
double
)
rhs
->
n
,
lhs
->
imag
/
(
double
)
rhs
->
n
);
return
boxComplex
(
lhs
->
real
/
(
double
)
rhs
->
n
,
lhs
->
imag
/
(
double
)
rhs
->
n
);
}
}
extern
"C"
Box
*
complexDiv
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
complexDiv
(
BoxedComplex
*
lhs
,
Box
*
_
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
getTypeName
(
lhs
));
Box
*
rhs
=
toComplex
(
_rhs
);
if
(
rhs
==
NotImplemented
)
return
NotImplemented
;
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexDivComplex
(
lhs
,
rhs_complex
);
}
extern
"C"
Box
*
complexRDiv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rdiv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
Box
*
rhs
=
toComplex
(
_rhs
);
if
(
rhs
==
NotImplemented
)
return
NotImplemented
;
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexDivComplex
(
rhs_complex
,
lhs
);
}
Box
*
complexTruediv
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__truediv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
PyInt_Check
(
rhs
))
{
if
(
PyInt_Check
(
rhs
))
{
return
complexDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
complexDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
PyFloat_Check
(
rhs
)
)
{
return
complexDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
complexDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
}
else
if
(
PyComplex_Check
(
rhs
)
)
{
return
complexDivComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
return
complexDivComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
}
else
if
(
PyLong_Check
(
rhs
))
{
double
res
=
PyLong_AsDouble
(
rhs
);
if
(
res
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
return
complexDivFloat
(
lhs
,
(
BoxedFloat
*
)
boxFloat
(
res
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
}
}
extern
"C"
Box
*
complexRDiv
(
BoxedComplex
*
_lhs
,
Box
*
_rhs
)
{
Box
*
complexRTruediv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
_lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rdiv__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__rtruediv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_lhs
));
getTypeName
(
lhs
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
if
(
_rhs
==
None
)
if
(
PyInt_Check
(
_rhs
))
{
lhs
->
real
=
(
static_cast
<
BoxedInt
*>
(
_rhs
))
->
n
;
}
else
if
(
_rhs
->
cls
==
float_cls
)
{
lhs
->
real
=
(
static_cast
<
BoxedFloat
*>
(
_rhs
))
->
d
;
}
else
if
(
_rhs
->
cls
==
complex_cls
)
{
lhs
=
static_cast
<
BoxedComplex
*>
(
_rhs
);
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
return
complexDivComplex
(
lhs
,
_lhs
);
Box
*
rhs
=
toComplex
(
_rhs
);
if
(
rhs
==
NotImplemented
)
return
NotImplemented
;
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexDivComplex
(
rhs_complex
,
lhs
);
}
}
Box
*
complexPos
(
BoxedComplex
*
self
)
{
Box
*
complexPos
(
BoxedComplex
*
self
)
{
...
@@ -338,65 +309,13 @@ Box* complexPos(BoxedComplex* self) {
...
@@ -338,65 +309,13 @@ Box* complexPos(BoxedComplex* self) {
return
PyComplex_FromDoubles
(
self
->
real
,
self
->
imag
);
return
PyComplex_FromDoubles
(
self
->
real
,
self
->
imag
);
}
}
// str and repr
Box
*
complex_fmt
(
double
r
,
double
i
,
int
precision
,
char
format_code
)
noexcept
{
PyObject
*
result
=
NULL
;
/* If these are non-NULL, they'll need to be freed. */
char
*
pre
=
NULL
;
char
*
im
=
NULL
;
/* These do not need to be freed. re is either an alias
for pre or a pointer to a constant. lead and tail
are pointers to constants. */
std
::
string
lead
=
""
;
std
::
string
tail
=
""
;
std
::
string
re
=
""
;
std
::
string
result_str
;
if
(
r
==
0.
&&
copysign
(
1.0
,
r
)
==
1.0
)
{
re
=
""
;
im
=
PyOS_double_to_string
(
i
,
format_code
,
precision
,
0
,
NULL
);
if
(
!
im
)
{
PyErr_NoMemory
();
goto
done
;
}
}
else
{
/* Format imaginary part with signr part without */
pre
=
PyOS_double_to_string
(
r
,
format_code
,
precision
,
0
,
NULL
);
if
(
!
pre
)
{
PyErr_NoMemory
();
goto
done
;
}
re
=
std
::
string
(
pre
);
im
=
PyOS_double_to_string
(
i
,
format_code
,
precision
,
Py_DTSF_SIGN
,
NULL
);
if
(
!
im
)
{
PyErr_NoMemory
();
goto
done
;
}
lead
=
"("
;
tail
=
")"
;
}
/* Alloc the final buffer. Add one for the "j" in the format string,
and one for the trailing zero. */
result_str
=
lead
+
std
::
string
(
re
)
+
std
::
string
(
im
)
+
"j"
+
tail
;
result
=
PyString_FromString
(
result_str
.
c_str
());
done:
PyMem_Free
(
im
);
PyMem_Free
(
pre
);
return
result
;
}
static
void
_addFunc
(
const
char
*
name
,
ConcreteCompilerType
*
rtn_type
,
void
*
complex_func
,
void
*
float_func
,
static
void
_addFunc
(
const
char
*
name
,
ConcreteCompilerType
*
rtn_type
,
void
*
complex_func
,
void
*
float_func
,
void
*
int_func
,
void
*
boxed_func
)
{
void
*
int_func
,
void
*
boxed_func
)
{
FunctionMetadata
*
md
=
new
FunctionMetadata
(
2
,
false
,
false
);
FunctionMetadata
*
md
=
new
FunctionMetadata
(
2
,
false
,
false
);
md
->
addVersion
(
complex_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_COMPLEX
});
md
->
addVersion
(
complex_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_COMPLEX
});
md
->
addVersion
(
float_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_FLOAT
});
md
->
addVersion
(
float_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_FLOAT
});
md
->
addVersion
(
int_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_INT
});
md
->
addVersion
(
int_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_INT
});
md
->
addVersion
(
boxed_func
,
UNKNOWN
,
{
BOXED_COMPLEX
,
UNKNOWN
});
md
->
addVersion
(
boxed_func
,
UNKNOWN
,
{
UNKNOWN
,
UNKNOWN
});
complex_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
md
));
complex_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
md
));
}
}
...
@@ -411,21 +330,19 @@ Box* complexPow(BoxedComplex* lhs, Box* _rhs, Box* mod) {
...
@@ -411,21 +330,19 @@ Box* complexPow(BoxedComplex* lhs, Box* _rhs, Box* mod) {
return
res
;
return
res
;
}
}
Box
*
complexR
pow
(
BoxedComplex
*
_
lhs
,
Box
*
_rhs
)
{
Box
*
complexR
Pow
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
_
lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rpow__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__rpow__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_lhs
));
getTypeName
(
lhs
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
if
(
PyInt_Check
(
_rhs
))
{
Box
*
rhs
=
toComplex
(
_rhs
);
lhs
->
real
=
(
static_cast
<
BoxedInt
*>
(
_rhs
))
->
n
;
}
else
if
(
_rhs
->
cls
==
float_cls
)
{
if
(
rhs
==
NotImplemented
)
lhs
->
real
=
(
static_cast
<
BoxedFloat
*>
(
_rhs
))
->
d
;
}
else
if
(
_rhs
->
cls
==
complex_cls
)
{
lhs
=
static_cast
<
BoxedComplex
*>
(
_rhs
);
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
return
complexPow
(
lhs
,
_lhs
,
None
);
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexPow
(
rhs_complex
,
lhs
,
None
);
}
}
Box
*
complexHash
(
BoxedComplex
*
self
)
{
Box
*
complexHash
(
BoxedComplex
*
self
)
{
...
@@ -517,398 +434,164 @@ Box* complexStr(BoxedComplex* self) {
...
@@ -517,398 +434,164 @@ Box* complexStr(BoxedComplex* self) {
if
(
!
PyComplex_Check
(
self
))
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__str__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__str__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
getTypeName
(
self
));
Box
*
r
=
complex_fmt
(
self
->
real
,
self
->
imag
,
12
,
'g'
);
Box
*
r
=
complex_format
((
PyComplexObject
*
)
self
,
12
,
'g'
);
if
(
!
r
)
{
if
(
!
r
)
{
throwCAPIException
();
throwCAPIException
();
}
}
return
r
;
return
r
;
}
}
Box
*
complex
Repr
(
BoxedComplex
*
self
)
{
Box
*
complex
Int
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__
repr
__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__
int
__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
getTypeName
(
self
));
Box
*
r
=
complex_fmt
(
self
->
real
,
self
->
imag
,
16
,
'g'
);
if
(
!
r
)
{
throwCAPIException
();
}
return
r
;
}
static
PyObject
*
complex_subtype_from_string
(
PyObject
*
v
)
noexcept
{
const
char
*
s
,
*
start
;
char
*
end
;
double
x
=
0.0
,
y
=
0.0
,
z
;
int
got_bracket
=
0
;
#ifdef Py_USING_UNICODE
char
*
s_buffer
=
NULL
;
#endif
Py_ssize_t
len
;
if
(
PyString_Check
(
v
))
{
s
=
PyString_AS_STRING
(
v
);
len
=
PyString_GET_SIZE
(
v
);
}
#ifdef Py_USING_UNICODE
else
if
(
PyUnicode_Check
(
v
))
{
s_buffer
=
(
char
*
)
PyMem_MALLOC
(
PyUnicode_GET_SIZE
(
v
)
+
1
);
if
(
s_buffer
==
NULL
)
return
PyErr_NoMemory
();
if
(
PyUnicode_EncodeDecimal
(
PyUnicode_AS_UNICODE
(
v
),
PyUnicode_GET_SIZE
(
v
),
s_buffer
,
NULL
))
goto
error
;
s
=
s_buffer
;
len
=
strlen
(
s
);
}
#endif
else
if
(
PyObject_AsCharBuffer
(
v
,
&
s
,
&
len
))
{
PyErr_SetString
(
PyExc_TypeError
,
"complex() arg is not a string"
);
return
NULL
;
}
/* position on first nonblank */
start
=
s
;
while
(
Py_ISSPACE
(
*
s
))
s
++
;
if
(
*
s
==
'('
)
{
/* Skip over possible bracket from repr(). */
got_bracket
=
1
;
s
++
;
while
(
Py_ISSPACE
(
*
s
))
s
++
;
}
/* a valid complex string usually takes one of the three forms:
<float> - real part only
<float>j - imaginary part only
<float><signed-float>j - real and imaginary parts
where <float> represents any numeric string that's accepted by the
float constructor (including 'nan', 'inf', 'infinity', etc.), and
<signed-float> is any string of the form <float> whose first
character is '+' or '-'.
For backwards compatibility, the extra forms
<float><sign>j
<sign>j
j
are also accepted, though support for these forms may be removed from
a future version of Python.
*/
/* first look for forms starting with <float> */
z
=
PyOS_string_to_double
(
s
,
&
end
,
NULL
);
if
(
z
==
-
1.0
&&
PyErr_Occurred
())
{
if
(
PyErr_ExceptionMatches
(
PyExc_ValueError
))
PyErr_Clear
();
else
goto
error
;
}
if
(
end
!=
s
)
{
/* all 4 forms starting with <float> land here */
s
=
end
;
if
(
*
s
==
'+'
||
*
s
==
'-'
)
{
/* <float><signed-float>j | <float><sign>j */
x
=
z
;
y
=
PyOS_string_to_double
(
s
,
&
end
,
NULL
);
if
(
y
==
-
1.0
&&
PyErr_Occurred
())
{
if
(
PyErr_ExceptionMatches
(
PyExc_ValueError
))
PyErr_Clear
();
else
goto
error
;
}
if
(
end
!=
s
)
/* <float><signed-float>j */
s
=
end
;
else
{
/* <float><sign>j */
y
=
*
s
==
'+'
?
1.0
:
-
1.0
;
s
++
;
}
if
(
!
(
*
s
==
'j'
||
*
s
==
'J'
))
goto
parse_error
;
s
++
;
}
else
if
(
*
s
==
'j'
||
*
s
==
'J'
)
{
/* <float>j */
s
++
;
y
=
z
;
}
else
/* <float> */
x
=
z
;
}
else
{
/* not starting with <float>; must be <sign>j or j */
if
(
*
s
==
'+'
||
*
s
==
'-'
)
{
/* <sign>j */
y
=
*
s
==
'+'
?
1.0
:
-
1.0
;
s
++
;
}
else
/* j */
y
=
1.0
;
if
(
!
(
*
s
==
'j'
||
*
s
==
'J'
))
goto
parse_error
;
s
++
;
}
/* trailing whitespace and closing bracket */
while
(
Py_ISSPACE
(
*
s
))
s
++
;
if
(
got_bracket
)
{
/* if there was an opening parenthesis, then the corresponding
closing parenthesis should be right here */
if
(
*
s
!=
')'
)
goto
parse_error
;
s
++
;
while
(
Py_ISSPACE
(
*
s
))
s
++
;
}
/* we should now be at the end of the string */
if
(
s
-
start
!=
len
)
goto
parse_error
;
raiseExcHelper
(
TypeError
,
"can't convert complex to int"
);
}
#ifdef Py_USING_UNICODE
Box
*
complexFloat
(
BoxedComplex
*
self
)
{
if
(
s_buffer
)
if
(
!
PyComplex_Check
(
self
))
PyMem_FREE
(
s_buffer
);
raiseExcHelper
(
TypeError
,
"descriptor '__float__' requires a 'complex' object but received a '%s'"
,
#endif
getTypeName
(
self
));
return
new
BoxedComplex
(
x
,
y
);
parse_error:
raiseExcHelper
(
TypeError
,
"can't convert complex to float"
);
PyErr_SetString
(
PyExc_ValueError
,
"complex() arg is a malformed string"
);
error:
#ifdef Py_USING_UNICODE
if
(
s_buffer
)
PyMem_FREE
(
s_buffer
);
#endif
return
NULL
;
}
}
Box
*
complexLong
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__long__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
static
Box
*
to_complex
(
Box
*
self
)
noexcept
{
raiseExcHelper
(
TypeError
,
"can't convert complex to long"
);
BoxedComplex
*
r
;
if
(
self
==
None
||
self
==
NULL
)
{
return
new
BoxedComplex
(
0.0
,
0.0
);
}
static
BoxedString
*
complex_str
=
internStringImmortal
(
"__complex__"
);
if
(
PyComplex_Check
(
self
)
&&
!
PyObject_HasAttr
((
PyObject
*
)
self
,
complex_str
))
{
r
=
(
BoxedComplex
*
)
self
;
}
else
if
(
PyInt_Check
(
self
))
{
r
=
new
BoxedComplex
(
static_cast
<
BoxedInt
*>
(
self
)
->
n
,
0.0
);
}
else
if
(
PyFloat_Check
(
self
))
{
r
=
new
BoxedComplex
((
static_cast
<
BoxedFloat
*>
(
PyNumber_Float
(
self
)))
->
d
,
0.0
);
}
else
if
(
self
->
cls
==
long_cls
)
{
r
=
new
BoxedComplex
(
PyLong_AsDouble
(
self
),
0.0
);
}
else
{
return
NotImplemented
;
}
return
r
;
}
}
template
<
ExceptionStyle
S
>
static
Box
*
try_special_method
(
Box
*
self
)
noexcept
(
S
==
CAPI
)
{
Box
*
complexRepr
(
BoxedComplex
*
self
)
{
if
(
self
==
None
||
self
==
NULL
)
{
if
(
!
PyComplex_Check
(
self
))
return
None
;
raiseExcHelper
(
TypeError
,
"descriptor '__repr__' requires a 'complex' object but received a '%s'"
,
}
getTypeName
(
self
));
static
BoxedString
*
float_str
=
internStringImmortal
(
"__float__"
);
if
(
PyObject_HasAttr
((
PyObject
*
)
self
,
float_str
))
{
Box
*
r_f
=
callattrInternal
<
S
,
NOT_REWRITABLE
>
(
self
,
float_str
,
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
!
PyFloat_Check
(
r_f
))
{
if
(
S
==
CAPI
)
{
if
(
!
PyErr_Occurred
())
PyErr_Format
(
PyExc_TypeError
,
"__float__ returned non-float (type %.200s)"
,
r_f
->
cls
->
tp_name
);
return
NULL
;
}
else
{
raiseExcHelper
(
TypeError
,
"__float__ returned non-float (type %.200s)"
,
r_f
->
cls
->
tp_name
);
}
}
return
(
BoxedFloat
*
)
r_f
;
}
static
BoxedString
*
complex_str
=
internStringImmortal
(
"__complex__"
);
Box
*
r
=
complex_format
((
PyComplexObject
*
)
self
,
16
,
'g'
);
if
(
PyObject_HasAttr
((
PyObject
*
)
self
,
complex_str
))
{
Box
*
r
=
callattrInternal
<
S
,
NOT_REWRITABLE
>
(
self
,
complex_str
,
CLASS_OR_INST
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
!
r
)
{
if
(
!
r
)
{
if
(
S
==
CAPI
)
{
throwCAPIException
();
if
(
!
PyErr_Occurred
())
PyErr_Format
(
TypeError
,
"complex() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
self
));
return
NULL
;
}
else
{
raiseExcHelper
(
TypeError
,
"complex() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
self
));
}
}
}
return
r
;
}
if
(
!
PyComplex_Check
(
r
))
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"__complex__ returned non-complex (type %s)"
,
r
->
cls
->
tp_name
);
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"__complex__ returned non-complex (type %s)"
,
r
->
cls
->
tp_name
);
}
return
static_cast
<
BoxedComplex
*>
(
r
);
template
<
ExceptionStyle
S
>
Box
*
complexNew
(
BoxedClass
*
cls
,
Box
*
real
,
Box
*
imag
)
noexcept
(
S
==
CAPI
)
{
if
(
real
==
NULL
)
{
real
=
Py_False
;
imag
=
NULL
;
}
}
return
None
;
Box
*
res
=
complex_new
(
cls
,
real
,
imag
);
if
(
S
==
CXX
&&
res
==
NULL
)
throwCAPIException
();
return
res
;
}
}
template
<
ExceptionStyle
S
>
Box
*
_complexNew
(
Box
*
real
,
Box
*
imag
)
noexcept
(
S
==
CAPI
)
{
Box
*
complexDivmodComplex
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
// handle str and unicode
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
if
(
real
!=
None
&&
real
!=
NULL
)
{
if
(
PyString_Check
(
real
)
||
PyUnicode_Check
(
real
))
{
if
(
imag
!=
None
&&
imag
!=
NULL
)
{
raiseExcHelper
(
TypeError
,
"complex() can't take second arg if first is a string"
);
}
Box
*
res
=
complex_subtype_from_string
(
real
);
if
(
res
==
NULL
)
{
throwCAPIException
();
throwCAPIException
();
}
return
res
;
}
}
if
(
real
!=
None
&&
real
!=
NULL
&&
real
->
cls
==
complex_cls
&&
(
imag
==
NULL
||
imag
==
None
))
{
Box
*
rhs
=
toComplex
(
_rhs
);
return
static_cast
<
BoxedComplex
*>
(
real
);
}
Box
*
_real
=
try_special_method
<
S
>
(
real
);
if
(
rhs
==
NotImplemented
)
Box
*
_imag
=
try_special_method
<
S
>
(
imag
)
;
return
NotImplemented
;
if
(
_real
!=
None
&&
_real
!=
NULL
)
{
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
real
=
_real
;
}
if
(
_imag
!=
None
&&
_imag
!=
NULL
)
{
if
(
rhs_complex
->
real
==
0.0
&&
rhs_complex
->
imag
==
0.0
)
{
imag
=
_imag
;
raiseExcHelper
(
ZeroDivisionError
,
"complex divmod()"
)
;
}
}
double
real_f
,
imag_f
;
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs_complex
);
/* The raw divisor value. */
bool
real_is_complex
=
false
,
imag_is_complex
=
false
;
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
if
(
real
==
None
||
real
==
NULL
)
{
div
->
imag
=
0.0
;
real_f
=
0.0
;
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs_complex
,
div
));
}
else
if
(
PyComplex_Check
(
real
))
{
Box
*
res
=
BoxedTuple
::
create
({
div
,
mod
});
real_f
=
((
BoxedComplex
*
)
real
)
->
real
;
return
res
;
real_is_complex
=
true
;
}
}
else
{
real_f
=
((
BoxedFloat
*
)
PyNumber_Float
(
real
))
->
d
;
}
if
(
imag
==
None
||
imag
==
NULL
)
{
imag_f
=
0.0
;
}
else
if
(
PyComplex_Check
(
imag
))
{
imag_f
=
((
BoxedComplex
*
)
imag
)
->
real
;
imag_is_complex
=
true
;
}
else
{
imag_f
=
((
BoxedFloat
*
)
PyNumber_Float
(
imag
))
->
d
;
}
if
(
imag_is_complex
)
{
Box
*
complexDivmod
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
real_f
-=
((
BoxedComplex
*
)
imag
)
->
imag
;
if
(
!
PyComplex_Check
(
lhs
))
}
raiseExcHelper
(
TypeError
,
"descriptor '__divmod__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
real_is_complex
)
{
if
(
rhs
==
None
)
imag_f
+=
((
BoxedComplex
*
)
real
)
->
imag
;
return
NotImplemented
;
}
return
new
BoxedComplex
(
real_f
,
imag_f
);
return
complexDivmodComplex
(
lhs
,
rhs
);
}
}
template
<
ExceptionStyle
S
>
Box
*
complexNew
(
BoxedClass
*
_cls
,
Box
*
_real
,
Box
*
_imag
)
noexcept
(
S
==
CAPI
)
{
Box
*
complexRDivmod
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
{
if
(
!
PyComplex_Check
(
lhs
))
if
(
S
==
CAPI
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__rdivmod__' requires a 'complex' object but received a '%s'"
,
PyErr_Format
(
TypeError
,
"complex.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
getTypeName
(
lhs
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"complex.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
}
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
_cls
);
if
(
PyComplex_Check
(
cls
))
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"complex.__new__(%s): %s is not a subtype of complex"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"complex.__new__(%s): %s is not a subtype of complex"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
}
// check second argument
if
(
_imag
!=
NULL
&&
(
PyString_Check
(
_imag
)
||
PyUnicode_Check
(
_imag
)))
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"complex() second arg can't be a string"
);
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"complex() second arg can't be a string"
);
}
// we can't use None as default value, because complex(None) should raise TypeError,
if
(
_rhs
==
None
)
// but complex() should return `0j`. So use NULL as default value.
return
NotImplemented
;
// Here check we pass complex(None, None), complex(None)
// or complex(imag=None) to the constructor
if
((
_real
==
None
)
&&
(
_imag
==
None
||
_imag
==
NULL
))
{
raiseExcHelper
(
TypeError
,
"complex() argument must be a string or number"
);
}
if
(
cls
==
complex_cls
)
Box
*
rhs
=
toComplex
(
_rhs
);
return
_complexNew
<
S
>
(
_real
,
_imag
);
BoxedComplex
*
r
=
(
BoxedComplex
*
)
_complexNew
<
S
>
(
_real
,
_imag
);
if
(
rhs
==
NotImplemented
)
return
NotImplemented
;
if
(
!
r
)
{
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
assert
(
S
==
CAPI
);
return
NULL
;
}
return
new
(
_cls
)
BoxedComplex
(
r
->
real
,
r
->
imag
);
return
complexDivmodComplex
(
rhs_complex
,
lhs
);
}
}
extern
"C"
Box
*
complexDivmod
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
Box
*
complexModComplex
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__divmod__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
return
NULL
;
Box
*
res
=
toComplex
(
_rhs
);
if
(
res
==
NotImplemented
)
{
return
NotImplemented
;
}
BoxedComplex
*
rhs
=
(
BoxedComplex
*
)
res
;
if
(
rhs
->
real
==
0.0
&&
rhs
->
imag
==
0.0
)
{
if
(
rhs
->
real
==
0.0
&&
rhs
->
imag
==
0.0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"complex
divmod()
"
);
raiseExcHelper
(
ZeroDivisionError
,
"complex
remainder
"
);
}
}
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs
);
/* The raw divisor value. */
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs
);
/* The raw divisor value. */
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
div
->
imag
=
0.0
;
div
->
imag
=
0.0
;
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs
,
div
));
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs
,
div
));
Box
*
res
=
BoxedTuple
::
create
({
div
,
mod
});
return
mod
;
return
res
;
}
}
extern
"C"
Box
*
complexMod
(
BoxedComplex
*
lhs
,
Box
*
_
rhs
)
{
Box
*
complexMod
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__mod__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__mod__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
getTypeName
(
lhs
));
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
Box
*
res
=
to_complex
(
_rhs
);
if
(
rhs
==
None
)
if
(
res
==
NotImplemented
)
{
return
NotImplemented
;
return
NotImplemented
;
}
BoxedComplex
*
rhs
=
(
BoxedComplex
*
)
res
;
return
complexModComplex
(
lhs
,
rhs
);
}
if
(
rhs
->
real
==
0.0
&&
rhs
->
imag
==
0.0
)
{
Box
*
complexRMod
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
raiseExcHelper
(
ZeroDivisionError
,
"complex remainder"
);
if
(
!
PyComplex_Check
(
lhs
))
}
raiseExcHelper
(
TypeError
,
"descriptor '__rmod__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs
);
/* The raw divisor value. */
if
(
_rhs
==
None
)
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
return
NotImplemented
;
div
->
imag
=
0.0
;
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs
,
div
));
Box
*
rhs
=
toComplex
(
_rhs
);
return
mod
;
if
(
rhs
==
NotImplemented
)
return
NotImplemented
;
BoxedComplex
*
rhs_complex
=
static_cast
<
BoxedComplex
*>
(
rhs
);
return
complexModComplex
(
rhs_complex
,
lhs
);
}
}
extern
"C"
Box
*
complexFloordiv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
extern
"C"
Box
*
complexFloordiv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
...
@@ -916,68 +599,38 @@ extern "C" Box* complexFloordiv(BoxedComplex* lhs, Box* _rhs) {
...
@@ -916,68 +599,38 @@ extern "C" Box* complexFloordiv(BoxedComplex* lhs, Box* _rhs) {
raiseExcHelper
(
TypeError
,
"descriptor '__floordiv__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__floordiv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
getTypeName
(
lhs
));
Box
*
res
=
to_complex
(
_rhs
);
if
(
_rhs
==
None
)
if
(
res
==
NotImplemented
)
{
return
NotImplemented
;
Box
*
rhs
=
toComplex
(
_rhs
);
if
(
rhs
==
NotImplemented
)
{
return
NotImplemented
;
return
NotImplemented
;
}
}
BoxedComplex
*
rhs
=
(
BoxedComplex
*
)
res
;
BoxedTuple
*
t
=
(
BoxedTuple
*
)
complexDivmod
(
lhs
,
rhs
);
BoxedComplex
*
rhs_complex
=
(
BoxedComplex
*
)
rhs
;
BoxedTuple
*
t
=
(
BoxedTuple
*
)
complexDivmod
(
lhs
,
rhs_complex
);
return
t
->
elts
[
0
];
return
t
->
elts
[
0
];
}
}
static
PyObject
*
complex_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
noexcept
{
Box
*
complexRFloordiv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
PyObject
*
res
;
if
(
!
PyComplex_Check
(
lhs
))
int
equal
;
raiseExcHelper
(
TypeError
,
"descriptor '__rfloordiv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
op
!=
Py_EQ
&&
op
!=
Py_NE
)
{
if
(
_rhs
==
None
)
/* for backwards compatibility, comparisons with non-numbers return
return
NotImplemented
;
* NotImplemented. Only comparisons with core numeric types raise
* TypeError.
*/
if
(
PyInt_Check
(
w
)
||
PyLong_Check
(
w
)
||
PyFloat_Check
(
w
)
||
PyComplex_Check
(
w
))
{
PyErr_SetString
(
PyExc_TypeError
,
"no ordering relation is defined "
"for complex numbers"
);
return
NULL
;
}
return
Py_NotImplemented
;
}
assert
(
PyComplex_Check
(
v
));
Box
*
rhs
=
toComplex
(
_rhs
);
BoxedComplex
*
lhs
=
static_cast
<
BoxedComplex
*>
(
v
);
if
(
PyInt_Check
(
w
)
||
PyLong_Check
(
w
))
{
if
(
rhs
==
NotImplemented
)
{
/* Check for 0->g0 imaginary part first to avoid the rich
return
NotImplemented
;
* comparison when possible->g
*/
if
(
lhs
->
imag
==
0.0
)
{
PyObject
*
j
,
*
sub_res
;
j
=
PyFloat_FromDouble
(
lhs
->
real
);
if
(
j
==
NULL
)
return
NULL
;
sub_res
=
PyObject_RichCompare
(
j
,
w
,
op
);
Py_DECREF
(
j
);
return
sub_res
;
}
else
{
equal
=
0
;
}
}
else
if
(
PyFloat_Check
(
w
))
{
equal
=
(
lhs
->
real
==
PyFloat_AsDouble
(
w
)
&&
lhs
->
imag
==
0.0
);
}
else
if
(
PyComplex_Check
(
w
))
{
BoxedComplex
*
rhs
=
static_cast
<
BoxedComplex
*>
(
w
);
equal
=
(
lhs
->
real
==
rhs
->
real
&&
lhs
->
imag
==
rhs
->
imag
);
}
else
{
return
Py_NotImplemented
;
}
}
BoxedComplex
*
rhs_complex
=
(
BoxedComplex
*
)
rhs
;
if
(
equal
==
(
op
==
Py_EQ
))
BoxedTuple
*
t
=
(
BoxedTuple
*
)
complexDivmod
(
rhs_complex
,
lhs
);
res
=
Py_True
;
return
t
->
elts
[
0
];
else
res
=
Py_False
;
Py_INCREF
(
res
);
return
res
;
}
}
extern
"C"
Box
*
complexEq
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
complexEq
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
...
@@ -1068,31 +721,6 @@ PyObject* complex_neg(PyComplexObject* v) {
...
@@ -1068,31 +721,6 @@ PyObject* complex_neg(PyComplexObject* v) {
return
PyComplex_FromDoubles
(
-
self
->
real
,
-
self
->
imag
);
return
PyComplex_FromDoubles
(
-
self
->
real
,
-
self
->
imag
);
}
}
// Pyston change: make not static
PyObject
*
complex__format__
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
format_spec
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:__format__"
,
&
format_spec
))
return
NULL
;
if
(
PyBytes_Check
(
format_spec
))
return
_PyComplex_FormatAdvanced
(
self
,
PyBytes_AS_STRING
(
format_spec
),
PyBytes_GET_SIZE
(
format_spec
));
if
(
PyUnicode_Check
(
format_spec
))
{
/* Convert format_spec to a str */
PyObject
*
result
;
PyObject
*
str_spec
=
PyObject_Str
(
format_spec
);
if
(
str_spec
==
NULL
)
return
NULL
;
result
=
_PyComplex_FormatAdvanced
(
self
,
PyBytes_AS_STRING
(
str_spec
),
PyBytes_GET_SIZE
(
str_spec
));
Py_DECREF
(
str_spec
);
return
result
;
}
PyErr_SetString
(
PyExc_TypeError
,
"__format__ requires str or unicode"
);
return
NULL
;
}
static
PyMethodDef
complex_methods
[]
=
{
static
PyMethodDef
complex_methods
[]
=
{
{
"__format__"
,
(
PyCFunction
)
complex__format__
,
METH_VARARGS
,
NULL
},
{
"__format__"
,
(
PyCFunction
)
complex__format__
,
METH_VARARGS
,
NULL
},
};
};
...
@@ -1101,10 +729,10 @@ void setupComplex() {
...
@@ -1101,10 +729,10 @@ void setupComplex() {
static
PyNumberMethods
complex_as_number
;
static
PyNumberMethods
complex_as_number
;
complex_cls
->
tp_as_number
=
&
complex_as_number
;
complex_cls
->
tp_as_number
=
&
complex_as_number
;
auto
complex_new
=
FunctionMetadata
::
create
((
void
*
)
complexNew
<
CXX
>
,
UNKNOWN
,
3
,
false
,
false
,
auto
complex_new
_func
=
FunctionMetadata
::
create
((
void
*
)
complexNew
<
CXX
>
,
UNKNOWN
,
3
,
false
,
false
,
ParamNames
({
""
,
"real"
,
"imag"
},
""
,
""
),
CXX
);
ParamNames
({
""
,
"real"
,
"imag"
},
""
,
""
),
CXX
);
complex_new
->
addVersion
((
void
*
)
complexNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
complex_new
_func
->
addVersion
((
void
*
)
complexNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
complex_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
complex_new
,
{
NULL
,
NULL
}));
complex_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
complex_new
_func
,
{
NULL
,
NULL
}));
_addFunc
(
"__add__"
,
BOXED_COMPLEX
,
(
void
*
)
complexAddComplex
,
(
void
*
)
complexAddFloat
,
(
void
*
)
complexAddInt
,
_addFunc
(
"__add__"
,
BOXED_COMPLEX
,
(
void
*
)
complexAddComplex
,
(
void
*
)
complexAddFloat
,
(
void
*
)
complexAddInt
,
(
void
*
)
complexAdd
);
(
void
*
)
complexAdd
);
...
@@ -1126,16 +754,21 @@ void setupComplex() {
...
@@ -1126,16 +754,21 @@ void setupComplex() {
complex_cls
->
giveAttr
(
"__rdiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRDiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rdiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRDiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
complex_cls
->
giveAttr
(
"__pow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexPow
,
UNKNOWN
,
3
,
false
,
false
),
{
None
}));
"__pow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexPow
,
UNKNOWN
,
3
,
false
,
false
),
{
None
}));
complex_cls
->
giveAttr
(
"__rpow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexR
p
ow
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rpow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexR
P
ow
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__mod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexMod
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__mod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexMod
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__divmod__"
,
complex_cls
->
giveAttr
(
"__rmod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRMod
,
UNKNOWN
,
2
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivmod
,
BOXED_TUPLE
,
2
)));
complex_cls
->
giveAttr
(
"__divmod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivmod
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rdivmod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRDivmod
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__floordiv__"
,
complex_cls
->
giveAttr
(
"__floordiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexFloordiv
,
UNKNOWN
,
2
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexFloordiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rfloordiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRFloordiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__truediv__"
,
complex_cls
->
giveAttr
(
"__truediv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivComplex
,
BOXED_COMPLEX
,
2
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexTruediv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rtruediv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRTruediv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"conjugate"
,
complex_cls
->
giveAttr
(
"conjugate"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexConjugate
,
BOXED_COMPLEX
,
1
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexConjugate
,
BOXED_COMPLEX
,
1
)));
complex_cls
->
giveAttr
(
"__coerce__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexCoerce
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__coerce__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexCoerce
,
UNKNOWN
,
2
)));
...
@@ -1154,11 +787,20 @@ void setupComplex() {
...
@@ -1154,11 +787,20 @@ void setupComplex() {
complex_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexPos
,
BOXED_COMPLEX
,
1
)));
complex_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexPos
,
BOXED_COMPLEX
,
1
)));
complex_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexHash
,
BOXED_INT
,
1
)));
complex_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexHash
,
BOXED_INT
,
1
)));
complex_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexStr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexStr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"__int__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexInt
,
UNKNOWN
,
1
)));
complex_cls
->
giveAttr
(
"__float__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexFloat
,
UNKNOWN
,
1
)));
complex_cls
->
giveAttr
(
"__long__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexLong
,
UNKNOWN
,
1
)));
complex_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRepr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRepr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"real"
,
complex_cls
->
giveAttr
(
"real"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
real
)));
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
real
)));
complex_cls
->
giveAttr
(
"imag"
,
complex_cls
->
giveAttr
(
"imag"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
imag
)));
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
imag
)));
complex_cls
->
giveAttr
(
"__doc__"
,
boxString
(
"complex(real[, imag]) -> complex number
\n
"
"
\n
"
"Create a complex number from a real part and an optional imaginary part.
\n
"
"This is equivalent to (real + imag*1j) where imag defaults to 0."
));
for
(
auto
&
md
:
complex_methods
)
{
for
(
auto
&
md
:
complex_methods
)
{
complex_cls
->
giveAttr
(
md
.
ml_name
,
new
BoxedMethodDescriptor
(
&
md
,
complex_cls
));
complex_cls
->
giveAttr
(
md
.
ml_name
,
new
BoxedMethodDescriptor
(
&
md
,
complex_cls
));
}
}
...
...
src/runtime/types.h
View file @
1ebb95b4
...
@@ -390,6 +390,10 @@ public:
...
@@ -390,6 +390,10 @@ public:
DEFAULT_CLASS_SIMPLE
(
complex_cls
);
DEFAULT_CLASS_SIMPLE
(
complex_cls
);
};
};
static_assert
(
sizeof
(
BoxedComplex
)
==
sizeof
(
PyComplexObject
),
""
);
static_assert
(
offsetof
(
BoxedComplex
,
real
)
==
offsetof
(
PyComplexObject
,
cval
.
real
),
""
);
static_assert
(
offsetof
(
BoxedComplex
,
imag
)
==
offsetof
(
PyComplexObject
,
cval
.
imag
),
""
);
class
BoxedBool
:
public
BoxedInt
{
class
BoxedBool
:
public
BoxedInt
{
public:
public:
BoxedBool
(
bool
b
)
__attribute__
((
visibility
(
"default"
)))
:
BoxedInt
(
b
?
1
:
0
)
{}
BoxedBool
(
bool
b
)
__attribute__
((
visibility
(
"default"
)))
:
BoxedInt
(
b
?
1
:
0
)
{}
...
...
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