def p_operand_equal_first(t): """operation : ident EQUALSFIRST operand""" ops = { '+': 'add', '-': 'subtract', '*': 'multiply', '/': 'divide', '<': 'lt', '>': 'gt', '^': 'power', '**': 'power', '<=': 'le', '>=': 'ge', '==': 'eq', '>>': 'shift_right', '<<': 'shift_left', '&': 'iand', '&&': 'and', '!=': 'NE', '|': 'ior', '||': 'or', '//': 'concat' } items = ops.items() ef_dict = dict() for itm in items: ef_dict.setdefault(itm[0] + '=', itm[1]) t[0] = Builtin('equals_first', (Builtin(ef_dict[t[2]], (t[1], t[3])), ))
def p_inc_dec(t): """operation : ident PLUSPLUS\n| ident MINUSMINUS\n| PLUSPLUS ident\n| MINUSMINUS ident""" op = {'++': '_inc', '--': '_dec'} if isinstance(t[1], str): t[0] = Builtin('pre' + op[t[1]], (t[2], )) else: t[0] = Builtin('post' + op[t[2]], (t[1], ))
def p_vector(t): """vector_part : LBRACKET operand | LBRACKET | vector_part COMMA operand vector : vector_part RBRACKET""" if isinstance(t[1], str): if len(t) == 2: t[0] = Builtin('vector', tuple()) t[0].isarray = True else: t[0] = Builtin('vector', (t[2], )) t[0].isarray = isinstance(t[2], Scalar) or isinstance( t[2], Array) elif t[2] == ',': args = list(t[1].args) if len(args) > 250: args = [Builtin('vector', tuple(args)), t[3]] else: args.append(t[3]) t[1].args = tuple(args) t[0] = t[1] t[0].isarray = t[1].isarray and (isinstance(t[3], Scalar) or isinstance(t[3], Array)) else: if t[1].isarray: t[0] = Data.evaluate(t[1]) else: t[0] = Builtin('vector', t[1].args)
def p_statements(t): """statements : statement\n| statements statement\n| statements braced_statements""" if len(t) == 2: t[0] = Builtin('statement', (t[1], )) else: if t[2] is None: t[0] = t[1] elif len(t[1].args) < 250: t[1].args = tuple(list(t[1].args) + [t[2]]) t[0] = t[1] else: t[0] = Builtin('statement', (t[1], t[2]))
def p_case(t): """case : CASE LPAREN operand RPAREN braced_statements\n| CASE LPAREN operand RPAREN statement | CASE LPAREN operand RPAREN\n| CASE DEFAULT braced_statements | CASE DEFAULT statement\n| statement""" if len(t)==4: t[0]=Builtin('default',(t[3],)) elif len(t)==5: t[0]=Builtin('case',(None,None)) t[0].args=(t[3],) t[0].doAppendCase=True elif len(t)==6: t[0]=Builtin('case',(t[3],t[5])) else: t[0]=t[1]
def p_binop(t): """operation : operand PLUS operand | operand MINUS operand\n| operand TIMES operand\n| operand DIVIDE operand | operand RAISE operand\n| operand RSHIFT operand\n| operand LSHIFT operand | operand LESS operand\n| operand GREATER operand\n| operand LESS_EQUAL operand | operand GREATER_EQUAL operand\n| operand EQUALS operand \n| operand IAND operand | operand AND operand \n| operand OR operand \n| operand NOT_EQUAL operand | operand IOR operand\n| operand AND_S operand \n| operand OR_S operand\n| operand NOR_S operand | operand MOD_S operand | MOD_S LPAREN operand COMMA operand RPAREN | operand GT_S operand\n| operand GE_S operand\n| operand LT_S operand\n| operand LE_S operand | operand EQ_S operand\n| operand NE_S operand """ ops = { '+': 'add', '-': 'subtract', '*': 'multiply', '/': 'divide', '<': 'lt', '>': 'gt', '^': 'power', '**': 'power', '<=': 'le', '>=': 'ge', '==': 'eq', '>>': 'shift_right', '<<': 'shift_left', '&': 'iand', '&&': 'and', '!=': 'NE', '<>': 'NE', '|': 'ior', '||': 'or', 'and': 'and', 'or': 'or', 'nor': 'nor', 'mod': 'MOD', 'gt': 'gt', 'ge': 'ge', 'lt': 'lt', 'le': 'le', 'eq': 'eq', 'ne': 'ne' } if len(t) == 4: t[0] = Builtin(ops[t[2].lower()], (t[1], t[3])) else: t[0] = Builtin(ops[t[1].lower()], (t[3], t[5]))
def buildPath(args): if isinstance(args[0], (str, String)): name = str(args[0]) if len(name) > 1 and name[0:2] == '\\\\': name = name[1:] ans = TreePath(name) else: ans = Builtin('build_path', args) return ans
def p_fun(t): """operation : IDENTTYPE FUN NAME fun_args braced_statements | FUN IDENTTYPE NAME fun_args braced_statements | FUN NAME fun_args braced_statements""" args = list() if len(t) == 6: if t[1].lower() == 'fun': itype = t[2] else: itype = t[1] args.append(Builtin(itype, (t[3], ))) args.append(t[5]) for arg in t[4]: args.append(arg) else: args.append(t[2]) args.append(t[4]) for arg in t[3]: args.append(arg) t[0] = Builtin('fun', tuple(args))
def t_IDENT(t): if t.value.lower() == "$roprand": import numpy as np t.value = np.frombuffer(np.getbuffer(np.int32(2147483647)), dtype=np.float32)[0] else: try: t.value = Builtin(t.value, ()) except Exception: t.value = Ident(t.value) return t
def p_case(t): """case : CASE LPAREN operand RPAREN braced_statements\n| CASE LPAREN operand RPAREN statement | CASE LPAREN operand RPAREN\n| CASE DEFAULT braced_statements | CASE DEFAULT statement\n| statement""" if len(t) == 4: t[0] = Builtin('default', (t[3], )) elif len(t) == 5: t[0] = Builtin('case', (None, None)) t[0].args = (t[3], ) t[0].doAppendCase = True elif len(t) == 6: t[0] = Builtin('case', (t[3], t[5])) else: t[0] = t[1]
def p_vector(t): """vector_part : LBRACKET operand | LBRACKET | vector_part COMMA operand vector : vector_part RBRACKET""" if isinstance(t[1],str): if len(t)==2: t[0]=Builtin('vector',tuple()) t[0].isarray=True else: t[0]=Builtin('vector',(t[2],)) t[0].isarray = isinstance(t[2],Scalar) or isinstance(t[2],Array) elif t[2] == ',': args=list(t[1].args) if len(args) > 250: args=[Builtin('vector',tuple(args)),t[3]] else: args.append(t[3]) t[1].args=tuple(args) t[0]=t[1] t[0].isarray = t[1].isarray and (isinstance(t[3],Scalar) or isinstance(t[3],Array)) else: if t[1].isarray: t[0]=Data.evaluate(t[1]) else: t[0]=Builtin('vector',t[1].args)
def get(self): compile_time_concat = True for arg in self: if not isinstance(arg, (str, String)): compile_time_concat = False break if compile_time_concat: c = list() c.append(self[0]) if len(self) % 2 == 0: for arg in self[1:-1]: c[-1] = str(c[-1]) + str(arg) c.append(self[-1]) else: for arg in self[1:]: c[-1] = String(str(c[-1]) + str(arg)) if len(c) > 1: return Builtin('concat', tuple(c)) else: return c[0] else: return Builtin('concat', tuple(self))
def p_subscript(t): """operation : operand vector""" if len(t) == 2: t[0] = t[1] else: args = [ t[1], ] if isinstance(t[2], Builtin): for arg in t[2].args: args.append(arg) else: for arg in t[2]: args.append(arg) t[0] = Builtin('subscript', tuple(args))
def p_unaryop(t): """operation : NOT operand %prec UNOP\n| INOT operand %prec UNOP\n| MINUS operand %prec UNOP\n| PLUS operand %prec UNOP | NOT_S operand %prec UNOP""" ops = { '!': 'NOT', '~': 'INOT', '-': 'UNARY_MINUS', 'not': 'NOT', '+': 'UNARY_PLUS' } if t[1] == '-' and isinstance(t[2], Scalar): t[0] = makeData(-t[2].data()) elif t[1] == '+' and isinstance(t[2], Scalar): t[0] = t[2] else: t[0] = Builtin(ops[t[1].lower()], (t[2], ))
def p_fun_arg(t): """fun_arg : ARGTYPE IDENT\n| ARGTYPE ARGTYPE IDENT\n| IDENT\n| ARGTYPE LPAREN IDENT RPAREN\n| ARGTYPE ARGTYPE LPAREN IDENT RPAREN""" if len(t) == 2: t[0] = t[1] elif len(t) == 3: t[0] = Builtin(t[1], (str(t[2]), )) elif len(t) == 4: t[0] = Builtin(t[1], (Builtin(t[2], (str(t[3]), )), )) elif len(t) == 5: t[0] = Builtin(t[1], (t[3], )) else: t[0] = Builtin(t[1], (Builtin(t[2], (t[4], )), ))
def buildUsing(args_in): def restoreTreePaths(arg): if isinstance(arg, Compound): args = list() for a in arg.args: args.append(restoreTreePaths(a)) arg.args = tuple(args) ans = arg elif isinstance(arg, (TreePath, TreeNode)) and hasattr( arg, 'original_value'): ans = TreePath(arg.original_value) else: ans = arg return ans args = list() for arg in args_in: args.append(restoreTreePaths(arg)) ans = Builtin('using', tuple(args)) return ans
def p_arglist(t): """arglist : LPAREN args RPAREN\n args :\n| args operand\n| args COMMA\n| args ARGTYPE LPAREN operand RPAREN""" if len(t) == 4: t[0] = t[2] elif len(t) == 1: t[0] = list() else: if len(t) == 6: t[2] = Builtin(t[2], (t[4], )) if isinstance(t[2], str): if len(t[1]) == 0: t[1].append(None) t[1].append(None) else: if len(t[1]) > 0 and (t[1][-1] is None or isinstance(t[1][-1], EmptyData)): t[1][-1] = t[2] else: t[1].append(t[2]) t[0] = t[1]
def p_assignment(t): 'operation : operand EQUAL operand %prec EQUAL' t[0] = Builtin('EQUALS', (t[1], t[3]))
def p_loop_control(t): 'operation : BREAK\n| CONTINUE' t[0] = Builtin(t[1], tuple())
def p_while(t): """operation : WHILE LPAREN operand RPAREN braced_statements | WHILE LPAREN operand RPAREN statement""" t[0] = Builtin('while', (t[3], t[5]))
def p_if(t): """operation : if_begin ifelse_body\n| if_begin ifelse_body ELSE ifelse_body""" args = [t[1], t[2]] if len(t) > 3: args.append(t[4]) t[0] = Builtin('if', tuple(args))
def p_for(t): """operation : FOR LPAREN optional_operand SEMICOLON operand SEMICOLON optional_operand RPAREN braced_statements | FOR LPAREN optional_operand SEMICOLON operand SEMICOLON optional_operand RPAREN statement""" t[0] = Builtin('for', (t[3], t[5], t[7], t[9]))
def p_switch(t): """operation : SWITCH LPAREN operand RPAREN LBRACE cases RBRACE""" t[0] = Builtin('switch', (t[3], t[6]))
def get(self): return Builtin('comma', tuple(self))
def p_ident(t): """ident : IDENT\n| PLACEHOLDER\n| IDENTTYPE IDENT""" if len(t) == 2: t[0] = t[1] else: t[0] = Builtin(t[1], (str(t[2]), ))
def p_function(t): """operation : NAME arglist\n| EQ_S arglist\n| NE_S arglist\n| LE_S arglist | LT_S arglist\n| GT_S arglist\n| GE_S arglist""" def doBuild(name, args): def build_with_units(args): args[0].units = args[1] return args[0] def build_with_error(args): args[0].error = args[1] return args[0] def build_param(args): try: args[0].help = args[1] args[0].validation = args[2] except: pass return args[0] def build_slope(args): new_args = list() if len(args) > 1: new_args.append(args[1]) else: new_args.append(None) if len(args) > 2: new_args.append(args[2]) else: new_args.append(None) new_args.append(args[0]) return Range(tuple(new_args)) def buildPath(args): if isinstance(args[0], (str, String)): name = str(args[0]) if len(name) > 1 and name[0:2] == '\\\\': name = name[1:] ans = TreePath(name) else: ans = Builtin('build_path', args) return ans def buildCall(args): ans = Call(args[1:]) ans.retType = args[0] return ans ### retain original node specifiers when building a using function def buildUsing(args_in): def restoreTreePaths(arg): if isinstance(arg, Compound): args = list() for a in arg.args: args.append(restoreTreePaths(a)) arg.args = tuple(args) ans = arg elif isinstance(arg, (TreePath, TreeNode)) and hasattr( arg, 'original_value'): ans = TreePath(arg.original_value) else: ans = arg return ans args = list() for arg in args_in: args.append(restoreTreePaths(arg)) ans = Builtin('using', tuple(args)) return ans known_builds = { 'BUILD_ACTION': Action, #BUILD_CONDITION':Condition, 'BUILD_CONGLOM': Conglom, 'BUILD_DEPENDENCY': Dependency, 'BUILD_DIM': Dimension, 'BUILD_DISPATCH': Dispatch, 'BUILD_EVENT': Event, 'BUILD_FUNCTION': Builtin, 'BUILD_METHOD': Method, 'BUILD_PARAM': build_param, 'BUILD_PROCEDURE': Procedure, 'BUILD_PROGRAM': Program, 'BUILD_RANGE': Range, 'BUILD_ROUTINE': Routine, 'BUILD_SIGNAL': Signal, 'BUILD_SLOPE': build_slope, 'BUILD_WINDOW': Window, 'BUILD_WITH_UNITS': build_with_units, 'BUILD_CALL': buildCall, 'BUILD_WITH_ERROR': build_with_error, 'BUILD_OPAQUE': Opaque, 'BUILD_PATH': buildPath, 'USING': buildUsing, } return known_builds[name.upper()](args) def doMake(name, args): for arg in args: if not isinstance( arg, (Array, Scalar, EmptyData)) and arg is not None: raise Exception('use make opcode') name = name.upper().replace('MAKE_', 'BUILD_') if 'BUILD_' in name: return doBuild(name, tuple(args)) else: raise Exception("not a make_ call") try: t[0] = doBuild(t[1], tuple(t[2])) except Exception: try: t[0] = doMake(t[1], tuple(t[2])) except Exception: try: numbers = [ 'byte', 'byte_unsigned', 'unsigned_byte', 'word', 'word_unsigned', 'unsigned_word', 'long', 'long_unsigned', 'unsigned_long', 'quadword', 'quadword_unsigned', 'unsigned_quadword', 'float', 'double', 'f_float', 'g_float', 'd_float', 'fs_float', 'ft_float' ] if t[1].lower() in numbers and (isinstance( t[2][0], Scalar) or isinstance(t[2][0], Array)): t[0] = Data.evaluate(Builtin(t[1], tuple(t[2]))) else: t[0] = Builtin(t[1], tuple(t[2])) except Exception: t[0] = Builtin('ext_function', tuple([None, t[1]] + t[2]))
def p_conditional(t): 'operation : operand QUESTION operand COLON operand' t[0] = Builtin('conditional', (t[3], t[5], t[1]))