# HG changeset patch # User Paul Boddie # Date 1491176207 -7200 # Node ID 4f77605e14e883a6036ecf99069b04fd311f433c # Parent 6487964362bacf51058af435dd17f899da424287 Added support for left and right shift operators. diff -r 6487964362ba -r 4f77605e14e8 lib/__builtins__/int.py --- a/lib/__builtins__/int.py Mon Apr 03 00:13:46 2017 +0200 +++ b/lib/__builtins__/int.py Mon Apr 03 01:36:47 2017 +0200 @@ -22,9 +22,9 @@ from __builtins__.operator import _negate from __builtins__.unicode import utf8string from native import get_maxint, get_minint, is_int, \ - int_add, int_and, int_div, int_eq, int_gt, int_lt, int_mod, \ - int_mul, int_ne, int_neg, int_not, int_or, int_pow, \ - int_str, int_sub, int_xor + int_add, int_and, int_div, int_eq, int_gt, int_lshift, \ + int_lt, int_mod, int_mul, int_ne, int_neg, int_not, \ + int_or, int_pow, int_rshift, int_str, int_sub, int_xor class int: @@ -164,6 +164,34 @@ __or__ = __ror__ = __ior__ __xor__ = __rxor__ = __ixor__ + def __lshift__(self, other): + + "Return a new int left-shifted by 'other'." + + return self._binary_op(int_lshift, other) + + def __rlshift__(self, other): + + "Return a new int left-shifted by 'other'." + + return self._binary_op_rev(int_lshift, other) + + def __rshift__(self, other): + + "Return a new int right-shifted by 'other'." + + return self._binary_op(int_rshift, other) + + def __rrshift__(self, other): + + "Return a new int right-shifted by 'other'." + + return self._binary_op_rev(int_rshift, other) + + __ilshift__ = __lshift__ + + __irshift__ = __rshift__ + def __lt__(self, other): "Return whether this int is less than 'other'." @@ -220,13 +248,6 @@ __repr__ = __str__ - def __lshift__(self): pass - def __rlshift__(self): pass - def __rshift__(self): pass - def __rrshift__(self): pass - def __ilshift__(self): pass - def __irshift__(self): pass - def __bool__(self): "Return whether this int is non-zero." diff -r 6487964362ba -r 4f77605e14e8 lib/native/__init__.py --- a/lib/native/__init__.py Mon Apr 03 00:13:46 2017 +0200 +++ b/lib/native/__init__.py Mon Apr 03 01:36:47 2017 +0200 @@ -25,6 +25,7 @@ from native.int import int_add, int_div, int_mod, int_mul, int_neg, int_pow, \ int_sub, int_and, int_not, int_or, int_xor, \ + int_lshift, int_rshift, \ int_eq, int_ge, int_gt, int_le, int_lt, int_ne, \ int_str, is_int diff -r 6487964362ba -r 4f77605e14e8 lib/native/int.py --- a/lib/native/int.py Mon Apr 03 00:13:46 2017 +0200 +++ b/lib/native/int.py Mon Apr 03 01:36:47 2017 +0200 @@ -42,6 +42,9 @@ def int_or(self, other): return 0 def int_xor(self, other): return 0 +def int_lshift(self, other): return 0 +def int_rshift(self, other): return 0 + def int_eq(self, other): return True or False def int_ge(self, other): return True or False def int_gt(self, other): return True or False diff -r 6487964362ba -r 4f77605e14e8 lib/operator/binary.py --- a/lib/operator/binary.py Mon Apr 03 00:13:46 2017 +0200 +++ b/lib/operator/binary.py Mon Apr 03 01:36:47 2017 +0200 @@ -21,6 +21,7 @@ from operator.core import binary_op, is_, is_not from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \ + int_lshift, int_rshift, \ int_and, int_not, int_or, int_xor, \ is_int @@ -58,6 +59,8 @@ return not b.__contains__(a) def lshift(a, b): + if is_int(a) and is_int(b): + return int_lshift(a, b) return binary_op(a, b, lambda a: a.__lshift__, lambda b: b.__rlshift__) def mod(a, b): @@ -81,6 +84,8 @@ return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__) def rshift(a, b): + if is_int(a) and is_int(b): + return int_rshift(a, b) return binary_op(a, b, lambda a: a.__rshift__, lambda b: b.__rrshift__) def sub(a, b): diff -r 6487964362ba -r 4f77605e14e8 templates/native/int.c --- a/templates/native/int.c Mon Apr 03 00:13:46 2017 +0200 +++ b/templates/native/int.c Mon Apr 03 01:36:47 2017 +0200 @@ -192,6 +192,28 @@ return __new_int(i ^ j); } +__attr __fn_native_int_int_lshift(__attr __self, __attr self, __attr other) +{ + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); + + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i << j); +} + +__attr __fn_native_int_int_rshift(__attr __self, __attr self, __attr other) +{ + /* self and other interpreted as int */ + int i = __TOINT(self); + int j = __TOINT(other); + + /* Return the new integer. */ + /* NOTE: No overflow test applied. */ + return __new_int(i >> j); +} + __attr __fn_native_int_int_le(__attr __self, __attr self, __attr other) { /* self and other interpreted as int */ diff -r 6487964362ba -r 4f77605e14e8 templates/native/int.h --- a/templates/native/int.h Mon Apr 03 00:13:46 2017 +0200 +++ b/templates/native/int.h Mon Apr 03 01:36:47 2017 +0200 @@ -37,6 +37,9 @@ __attr __fn_native_int_int_or(__attr __self, __attr _data, __attr other); __attr __fn_native_int_int_xor(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_lshift(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_rshift(__attr __self, __attr _data, __attr other); + __attr __fn_native_int_int_eq(__attr __self, __attr _data, __attr other); __attr __fn_native_int_int_ge(__attr __self, __attr _data, __attr other); __attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other); diff -r 6487964362ba -r 4f77605e14e8 tests/bitwise.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/bitwise.py Mon Apr 03 01:36:47 2017 +0200 @@ -0,0 +1,7 @@ +def encode(value): + return ((value & 8) << 4) | ((value & 4) << 3) | ((value & 2) << 2) | ((value & 1) << 1) + +print encode(15) # 170 +print encode(8) # 128 +print encode(2) # 8 +print encode(0) # 0