Skip to content

Commit 2164099

Browse files
committed
implement most bit-* on integers
unsigned-bit-shift-right is missing, but the others are there.
1 parent 952cbc8 commit 2164099

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

pixie/vm/bits.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from pixie.vm.code import as_var
2+
from pixie.vm.object import affirm
3+
4+
from pixie.vm.numbers import Integer
5+
6+
import pixie.vm.rt as rt
7+
8+
@as_var("bit-clear")
9+
def bit_clear(x, n):
10+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
11+
return rt.wrap(x.int_val() & ~(1 << n.int_val()))
12+
13+
@as_var("bit-set")
14+
def bit_set(x, n):
15+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
16+
return rt.wrap(x.int_val() | (1 << n.int_val()))
17+
18+
@as_var("bit-flip")
19+
def bit_flip(x, n):
20+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
21+
return rt.wrap(x.int_val() ^ (1 << n.int_val()))
22+
23+
@as_var("bit-test")
24+
def bit_test(x, n):
25+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
26+
return rt.wrap((x.int_val() & (1 << n.int_val())) != 0)
27+
28+
@as_var("bit-and")
29+
def bit_and(x, y):
30+
affirm(isinstance(x, Integer) and isinstance(y, Integer), u"x and y must be Integers")
31+
return rt.wrap(x.int_val() & y.int_val())
32+
33+
@as_var("bit-or")
34+
def bit_or(x, y):
35+
affirm(isinstance(x, Integer) and isinstance(y, Integer), u"x and y must be Integers")
36+
return rt.wrap(x.int_val() | y.int_val())
37+
38+
@as_var("bit-xor")
39+
def bit_xor(x, y):
40+
affirm(isinstance(x, Integer) and isinstance(y, Integer), u"x and y must be Integers")
41+
return rt.wrap(x.int_val() ^ y.int_val())
42+
43+
@as_var("bit-shift-left")
44+
def bit_shift_left(x, n):
45+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
46+
return rt.wrap(x.int_val() << n.int_val())
47+
48+
@as_var("bit-shift-right")
49+
def bit_shift_right(x, n):
50+
affirm(isinstance(x, Integer) and isinstance(n, Integer), u"x and n must be Integers")
51+
return rt.wrap(x.int_val() >> n.int_val())
52+
53+
# unsigned-bit-shift-right (sets sign bit to zero)
54+
55+
digits = "0123456789abcdefghijklmnopqrstuvwxyz"
56+
57+
@as_var("bit-str")
58+
def bit_str(x, shift):
59+
affirm(isinstance(x, Integer) and isinstance(shift, Integer), u"x and shift must be Integers")
60+
x = x.int_val()
61+
shift = shift.int_val()
62+
63+
buf = ['_'] * 32
64+
char_pos = 32
65+
radix = 1 << shift
66+
mask = radix - 1
67+
while True:
68+
char_pos -= 1
69+
buf[char_pos] = digits[x & mask]
70+
x = x >> shift
71+
if x == 0:
72+
break
73+
74+
res = ""
75+
for i in range(char_pos, char_pos + 32 - char_pos):
76+
res += buf[i]
77+
return rt.wrap(res)

pixie/vm/rt.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def wrapper(*args):
4848
sys.setrecursionlimit(10000) # Yeah we blow the stack sometimes, we promise it's not a bug
4949

5050
import pixie.vm.numbers as numbers
51+
import pixie.vm.bits as bits
5152
from pixie.vm.code import wrap_fn
5253
import pixie.vm.interpreter
5354
import pixie.vm.stacklet as stacklet

0 commit comments

Comments
 (0)