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
d5356e46
Commit
d5356e46
authored
Mar 09, 2015
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 'int << long', 'int >> long', '~long', 'long | long', long.__hex__(), long.__oct__()
parent
020ce1ba
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
253 additions
and
23 deletions
+253
-23
src/runtime/int.cpp
src/runtime/int.cpp
+7
-1
src/runtime/long.cpp
src/runtime/long.cpp
+97
-18
src/runtime/long.h
src/runtime/long.h
+6
-0
src/runtime/str.cpp
src/runtime/str.cpp
+133
-2
test/tests/long.py
test/tests/long.py
+10
-2
No files found.
src/runtime/int.cpp
View file @
d5356e46
...
...
@@ -665,6 +665,9 @@ extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) {
raiseExcHelper
(
TypeError
,
"descriptor '__lshift__' requires a 'int' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
rhs
->
cls
==
long_cls
)
return
longLshift
(
boxLong
(
lhs
->
n
),
rhs
);
if
(
rhs
->
cls
!=
int_cls
)
{
return
NotImplemented
;
}
...
...
@@ -781,6 +784,9 @@ extern "C" Box* intRShift(BoxedInt* lhs, Box* rhs) {
raiseExcHelper
(
TypeError
,
"descriptor '__rshift__' requires a 'int' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
rhs
->
cls
==
long_cls
)
return
longRshift
(
boxLong
(
lhs
->
n
),
rhs
);
if
(
rhs
->
cls
!=
int_cls
)
{
return
NotImplemented
;
}
...
...
@@ -1049,7 +1055,7 @@ void setupInt() {
_addFuncIntUnknown
(
"__ge__"
,
BOXED_BOOL
,
(
void
*
)
intGeInt
,
(
void
*
)
intGe
);
_addFuncIntUnknown
(
"__lshift__"
,
UNKNOWN
,
(
void
*
)
intLShiftInt
,
(
void
*
)
intLShift
);
_addFuncIntUnknown
(
"__rshift__"
,
BOXED_INT
,
(
void
*
)
intRShiftInt
,
(
void
*
)
intRShift
);
_addFuncIntUnknown
(
"__rshift__"
,
UNKNOWN
,
(
void
*
)
intRShiftInt
,
(
void
*
)
intRShift
);
int_cls
->
giveAttr
(
"__invert__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intInvert
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intPos
,
BOXED_INT
,
1
)));
...
...
src/runtime/long.cpp
View file @
d5356e46
...
...
@@ -18,6 +18,8 @@
#include <gmp.h>
#include <sstream>
#include "llvm/Support/raw_ostream.h"
#include "core/common.h"
#include "core/options.h"
#include "core/stats.h"
...
...
@@ -216,8 +218,47 @@ extern "C" double PyLong_AsDouble(PyObject* vv) noexcept {
return
mpz_get_d
(
l
->
n
);
}
/* Convert the long to a string object with given base,
appending a base prefix of 0[box] if base is 2, 8 or 16.
Add a trailing "L" if addL is non-zero.
If newstyle is zero, then use the pre-2.6 behavior of octal having
a leading "0", instead of the prefix "0o" */
extern
"C"
PyAPI_FUNC
(
PyObject
*
)
_PyLong_Format
(
PyObject
*
aa
,
int
base
,
int
addL
,
int
newstyle
)
noexcept
{
Py_FatalError
(
"unimplemented"
);
BoxedLong
*
v
=
(
BoxedLong
*
)
aa
;
RELEASE_ASSERT
(
isSubclass
(
v
->
cls
,
long_cls
),
""
);
RELEASE_ASSERT
(
base
>=
2
&&
base
<=
62
,
""
);
bool
is_negative
=
mpz_sgn
(
v
->
n
)
==
-
1
;
int
space_required
=
mpz_sizeinbase
(
v
->
n
,
base
)
+
2
;
char
*
buf
=
(
char
*
)
malloc
(
space_required
);
mpz_get_str
(
buf
,
base
,
v
->
n
);
std
::
string
str
;
llvm
::
raw_string_ostream
os
(
str
);
if
(
is_negative
)
os
<<
'-'
;
if
(
base
==
2
)
os
<<
"0b"
;
else
if
(
base
==
8
)
os
<<
(
newstyle
?
"0o"
:
"0"
);
else
if
(
base
==
16
)
os
<<
"0x"
;
if
(
is_negative
)
os
<<
buf
+
1
;
// +1 to remove sign
else
os
<<
buf
;
if
(
addL
)
os
<<
"L"
;
os
.
flush
();
auto
rtn
=
new
BoxedString
(
std
::
move
(
str
));
free
(
buf
);
return
rtn
;
}
extern
"C"
PyObject
*
PyLong_FromDouble
(
double
v
)
noexcept
{
...
...
@@ -474,30 +515,25 @@ Box* longInt(Box* v) {
Box
*
longRepr
(
BoxedLong
*
v
)
{
if
(
!
isSubclass
(
v
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__repr__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v
));
int
space_required
=
mpz_sizeinbase
(
v
->
n
,
10
)
+
2
;
// basic size
space_required
+=
1
;
// 'L' suffix
char
*
buf
=
(
char
*
)
malloc
(
space_required
);
mpz_get_str
(
buf
,
10
,
v
->
n
);
strcat
(
buf
,
"L"
);
auto
rtn
=
new
BoxedString
(
buf
);
free
(
buf
);
return
rtn
;
return
_PyLong_Format
(
v
,
10
,
1
/* add L */
,
0
);
}
Box
*
longStr
(
BoxedLong
*
v
)
{
if
(
!
isSubclass
(
v
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__str__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v
));
int
space_required
=
mpz_sizeinbase
(
v
->
n
,
10
)
+
2
;
char
*
buf
=
(
char
*
)
malloc
(
space_required
);
mpz_get_str
(
buf
,
10
,
v
->
n
);
return
_PyLong_Format
(
v
,
10
,
0
/* no L */
,
0
);
}
auto
rtn
=
new
BoxedString
(
buf
);
free
(
buf
);
Box
*
longHex
(
BoxedLong
*
v
)
{
if
(
!
isSubclass
(
v
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__hex__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v
));
return
_PyLong_Format
(
v
,
16
,
1
/* add L */
,
0
);
}
return
rtn
;
Box
*
longOct
(
BoxedLong
*
v
)
{
if
(
!
isSubclass
(
v
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__oct__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v
));
return
_PyLong_Format
(
v
,
8
,
1
/* add L */
,
0
);
}
Box
*
longNeg
(
BoxedLong
*
v1
)
{
...
...
@@ -544,6 +580,7 @@ Box* longAdd(BoxedLong* v1, Box* _v2) {
}
}
// TODO: split common code out into a helper function
extern
"C"
Box
*
longAnd
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__and__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
...
...
@@ -570,6 +607,32 @@ extern "C" Box* longAnd(BoxedLong* v1, Box* _v2) {
return
NotImplemented
;
}
extern
"C"
Box
*
longOr
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__or__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
if
(
isSubclass
(
_v2
->
cls
,
long_cls
))
{
BoxedLong
*
v2
=
static_cast
<
BoxedLong
*>
(
_v2
);
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
mpz_ior
(
r
->
n
,
v1
->
n
,
v2
->
n
);
return
r
;
}
else
if
(
isSubclass
(
_v2
->
cls
,
int_cls
))
{
BoxedInt
*
v2_int
=
static_cast
<
BoxedInt
*>
(
_v2
);
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
mpz_t
v2_long
;
mpz_init
(
v2_long
);
if
(
v2_int
->
n
>=
0
)
mpz_init_set_ui
(
v2_long
,
v2_int
->
n
);
else
mpz_init_set_si
(
v2_long
,
v2_int
->
n
);
mpz_ior
(
r
->
n
,
v1
->
n
,
v2_long
);
return
r
;
}
return
NotImplemented
;
}
extern
"C"
Box
*
longXor
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__xor__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
...
...
@@ -924,6 +987,17 @@ Box* longPow(BoxedLong* v1, Box* _v2) {
return
r
;
}
extern
"C"
Box
*
longInvert
(
BoxedLong
*
v
)
{
if
(
!
isSubclass
(
v
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__invert__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v
));
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
mpz_com
(
r
->
n
,
v
->
n
);
return
r
;
}
Box
*
longNonzero
(
BoxedLong
*
self
)
{
if
(
!
isSubclass
(
self
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'long' object but received a '%s'"
,
...
...
@@ -983,6 +1057,8 @@ void setupLong() {
long_cls
->
giveAttr
(
"__and__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longAnd
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rand__"
,
long_cls
->
getattr
(
"__and__"
));
long_cls
->
giveAttr
(
"__or__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longOr
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__ror__"
,
long_cls
->
getattr
(
"__or__"
));
long_cls
->
giveAttr
(
"__xor__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longXor
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rxor__"
,
long_cls
->
getattr
(
"__xor__"
));
...
...
@@ -999,7 +1075,10 @@ void setupLong() {
long_cls
->
giveAttr
(
"__int__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longInt
,
UNKNOWN
,
1
)));
long_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRepr
,
STR
,
1
)));
long_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longStr
,
STR
,
1
)));
long_cls
->
giveAttr
(
"__hex__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longHex
,
STR
,
1
)));
long_cls
->
giveAttr
(
"__oct__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longOct
,
STR
,
1
)));
long_cls
->
giveAttr
(
"__invert__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longInvert
,
UNKNOWN
,
1
)));
long_cls
->
giveAttr
(
"__nonzero__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longNonzero
,
BOXED_BOOL
,
1
)));
long_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longHash
,
BOXED_INT
,
1
)));
...
...
src/runtime/long.h
View file @
d5356e46
...
...
@@ -48,6 +48,12 @@ Box* longSub(BoxedLong* lhs, Box* rhs);
Box
*
longMul
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longDiv
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longPow
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longLshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longRshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longHex
(
BoxedLong
*
v
);
Box
*
longOct
(
BoxedLong
*
v
);
Box
*
longStr
(
BoxedLong
*
v
);
}
#endif
src/runtime/str.cpp
View file @
d5356e46
...
...
@@ -30,6 +30,7 @@
#include "gc/collector.h"
#include "runtime/capi.h"
#include "runtime/dict.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
...
...
@@ -342,8 +343,138 @@ Py_LOCAL_INLINE(PyObject*) getnextarg(PyObject* args, Py_ssize_t arglen, Py_ssiz
return
NULL
;
}
extern
"C"
PyObject
*
_PyString_FormatLong
(
PyObject
*
,
int
,
int
,
int
,
const
char
**
,
int
*
)
noexcept
{
Py_FatalError
(
"unimplemented"
);
extern
"C"
PyObject
*
_PyString_FormatLong
(
PyObject
*
val
,
int
flags
,
int
prec
,
int
type
,
const
char
**
pbuf
,
int
*
plen
)
noexcept
{
// Pyston change:
RELEASE_ASSERT
(
val
->
cls
==
long_cls
,
""
);
PyObject
*
result
=
NULL
;
char
*
buf
;
Py_ssize_t
i
;
int
sign
;
/* 1 if '-', else 0 */
int
len
;
/* number of characters */
Py_ssize_t
llen
;
int
numdigits
;
/* len == numnondigits + numdigits */
int
numnondigits
=
0
;
switch
(
type
)
{
case
'd'
:
case
'u'
:
// Pyston change:
// result = Py_TYPE(val)->tp_str(val);
result
=
longStr
((
BoxedLong
*
)
val
);
break
;
case
'o'
:
// Pyston change:
// result = Py_TYPE(val)->tp_as_number->nb_oct(val);
result
=
longOct
((
BoxedLong
*
)
val
);
break
;
case
'x'
:
case
'X'
:
numnondigits
=
2
;
// Pyston change:
// result = Py_TYPE(val)->tp_as_number->nb_hex(val);
result
=
longHex
((
BoxedLong
*
)
val
);
break
;
default:
assert
(
!
"'type' not in [duoxX]"
);
}
if
(
!
result
)
return
NULL
;
buf
=
PyString_AsString
(
result
);
if
(
!
buf
)
{
Py_DECREF
(
result
);
return
NULL
;
}
/* To modify the string in-place, there can only be one reference. */
// Pyston change:
// if (Py_REFCNT(result) != 1) {
if
(
0
)
{
PyErr_BadInternalCall
();
return
NULL
;
}
llen
=
PyString_Size
(
result
);
if
(
llen
>
INT_MAX
)
{
PyErr_SetString
(
PyExc_ValueError
,
"string too large in _PyString_FormatLong"
);
return
NULL
;
}
len
=
(
int
)
llen
;
if
(
buf
[
len
-
1
]
==
'L'
)
{
--
len
;
buf
[
len
]
=
'\0'
;
}
sign
=
buf
[
0
]
==
'-'
;
numnondigits
+=
sign
;
numdigits
=
len
-
numnondigits
;
assert
(
numdigits
>
0
);
/* Get rid of base marker unless F_ALT */
if
((
flags
&
F_ALT
)
==
0
)
{
/* Need to skip 0x, 0X or 0. */
int
skipped
=
0
;
switch
(
type
)
{
case
'o'
:
assert
(
buf
[
sign
]
==
'0'
);
/* If 0 is only digit, leave it alone. */
if
(
numdigits
>
1
)
{
skipped
=
1
;
--
numdigits
;
}
break
;
case
'x'
:
case
'X'
:
assert
(
buf
[
sign
]
==
'0'
);
assert
(
buf
[
sign
+
1
]
==
'x'
);
skipped
=
2
;
numnondigits
-=
2
;
break
;
}
if
(
skipped
)
{
buf
+=
skipped
;
len
-=
skipped
;
if
(
sign
)
buf
[
0
]
=
'-'
;
}
assert
(
len
==
numnondigits
+
numdigits
);
assert
(
numdigits
>
0
);
}
/* Fill with leading zeroes to meet minimum width. */
if
(
prec
>
numdigits
)
{
PyObject
*
r1
=
PyString_FromStringAndSize
(
NULL
,
numnondigits
+
prec
);
char
*
b1
;
if
(
!
r1
)
{
Py_DECREF
(
result
);
return
NULL
;
}
b1
=
PyString_AS_STRING
(
r1
);
for
(
i
=
0
;
i
<
numnondigits
;
++
i
)
*
b1
++
=
*
buf
++
;
for
(
i
=
0
;
i
<
prec
-
numdigits
;
i
++
)
*
b1
++
=
'0'
;
for
(
i
=
0
;
i
<
numdigits
;
i
++
)
*
b1
++
=
*
buf
++
;
*
b1
=
'\0'
;
Py_DECREF
(
result
);
result
=
r1
;
buf
=
PyString_AS_STRING
(
result
);
len
=
numnondigits
+
prec
;
}
/* Fix up case for hex conversions. */
if
(
type
==
'X'
)
{
/* Need to convert all lower case letters to upper case.
and need to convert 0x to 0X (and -0x to -0X). */
for
(
i
=
0
;
i
<
len
;
i
++
)
if
(
buf
[
i
]
>=
'a'
&&
buf
[
i
]
<=
'x'
)
buf
[
i
]
-=
'a'
-
'A'
;
}
*
pbuf
=
buf
;
*
plen
=
len
;
return
result
;
}
static
PyObject
*
formatfloat
(
PyObject
*
v
,
int
flags
,
int
prec
,
int
type
)
{
...
...
test/tests/long.py
View file @
d5356e46
...
...
@@ -14,7 +14,9 @@ def test(a, b):
print
a
*
b
,
b
*
a
,
a
.
__mul__
(
b
),
b
.
__mul__
(
a
)
print
a
/
b
,
b
/
a
,
a
.
__div__
(
b
),
b
.
__div__
(
a
)
print
repr
(
a
),
repr
(
b
),
a
<
b
,
a
>
b
,
a
<=
b
,
a
>=
b
,
a
==
b
,
a
!=
b
# print a ^ b, a | b, a & b
if
not
isinstance
(
a
,
float
)
and
not
isinstance
(
b
,
float
):
print
a
^
b
,
a
|
b
,
a
&
b
print
a
.
__hex__
(),
b
.
__hex__
(),
a
.
__oct__
(),
b
.
__oct__
()
print
1L
/
5L
...
...
@@ -22,7 +24,7 @@ print -1L / 5L
print
1L
/
-
5L
print
-
1L
/
-
5L
for
a
in
[
-
5
,
-
1
,
1
,
5
,
-
2L
,
-
1L
,
1L
,
2L
]:
for
a
in
[
-
5
,
-
1
,
1
,
5
,
-
2L
,
-
1L
,
1L
,
2L
,
15L
]:
for
b
in
[
-
5
,
-
1
,
1
,
5
,
-
2L
,
-
1L
,
1L
,
2L
]:
test
(
a
,
b
)
...
...
@@ -36,6 +38,8 @@ print (-2L).__rdiv__(1)
print
(
1L
)
<<
(
2L
)
print
(
1L
)
<<
(
2
)
print
(
1
)
<<
(
1L
)
print
(
1
)
<<
(
128L
)
try
:
print
(
1L
)
<<
(
-
1L
)
except
ValueError
,
e
:
...
...
@@ -45,6 +49,10 @@ try:
except
ValueError
,
e
:
print
e
print
~
(
1L
)
print
~
(
10L
)
print
~
(
-
10L
)
print
long
(
"100"
,
16
)
print
long
(
"100"
,
10
)
print
long
(
"100"
,
26
)
...
...
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