From 8957f507db33af43e0e11dda7163f67e5025b76b Mon Sep 17 00:00:00 2001 From: Yann Weber Date: Sun, 13 May 2018 18:10:21 +0200 Subject: [PATCH] Implement Turmit.__call__() + bugfixes Bugfixes in Turmit tests and in rpn op wrapper (in argument orders) Add small test for Turmit.__call__() --- gte/rpnlib.py | 11 ++++++----- gte/turmit.py | 28 +++++++++++++++++++++++++++- tests/test_turmit.py | 27 ++++++++++++++++++--------- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/gte/rpnlib.py b/gte/rpnlib.py index 4cb4c1f..9c1c27f 100644 --- a/gte/rpnlib.py +++ b/gte/rpnlib.py @@ -23,7 +23,11 @@ def RpnOp(method): def wrapped(self): narg = len(inspect.signature(method).parameters)-1 args = [ self._pop() for _ in range(narg) ] - res = method(self, *args) + 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): diff --git a/gte/turmit.py b/gte/turmit.py index 9b1bc32..06c0129 100644 --- a/gte/turmit.py +++ b/gte/turmit.py @@ -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): diff --git a/tests/test_turmit.py b/tests/test_turmit.py index 2768924..9a56feb 100644 --- a/tests/test_turmit.py +++ b/tests/test_turmit.py @@ -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)