def execute_ArrayIndex(self, ai, mem): a = self.execute(ai.args[0], mem) if not isinstance(a, list): raise RuntimeErr("Expected 'list', for '%s'" % (a, )) i = int(self.tonumeric(self.execute(ai.args[1], mem))) if i < 0 or i >= len(a): raise RuntimeErr("Array index out of bounds: %d" % (i, )) return a[i]
def convert(self, val, t): if isinstance(val, UndefValue): return val if t == 'int': if val in [True, False]: val = 1 if val else 0 return int(val) if t == 'float': if val in [True, False]: val = 1.0 if val else 0.0 return float(val) if t == 'char': if val in [True, False]: val = 1 if val else 0 return int(val) % 128 if t.endswith('[]'): st = t[:-2] if isinstance(val, list): return map(lambda x: x if x is None else self.convert(x, st), val) raise RuntimeErr("Expected list, got '%s'" % (val, )) return val
def execute_ArrayAssign(self, aa, mem): a = self.execute(aa.args[0], mem) if not isinstance(a, list): raise RuntimeErr("Expected 'list', got '%s'" % (a, )) a = list(a) i = int(self.tonumeric(self.execute(aa.args[1], mem))) if i < 0 or i >= len(a): raise RuntimeErr("Array index out of bounds: %d" % (i, )) v = self.execute(aa.args[2], mem) a[i] = v return a
def tonumeric(self, v): if v in [True, False]: return 1 if v else 0 if not isinstance(v, (int, float)): raise RuntimeErr("Non-numeric value: '%s'" % (v, )) return v
def wrap(self, f, mem): # First check number of arguments if len(args) != len(f.args): raise RuntimeErr("Expected '%d' args in '%s', got '%d'" % (len(args), f.name, len(f.args))) # Evaluate args fargs = map(lambda x: self.execute(x, mem), f.args) # Convert args nargs = [] for a, t in zip(fargs, args): nargs.append(self.convert(a, t)) # Call original function return fun(self, *nargs)
def execute_DictComp(self, lc, mem): # Arg #1,#2 are key val exprs kexpr = lc.args[1] vexpr = lc.args[2] # Arg #3 is a list expression l = self.execute(lc.args[3], mem) # Arg #4 is a filter filt = lc.args[4] # Arg #0 is a number of bound variables boundlen = int(lc.args[0].value) mem = deepcopy(mem) bound = mem['#__bound'] = ([None for _ in xrange(boundlen)] \ + mem.get('#__bound', [])) # Construct a dict nd = {} for el in l: # Construct a new memory from a list element if boundlen == 1: bound[0] = el else: el = tuple(el) if len(el) != boundlen: raise RuntimeErr('Cannot unpack') for var, val in zip(xrange(boundlen), el): bound[var] = val # Apply filter ok = self.execute(filt, mem) if not ok: continue # Get a value of an element by executing it key = self.execute(kexpr, mem) val = self.execute(vexpr, mem) nd[key] = val return nd
def execute_ListComp(self, lc, mem): # Arg #1 is an elements expresion eexpr = lc.args[1] # Arg #2 is a list expression l = self.execute(lc.args[2], mem) # Arg #3 is a filter filt = lc.args[3] # Arg #0 is a number of bound variables boundlen = int(lc.args[0].value) mem = deepcopy(mem) bound = mem['#__bound'] = ([None for _ in xrange(boundlen)] \ + mem.get('#__bound', [])) # Construct a new list nl = [] for el in l: # Construct a new memory from a list element if boundlen == 1: bound[0] = el else: el = tuple(el) if len(el) != boundlen: raise RuntimeErr('Cannot unpack') for var, val in zip(xrange(boundlen), el): bound[var] = val # Apply filter ok = self.execute(filt, mem) if not ok: continue # Get a value of an element by executing it el = self.execute(eexpr, mem) nl.append(el) return nl
def wrap(self, f, mem): args = map(lambda x: self.execute(x, mem), f.args) for a in args: if isinstance(a, UndefValue): raise RuntimeErr('undefined value') return fun(self, *args)