def _scan_special(self, buf, regex): match = regex.match(buf) if match: args = list(match.groups()) buf = args.pop() return (buf, args) raise skError("Malformed string (interpolation): '%s'" % (buf))
def setAll(self, varDict, nonew=False): if nonew: diff = set(varDict.keys()).difference(set( self.variable_map.keys())) if diff: raise skError("Variables do not exist in scope: %s" % (str(list(diff)))) self.variable_map.update(varDict)
def get(self, key): if key in self.special_keys: # These eventually get resolved in the ParaValidator return '@' + key for rib in self.ribs: if key in rib: return rib[key] raise skError("Variable accessed before assignment: '@%s'" % (key))
def eval_string_interpolate(self, stg, vars_only=False): """Evaluate a string ast in the current environment. Returns a python string with values interpolated. """ if vars_only: specials = ['$', '&'] else: specials = list(self.spc_dict.keys()) res = [] buf = stg try: # Iterate over buffer. If a character is not a special one, just # append it to the output buffer. Otherwise, scan the token and # call the "getter" function on it, appending the results to the # buffer. while len(buf) > 0: c = buf[0] buf = buf[1:] # Handle escaped specials. # TODO: is there a SOSS string escape char? if c == '\\': if len(buf) > 0: res.append(buf[0]) buf = buf[1:] continue # If not a special character, then append to buffer and carry on if not c in specials: res.append(c) continue # Scan the special token and deal with it (regex, get_fn) = self.spc_dict[c] buf, args = self._scan_special(buf, regex) # Call the getter for this kind of token, convert to # a string and append to the result list val = get_fn(*args) res.append(str(val)) except Exception as e: raise skError("Error interpolating string '%s': %s" % (stg, str(e))) # Return the string made by concatenating all results res_str = ''.join(res) #self.logger.debug("interpolation result is '%s'" % res_str) return res_str
def get(self, var): try: val = self.variable_map[var] except KeyError: raise skError("Variable does not exist in scope: '%s'" % var) if not isinstance(val, Closure): return val val = val.thaw() return val
def getAST(self, var): #print "fetch(%s); vars=%s" % (var, str(self.variable_map)) try: val = self.variable_map[var] except KeyError: raise skError("Variable does not exist in scope: '%s'" % var) ## if not isinstance(val, Closure): ## return val ## #print "Closure ast: %s" % str(val.ast) ## return val.ast return val
def get(self, *args): if len(args) == 3: (instname, frametype, count) = args if count != None: count = int(count) elif len(args) == 2: (instname, frametype) = args count = None else: frames = "Bad arguments to get_f_no: %s" % str(args) raise skError(str(frames)) if count == None: # Should return one frame frames = self.frameObj.getFrames(instname, frametype, 1) return frames[0] else: frames = self.frameObj.getFrames(instname, frametype, count) return '%s:%04d' % (frames[0], len(frames))
def _skcompile_exp(self, ast, info): """Compile an expression and return the string for the code. """ self.logger.debug("skcompile_exp: ast=%s" % str(ast)) assert isinstance(ast, ASTNode), \ SkCompileError("Malformed expression AST: %s" % str(ast)) if ast.tag == 'dyad': assert len(ast.items) == 3, \ SkCompilerError("Malformed dyad AST: %s" % str(ast)) val1 = self._skcompile_exp(ast.items[0], info) val2 = self._skcompile_exp(ast.items[2], info) opr = ast.items[1] if opr in ('+', '-', '*', '/'): val1 = 'float(%s)' % val1 val2 = 'float(%s)' % val2 elif opr in ('AND', 'OR'): opr = opr.lower() return "(%s %s %s)" % (val1, opr, val2) elif ast.tag == 'monad': assert len(ast.items) == 2, \ SkCompileError("Malformed modad AST: %s" % str(ast)) opr = ast.items[0] val1 = self._skcompile_exp(ast.items[1], info) if opr == '-': val1 = 'float(%s)' % val1 elif opr == 'NOT': opr = opr.lower() return "(%s %s)" % (opr, val1) elif ast.tag == 'func_call': raise SkCompileError("Function calls not yet implemented: %s" % str(ast)) func_name = ast.items[0].lower() tmp_vals = [self.eval_num(exp) for exp in ast.items[1].items[0]] if func_name == 'sin': return math.sin(math.radians(tmp_vals[0])) if func_name == 'cos': return math.cos(math.radians(tmp_vals[0])) if func_name == 'tan': return math.tan(math.radians(tmp_vals[0])) raise skError("Unrecognized built in function: '%s'" % func_name) elif ast.tag == 'frame_id_ref': assert isinstance(ast.items[0], str), \ SkCompileError("Unrecognized frame id reference AST: %s" % ( str(ast))) args = ast.items[0].split() assert (len(args) >= 2) and (len(args) < 4), \ SkCompileError("Unrecognized frame id reference AST: %s" % ( str(ast.items))) ins = repr(args[0]) typ = repr(args[1]) if len(args) == 3: count = self.string_interpolate(args[2], info) return "self.get_frames(%s, %s, %s)" % (ins, typ, count) else: return "self.get_frame(%s, %s)" % (ins, typ) elif ast.tag == 'asnum': val1 = self._skcompile_exp(ast.items[0], info) return "float(%s)" % (val1) elif ast.tag == 'expression_list': raise SkCompileError("AST handling not yet implemented: %s" % str(ast)) l = [self.eval(exp) for exp in ast.items[0]] return l elif ast.tag == 'list': return self.string_interpolate(ast.items[0], info) elif ast.tag == 'param_list': res = [] for ast in ast.items: res.append(self._skcompile_exp(ast, info)) return ', '.join(res) elif ast.tag == 'key_value_pair': key = ast.items[0] val_s = self._skcompile_exp(ast.items[1], info) return '%s=%s' % (str(key), val_s) elif ast.tag in ('number', 'string'): return repr(ast.items[0]) elif ast.tag in ('qstring', 'lstring'): return self.string_interpolate(ast.items[0], info) elif ast.tag == 'alias_ref': alias = ast.items[0] return self._resolve_alias(alias, info) elif ast.tag == 'id_ref': varname = ast.items[0] varname = varname.lower() return self._resolve_var(varname) elif ast.tag == 'reg_ref': raise SkCompileError("AST handling not yet implemented: %s" % str(ast)) return self.registers.get(ast.items[0]) else: # Everything else evaluates to itself raise SkCompileError("AST handling not yet implemented: %s" % str(ast)) return ast
def eval(self, ast): self.logger.debug("eval: ast=%s" % str(ast)) if isinstance(ast, Closure): return ast.thaw() if not isinstance(ast, ASTNode): return ast elif ast.tag == 'dyad': assert len(ast.items) == 3, ASTerr(ast) val1 = self.eval(ast.items[0]) val2 = self.eval(ast.items[2]) opr = ast.items[1] if opr == '+': return (float(val1) + float(val2)) elif opr == '-': return (float(val1) - float(val2)) elif opr == '*': return (float(val1) * float(val2)) elif opr == '/': return (float(val1) / float(val2)) elif opr == '==': return (val1 == val2) elif opr == '>': return (val1 > val2) elif opr == '<': return (val1 < val2) elif opr == '>=': return (val1 >= val2) elif opr == '<=': return (val1 <= val2) elif opr == '!=': return (val1 != val2) elif opr == 'AND': return (self.isTrue(val1) and self.isTrue(val2)) elif opr == 'OR': return (self.isTrue(val1) or self.isTrue(val2)) else: raise skError("Unrecognized expression operator: '%s'" % opr) elif ast.tag == 'monad': assert len(ast.items) == 2, ASTerr(ast) opr = ast.items[0] val1 = self.eval(ast.items[1]) if opr == '-': return -(float(val1)) elif opr == 'NOT': return (not self.isTrue(val1)) else: raise skError("Unrecognized expression operator: '%s'" % opr) #elif ast.tag == 'uminus': # return self.eval_num(ast.items[0]) * -1 #elif ast.tag == 'param_list': # return self.eval_params(ast) elif ast.tag == 'func_call': func_name = ast.items[0].lower() explst, kwdargs = self.eval_args(ast.items[1]) if func_name == 'idx': return explst[0][explst[1]] elif func_name == 'attr': return getattr(explst[0], explst[1]) elif func_name == 'apply': return (explst[0])(*explst[1:], **kwdargs) elif func_name == 'list': return list(explst) elif func_name == 'dict': return dict(kwdargs) elif func_name == 'sin': tmp_vals = [float(x) for x in explst] return math.sin(math.radians(tmp_vals[0])) elif func_name == 'cos': tmp_vals = [float(x) for x in explst] return math.cos(math.radians(tmp_vals[0])) elif func_name == 'tan': tmp_vals = [float(x) for x in explst] return math.tan(math.radians(tmp_vals[0])) elif func_name == 'int': return int(explst[0]) elif func_name == 'float': return float(explst[0]) elif func_name == 'frame': return self.frame_id_source.get(*explst) elif func_name == 'format': return explst[0] % tuple(explst[1:]) raise skError("Unrecognized built in function: '%s'" % func_name) elif ast.tag == 'frame_id_ref': s = self.eval_string_interpolate(ast.items[0]) args = s.split() return self.frame_id_source.get(*args) elif ast.tag == 'asnum': return self.eval_num(ast.items[0]) elif ast.tag == 'expression_list': l = [self.eval(exp) for exp in ast.items] return l elif ast.tag == 'list': return self.eval_string_interpolate(ast.items[0]) elif ast.tag in ('number', 'string'): return ast.items[0] elif ast.tag in ('qstring', 'lstring'): if hasattr(ast, 'cls'): return ast.cls.thaw() return self.eval_string_interpolate(ast.items[0]) elif ast.tag == 'alias_ref': alias = ast.items[0] val = self.status.get(alias) self.logger.debug("eval %s -> %s" % (alias, str(val))) return val elif ast.tag == 'id_ref': return self.variables.get(ast.items[0]) elif ast.tag == 'reg_ref': return self.registers.get(ast.items[0]) elif ast.tag == 'proc_call': regref, args_ast = ast.items # get function fn = self.registers.get(regref[1:]) # eval parameters if args_ast is None: args, kwdargs = [], {} else: args, kwdargs = self.eval_args(args_ast) return fn(*args, **kwdargs) else: # Everything else evaluates to itself return ast
def ASTerr(ast): raise skError("AST does not match expected format: %s" % str(ast))
def get(self, alias): try: return self.statusDict[alias] except KeyError: raise skError("Illegal status fetch (%s) in decoding!" % (alias))
def get(self, alias): raise skError("Illegal register fetch in decoding!")
def set(self, var, val, nonew=False): if nonew and (var not in self.variable_map): raise skError("Variable does not exist in scope: '%s'" % (var)) self.variable_map[var] = val