Implement Turmit.__call__() + bugfixes

Bugfixes in Turmit tests and in rpn op wrapper (in argument orders)

Add small test for Turmit.__call__()
This commit is contained in:
Yann Weber 2018-05-13 18:10:21 +02:00
commit 8957f507db
3 changed files with 51 additions and 15 deletions

View file

@ -23,7 +23,11 @@ def RpnOp(method):
def wrapped(self):
narg = len(inspect.signature(method).parameters)-1
args = [ self._pop() for _ in range(narg) ]
args.reverse()
try:
res = method(self, *args)
except ZeroDivisionError:
res = None
if res is None:
return None
try:
@ -31,10 +35,7 @@ def RpnOp(method):
if not isinstance(topush, int):
raise ValueError('Turmit.%s() returned a list containing a\
%s : %s' % (method.__name__, type(topush), topush))
if self._max_int is not None:
topush %= self._max_int
if not self._signed_int and topush < 0:
topush = self._max_int - topush
topush = self._cast_int(topush)
self._push(topush)
except TypeError:
if not isinstance(res, int):

View file

@ -70,6 +70,19 @@ class Turmit(object):
if self._prog is None:
self._prog = RpnExpr.random(self._prog_sz)
def __call__(self, **context):
''' @brief Exec the RPN expression and return the stack head
@param context dict : dict with variable values (see @ref rpnlib._var_list)
@return stack head after RPN
'''
for sym in self._prog:
if sym.optype == RpnSymbol.VALUE:
self._push(sym.value)
elif sym.optype == RpnSymbol.VARIABLE:
self._push(context[sym.value.lower()])
elif sym.optype == RpnSymbol.OPERATION:
getattr(self, sym.value.lower())()
return self.shead
@property
def shead(self):
@ -101,7 +114,20 @@ class Turmit(object):
self._cur += 1
if self._cur >= len(self._stack):
self._cur = 0
self._stack[self._cur] = val
self._stack[self._cur] = self._cast_int(val)
def _cast_int(self, val):
''' @brief Transform integer given Turmit max int and signed_int
attr
@param val int : integer to transform
@return integer
'''
val = int(val)
if self._max_int is not None:
val %= self._max_int
if not self._signed_int and val < 0:
val = self._max_int - val
return val
@RpnOp
def mem_sz(self, new_sz):

View file

@ -24,9 +24,18 @@ class TurmitTestCase(unittest.TestCase):
self.assertEqual(t._max_int, 42)
t = Turmit(signed_int = False)
self.assertFalse(t._signed_int)
t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 42,
t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
signed_int = False, stack_size=42)
def test_call(self):
''' Test Turmit.__call__ '''
t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
signed_int = False, stack_size=42)
r = t(x=1, y=2, r=255, g=255, b=255)
self.assertEqual(r, 9)
r = t(x=2, y=2, r=255, g=0, b=0)
self.assertEqual(r, 3)
def test_init_badargs(self):
''' Test Turmit __init__ bad arguments '''
with self.assertRaises(RuntimeError):
@ -104,15 +113,15 @@ class TurmitOperationTestCase(unittest.TestCase):
t = Turmit()
t._push(8)
t._push(50)
t._push(8)
t.sub()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 42)
t._push(8)
t._push(50)
t._push(8)
t.sub()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 42)
@ -150,8 +159,8 @@ class TurmitOperationTestCase(unittest.TestCase):
t = Turmit()
t._push(7)
t._push(43)
t._push(7)
t.div()
self.assertEqual(t._cur, 0)
@ -162,8 +171,8 @@ class TurmitOperationTestCase(unittest.TestCase):
self._rpn('mod')
t = Turmit()
t._push(4)
t._push(42)
t._push(4)
t.mod()
self.assertEqual(t._cur, 0)
@ -174,8 +183,8 @@ class TurmitOperationTestCase(unittest.TestCase):
self._rpn('pow')
t = Turmit()
t._push(4)
t._push(2)
t._push(4)
t.pow()
self.assertEqual(t._cur, 0)
@ -198,8 +207,8 @@ class TurmitOperationTestCase(unittest.TestCase):
self._rpn('bin_and')
t = Turmit()
t._push(42)
t._push(10)
t._push(42)
t.bin_and()
@ -236,8 +245,8 @@ class TurmitOperationTestCase(unittest.TestCase):
self._rpn('rshift')
t = Turmit()
t._push(2)
t._push(42)
t._push(2)
t.rshift()
self.assertEqual(t._cur, 0)
@ -248,8 +257,8 @@ class TurmitOperationTestCase(unittest.TestCase):
self._rpn('lshift')
t = Turmit()
t._push(2)
t._push(10)
t._push(2)
t.lshift()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 40)