Add forgotten rpnlib module

This commit is contained in:
Yann Weber 2018-04-24 22:41:23 +02:00
commit fe7e459b26

75
gte/rpnlib.py Normal file
View file

@ -0,0 +1,75 @@
import collections
import inspect
import random
_op_list = collections.OrderedDict()
_var_list = collections.OrderedDict()
_var_list['x'] = 0
_var_list['y'] = 0
_var_list['r'] = 0
_var_list['g'] = 0
_var_list['b'] = 0
def RpnOp(method):
''' @brief Decorator for RPN operation that autodetect argument count
Autodetect argument count and pop them from the stack. Then attempt
to push values from result as an array. If it fails result is push
as it.
@warning if result is None nothing is push
'''
def wrapped(self):
narg = len(inspect.signature(method).parameters)-1
args = [ self._pop() for _ in range(narg) ]
res = method(self, *args)
if res is None:
return None
try:
for topush in res:
if not isinstance(topush, int):
raise ValueError('Turmit.%s() returned a list containing a\
%s : %s' % (method.__name__, type(topush), topush))
self._push(topush)
except TypeError:
if not isinstance(res, int):
raise ValueError('Turmit.%s() returned a list containing a\
%s : %s' % (method.__name__, type(res), res))
self._push(res)
return res
_op_list[method.__name__] = (method, wrapped)
return wrapped
class RpnSymbol(object):
''' @brief Designed to handle operation and operand for Turmit expr '''
OPERATION = 0x0
VALUE = 0x1
VARIABLE = 0x3
def __init__(self, value, optype = VALUE):
self.optype = optype
self.value = value
if optype == self.OPERATION:
self.value = list(_op_list.keys())[value % len(_op_list)]
elif optype == self.VARIABLE:
self.value = list(_var_list.keys())[value % len(_var_list)]
def __str__(self):
if self.optype == self.OPERATION:
return _op_list[self.value][0].__name__.upper()
elif self.optype == self.VALUE:
return '0x%04X' % self.value
else:
return self.value.upper()
@classmethod
def random(cls):
optype = [cls.OPERATION, cls.VALUE, cls.VARIABLE]
optype = optype[random.randint(0,2)]
return cls(random.randint(0, 0xFFFF), optype)