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
e6ba3768
Commit
e6ba3768
authored
Nov 06, 2015
by
Boxiang Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
some improvements that let test_fractions could pass
parent
48b9a874
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
186 additions
and
51 deletions
+186
-51
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+7
-2
src/runtime/complex.cpp
src/runtime/complex.cpp
+19
-0
src/runtime/float.cpp
src/runtime/float.cpp
+88
-11
src/runtime/long.cpp
src/runtime/long.cpp
+72
-38
No files found.
src/runtime/classobj.cpp
View file @
e6ba3768
...
@@ -1528,8 +1528,13 @@ Box* instanceLong(Box* _inst) {
...
@@ -1528,8 +1528,13 @@ Box* instanceLong(Box* _inst) {
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
static
BoxedString
*
long_str
=
internStringImmortal
(
"__long__"
);
static
BoxedString
*
long_str
=
internStringImmortal
(
"__long__"
);
Box
*
long_func
=
_instanceGetattribute
(
inst
,
long_str
,
true
);
if
(
PyObject_HasAttr
((
PyObject
*
)
inst
,
long_str
))
{
return
runtimeCall
(
long_func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Box
*
long_func
=
_instanceGetattribute
(
inst
,
long_str
,
true
);
return
runtimeCall
(
long_func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
}
Box
*
res
=
instanceInt
(
inst
);
return
res
;
}
}
Box
*
instanceFloat
(
Box
*
_inst
)
{
Box
*
instanceFloat
(
Box
*
_inst
)
{
...
...
src/runtime/complex.cpp
View file @
e6ba3768
...
@@ -541,6 +541,23 @@ Box* complexPow(BoxedComplex* lhs, Box* _rhs, Box* mod) {
...
@@ -541,6 +541,23 @@ Box* complexPow(BoxedComplex* lhs, Box* _rhs, Box* mod) {
return
boxComplex
(
p
.
real
,
p
.
imag
);
return
boxComplex
(
p
.
real
,
p
.
imag
);
}
}
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
)
{
Box
*
complexHash
(
BoxedComplex
*
self
)
{
if
(
!
PyComplex_Check
(
self
))
if
(
!
PyComplex_Check
(
self
))
raiseExcHelper
(
TypeError
,
"descriptor '__hash__' requires a 'complex' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__hash__' requires a 'complex' object but received a '%s'"
,
...
@@ -1254,6 +1271,8 @@ void setupComplex() {
...
@@ -1254,6 +1271,8 @@ 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
*
)
complexRpow
,
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
(
"__divmod__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivmod
,
BOXED_TUPLE
,
2
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
complexDivmod
,
BOXED_TUPLE
,
2
)));
...
...
src/runtime/float.cpp
View file @
e6ba3768
...
@@ -54,8 +54,13 @@ extern "C" double PyFloat_AsDouble(PyObject* o) noexcept {
...
@@ -54,8 +54,13 @@ extern "C" double PyFloat_AsDouble(PyObject* o) noexcept {
if
(
o
->
cls
==
int_cls
||
o
->
cls
==
bool_cls
)
if
(
o
->
cls
==
int_cls
||
o
->
cls
==
bool_cls
)
return
(
double
)
static_cast
<
BoxedInt
*>
(
o
)
->
n
;
return
(
double
)
static_cast
<
BoxedInt
*>
(
o
)
->
n
;
// special case: long
// special case: long
if
(
o
->
cls
==
long_cls
)
if
(
o
->
cls
==
long_cls
)
{
return
mpz_get_d
(
static_cast
<
BoxedLong
*>
(
o
)
->
n
);
double
result
=
PyLong_AsDouble
(
static_cast
<
BoxedLong
*>
(
o
));
if
(
result
==
-
1.0
&&
PyErr_Occurred
())
return
-
1.0
;
return
result
;
}
// implementation from cpython:
// implementation from cpython:
PyNumberMethods
*
nb
;
PyNumberMethods
*
nb
;
...
@@ -125,7 +130,11 @@ extern "C" Box* floatAdd(BoxedFloat* lhs, Box* rhs) {
...
@@ -125,7 +130,11 @@ extern "C" Box* floatAdd(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatAddFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
+
PyLong_AsDouble
(
rhs
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
lhs
->
d
+
rhs_f
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -152,7 +161,11 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -152,7 +161,11 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
/
PyLong_AsDouble
(
rhs
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
lhs
->
d
/
rhs_f
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -165,7 +178,11 @@ extern "C" Box* floatTruediv(BoxedFloat* lhs, Box* rhs) {
...
@@ -165,7 +178,11 @@ extern "C" Box* floatTruediv(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
/
PyLong_AsDouble
(
rhs
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
lhs
->
d
/
rhs_f
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -192,7 +209,11 @@ extern "C" Box* floatRDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -192,7 +209,11 @@ extern "C" Box* floatRDiv(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
PyLong_AsDouble
(
rhs
)
/
lhs
->
d
);
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
rhs_f
/
lhs
->
d
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -218,6 +239,33 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -218,6 +239,33 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box* rhs) {
return
floatFloorDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatFloorDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatFloorDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatFloorDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
floatFloorDivFloat
(
lhs
,
new
BoxedFloat
(
rhs_f
));
}
else
{
return
NotImplemented
;
}
}
extern
"C"
Box
*
floatRFloorDiv
(
BoxedFloat
*
lhs
,
Box
*
_rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
PyInt_Check
(
_rhs
))
{
BoxedInt
*
rhs
=
(
BoxedInt
*
)
_rhs
;
raiseDivZeroExcIfZero
(
lhs
->
d
);
return
boxFloat
(
floor
(
rhs
->
n
/
lhs
->
d
));
}
else
if
(
_rhs
->
cls
==
float_cls
)
{
BoxedFloat
*
rhs
=
(
BoxedFloat
*
)
_rhs
;
raiseDivZeroExcIfZero
(
lhs
->
d
);
return
boxFloat
(
floor
(
rhs
->
d
/
lhs
->
d
));
}
else
if
(
_rhs
->
cls
==
long_cls
)
{
double
rhs_f
=
PyLong_AsDouble
(
_rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
floatFloorDivFloat
(
new
BoxedFloat
(
rhs_f
),
lhs
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -544,7 +592,11 @@ extern "C" Box* floatMod(BoxedFloat* lhs, Box* rhs) {
...
@@ -544,7 +592,11 @@ extern "C" Box* floatMod(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
mod_float_float
(
lhs
->
d
,
PyLong_AsDouble
(
rhs
)));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
mod_float_float
(
lhs
->
d
,
rhs_f
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -569,7 +621,11 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
...
@@ -569,7 +621,11 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRModFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
mod_float_float
(
PyLong_AsDouble
(
rhs
),
lhs
->
d
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
mod_float_float
(
rhs_f
,
lhs
->
d
));
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -626,7 +682,11 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box* rhs) {
...
@@ -626,7 +682,11 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatMulFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
*
PyLong_AsDouble
(
rhs
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
lhs
->
d
*
rhs_f
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -651,7 +711,11 @@ extern "C" Box* floatSub(BoxedFloat* lhs, Box* rhs) {
...
@@ -651,7 +711,11 @@ extern "C" Box* floatSub(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
lhs
->
d
-
PyLong_AsDouble
(
rhs
));
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
lhs
->
d
-
rhs_f
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -676,7 +740,11 @@ extern "C" Box* floatRSub(BoxedFloat* lhs, Box* rhs) {
...
@@ -676,7 +740,11 @@ extern "C" Box* floatRSub(BoxedFloat* lhs, Box* rhs) {
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatRSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
return
floatRSubFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
long_cls
)
{
}
else
if
(
rhs
->
cls
==
long_cls
)
{
return
boxFloat
(
PyLong_AsDouble
(
rhs
)
-
lhs
->
d
);
double
rhs_f
=
PyLong_AsDouble
(
rhs
);
if
(
rhs_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
boxFloat
(
rhs_f
-
lhs
->
d
);
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
}
...
@@ -782,6 +850,13 @@ template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == C
...
@@ -782,6 +850,13 @@ template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == C
return
static_cast
<
BoxedFloat
*>
(
a
);
return
static_cast
<
BoxedFloat
*>
(
a
);
}
else
if
(
PyInt_Check
(
a
))
{
}
else
if
(
PyInt_Check
(
a
))
{
return
new
BoxedFloat
(
static_cast
<
BoxedInt
*>
(
a
)
->
n
);
return
new
BoxedFloat
(
static_cast
<
BoxedInt
*>
(
a
)
->
n
);
}
else
if
(
PyLong_Check
(
a
))
{
double
a_f
=
PyLong_AsDouble
(
a
);
if
(
a_f
==
-
1.0
&&
PyErr_Occurred
())
{
throwCAPIException
();
}
return
new
BoxedFloat
(
a_f
);
}
else
if
(
a
->
cls
==
str_cls
||
a
->
cls
==
unicode_cls
)
{
}
else
if
(
a
->
cls
==
str_cls
||
a
->
cls
==
unicode_cls
)
{
BoxedFloat
*
res
=
(
BoxedFloat
*
)
PyFloat_FromString
(
a
,
NULL
);
BoxedFloat
*
res
=
(
BoxedFloat
*
)
PyFloat_FromString
(
a
,
NULL
);
...
@@ -1652,6 +1727,8 @@ void setupFloat() {
...
@@ -1652,6 +1727,8 @@ void setupFloat() {
_addFunc
(
"__div__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatDiv
);
_addFunc
(
"__div__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatDiv
);
_addFunc
(
"__rdiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatRDivFloat
,
(
void
*
)
floatRDivInt
,
(
void
*
)
floatRDiv
);
_addFunc
(
"__rdiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatRDivFloat
,
(
void
*
)
floatRDivInt
,
(
void
*
)
floatRDiv
);
_addFunc
(
"__floordiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatFloorDivFloat
,
(
void
*
)
floatFloorDivInt
,
(
void
*
)
floatFloorDiv
);
_addFunc
(
"__floordiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatFloorDivFloat
,
(
void
*
)
floatFloorDivInt
,
(
void
*
)
floatFloorDiv
);
float_cls
->
giveAttr
(
"__rfloordiv__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
floatRFloorDiv
,
BOXED_FLOAT
,
2
)));
_addFunc
(
"__truediv__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatTruediv
);
_addFunc
(
"__truediv__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatTruediv
);
_addFunc
(
"__mod__"
,
BOXED_FLOAT
,
(
void
*
)
floatModFloat
,
(
void
*
)
floatModInt
,
(
void
*
)
floatMod
);
_addFunc
(
"__mod__"
,
BOXED_FLOAT
,
(
void
*
)
floatModFloat
,
(
void
*
)
floatModInt
,
(
void
*
)
floatMod
);
...
...
src/runtime/long.cpp
View file @
e6ba3768
...
@@ -15,7 +15,9 @@
...
@@ -15,7 +15,9 @@
#include "runtime/long.h"
#include "runtime/long.h"
#include <cmath>
#include <cmath>
#include <float.h>
#include <gmp.h>
#include <gmp.h>
#include <mpfr.h>
#include <sstream>
#include <sstream>
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/raw_ostream.h"
...
@@ -212,17 +214,18 @@ extern "C" PyObject* PyLong_FromString(const char* str, char** pend, int base) n
...
@@ -212,17 +214,18 @@ extern "C" PyObject* PyLong_FromString(const char* str, char** pend, int base) n
BoxedLong
*
rtn
=
new
BoxedLong
();
BoxedLong
*
rtn
=
new
BoxedLong
();
int
r
=
0
;
int
r
=
0
;
if
(
str
[
strlen
(
str
)
-
1
]
==
'L'
||
str
[
strlen
(
str
)
-
1
]
==
'l'
)
{
if
(
(
str
[
strlen
(
str
)
-
1
]
==
'L'
||
str
[
strlen
(
str
)
-
1
]
==
'l'
)
&&
base
<
22
)
{
std
::
string
without_l
(
str
,
strlen
(
str
)
-
1
);
std
::
string
without_l
(
str
,
strlen
(
str
)
-
1
);
r
=
mpz_init_set_str
(
rtn
->
n
,
without_l
.
c_str
(),
base
);
r
=
mpz_init_set_str
(
rtn
->
n
,
without_l
.
c_str
(),
base
);
}
else
{
}
else
{
// if base great than 22, 'l' or 'L' should count as a digit.
r
=
mpz_init_set_str
(
rtn
->
n
,
str
,
base
);
r
=
mpz_init_set_str
(
rtn
->
n
,
str
,
base
);
}
}
if
(
pend
)
if
(
pend
)
*
pend
=
const_cast
<
char
*>
(
str
)
+
strlen
(
str
);
*
pend
=
const_cast
<
char
*>
(
str
)
+
strlen
(
str
);
if
(
r
!=
0
)
{
if
(
r
!=
0
)
{
PyErr_Format
(
PyExc_ValueError
,
"invalid literal for long() with base %d:
%s
"
,
base
,
str
);
PyErr_Format
(
PyExc_ValueError
,
"invalid literal for long() with base %d:
'%s'
"
,
base
,
str
);
return
NULL
;
return
NULL
;
}
}
...
@@ -347,15 +350,17 @@ extern "C" long PyLong_AsLongAndOverflow(Box* vv, int* overflow) noexcept {
...
@@ -347,15 +350,17 @@ extern "C" long PyLong_AsLongAndOverflow(Box* vv, int* overflow) noexcept {
extern
"C"
double
PyLong_AsDouble
(
PyObject
*
vv
)
noexcept
{
extern
"C"
double
PyLong_AsDouble
(
PyObject
*
vv
)
noexcept
{
RELEASE_ASSERT
(
PyLong_Check
(
vv
),
""
);
RELEASE_ASSERT
(
PyLong_Check
(
vv
),
""
);
BoxedLong
*
l
=
static_cast
<
BoxedLong
*>
(
vv
);
BoxedLong
*
l
=
static_cast
<
BoxedLong
*>
(
vv
);
mpfr_t
result
;
mpfr_init
(
result
);
mpfr_init_set_z
(
result
,
l
->
n
,
MPFR_RNDN
);
double
result
=
mpz_get_d
(
l
->
n
);
double
result_f
=
mpfr_get_d
(
result
,
MPFR_RNDN
);
if
(
isinf
(
result_f
))
{
if
(
std
::
isinf
(
result
))
{
PyErr_SetString
(
PyExc_OverflowError
,
"long int too large to convert to float"
);
PyErr_SetString
(
PyExc_OverflowError
,
"long int too large to convert to float"
);
return
-
1
;
return
-
1
;
}
}
return
result
;
return
result
_f
;
}
}
/* Convert the long to a string object with given base,
/* Convert the long to a string object with given base,
...
@@ -463,7 +468,10 @@ extern "C" PyObject* PyLong_FromSize_t(size_t ival) noexcept {
...
@@ -463,7 +468,10 @@ extern "C" PyObject* PyLong_FromSize_t(size_t ival) noexcept {
#undef IS_LITTLE_ENDIAN
#undef IS_LITTLE_ENDIAN
extern
"C"
double
_PyLong_Frexp
(
PyLongObject
*
a
,
Py_ssize_t
*
e
)
noexcept
{
extern
"C"
double
_PyLong_Frexp
(
PyLongObject
*
a
,
Py_ssize_t
*
e
)
noexcept
{
Py_FatalError
(
"unimplemented"
);
BoxedLong
*
v
=
(
BoxedLong
*
)
a
;
double
result
=
mpz_get_d_2exp
(
e
,
v
->
n
);
static_assert
(
sizeof
(
Py_ssize_t
)
==
8
,
"need to add overflow checking"
);
return
result
;
}
}
/* Create a new long (or int) object from a C pointer */
/* Create a new long (or int) object from a C pointer */
...
@@ -698,11 +706,11 @@ template <ExceptionStyle S> Box* _longNew(Box* val, Box* _base) noexcept(S == CA
...
@@ -698,11 +706,11 @@ template <ExceptionStyle S> Box* _longNew(Box* val, Box* _base) noexcept(S == CA
if
(
s
->
size
()
!=
strlen
(
s
->
data
()))
{
if
(
s
->
size
()
!=
strlen
(
s
->
data
()))
{
Box
*
srepr
=
PyObject_Repr
(
val
);
Box
*
srepr
=
PyObject_Repr
(
val
);
if
(
S
==
CAPI
)
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
PyExc_ValueError
,
"invalid literal for long() with base %d:
%s
"
,
base
,
PyErr_Format
(
PyExc_ValueError
,
"invalid literal for long() with base %d:
'%s'
"
,
base
,
PyString_AS_STRING
(
srepr
));
PyString_AS_STRING
(
srepr
));
return
NULL
;
return
NULL
;
}
else
{
}
else
{
raiseExcHelper
(
ValueError
,
"invalid literal for long() with base %d:
%s
"
,
base
,
raiseExcHelper
(
ValueError
,
"invalid literal for long() with base %d:
'%s'
"
,
base
,
PyString_AS_STRING
(
srepr
));
PyString_AS_STRING
(
srepr
));
}
}
}
}
...
@@ -780,8 +788,8 @@ Box* longFloat(BoxedLong* v) {
...
@@ -780,8 +788,8 @@ Box* longFloat(BoxedLong* v) {
double
result
=
PyLong_AsDouble
(
v
);
double
result
=
PyLong_AsDouble
(
v
);
if
(
result
==
-
1
)
if
(
result
==
-
1
.0
&&
PyErr_Occurred
()
)
checkAndT
hrowCAPIException
();
t
hrowCAPIException
();
return
new
BoxedFloat
(
result
);
return
new
BoxedFloat
(
result
);
}
}
...
@@ -1241,18 +1249,32 @@ Box* longTrueDiv(BoxedLong* v1, Box* _v2) {
...
@@ -1241,18 +1249,32 @@ Box* longTrueDiv(BoxedLong* v1, Box* _v2) {
raiseExcHelper
(
TypeError
,
"descriptor '__truediv__' requires a 'long' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__truediv__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
getTypeName
(
v1
));
// We only support args which fit into an int for now...
BoxedLong
*
v2
;
i
nt
overflow
=
0
;
i
f
(
PyInt_Check
(
_v2
)
||
PyLong_Check
(
_v2
))
{
long
lhs
=
PyLong_AsLongAndOverflow
(
v1
,
&
overflow
);
v2
=
(
BoxedLong
*
)
PyNumber_Long
(
_v2
);
if
(
overflow
)
if
(
!
v2
)
{
return
NotImplemented
;
throwCAPIException
()
;
long
rhs
=
PyLong_AsLongAndOverflow
(
_v2
,
&
overflow
);
}
if
(
overflow
)
}
else
{
return
NotImplemented
;
return
NotImplemented
;
}
if
(
rhs
==
0
)
if
(
mpz_sgn
(
v2
->
n
)
==
0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
return
boxFloat
(
lhs
/
(
double
)
rhs
);
}
mpfr_t
lhs_f
,
rhs_f
,
result
;
mpfr_init
(
result
);
mpfr_init_set_z
(
lhs_f
,
v1
->
n
,
MPFR_RNDN
);
mpfr_init_set_z
(
rhs_f
,
v2
->
n
,
MPFR_RNDZ
);
mpfr_div
(
result
,
lhs_f
,
rhs_f
,
MPFR_RNDN
);
double
result_f
=
mpfr_get_d
(
result
,
MPFR_RNDN
);
if
(
isinf
(
result_f
))
{
raiseExcHelper
(
OverflowError
,
"integer division result too large for a float"
);
}
return
boxFloat
(
result_f
);
}
}
Box
*
longRTrueDiv
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
Box
*
longRTrueDiv
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
...
@@ -1260,18 +1282,27 @@ Box* longRTrueDiv(BoxedLong* v1, Box* _v2) {
...
@@ -1260,18 +1282,27 @@ Box* longRTrueDiv(BoxedLong* v1, Box* _v2) {
raiseExcHelper
(
TypeError
,
"descriptor '__rtruediv__' requires a 'long' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__rtruediv__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
getTypeName
(
v1
));
// We only support args which fit into an int for now...
BoxedLong
*
v2
;
int
overflow
=
0
;
if
(
PyInt_Check
(
_v2
)
||
PyLong_Check
(
_v2
))
{
long
lhs
=
PyLong_AsLongAndOverflow
(
_v2
,
&
overflow
);
v2
=
(
BoxedLong
*
)
PyNumber_Long
(
_v2
);
if
(
overflow
)
}
else
{
return
NotImplemented
;
long
rhs
=
PyLong_AsLongAndOverflow
(
v1
,
&
overflow
);
if
(
overflow
)
return
NotImplemented
;
return
NotImplemented
;
}
if
(
rhs
==
0
)
if
(
mpz_sgn
(
v2
->
n
)
==
0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
return
boxFloat
(
lhs
/
(
double
)
rhs
);
}
mpfr_t
lhs_f
,
rhs_f
,
result
;
mpfr_init
(
result
);
mpfr_init_set_z
(
lhs_f
,
v2
->
n
,
MPFR_RNDN
);
mpfr_init_set_z
(
rhs_f
,
v1
->
n
,
MPFR_RNDZ
);
mpfr_div
(
result
,
lhs_f
,
rhs_f
,
MPFR_RNDN
);
double
result_f
=
mpfr_get_d
(
result
,
MPFR_RNDZ
);
if
(
isinf
(
result_f
))
{
raiseExcHelper
(
OverflowError
,
"integer division result too large for a float"
);
}
return
boxFloat
(
result_f
);
}
}
static
void
_addFuncPow
(
const
char
*
name
,
ConcreteCompilerType
*
rtn_type
,
void
*
float_func
,
void
*
long_func
)
{
static
void
_addFuncPow
(
const
char
*
name
,
ConcreteCompilerType
*
rtn_type
,
void
*
float_func
,
void
*
long_func
)
{
...
@@ -1393,14 +1424,17 @@ Box* longHash(BoxedLong* self) {
...
@@ -1393,14 +1424,17 @@ Box* longHash(BoxedLong* self) {
if
(
mpz_fits_slong_p
(
self
->
n
))
if
(
mpz_fits_slong_p
(
self
->
n
))
return
boxInt
(
mpz_get_si
(
self
->
n
));
return
boxInt
(
mpz_get_si
(
self
->
n
));
// Not sure if this is a good hash function or not;
// CPython use the absolute value of self mod ULONG_MAX.
// simple, but only includes top bits:
unsigned
long
remainder
=
mpz_tdiv_ui
(
self
->
n
,
ULONG_MAX
);
union
{
if
(
remainder
==
0
)
uint64_t
n
;
remainder
=
-
1
;
// CPython compatibility -- ULONG_MAX mod ULONG_MAX is ULONG_MAX to them.
double
d
;
};
remainder
*=
mpz_sgn
(
self
->
n
);
d
=
mpz_get_d
(
self
->
n
);
return
boxInt
(
n
);
if
(
remainder
==
-
1
)
remainder
=
-
2
;
return
boxInt
(
remainder
);
}
}
extern
"C"
Box
*
longTrunc
(
BoxedLong
*
self
)
{
extern
"C"
Box
*
longTrunc
(
BoxedLong
*
self
)
{
...
...
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