Browse Source

Implement Turmit.__call__() + bugfixes

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

Add small test for Turmit.__call__()
Yann Weber 6 years ago
parent
commit
8957f507db
3 changed files with 51 additions and 15 deletions
  1. 6
    5
      gte/rpnlib.py
  2. 27
    1
      gte/turmit.py
  3. 18
    9
      tests/test_turmit.py

+ 6
- 5
gte/rpnlib.py View File

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

+ 27
- 1
gte/turmit.py View File

@@ -70,6 +70,19 @@ class Turmit(object):
70 70
         if self._prog is None:
71 71
             self._prog = RpnExpr.random(self._prog_sz)
72 72
             
73
+    def __call__(self, **context):
74
+        ''' @brief Exec the RPN expression and return the stack head
75
+            @param context dict : dict with variable values (see @ref rpnlib._var_list)
76
+            @return stack head after RPN
77
+        '''
78
+        for sym in self._prog:
79
+            if sym.optype == RpnSymbol.VALUE:
80
+                self._push(sym.value)
81
+            elif sym.optype == RpnSymbol.VARIABLE:
82
+                self._push(context[sym.value.lower()])
83
+            elif sym.optype == RpnSymbol.OPERATION:
84
+                getattr(self, sym.value.lower())()
85
+        return self.shead
73 86
 
74 87
     @property
75 88
     def shead(self):
@@ -101,7 +114,20 @@ class Turmit(object):
101 114
         self._cur += 1
102 115
         if self._cur >= len(self._stack):
103 116
             self._cur = 0
104
-        self._stack[self._cur] = val
117
+        self._stack[self._cur] = self._cast_int(val)
118
+
119
+    def _cast_int(self, val):
120
+        ''' @brief Transform integer given Turmit max int and signed_int
121
+            attr
122
+            @param val int : integer to transform
123
+            @return integer
124
+        '''
125
+        val = int(val)
126
+        if self._max_int is not None:
127
+            val %= self._max_int
128
+            if not self._signed_int and val < 0:
129
+                val = self._max_int - val
130
+        return val
105 131
 
106 132
     @RpnOp
107 133
     def mem_sz(self, new_sz):

+ 18
- 9
tests/test_turmit.py View File

@@ -24,9 +24,18 @@ class TurmitTestCase(unittest.TestCase):
24 24
         self.assertEqual(t._max_int, 42)
25 25
         t = Turmit(signed_int = False)
26 26
         self.assertFalse(t._signed_int)
27
-        t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 42,
27
+        t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
28 28
                    signed_int = False, stack_size=42)
29 29
 
30
+    def test_call(self):
31
+        ''' Test Turmit.__call__ '''
32
+        t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
33
+                   signed_int = False, stack_size=42)
34
+        r = t(x=1, y=2, r=255, g=255, b=255)
35
+        self.assertEqual(r, 9)
36
+        r = t(x=2, y=2, r=255, g=0, b=0)
37
+        self.assertEqual(r, 3)
38
+
30 39
     def test_init_badargs(self):
31 40
         ''' Test Turmit __init__ bad arguments '''
32 41
         with self.assertRaises(RuntimeError):
@@ -104,15 +113,15 @@ class TurmitOperationTestCase(unittest.TestCase):
104 113
 
105 114
         t = Turmit()
106 115
 
107
-        t._push(8)
108 116
         t._push(50)
117
+        t._push(8)
109 118
 
110 119
         t.sub()
111 120
         self.assertEqual(t._cur, 0)
112 121
         self.assertEqual(t.shead, 42)
113 122
 
114
-        t._push(8)
115 123
         t._push(50)
124
+        t._push(8)
116 125
         t.sub()
117 126
         self.assertEqual(t._cur, 1)
118 127
         self.assertEqual(t.shead, 42)
@@ -150,8 +159,8 @@ class TurmitOperationTestCase(unittest.TestCase):
150 159
 
151 160
         t = Turmit()
152 161
 
153
-        t._push(7)
154 162
         t._push(43)
163
+        t._push(7)
155 164
 
156 165
         t.div()
157 166
         self.assertEqual(t._cur, 0)
@@ -162,8 +171,8 @@ class TurmitOperationTestCase(unittest.TestCase):
162 171
         self._rpn('mod')
163 172
 
164 173
         t = Turmit()
165
-        t._push(4)
166 174
         t._push(42)
175
+        t._push(4)
167 176
 
168 177
         t.mod()
169 178
         self.assertEqual(t._cur, 0)
@@ -174,8 +183,8 @@ class TurmitOperationTestCase(unittest.TestCase):
174 183
         self._rpn('pow')
175 184
 
176 185
         t = Turmit()
177
-        t._push(4)
178 186
         t._push(2)
187
+        t._push(4)
179 188
 
180 189
         t.pow()
181 190
         self.assertEqual(t._cur, 0)
@@ -198,8 +207,8 @@ class TurmitOperationTestCase(unittest.TestCase):
198 207
         self._rpn('bin_and')
199 208
 
200 209
         t = Turmit()
201
-        t._push(42)
202 210
         t._push(10)
211
+        t._push(42)
203 212
 
204 213
         t.bin_and()
205 214
 
@@ -236,8 +245,8 @@ class TurmitOperationTestCase(unittest.TestCase):
236 245
         self._rpn('rshift')
237 246
 
238 247
         t = Turmit()
239
-        t._push(2)
240 248
         t._push(42)
249
+        t._push(2)
241 250
 
242 251
         t.rshift()
243 252
         self.assertEqual(t._cur, 0)
@@ -248,8 +257,8 @@ class TurmitOperationTestCase(unittest.TestCase):
248 257
         self._rpn('lshift')
249 258
 
250 259
         t = Turmit()
251
-        t._push(2)
252 260
         t._push(10)
261
+        t._push(2)
253 262
         t.lshift()
254 263
         self.assertEqual(t._cur, 0)
255 264
         self.assertEqual(t.shead, 40)

Loading…
Cancel
Save