|
@@ -0,0 +1,75 @@
|
|
1
|
+import collections
|
|
2
|
+import inspect
|
|
3
|
+import random
|
|
4
|
+
|
|
5
|
+_op_list = collections.OrderedDict()
|
|
6
|
+_var_list = collections.OrderedDict()
|
|
7
|
+
|
|
8
|
+_var_list['x'] = 0
|
|
9
|
+_var_list['y'] = 0
|
|
10
|
+_var_list['r'] = 0
|
|
11
|
+_var_list['g'] = 0
|
|
12
|
+_var_list['b'] = 0
|
|
13
|
+
|
|
14
|
+def RpnOp(method):
|
|
15
|
+ ''' @brief Decorator for RPN operation that autodetect argument count
|
|
16
|
+
|
|
17
|
+ Autodetect argument count and pop them from the stack. Then attempt
|
|
18
|
+ to push values from result as an array. If it fails result is push
|
|
19
|
+ as it.
|
|
20
|
+
|
|
21
|
+ @warning if result is None nothing is push
|
|
22
|
+ '''
|
|
23
|
+ def wrapped(self):
|
|
24
|
+ narg = len(inspect.signature(method).parameters)-1
|
|
25
|
+ args = [ self._pop() for _ in range(narg) ]
|
|
26
|
+ res = method(self, *args)
|
|
27
|
+ if res is None:
|
|
28
|
+ return None
|
|
29
|
+ try:
|
|
30
|
+ for topush in res:
|
|
31
|
+ if not isinstance(topush, int):
|
|
32
|
+ raise ValueError('Turmit.%s() returned a list containing a\
|
|
33
|
+ %s : %s' % (method.__name__, type(topush), topush))
|
|
34
|
+ self._push(topush)
|
|
35
|
+ except TypeError:
|
|
36
|
+ if not isinstance(res, int):
|
|
37
|
+ raise ValueError('Turmit.%s() returned a list containing a\
|
|
38
|
+%s : %s' % (method.__name__, type(res), res))
|
|
39
|
+ self._push(res)
|
|
40
|
+ return res
|
|
41
|
+ _op_list[method.__name__] = (method, wrapped)
|
|
42
|
+ return wrapped
|
|
43
|
+
|
|
44
|
+class RpnSymbol(object):
|
|
45
|
+ ''' @brief Designed to handle operation and operand for Turmit expr '''
|
|
46
|
+
|
|
47
|
+ OPERATION = 0x0
|
|
48
|
+ VALUE = 0x1
|
|
49
|
+ VARIABLE = 0x3
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+ def __init__(self, value, optype = VALUE):
|
|
53
|
+ self.optype = optype
|
|
54
|
+ self.value = value
|
|
55
|
+ if optype == self.OPERATION:
|
|
56
|
+ self.value = list(_op_list.keys())[value % len(_op_list)]
|
|
57
|
+ elif optype == self.VARIABLE:
|
|
58
|
+ self.value = list(_var_list.keys())[value % len(_var_list)]
|
|
59
|
+
|
|
60
|
+ def __str__(self):
|
|
61
|
+ if self.optype == self.OPERATION:
|
|
62
|
+ return _op_list[self.value][0].__name__.upper()
|
|
63
|
+ elif self.optype == self.VALUE:
|
|
64
|
+ return '0x%04X' % self.value
|
|
65
|
+ else:
|
|
66
|
+ return self.value.upper()
|
|
67
|
+
|
|
68
|
+ @classmethod
|
|
69
|
+ def random(cls):
|
|
70
|
+ optype = [cls.OPERATION, cls.VALUE, cls.VARIABLE]
|
|
71
|
+ optype = optype[random.randint(0,2)]
|
|
72
|
+ return cls(random.randint(0, 0xFFFF), optype)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|