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
1ac82dda
Commit
1ac82dda
authored
Dec 20, 2015
by
Boxiang Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apply experimental complex changes
parent
9dbcaa45
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
33 additions
and
1235 deletions
+33
-1235
Makefile
Makefile
+1
-0
src/CMakeLists.txt
src/CMakeLists.txt
+0
-1
src/codegen/runtime_hooks.cpp
src/codegen/runtime_hooks.cpp
+1
-1
src/core/options.cpp
src/core/options.cpp
+1
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+1
-0
src/runtime/complex.cpp
src/runtime/complex.cpp
+0
-1175
src/runtime/complex.h
src/runtime/complex.h
+0
-25
src/runtime/inline/boxing.h
src/runtime/inline/boxing.h
+4
-4
src/runtime/inline/link_forcer.cpp
src/runtime/inline/link_forcer.cpp
+2
-2
src/runtime/types.cpp
src/runtime/types.cpp
+10
-10
src/runtime/types.h
src/runtime/types.h
+13
-17
No files found.
Makefile
View file @
1ac82dda
...
...
@@ -324,6 +324,7 @@ STDMODULE_SRCS := \
STDOBJECT_SRCS
:=
\
structseq.c
\
capsule.c
\
complexobject.c
\
stringobject.c
\
exceptions.c
\
floatobject.c
\
...
...
src/CMakeLists.txt
View file @
1ac82dda
...
...
@@ -86,7 +86,6 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
runtime/capi.cpp
runtime/classobj.cpp
runtime/code.cpp
runtime/complex.cpp
runtime/ctxswitching.S
runtime/cxx_unwind.cpp
runtime/descr.cpp
...
...
src/codegen/runtime_hooks.cpp
View file @
1ac82dda
...
...
@@ -36,7 +36,7 @@
#include "codegen/irgen/util.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/complex.h"
//
#include "runtime/complex.h"
#include "runtime/float.h"
#include "runtime/generator.h"
#include "runtime/import.h"
...
...
src/core/options.cpp
View file @
1ac82dda
...
...
@@ -91,5 +91,6 @@ int Py_NoSiteFlag = 0;
int
Py_OptimizeFlag
=
0
;
int
Py_VerboseFlag
=
0
;
int
Py_UnicodeFlag
=
0
;
int
Py_DivisionWarningFlag
=
0
;
}
}
src/runtime/builtin_modules/builtins.cpp
View file @
1ac82dda
...
...
@@ -2083,6 +2083,7 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"set"
,
set_cls
);
builtins_module
->
giveAttr
(
"frozenset"
,
frozenset_cls
);
builtins_module
->
giveAttr
(
"tuple"
,
tuple_cls
);
assert
(
complex_cls
);
builtins_module
->
giveAttr
(
"complex"
,
complex_cls
);
builtins_module
->
giveAttr
(
"super"
,
super_cls
);
builtins_module
->
giveAttr
(
"property"
,
property_cls
);
...
...
src/runtime/complex.cpp
deleted
100644 → 0
View file @
9dbcaa45
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "runtime/complex.h"
#include "capi/typeobject.h"
#include "core/types.h"
#include "runtime/float.h"
#include "runtime/inline/boxing.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
extern
"C"
PyObject
*
complex_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
noexcept
;
namespace
pyston
{
static
inline
void
raiseDivZeroExc
()
{
raiseExcHelper
(
ZeroDivisionError
,
"complex divide by zero"
);
}
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
(
op
))
{
return
static_cast
<
BoxedComplex
*>
(
op
)
->
imag
;
}
else
{
return
0.0
;
}
}
extern
"C"
PyObject
*
PyComplex_FromDoubles
(
double
real
,
double
imag
)
noexcept
{
return
new
BoxedComplex
(
real
,
imag
);
}
extern
"C"
PyObject
*
PyComplex_FromCComplex
(
Py_complex
val
)
noexcept
{
return
new
BoxedComplex
(
val
.
real
,
val
.
imag
);
}
// addition
extern
"C"
Box
*
complexAddComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
complex_cls
);
return
boxComplex
(
lhs
->
real
+
rhs
->
real
,
lhs
->
imag
+
rhs
->
imag
);
}
extern
"C"
Box
*
complexAddFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxComplex
(
lhs
->
real
+
rhs
->
d
,
lhs
->
imag
);
}
extern
"C"
Box
*
complexAddInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
+
(
double
)
rhs
->
n
,
lhs
->
imag
);
}
extern
"C"
Box
*
complexAdd
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
PyInt_Check
(
rhs
))
{
return
complexAddInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexAddComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
// subtraction
extern
"C"
Box
*
complexSubComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
complex_cls
);
return
boxComplex
(
lhs
->
real
-
rhs
->
real
,
lhs
->
imag
-
rhs
->
imag
);
}
extern
"C"
Box
*
complexSubFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxComplex
(
lhs
->
real
-
rhs
->
d
,
lhs
->
imag
);
}
extern
"C"
Box
*
complexSubInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
-
(
double
)
rhs
->
n
,
lhs
->
imag
);
}
extern
"C"
Box
*
complexSub
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
PyInt_Check
(
rhs
))
{
return
complexSubInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexSubComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
extern
"C"
Box
*
complexRSub
(
BoxedComplex
*
_lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
_lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rsub__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_lhs
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
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
complexSubComplex
(
lhs
,
_lhs
);
}
// multiplication
extern
"C"
Box
*
complexMulComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
complex_cls
);
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
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxComplex
(
lhs
->
real
*
rhs
->
d
,
lhs
->
imag
*
rhs
->
d
);
}
extern
"C"
Box
*
complexMulInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
assert
(
PyInt_Check
(
rhs
));
return
boxComplex
(
lhs
->
real
*
(
double
)
rhs
->
n
,
lhs
->
imag
*
(
double
)
rhs
->
n
);
}
extern
"C"
Box
*
complexMul
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
complex_cls
);
if
(
PyInt_Check
(
rhs
))
{
return
complexMulInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexMulComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
// division
Box
*
complexDivComplex
(
BoxedComplex
*
lhs
,
BoxedComplex
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
assert
(
rhs
->
cls
==
complex_cls
);
double
real_f
,
imag_f
;
const
double
abs_breal
=
rhs
->
real
<
0
?
-
rhs
->
real
:
rhs
->
real
;
const
double
abs_bimag
=
rhs
->
imag
<
0
?
-
rhs
->
imag
:
rhs
->
imag
;
if
(
abs_breal
>=
abs_bimag
)
{
/* divide tops and bottom by rhs.real */
if
(
abs_breal
==
0.0
)
{
raiseDivZeroExc
();
real_f
=
imag_f
=
0.0
;
}
else
{
const
double
ratio
=
rhs
->
imag
/
rhs
->
real
;
const
double
denom
=
rhs
->
real
+
rhs
->
imag
*
ratio
;
real_f
=
(
lhs
->
real
+
lhs
->
imag
*
ratio
)
/
denom
;
imag_f
=
(
lhs
->
imag
-
lhs
->
real
*
ratio
)
/
denom
;
}
}
else
{
/* divide tops and bottom by rhs->imag */
const
double
ratio
=
rhs
->
real
/
rhs
->
imag
;
const
double
denom
=
rhs
->
real
*
ratio
+
rhs
->
imag
;
real_f
=
(
lhs
->
real
*
ratio
+
lhs
->
imag
)
/
denom
;
imag_f
=
(
lhs
->
imag
*
ratio
-
lhs
->
real
)
/
denom
;
}
return
boxComplex
(
real_f
,
imag_f
);
}
extern
"C"
Box
*
complexDivFloat
(
BoxedComplex
*
lhs
,
BoxedFloat
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
assert
(
rhs
->
cls
==
float_cls
);
if
(
rhs
->
d
==
0.0
)
{
raiseDivZeroExc
();
}
return
boxComplex
(
lhs
->
real
/
rhs
->
d
,
lhs
->
imag
/
rhs
->
d
);
}
extern
"C"
Box
*
complexDivInt
(
BoxedComplex
*
lhs
,
BoxedInt
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
assert
(
PyInt_Check
(
rhs
));
if
(
rhs
->
n
==
0
)
{
raiseDivZeroExc
();
}
return
boxComplex
(
lhs
->
real
/
(
double
)
rhs
->
n
,
lhs
->
imag
/
(
double
)
rhs
->
n
);
}
extern
"C"
Box
*
complexDiv
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
PyInt_Check
(
rhs
))
{
return
complexDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
complexDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
complex_cls
)
{
return
complexDivComplex
(
lhs
,
static_cast
<
BoxedComplex
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
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
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
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
complexDivComplex
(
lhs
,
_lhs
);
}
Box
*
complexPos
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__pos__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
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
,
void
*
int_func
,
void
*
boxed_func
)
{
FunctionMetadata
*
md
=
new
FunctionMetadata
(
2
,
false
,
false
);
md
->
addVersion
(
complex_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_COMPLEX
});
md
->
addVersion
(
float_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_FLOAT
});
md
->
addVersion
(
int_func
,
rtn_type
,
{
BOXED_COMPLEX
,
BOXED_INT
});
md
->
addVersion
(
boxed_func
,
UNKNOWN
,
{
BOXED_COMPLEX
,
UNKNOWN
});
complex_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
md
));
}
Box
*
complexPow
(
BoxedComplex
*
lhs
,
Box
*
_rhs
,
Box
*
mod
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
PyObject
*
res
=
complex_pow
(
lhs
,
_rhs
,
mod
);
if
(
res
==
NULL
)
throwCAPIException
();
return
res
;
}
Box
*
complexRpow
(
BoxedComplex
*
_lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
_lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__rpow__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_lhs
));
BoxedComplex
*
lhs
=
new
BoxedComplex
(
0.0
,
0.0
);
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
complexPow
(
lhs
,
_lhs
,
None
);
}
Box
*
complexHash
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__hash__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
long
hashreal
,
hashimag
,
combined
;
hashreal
=
_Py_HashDouble
(
self
->
real
);
if
(
hashreal
==
-
1
)
{
throwCAPIException
();
}
hashimag
=
_Py_HashDouble
(
self
->
imag
);
if
(
hashimag
==
-
1
)
{
throwCAPIException
();
}
/* Note: if the imaginary part is 0, hashimag is 0 now,
* so the following returns hashreal unchanged. This is
* important because numbers of different types that
* compare equal must have the same hash value, so that
* hash(x + 0*j) must equal hash(x).
*/
combined
=
hashreal
+
1000003
*
hashimag
;
if
(
combined
==
-
1
)
combined
=
-
2
;
return
boxInt
(
combined
);
}
Box
*
complexCoerce
(
Box
*
lhs
,
Box
*
rhs
)
{
Py_complex
cval
;
cval
.
imag
=
0.
;
if
(
PyInt_Check
(
rhs
))
{
cval
.
real
=
(
double
)
PyInt_AsLong
(
rhs
);
rhs
=
PyComplex_FromCComplex
(
cval
);
}
else
if
(
PyLong_Check
(
rhs
))
{
cval
.
real
=
PyLong_AsDouble
(
rhs
);
if
(
cval
.
real
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
rhs
=
PyComplex_FromCComplex
(
cval
);
}
else
if
(
PyFloat_Check
(
rhs
))
{
cval
.
real
=
PyFloat_AsDouble
(
rhs
);
rhs
=
PyComplex_FromCComplex
(
cval
);
}
else
if
(
!
PyComplex_Check
(
rhs
))
{
return
NotImplemented
;
}
return
BoxedTuple
::
create
({
lhs
,
rhs
});
}
Box
*
complexConjugate
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor 'conjuagte' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
return
new
BoxedComplex
(
self
->
real
,
-
self
->
imag
);
}
Box
*
complexAbs
(
BoxedComplex
*
_self
)
{
if
(
!
PyComplex_Check
(
_self
))
raiseExcHelper
(
TypeError
,
"descriptor '__abs__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
_self
));
double
result
;
Py_complex
self
=
PyComplex_AsCComplex
(
_self
);
result
=
c_abs
(
self
);
if
(
errno
==
ERANGE
)
{
raiseExcHelper
(
OverflowError
,
"absolute value too large"
);
}
return
PyFloat_FromDouble
(
result
);
}
Box
*
complexGetnewargs
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__getnewargs__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
return
BoxedTuple
::
create
({
boxFloat
(
self
->
real
),
boxFloat
(
self
->
imag
)
});
}
Box
*
complexNonzero
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__nonzero__' require a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
bool
res
=
self
->
real
!=
0.0
||
self
->
imag
!=
0.0
;
return
boxBool
(
res
);
}
Box
*
complexStr
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__str__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
self
));
Box
*
r
=
complex_fmt
(
self
->
real
,
self
->
imag
,
12
,
'g'
);
if
(
!
r
)
{
throwCAPIException
();
}
return
r
;
}
Box
*
complexRepr
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__repr__' requires a 'complex' object but received a '%s'"
,
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
;
#ifdef Py_USING_UNICODE
if
(
s_buffer
)
PyMem_FREE
(
s_buffer
);
#endif
return
new
BoxedComplex
(
x
,
y
);
parse_error:
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
;
}
static
Box
*
to_complex
(
Box
*
self
)
noexcept
{
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
)
{
if
(
self
==
None
||
self
==
NULL
)
{
return
None
;
}
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__"
);
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
(
S
==
CAPI
)
{
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
));
}
}
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
);
}
return
None
;
}
template
<
ExceptionStyle
S
>
Box
*
_complexNew
(
Box
*
real
,
Box
*
imag
)
noexcept
(
S
==
CAPI
)
{
// handle str and unicode
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
();
}
return
res
;
}
}
if
(
real
!=
None
&&
real
!=
NULL
&&
real
->
cls
==
complex_cls
&&
(
imag
==
NULL
||
imag
==
None
))
{
return
static_cast
<
BoxedComplex
*>
(
real
);
}
Box
*
_real
=
try_special_method
<
S
>
(
real
);
Box
*
_imag
=
try_special_method
<
S
>
(
imag
);
if
(
_real
!=
None
&&
_real
!=
NULL
)
{
real
=
_real
;
}
if
(
_imag
!=
None
&&
_imag
!=
NULL
)
{
imag
=
_imag
;
}
double
real_f
,
imag_f
;
bool
real_is_complex
=
false
,
imag_is_complex
=
false
;
if
(
real
==
None
||
real
==
NULL
)
{
real_f
=
0.0
;
}
else
if
(
PyComplex_Check
(
real
))
{
real_f
=
((
BoxedComplex
*
)
real
)
->
real
;
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
)
{
real_f
-=
((
BoxedComplex
*
)
imag
)
->
imag
;
}
if
(
real_is_complex
)
{
imag_f
+=
((
BoxedComplex
*
)
real
)
->
imag
;
}
return
new
BoxedComplex
(
real_f
,
imag_f
);
}
template
<
ExceptionStyle
S
>
Box
*
complexNew
(
BoxedClass
*
_cls
,
Box
*
_real
,
Box
*
_imag
)
noexcept
(
S
==
CAPI
)
{
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"complex.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
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,
// but complex() should return `0j`. So use NULL as default value.
// 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
)
return
_complexNew
<
S
>
(
_real
,
_imag
);
BoxedComplex
*
r
=
(
BoxedComplex
*
)
_complexNew
<
S
>
(
_real
,
_imag
);
if
(
!
r
)
{
assert
(
S
==
CAPI
);
return
NULL
;
}
return
new
(
_cls
)
BoxedComplex
(
r
->
real
,
r
->
imag
);
}
extern
"C"
Box
*
complexDivmod
(
BoxedComplex
*
lhs
,
BoxedComplex
*
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
)
return
NULL
;
if
(
rhs
->
real
==
0.0
&&
rhs
->
imag
==
0.0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"complex divmod()"
);
}
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs
);
/* The raw divisor value. */
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
div
->
imag
=
0.0
;
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs
,
div
));
Box
*
res
=
BoxedTuple
::
create
({
div
,
mod
});
return
res
;
}
extern
"C"
Box
*
complexMod
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__mod__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
Box
*
res
=
to_complex
(
_rhs
);
if
(
res
==
NotImplemented
)
{
return
NotImplemented
;
}
BoxedComplex
*
rhs
=
(
BoxedComplex
*
)
res
;
if
(
rhs
->
real
==
0.0
&&
rhs
->
imag
==
0.0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"complex remainder"
);
}
BoxedComplex
*
div
=
(
BoxedComplex
*
)
complexDiv
(
lhs
,
rhs
);
/* The raw divisor value. */
div
->
real
=
floor
(
div
->
real
);
/* Use the floor of the real part. */
div
->
imag
=
0.0
;
BoxedComplex
*
mod
=
(
BoxedComplex
*
)
complexSubComplex
(
lhs
,
(
BoxedComplex
*
)
complexMulComplex
(
rhs
,
div
));
return
mod
;
}
extern
"C"
Box
*
complexFloordiv
(
BoxedComplex
*
lhs
,
Box
*
_rhs
)
{
if
(
!
PyComplex_Check
(
lhs
))
raiseExcHelper
(
TypeError
,
"descriptor '__floordiv__' requires a 'complex' object but received a '%s'"
,
getTypeName
(
lhs
));
Box
*
res
=
to_complex
(
_rhs
);
if
(
res
==
NotImplemented
)
{
return
NotImplemented
;
}
BoxedComplex
*
rhs
=
(
BoxedComplex
*
)
res
;
BoxedTuple
*
t
=
(
BoxedTuple
*
)
complexDivmod
(
lhs
,
rhs
);
return
t
->
elts
[
0
];
}
static
PyObject
*
complex_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
noexcept
{
PyObject
*
res
;
int
equal
;
if
(
op
!=
Py_EQ
&&
op
!=
Py_NE
)
{
/* for backwards compatibility, comparisons with non-numbers return
* 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
));
BoxedComplex
*
lhs
=
static_cast
<
BoxedComplex
*>
(
v
);
if
(
PyInt_Check
(
w
)
||
PyLong_Check
(
w
))
{
/* Check for 0->g0 imaginary part first to avoid the rich
* 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
;
}
if
(
equal
==
(
op
==
Py_EQ
))
res
=
Py_True
;
else
res
=
Py_False
;
Py_INCREF
(
res
);
return
res
;
}
extern
"C"
Box
*
complexEq
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__eq__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_EQ
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
extern
"C"
Box
*
complexNe
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__ne__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_NE
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
extern
"C"
Box
*
complexLe
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__le__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_LE
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
extern
"C"
Box
*
complexLt
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__lt__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_LT
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
extern
"C"
Box
*
complexGe
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__ge__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_GE
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
extern
"C"
Box
*
complexGt
(
BoxedComplex
*
lhs
,
Box
*
rhs
)
{
if
(
lhs
->
cls
!=
complex_cls
)
{
raiseExcHelper
(
TypeError
,
"descriptor '__gt__' requires a 'complex' object but recieved a '%s'"
,
getTypeName
(
lhs
));
}
Box
*
res
=
complex_richcompare
(
lhs
,
rhs
,
Py_GT
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
Box
*
complexNeg
(
Box
*
_self
)
{
assert
(
_self
->
cls
==
complex_cls
);
BoxedComplex
*
self
=
(
BoxedComplex
*
)
_self
;
return
PyComplex_FromDoubles
(
-
self
->
real
,
-
self
->
imag
);
}
PyObject
*
complex_neg
(
PyComplexObject
*
v
)
{
BoxedComplex
*
self
=
(
BoxedComplex
*
)
v
;
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
[]
=
{
{
"__format__"
,
(
PyCFunction
)
complex__format__
,
METH_VARARGS
,
NULL
},
};
void
setupComplex
()
{
static
PyNumberMethods
complex_as_number
;
complex_cls
->
tp_as_number
=
&
complex_as_number
;
auto
complex_new
=
FunctionMetadata
::
create
((
void
*
)
complexNew
<
CXX
>
,
UNKNOWN
,
3
,
false
,
false
,
ParamNames
({
""
,
"real"
,
"imag"
},
""
,
""
),
CXX
);
complex_new
->
addVersion
((
void
*
)
complexNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
complex_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
complex_new
,
{
NULL
,
NULL
}));
_addFunc
(
"__add__"
,
BOXED_COMPLEX
,
(
void
*
)
complexAddComplex
,
(
void
*
)
complexAddFloat
,
(
void
*
)
complexAddInt
,
(
void
*
)
complexAdd
);
_addFunc
(
"__radd__"
,
BOXED_COMPLEX
,
(
void
*
)
complexAddComplex
,
(
void
*
)
complexAddFloat
,
(
void
*
)
complexAddInt
,
(
void
*
)
complexAdd
);
_addFunc
(
"__sub__"
,
BOXED_COMPLEX
,
(
void
*
)
complexSubComplex
,
(
void
*
)
complexSubFloat
,
(
void
*
)
complexSubInt
,
(
void
*
)
complexSub
);
_addFunc
(
"__mul__"
,
BOXED_COMPLEX
,
(
void
*
)
complexMulComplex
,
(
void
*
)
complexMulFloat
,
(
void
*
)
complexMulInt
,
(
void
*
)
complexMul
);
_addFunc
(
"__rmul__"
,
BOXED_COMPLEX
,
(
void
*
)
complexMulComplex
,
(
void
*
)
complexMulFloat
,
(
void
*
)
complexMulInt
,
(
void
*
)
complexMul
);
_addFunc
(
"__div__"
,
BOXED_COMPLEX
,
(
void
*
)
complexDivComplex
,
(
void
*
)
complexDivFloat
,
(
void
*
)
complexDivInt
,
(
void
*
)
complexDiv
);
complex_cls
->
giveAttr
(
"__rsub__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRSub
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__rdiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRDiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__pow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexPow
,
UNKNOWN
,
3
,
false
,
false
),
{
None
}));
complex_cls
->
giveAttr
(
"__rpow__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRpow
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__mod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexMod
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__divmod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivmod
,
BOXED_TUPLE
,
2
)));
complex_cls
->
giveAttr
(
"__floordiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexFloordiv
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__truediv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivComplex
,
BOXED_COMPLEX
,
2
)));
complex_cls
->
giveAttr
(
"conjugate"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexConjugate
,
BOXED_COMPLEX
,
1
)));
complex_cls
->
giveAttr
(
"__coerce__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexCoerce
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__abs__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexAbs
,
BOXED_FLOAT
,
1
)));
complex_cls
->
giveAttr
(
"__getnewargs__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexGetnewargs
,
BOXED_TUPLE
,
1
)));
complex_cls
->
giveAttr
(
"__nonzero__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexNonzero
,
BOXED_BOOL
,
1
)));
complex_cls
->
giveAttr
(
"__eq__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexEq
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__ne__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexNe
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__le__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexLe
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__lt__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexLt
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__ge__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexGe
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__gt__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexGt
,
UNKNOWN
,
2
)));
complex_cls
->
giveAttr
(
"__neg__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexNeg
,
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
(
"__str__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexStr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexRepr
,
STR
,
1
)));
complex_cls
->
giveAttr
(
"real"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
real
)));
complex_cls
->
giveAttr
(
"imag"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
DOUBLE
,
offsetof
(
BoxedComplex
,
imag
)));
for
(
auto
&
md
:
complex_methods
)
{
complex_cls
->
giveAttr
(
md
.
ml_name
,
new
BoxedMethodDescriptor
(
&
md
,
complex_cls
));
}
add_operators
(
complex_cls
);
complex_cls
->
freeze
();
complex_cls
->
tp_as_number
->
nb_negative
=
(
unaryfunc
)
complex_neg
;
complex_cls
->
tp_richcompare
=
complex_richcompare
;
}
void
teardownComplex
()
{
}
}
src/runtime/complex.h
deleted
100644 → 0
View file @
9dbcaa45
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_RUNTIME_COMPLEX_H
#define PYSTON_RUNTIME_COMPLEX_H
#include "core/types.h"
namespace
pyston
{
extern
"C"
Box
*
createPureImaginary
(
double
i
);
}
#endif
src/runtime/inline/boxing.h
View file @
1ac82dda
...
...
@@ -26,10 +26,10 @@ extern "C" inline Box* boxFloat(double d) {
return
new
BoxedFloat
(
d
);
}
extern
"C"
inline
Box
*
boxComplex
(
double
r
,
double
i
)
__attribute__
((
visibility
(
"default"
)));
extern
"C"
inline
Box
*
boxComplex
(
double
r
,
double
i
)
{
return
new
BoxedComplex
(
r
,
i
);
}
//
extern "C" inline Box* boxComplex(double r, double i) __attribute__((visibility("default")));
//
extern "C" inline Box* boxComplex(double r, double i) {
//
return new BoxedComplex(r, i);
//
}
extern
"C"
inline
bool
unboxBool
(
Box
*
b
)
__attribute__
((
visibility
(
"default"
)));
extern
"C"
inline
bool
unboxBool
(
Box
*
b
)
{
...
...
src/runtime/inline/link_forcer.cpp
View file @
1ac82dda
...
...
@@ -20,7 +20,7 @@
#include "core/ast.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/complex.h"
//
#include "runtime/complex.h"
#include "runtime/float.h"
#include "runtime/generator.h"
#include "runtime/import.h"
...
...
@@ -69,7 +69,7 @@ void force() {
FORCE
(
createClosure
);
FORCE
(
createGenerator
);
FORCE
(
createLong
);
FORCE
(
createPureImaginary
);
//
FORCE(createPureImaginary);
FORCE
(
createSet
);
FORCE
(
decodeUTF8StringPtr
);
...
...
src/runtime/types.cpp
View file @
1ac82dda
...
...
@@ -35,7 +35,7 @@
#include "core/types.h"
#include "runtime/classobj.h"
#include "runtime/code.h"
#include "runtime/complex.h"
//
#include "runtime/complex.h"
#include "runtime/dict.h"
#include "runtime/file.h"
#include "runtime/hiddenclass.h"
...
...
@@ -568,7 +568,7 @@ BoxedFloat* BoxedModule::getFloatConstant(double d) {
Box
*
BoxedModule
::
getPureImaginaryConstant
(
double
d
)
{
Box
*&
r
=
imaginary_constants
[
getDoubleBits
(
d
)];
if
(
!
r
)
r
=
createPureImaginary
(
d
);
r
=
PyComplex_FromDoubles
(
0.0
,
d
);
return
r
;
}
...
...
@@ -1557,9 +1557,9 @@ void BoxedClosure::gcHandler(GCVisitor* v, Box* b) {
extern
"C"
{
BoxedClass
*
object_cls
,
*
type_cls
,
*
none_cls
,
*
bool_cls
,
*
int_cls
,
*
float_cls
,
*
str_cls
=
NULL
,
*
function_cls
,
*
instancemethod_cls
,
*
list_cls
,
*
slice_cls
,
*
module_cls
,
*
dict_cls
,
*
tuple_cls
,
*
file_cls
,
*
member_descriptor_cls
,
*
closure_cls
,
*
generator_cls
,
*
null_importer_cls
,
*
complex
_cls
,
*
basestring_cls
,
*
property_cls
,
*
staticmethod_cls
,
*
classmethod_cls
,
*
attrwrapper_cls
,
*
pyston
_getset_cls
,
*
capi_getset_cls
,
*
builtin_function_or_method_cls
,
*
attrwrapperiter_cls
,
*
set_cls
,
*
frozenset_cls
;
*
file_cls
,
*
member_descriptor_cls
,
*
closure_cls
,
*
generator_cls
,
*
null_importer_cls
,
*
basestring
_cls
,
*
property_cls
,
*
staticmethod_cls
,
*
classmethod_cls
,
*
attrwrapper_cls
,
*
pyston_getset_cls
,
*
capi
_getset_cls
,
*
builtin_function_or_method_cls
,
*
attrwrapperiter_cls
,
*
set_cls
,
*
frozenset_cls
;
BoxedTuple
*
EmptyTuple
;
}
...
...
@@ -3689,7 +3689,7 @@ void setupRuntime() {
int_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedInt
),
false
,
"int"
);
int_cls
->
tp_flags
|=
Py_TPFLAGS_INT_SUBCLASS
;
bool_cls
=
new
(
0
)
BoxedClass
(
int_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedBool
),
false
,
"bool"
);
complex_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedComplex
),
false
,
"complex"
);
//
complex_cls = new (0) BoxedClass(object_cls, NULL, 0, 0, sizeof(BoxedComplex), false, "complex");
long_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
&
BoxedLong
::
gchandler
,
0
,
0
,
sizeof
(
BoxedLong
),
false
,
"long"
);
long_cls
->
tp_flags
|=
Py_TPFLAGS_LONG_SUBCLASS
;
float_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
NULL
,
0
,
0
,
sizeof
(
BoxedFloat
),
false
,
"float"
);
...
...
@@ -3739,7 +3739,7 @@ void setupRuntime() {
file_cls
->
tp_mro
=
BoxedTuple
::
create
({
file_cls
,
object_cls
});
int_cls
->
tp_mro
=
BoxedTuple
::
create
({
int_cls
,
object_cls
});
bool_cls
->
tp_mro
=
BoxedTuple
::
create
({
bool_cls
,
object_cls
});
complex_cls
->
tp_mro
=
BoxedTuple
::
create
({
complex_cls
,
object_cls
});
//
complex_cls->tp_mro = BoxedTuple::create({ complex_cls, object_cls });
long_cls
->
tp_mro
=
BoxedTuple
::
create
({
long_cls
,
object_cls
});
float_cls
->
tp_mro
=
BoxedTuple
::
create
({
float_cls
,
object_cls
});
function_cls
->
tp_mro
=
BoxedTuple
::
create
({
function_cls
,
object_cls
});
...
...
@@ -3794,7 +3794,7 @@ void setupRuntime() {
file_cls
->
finishInitialization
();
int_cls
->
finishInitialization
();
bool_cls
->
finishInitialization
();
complex_cls
->
finishInitialization
();
//
complex_cls->finishInitialization();
long_cls
->
finishInitialization
();
float_cls
->
finishInitialization
();
function_cls
->
finishInitialization
();
...
...
@@ -3925,7 +3925,6 @@ void setupRuntime() {
setupBool
();
setupLong
();
setupFloat
();
setupComplex
();
setupStr
();
setupList
();
setupDict
();
...
...
@@ -4078,6 +4077,7 @@ void setupRuntime() {
attrwrapperiter_cls
->
tp_iter
=
PyObject_SelfIter
;
attrwrapperiter_cls
->
tp_iternext
=
AttrWrapperIter
::
next_capi
;
PyType_Ready
(
&
PyComplex_Type
);
setupBuiltins
();
_PyExc_Init
();
setupThread
();
...
...
@@ -4181,7 +4181,7 @@ void teardownRuntime() {
teardownList
();
teardownInt
();
teardownFloat
();
teardownComplex
();
//
teardownComplex();
teardownStr
();
teardownBool
();
teardownDict
();
...
...
src/runtime/types.h
View file @
1ac82dda
...
...
@@ -46,8 +46,6 @@ void setupInt();
void
teardownInt
();
void
setupFloat
();
void
teardownFloat
();
void
setupComplex
();
void
teardownComplex
();
void
setupStr
();
void
teardownStr
();
void
setupList
();
...
...
@@ -91,13 +89,11 @@ extern "C" {
extern
BoxedClass
*
object_cls
,
*
type_cls
,
*
bool_cls
,
*
int_cls
,
*
long_cls
,
*
float_cls
,
*
str_cls
,
*
function_cls
,
*
none_cls
,
*
instancemethod_cls
,
*
list_cls
,
*
slice_cls
,
*
module_cls
,
*
dict_cls
,
*
tuple_cls
,
*
file_cls
,
*
enumerate_cls
,
*
xrange_cls
,
*
member_descriptor_cls
,
*
null_importer_cls
,
*
method_cls
,
*
closure_cls
,
*
generator_cls
,
*
complex_cls
,
*
basestring_cls
,
*
property_cls
,
*
staticmethod_cls
,
*
classmethod_cls
,
*
attrwrapper
_cls
,
*
pyston_getset_cls
,
*
capi_getset_cls
,
*
builtin_function_or_method_cls
,
*
set_cls
,
*
frozenset_cls
,
*
code
_cls
,
*
frame_cls
,
*
capifunc_cls
,
*
wrapperdescr_cls
,
*
wrapperobject_cls
;
*
basestring_cls
,
*
property_cls
,
*
staticmethod_cls
,
*
classmethod_cls
,
*
attrwrapper_cls
,
*
pyston_getset
_cls
,
*
capi_getset_cls
,
*
builtin_function_or_method_cls
,
*
set_cls
,
*
frozenset_cls
,
*
code_cls
,
*
frame_cls
,
*
capifunc
_cls
,
*
wrapperdescr_cls
,
*
wrapperobject_cls
;
}
#define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type)
#define complex_cls (&PyComplex_Type)
#define unicode_cls (&PyUnicode_Type)
#define memoryview_cls (&PyMemoryView_Type)
...
...
@@ -380,15 +376,15 @@ public:
static_assert
(
sizeof
(
BoxedFloat
)
==
sizeof
(
PyFloatObject
),
""
);
static_assert
(
offsetof
(
BoxedFloat
,
d
)
==
offsetof
(
PyFloatObject
,
ob_fval
),
""
);
class
BoxedComplex
:
public
Box
{
public:
double
real
;
double
imag
;
BoxedComplex
(
double
r
,
double
i
)
__attribute__
((
visibility
(
"default"
)))
:
real
(
r
),
imag
(
i
)
{}
DEFAULT_CLASS_SIMPLE
(
complex_cls
);
};
//
class BoxedComplex : public Box {
//
public:
//
double real;
//
double imag;
//
//
BoxedComplex(double r, double i) __attribute__((visibility("default"))) : real(r), imag(i) {}
//
//
DEFAULT_CLASS_SIMPLE(complex_cls);
//
};
class
BoxedBool
:
public
BoxedInt
{
public:
...
...
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