def p_return_statement(self, p): '''return_statement : RETURN expression | RETURN''' f_symtable = self.tableptr.items[1] f_name = f_symtable.name ret_type = self.tableptr.items[0].symbols[f_name]['ret_type'] if len(p) > 2: p[0] = ReturnStmt(p[2]) if p[2].dtype != ret_type: print('invalid return.') print('expected %s, got %s.' % (str(ret_type), str(p[2].dtype))) sys.exit(0) else: p[0] = ReturnStmt(None) if ret_type != ('void', 0): print('invalid return.') print('expected %s, got %s.' % (str(ret_type), 'void')) sys.exit(0)
def create_function_node(self, ast): assert isinstance(ast, Function) if ast.has_def is False: # function prototype; return if not isinstance(ast.body[-1], ReturnStmt): ast.body.append(ReturnStmt(None)) self.create_nodes(ast.body, func=ast)
def stmt(self): """ try an assign, print, return, if or eval statement """ self.dbg_msg(" STMT ") ptok = self.peek() self.dbg_msg("stmt: peeking at " + str(ptok)) if (ptok.kind == Token.RETURN): ## return <expression> ret_tok = self.dequeue() [l, c] = ret_tok.get_line_col() rstmt = ReturnStmt(self.expr(), l, c, self.debug) self.dbg_msg("return statement parsed") return rstmt elif (ptok.kind == Token.PRINT): ## print <expression> print_tok = self.dequeue() [l, c] = print_tok.get_line_col() return PrintStmt(self.exprlist(), l, c, self.debug) elif (ptok.kind == Token.IF): ## if <expression> stmtlist end if_tok = self.dequeue() [l, c] = if_tok.get_line_col() exp = self.expr() ifstmt = IfStmt(exp, None, None, l, c, self.debug) self.if_stack.append(ifstmt) body = self.stmtlist() ifstmt.set_body(body) ptok = self.peek() if (ptok.kind in [Token.ELSEIF, Token.ELSE]): self.inside_if = True next_stmt = self.stmtlist() self.inside_if = False ifstmt.append_stmt(next_stmt) self.match(Token.END) return ifstmt elif (ptok.kind == Token.ELSEIF): ## elseif <expression> stmtlist elseif_tok = self.dequeue() [l, c] = elseif_tok.get_line_col() self.check_if_stack() exp = self.expr() elseif_stmt = IfStmt(exp, None, None, l, c, self.debug) ifstmt = self.if_stack[-1] ifstmt.append_stmt(elseif_stmt) self.if_stack.pop() self.if_stack.append(elseif_stmt) body = self.stmtlist() elseif_stmt.set_body(body) return elseif_stmt elif (ptok.kind == Token.ELSE): ## else stmtlist self.check_if_stack() ifstmt = self.if_stack.pop() self.dbg_msg("stmt-else: ") else_tok = self.dequeue() [l, c] = else_tok.get_line_col() body = self.stmtlist() else_stmt = ElseStmt(body, l, c, self.debug) ifstmt.append_stmt(else_stmt) return else_stmt elif (ptok.kind == Token.FOR): ## Fixme : empty for loops not allowed. """ For ( exp1 ; exp2 ; exp3 ) stmtlist end""" self.loop_stack.append(True) self.dbg_msg("for-statement") for_tok = self.dequeue() self.match(Token.LPAREN) lhs = self.expr() init = lhs ptok = self.peek() if (ptok.kind in Token.ASSIGNOP): assign_tok = self.dequeue() [l, c] = assign_tok.get_line_col() rhs = self.expr() init = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug) self.match(Token.COMMA) cond = self.expr() self.match(Token.COMMA) lhs = self.expr() update = lhs ptok = self.peek() if (ptok.kind in Token.ASSIGNOP): assign_tok = self.dequeue() [l, c] = assign_tok.get_line_col() rhs = self.expr() update = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug) self.match(Token.RPAREN) body = self.stmtlist() self.match(Token.END) [l, c] = for_tok.get_line_col() forstmt = ForStmt(init, cond, update, body, l, c, self.debug) self.loop_stack.pop() return forstmt elif (ptok.kind == Token.WHILE): ## while ( expr ) body end self.loop_stack.append(True) self.dbg_msg("while-statement") while_tok = self.dequeue() [l, c] = while_tok.get_line_col() wexpr = self.expr() body = self.stmtlist() self.match(Token.END) whilestmt = WhileStmt(wexpr, body, l, c, self.debug) self.loop_stack.pop() return whilestmt elif (ptok.kind == Token.BREAK): ## break, must be in loop-environment self.dbg_msg("break-statement") break_tok = self.dequeue() [l, c] = break_tok.get_line_col() self.check_loop_stack() ##raises a parse error brkstmt = BreakStmt(l, c, self.debug) return brkstmt elif (ptok.kind == Token.CONTINUE): ## continue, must be in loop-environment self.dbg_msg("continue-statement") cont_tok = self.dequeue() [l, c] = cont_tok.get_line_col() self.check_loop_stack() ##raises a parse error cntstmt = ContinueStmt(l, c, self.debug) return cntstmt else: ## lval := rval ptok = self.peek() [l, c] = ptok.get_line_col() lhs = self.expr() self.dbg_msg("parsing expr: " + str(lhs)) ptok = self.peek() if (ptok.kind in Token.ASSIGNOP): assign_tok = self.dequeue() rhs = self.expr() [l, c] = assign_tok.get_line_col() return AssignStmt(lhs, assign_tok, rhs, l, c, self.debug) return EvalStmt(lhs, l, c, self.debug) raise ParseException("parsing Statement, unkown operators" + str(ptok))
def stmt(self, pass_in_ATexpr=None): """ try an assign, print, return, if or eval statement """ self.dbg_msg(" STMT ") ptok = self.peek() self.dbg_msg("stmt: peeking at " + str(ptok)) if (ptok.kind == EzhilToken.RETURN): ## return <expression> self.dbg_msg('enter->return: <expression>') ret_tok = self.dequeue() [l, c] = ret_tok.get_line_col() rstmt = ReturnStmt(self.expr(), l, c, self.debug) self.dbg_msg("return statement parsed") return rstmt elif (ptok.kind == EzhilToken.PRINT): self.currently_parsing.append(ptok) ## print <expression> print_tok = self.dequeue() [l, c] = print_tok.get_line_col() exprlist_val = self.exprlist() self.currently_parsing.pop() return PrintStmt(exprlist_val, l, c, self.debug) elif (ptok.kind == EzhilToken.ATRATEOF or pass_in_ATexpr): ## @ <expression> {if | while | elseif} if not pass_in_ATexpr: at_tok = self.match(EzhilToken.ATRATEOF) self.currently_parsing.append(at_tok) exp = self.valuelist() self.currently_parsing.pop() else: exp = pass_in_ATexpr if (self.debug): print("return from valuelist ", str(exp)) ptok = self.peek() if (ptok.kind == EzhilToken.IF): return self.parseIfStmt(exp) elif (ptok.kind == EzhilToken.WHILE): ## @ ( expr ) while { body } end self.loop_stack.append(True) self.dbg_msg("while-statement") while_tok = self.dequeue() self.currently_parsing.append(while_tok) [l, c] = while_tok.get_line_col() wexpr = exp[0] body = self.stmtlist() self.match(EzhilToken.END) whilestmt = WhileStmt(wexpr, body, l, c, self.debug) self.loop_stack.pop() self.currently_parsing.pop() return whilestmt elif (ptok.kind == EzhilToken.SWITCH): return self.parseSwitchStmt(exp) elif (ptok.kind == EzhilToken.FOREACH): foreach_tok = self.dequeue() self.currently_parsing.append(foreach_tok) [l, c] = foreach_tok.get_line_col() if (self.debug): print("parsing FOREACH stmt") self.loop_stack.append(True) self.dbg_msg("foreach-statement") # convert to a for statement - building Ezhil AST - transformations if not isinstance(exp[1], Identifier): raise ParseError(" FOR-EACH statement " + str(foreach_tok)) foreach_iter = exp[1] iter = Identifier("__" + foreach_iter.id, l=0, c=-1) eq_token = EzhilLexeme("=", EzhilToken.EQUALS) plus_token = EzhilLexeme("+", EzhilToken.PLUS) lt_token = EzhilLexeme("<", EzhilToken.LT) if (self.debug): print("build init assign stmt") init = AssignStmt(iter, eq_token, Number(0), l, c, self.debug) if (self.debug): print("build cond expr") VL1 = ValueList([exp[0]], l, c, self.debug) cond = Expr( iter, lt_token, ExprCall(Identifier("len", l, c), VL1, l, c, self.debug), l, c, self.debug) if (self.debug): print("build plus1 stmt") plus1_iter = Expr(iter, plus_token, Number(1), l, c, self.debug) if (self.debug): print("build equals stmt") update = AssignStmt(iter, eq_token, plus1_iter, l, c, self.debug) body = self.stmtlist() #parse body # and insert artifical update variable in body VL2 = ValueList([exp[0], iter], l, c, self.debug) extract_foreach_iter_from_list = ExprCall( Identifier("__getitem__", l, c), VL2, l, c, self.debug) foreach_iter_Assign = AssignStmt( foreach_iter, eq_token, extract_foreach_iter_from_list, l, c, self.debug) body.List.insert(0, foreach_iter_Assign) # complete FOREACH stmt self.match(EzhilToken.END) self.currently_parsing.pop() foreach_stmt = ForStmt(init, cond, update, body, l, c, self.debug) self.loop_stack.pop() if (self.debug): print("completed parsing FOR-EACH loop", str(foreach_stmt)) return foreach_stmt elif (ptok.kind == EzhilToken.FOR): ## Fixme : empty for loops not allowed. """ For ( exp1 , exp2 , exp3 ) stmtlist end""" if (self.debug): print("parsing FOR stmt") self.loop_stack.append(True) self.dbg_msg("for-statement") for_tok = self.peek() self.currently_parsing.append(for_tok) if (self.debug): print("matching for STMT", str(self.peek())) self.match(EzhilToken.FOR) if (self.debug): print("matched for STMT", str(self.peek())) [l, c] = for_tok.get_line_col() init, cond, update = exp[0], exp[1], exp[2] if (self.debug): print("extract 3 parts", str(init), str(cond), str(update)) body = self.stmtlist() self.match(EzhilToken.END) self.currently_parsing.pop() if (self.debug): print("body of loop", str(body)) forstmt = ForStmt(init, cond, update, body, l, c, self.debug) self.loop_stack.pop() if (self.debug): print("completed parsing FOR loop", str(forstmt)) return forstmt elif (ptok.kind == EzhilToken.DO): if (self.debug): print("parsing DO-WHILE statement") self.loop_stack.append(True) do_tok = self.dequeue() self.currently_parsing.append(do_tok) [l, c] = do_tok.get_line_col() body = self.stmtlist() if (self.debug): print("parsed body") self.match(EzhilToken.DOWHILE) self.match(EzhilToken.ATRATEOF) exp = self.valuelist() if (self.debug): print("parsed EXP", exp[0]) doWhileStmt = DoWhileStmt(exp[0], body, l, c, self.debug) self.loop_stack.pop() self.currently_parsing.pop() return doWhileStmt elif (ptok.kind == EzhilToken.BREAK): ## break, must be in loop-environment self.dbg_msg("break-statement") break_tok = self.dequeue() [l, c] = break_tok.get_line_col() self.check_loop_stack() ##raises a parse error brkstmt = BreakStmt(l, c, self.debug) return brkstmt elif (ptok.kind == EzhilToken.CONTINUE): ## continue, must be in loop-environment self.dbg_msg("continue-statement") cont_tok = self.dequeue() [l, c] = cont_tok.get_line_col() self.check_loop_stack() ##raises a parse error cntstmt = ContinueStmt(l, c, self.debug) return cntstmt else: ## lval := rval ptok = self.peek() self.currently_parsing.append(ptok) [l, c] = ptok.get_line_col() lhs = self.expr() self.dbg_msg("parsing expr: " + str(lhs)) ptok = self.peek() if (ptok.kind in EzhilToken.ASSIGNOP): assign_tok = self.dequeue() rhs = self.expr() [l, c] = assign_tok.get_line_col() self.currently_parsing.pop() return AssignStmt(lhs, assign_tok, rhs, l, c, self.debug) self.currently_parsing.pop() return EvalStmt(lhs, l, c, self.debug) raise ParseException("parsing Statement, unkown operators" + str(ptok))