def constification(func, spec): # takes an ast.Function node and a list of expressions # and replaces the node with a stmt which when executed will define # the function and closureify the expressions cvars = [] for east in spec: cn = 'ClOsUrE%i__' % c_no() replace_ast(func.code, east, cn) cvars.append((cn, east)) func_name = func.name subfunc = ast.Function(func.decorators, func_name, func.argnames, func.defaults, func.flags, func.code, func.lineno) stmt = [ ast.Assign([ast.AssName(cn, 'OP_ASSIGN')], east) for cn, east in cvars ] stmt.append(subfunc) stmt.append(ast.Return(ast.Name(func_name, 0))) fn = 'CoNsTiFiCaTiOn%i' % f_no() dfunc = ast.Function(None, fn, (), (), 0, ast.Stmt(stmt), 0) creat = ast.Stmt( [dfunc, ast_Assign(func_name, ast.CallFunc(ast.Name(fn, 0), ()))]) # XXX add del(CoNsTiFiCaTiOn) make_copy(func, creat)
def p_funcdecl(p): '''funcdecl : type identifier '(' parList ')' block | type identifier '(' ')' block''' if len(p) == 7: p[0] = ast.Function(p[1], p[2], p[4], p[6]).addloc(p.lineno(1)) else: p[0] = ast.Function(p[1], p[2], [], p[5]).addloc(p.lineno(1))
def parse_function(self, token, frame): symbol = None arguments = None # Edge - func token only at end if not frame: _malformed(token) # Check first for private if isinstance(frame[0], ast.LiteralReference): if frame[0].value == ":private": frame.pop(0) # Should never get here due to pre-parse, but else: raise errors.ParseError( "{}:{} Function type only supports :private keyword." " Found {}".format(token.getsourcepos().lineno, token.getsourcepos().colno, frame[0].value)) # Should never get here due to pre-parse, but if not frame: _panic("{}:{} Missing symbol for {}", token) if isinstance(frame[0], ast.Symbol): symbol = frame.pop(0) else: _panic("{}:{} Expected symbol for {}", token) # Should never get here due to pre-parse, but if not frame: _panic("{}:{} Missing function arguments", token) elif not isinstance(frame[0], ast.CollectionAst): _panic("{}:{} Expected function arguments", token) else: arguments = frame.pop(0) # Verify all in collection are symbols if not isinstance(arguments, ast.EmptyCollection): for x in arguments.value: if ((not isinstance(x, ast.Symbol) or x.token.gettokentype() not in self._strict_symtokens)): _panic("{}:{} Invalid symbol in arguments for {}", token) expressions = [] index = 0 # Get all expressions in function for x in frame: if not isinstance(x, self._decl_set): expressions.append(x) index += 1 else: break frame = frame[index:] hdr = self._locals.get(symbol.name, None) if not hdr: _panic("{}:{} Function {} not in symbol table", symbol.token) frame.insert(0, ast.Function(hdr, expressions, self.input)) return frame
def parse_function(self, declr): func = declr.typ return ast.Declaration( typ=ast.Function( ret=func.ret, args=func.args, body=self.block()), name=declr.name)
def parse(self, parser, tokens): tokens.consume_expected('FUNCTION') id_token = tokens.consume_expected('NAME') tokens.consume_expected('LPAREN') arguments = self._parse_params(tokens) tokens.consume_expected('RPAREN', 'COLON') with enter_scope(parser, 'function'): block = Block().parse(parser, tokens) if block is None: raise ParserError('Expected function body', tokens.current()) return ast.Function(id_token.value, arguments, block)
def parse_function(tp: ast.Tuple, tail: Node) -> ast.Function: lmd = ast.Lambda(None, tail) while True: elements = tp.elements lmd.params = expand_formals(elements[1:]) if isinstance(elements[0], ast.Name): return ast.Function(elements[0], lmd) elif isinstance(elements[0], ast.Tuple): tp = elements[0] lmd = ast.Lambda(None, lmd) else: raise ParseError(f'Unsupported ast node type {elements[0]}')
def get_func(self, ftok, tstrm): h, tk, funcs = self.get_symbol(tstrm) if tk.getstr() not in "private" or tk.getstr() not in ":private": # print("Processing function {}".format(tk)) args = self.get_symbols_list(tstrm) argv = None if args: argv = ast.SymbolList(args) else: argv = ast.EmptyCollection(CollTypes.LIST, [], ftok, self.input) self.values.append( ast.Function(ast.FuncHeader(funcs, argv, ftok, self.input), None, self.input))
def parse(s): code = pp.Forward() opcode = pp.Or([ pp.Literal('+'), pp.Literal('-'), pp.Literal('*'), pp.Literal('/'), pp.Literal('_'), pp.Literal('='), pp.Literal('>'), pp.Literal('&'), pp.Literal('|'), pp.Literal('~'), pp.Literal('$'), pp.Literal('%'), pp.Literal('\\'), pp.Literal('@'), pp.Literal('ø'), pp.Literal('p'), pp.Literal(':'), pp.Literal(';'), pp.Literal('!'), pp.Literal('?'), pp.Literal('#'), ]).setParseAction(lambda toks: ast.Opcode(toks[0])) number = (pp.Word('1234567890').setParseAction( lambda toks: ast.Number(int(toks[0])))) str_def = ((pp.Literal('"') + pp.SkipTo(pp.Literal('"'), include=True) ).setParseAction(lambda toks: ast.String(toks[1]))) varname = (pp.Word( 'qwertyuiopasdfghjklzxcvbnm', exact=1).setParseAction(lambda toks: ast.Varname(toks[0]))) fn_def = pp.Suppress(pp.Literal('[')) + code + pp.Suppress(pp.Literal(']')) expr = pp.Or([opcode, number, varname, str_def, fn_def]) atom = pp.Or([expr]) code << pp.ZeroOrMore(atom) code.setParseAction(lambda toks: ast.Function(toks)) return code.parseString(s)[0]
def parse_declr_expr(self, typ, e): ''' parse an expression as declaration; e.g. "int *x[8]" when treated as expression will be parsed as `PrefixExpr(op='*', expr=Index(array='x', index=8))`, which we want to transform into this: `Array(Pointer(typ='int'), cap=8)` ''' while is_type_modifier(e): if type(e) == ast.Index: cap = int(e.index.val) if e.index is not None else None typ = ast.Array(typ=typ, cap=cap) e = e.array else: typ = ast.Pointer(typ=typ) e = e.expr if type(e) == ast.CallExpr: return self.parse_declr_expr( ast.Function(ret=typ or 'void', args=e.args, body=None), e.func) else: return ast.Declaration(typ=typ, name=e)
def p_function_definition_02(t): '''function_definition : type IDENTIFIER LPAR formal_parameters_list RPAR block''' t[0] = ast.Function(t[2], t[1], t[4], t[6])
def p_function_definition_01(t): '''function_definition : type IDENTIFIER LPAR RPAR block''' t[0] = ast.Function(t[2], t[1], ast.FormalParametersList(), t[5])
def translate(node, st=None, strings=None, funcName=False): if isinstance(node, oast.Add): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Add(left, right) elif isinstance(node, oast.And): left = translate(node.nodes[0], st, strings, funcName) right = translate(node.nodes[1], st, strings, funcName) return ast.And(left, right) elif isinstance(node, oast.Assign): # Translate the right hand side first so it can use the older version # of the left hand side. exp = translate(node.expr, st, strings, funcName) var = node.nodes.pop() if isinstance(var, oast.AssAttr): string = strings.setdefault(var.attrname, ast.String(var.attrname)) var = translate(var.expr, st, strings, funcName) return ast.SetAttr(var, string, exp) else: var = translate(var, st, strings, funcName) return ast.Assign(var, exp) elif isinstance(node, oast.AssName): return st.getSymbol(node.name, True) elif isinstance(node, oast.CallFunc): name = translate(node.node, st, strings, True) args = [translate(a, st, strings) for a in node.args] return ast.FunctionCall(name, *args) elif isinstance(node, oast.Class): bases = [translate(base, st, strings, funcName) for base in node.bases] body = translate(node.code, st, strings, funcName) body = ast.BasicBlock(body) sym = st.getSymbol(node.name, True) name = st.getName(node.name, True) # This is here temporarily. It will be moved to the typify pass # later. sym['type'] = 'class' klass = ast.Class(name, bases, body) return ast.Assign(sym, klass) elif isinstance(node, oast.Compare): left = translate(node.expr, st, strings, funcName) op, right = node.ops[0] right = translate(right, st, strings, funcName) if op == '==': return ast.Eq(left, right) elif op == '!=': return ast.Ne(left, right) elif op == 'is': return ast.Is(left, right) elif isinstance(node, oast.Const): return ast.Integer(node.value) elif isinstance(node, oast.Dict): pairs = {} for pair in node.items: key, value = pair key = translate(key, st, strings, funcName) value = translate(value, st, strings, funcName) pairs[key] = value return ast.Dictionary(pairs) elif isinstance(node, oast.Discard): return translate(node.expr, st, strings, funcName) elif isinstance(node, oast.Div): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Div(left, right) elif isinstance(node, oast.Function): sym = st.getSymbol(node.name, True) name = st.getName(node.name, True) sym['type'] = 'function' newST = SymbolTable(st) argSymbols = [ newST.getSymbol(argName, True) for argName in node.argnames ] body = translate(node.code, newST, strings, funcName) body = ast.BasicBlock(body) fun = ast.Function(name, argSymbols, body, newST) fun['simplified'] = False st.update(newST) return ast.Assign(sym, fun) elif isinstance(node, oast.Getattr): exp = translate(node.expr, st, strings, funcName) name = strings.setdefault(node.attrname, ast.String(node.attrname)) return ast.GetAttr(exp, name) elif isinstance(node, oast.If): tests = node.tests cond, then = tests.pop(0) # Translate the conditional expression. cond = translate(cond, st, strings) # Snapshot the SymbolTable st.snapshot() # Translate the 'then' clause. then = translate(then, st, strings, funcName) then = ast.BasicBlock(then) # Roll-back the SymbolTable for the 'else' clause. st.rollback() # Translate the 'else' clause. if len(tests) > 0: els = [translate(oast.If(tests, node.else_), st, funcName)] else: els = translate(node.else_, st, strings, funcName) els = ast.BasicBlock(els) return ast.If(cond, then, els, st) elif isinstance(node, oast.IfExp): cond = translate(node.test, st, strings, funcName) then = translate(node.then, st, strings, funcName) els = translate(node.else_, st, strings, funcName) return ast.IfExp(cond, then, els) elif isinstance(node, oast.Lambda): name = st.getName('lambda', True) newST = SymbolTable(st) argSymbols = map(lambda name: newST.getSymbol(name, True), node.argnames) code = ast.Return(translate(node.code, newST, strings, funcName)) block = ast.BasicBlock([code]) fun = ast.Function(name, argSymbols, block, newST) fun['simplified'] = False st.update(newST) return fun elif isinstance(node, oast.List): elements = [] for n in node.nodes: elements.append(translate(n, st, strings, funcName)) return ast.List(elements) elif isinstance(node, oast.Module): # Create a new SymbolTable for this module. st = SymbolTable() strings = {} children = translate(node.node, st, strings, funcName) block = ast.BasicBlock(children) fun = ast.Function(st.getBIF('main'), [], block, st) # Mark the main function as migrated so that it doesn't get moved # later. fun['simplified'] = True return ast.Module([fun], strings) elif isinstance(node, oast.Mul): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Mul(left, right) elif isinstance(node, oast.Name): ret = 'input_int' if node.name == 'input' else node.name if ret == 'input_int': ret = st.getBIF(ret) else: if ret == 'True': ret = ast.Tru() elif ret == 'False': ret = ast.Fals() else: ret = st.getSymbol(ret) return ret elif isinstance(node, oast.Not): operand = translate(node.expr, st, strings, funcName) return ast.Not(operand) elif isinstance(node, oast.Or): left = translate(node.nodes[0], st, strings, funcName) right = translate(node.nodes[1], st, strings, funcName) return ast.Or(left, right) elif isinstance(node, oast.Printnl): children = [ translate(e, st, strings, funcName) for e in node.getChildNodes() ] children = util.flatten(children) return ast.FunctionCall(st.getBIF('print_any'), *children) elif isinstance(node, oast.Return): return ast.Return(translate(node.value, st, strings, funcName)) elif isinstance(node, oast.Stmt): stmts = [ translate(s, st, strings, funcName) for s in node.getChildNodes() ] return util.flatten(stmts) elif isinstance(node, oast.Sub): left = translate(node.left, st, strings, funcName) right = translate(node.right, st, strings, funcName) return ast.Sub(left, right) elif isinstance(node, oast.Subscript): sym = translate(node.expr, st, strings, funcName) sub = translate(node.subs[0], st, strings, funcName) return ast.Subscript(sym, sub) elif isinstance(node, oast.While): cond = translate(node.test, st, strings, funcName) body = translate(node.body, st, strings, funcName) body = ast.BasicBlock(body) return ast.While(cond, body, st) elif isinstance(node, oast.UnarySub): operand = translate(node.expr, st, strings, funcName) return ast.Negate(operand) else: raise Exception("Unsupported AST node encountered: {}".format( node.__class__.__name__))
asm = (Keyword('asm') + QuotedString(quoteChar='\"')).setParseAction(lambda t: ast.Asm(t[1])) goto = (Keyword('goto') + identifier).setParseAction(lambda t: ast.Goto(t[1])) label = (Keyword('label') + identifier).setParseAction(lambda t: ast.Label(t[1])) comment = ('#' + SkipTo(lineEnd)) line = comment.suppress() | MatchFirst([ declarevar, declarefn, declare_struct, assignment, function, return_, halt, if_, while_, include, asm, goto, label, expr_statement, nop ]) + Literal(';').suppress() + Optional(comment).suppress() sequence = ZeroOrMore(line).setParseAction(lambda t: ast.Sequence(t.asList())) block_sequence << ('{' + sequence + '}').setParseAction(lambda t: t[1]) function_args = Group( Optional(identifier + ZeroOrMore(Suppress(',') + identifier))) functionOptions = Group(ZeroOrMore(MatchFirst([Keyword('returns')]))) function << (Keyword('function') + identifier + '(' + function_args + ')' + functionOptions + block_sequence)\ .setParseAction(lambda t: ast.Function(t[1], t[3], t[6], options = t[5])) # lambda q: ast.Function(t[1], t[3], + t[5] ) program = sequence + StringEnd()
is_undent = False rets = { 'System print': 'void', 'Float -': 'Float', 'Float *': 'Float', 'Float +': 'Float', 'Float /': 'Float', 'Int -': 'Int', 'Int *': 'Int', 'Int +': 'Int', 'Int /': 'Int', '$z 0': 'void' } index = {'$z': ast.Call('System', 'print', [])} tree = ast.Program( [ast.Definition('$main', ast.Function(ast.Args([]), [], ret='int'), True)]) anon_actor_num = 0 buff = '' # For names and values def parse(source): while True: try: q = parse_top_level(source) #raise_error(source) tree.append(q) except ValueError: break for i in tree: if isinstance(i, ast.Actor): tree[-1].value.append(ast.Call('$z', str(anon_actor_num), []))
def p_expression_fun(self, p): """ expression : function LPAREN expression RPAREN | function LPAREN sequence RPAREN """ p[0] = ast.Function(p[1], p[3], p.lexer.lexer.lineno)
if (args[0] == 'run'): args = args[1:] except IndexError: print('Welcome to the Rhea REPL!') print r'''____/\\\\\\\\\______/\\\________/\\\__/\\\\\\\\\\\\\\\_____/\\\\\\\\\____ __/\\\///////\\\___\/\\\_______\/\\\_\/\\\///////////____/\\\\\\\\\\\\\__ _\/\\\_____\/\\\___\/\\\_______\/\\\_\/\\\______________/\\\/////////\\\_ _\/\\\\\\\\\\\/____\/\\\\\\\\\\\\\\\_\/\\\\\\\\\\\_____\/\\\_______\/\\\_ _\/\\\//////\\\____\/\\\/////////\\\_\/\\\///////______\/\\\\\\\\\\\\\\\_ _\/\\\____\//\\\___\/\\\_______\/\\\_\/\\\_____________\/\\\/////////\\\_ _\/\\\_____\//\\\__\/\\\_______\/\\\_\/\\\_____________\/\\\_______\/\\\_ _\/\\\______\//\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\\\\\_\/\\\_______\/\\\_ _\///________\///__\///________\///__\///////////////__\///________\///__ ''' tree = ast.Initialization(True, '$main', ast.Function(ast.Args([]), [], ret='int')) while True: sys.stdout.write('rhea> ') line = sys.stdin.readline() if line == '': print('\nGoodbye!') sys.exit(0) line = line[:-1] + ' \n' parserizer.loc = 0 parserizer.source = line tmptree = parserizer.parse_expr() old = tree.value.get_last() if isinstance(old, ast.Send): if isinstance(old.args[0], ast.IntLiteral) or isinstance( old.args[0], ast.FloatLiteral) or isinstance( old.args[0], ast.Lookup):
def gen_actor(body): gen_define('$z' + str(parser.anon_actor_num), ast.Function(ast.Args([]), body, ret='void'), True)
def p_function(p): """function : FUNCTION LROUND var_list RROUND LCURLY summary stmt_list RETURN LROUND var_list RROUND RCURLY""" p[0] = ast.Function(p[3], p[10], p[7], p[6])