def valuelist(self): """parse: ( expr_1 , expr_2, ... ) """ valueList = list() self.dbg_msg("valuelist: ") lparen_tok = self.match(EzhilToken.LPAREN) while (self.peek().kind != EzhilToken.RPAREN): val = self.expr() if (self.debug): print("val = ", str(val)) ptok = self.peek() if (self.debug): print("ptok = ", str(ptok), str(ptok.kind), str(EzhilToken.ASSIGNOP)) if (ptok.kind in EzhilToken.ASSIGNOP): assign_tok = self.dequeue() rhs = self.expr() [l, c] = assign_tok.get_line_col() lhs = val val = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug) if (self.debug): print("AssignStmt = ", str(val)) ptok = self.peek() else: if (self.debug): print("No-Assign // Expr =", str(val)) self.dbg_msg("valuelist-expr: " + str(val)) valueList.append(val) if (ptok.kind == EzhilToken.RPAREN): break elif (ptok.kind == EzhilToken.COMMA): self.match(EzhilToken.COMMA) else: raise ParseException(" function call argument list " + str(ptok)) self.match(EzhilToken.RPAREN) [l, c] = lparen_tok.get_line_col() return ValueList(valueList, l, c, self.debug)
def valuelist(self): """parse: ( expr_1 , expr_2, ... ) """ valueList = list() self.dbg_msg("valuelist: ") lparen_tok = self.match(Token.LPAREN) while (self.peek().kind != Token.RPAREN): val = self.expr() self.dbg_msg("valuelist-expr: " + str(val)) valueList.append(val) ptok = self.peek() if (ptok.kind == Token.RPAREN): break elif (ptok.kind == Token.COMMA): self.match(Token.COMMA) else: raise ParseException(" function call argument list " + str(ptok)) self.match(Token.RPAREN) [l, c] = lparen_tok.get_line_col() return ValueList(valueList, l, c, self.debug)
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))
def factor(self): self.dbg_msg("factor") tok = self.peek() if tok.kind == EzhilToken.LPAREN: lparen_tok = self.dequeue() val = self.expr() if self.dequeue().kind != EzhilToken.RPAREN: raise SyntaxError("Missing Parens " + str(self.last_token())) elif tok.kind == EzhilToken.NUMBER: tok_num = self.dequeue() [l, c] = tok_num.get_line_col() val = Number(tok.val, l, c, self.debug) elif tok.kind == EzhilToken.LOGICAL_NOT: tok_not = self.dequeue() [l, c] = tok_not.get_line_col() val = UnaryExpr(self.expr(), tok_not, l, c, self.debug) self.dbg_msg("completed parsing unary expression" + str(val)) elif tok.kind == EzhilToken.ID: tok_id = self.dequeue() [l, c] = tok_id.get_line_col() val = Identifier(tok.val, l, c, self.debug) ptok = self.peek() self.dbg_msg("factor: " + str(ptok) + " / " + str(tok)) if (ptok.kind == EzhilToken.LPAREN): ## function call [l, c] = ptok.get_line_col() vallist = self.valuelist() val = ExprCall(val, vallist, l, c, self.debug) elif (ptok.kind == EzhilToken.LSQRBRACE): ## indexing a array type variable or ID [l, c] = ptok.get_line_col() ## replace with a call to __getitem__ exp = self.factor() if (hasattr(exp, '__getitem__')): VL2 = ValueList([val, exp[0]], l, c, self.debug) else: # when exp is a expression VL2 = ValueList([val, exp], l, c, self.debug) val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c, self.debug) for itr in range(1, len(exp)): VL2 = ValueList([val, exp[itr]], l, c, self.debug) val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c, self.debug) #raise ParseException("array indexing implemented"+str(ptok)); elif (ptok.kind == EzhilToken.LCURLBRACE): val = None raise ParseException("dictionary indexing implemented" + str(ptok)) elif tok.kind == EzhilToken.STRING: str_tok = self.dequeue() [l, c] = str_tok.get_line_col() val = String(tok.val, l, c, self.debug) elif tok.kind in EzhilToken.ADDSUB: unop = self.dequeue() [l, c] = unop.get_line_col() val = Expr(Number(0), unop, self.term(), l, c, self.debug) elif tok.kind == EzhilToken.LCURLBRACE: # creating a list/dictionary expression dict_start = self.dequeue() val = Dict() while (True): if (self.peek().kind == EzhilToken.RCURLBRACE): break exprkey = self.expr() tok_colon = self.match(EzhilToken.COLON) exprval = self.expr() val.update({exprkey: exprval}) if self.debug: print(self.peek().__class__, self.peek()) if (self.peek().kind == EzhilToken.RCURLBRACE): break else: assert (self.peek().kind == EzhilToken.COMMA) self.dequeue() assert (self.peek().kind == EzhilToken.RCURLBRACE) list_end = self.dequeue() elif tok.kind == EzhilToken.LSQRBRACE: # creating a list/array expression list_start = self.dequeue() val = Array() while (True): if (self.peek().kind == EzhilToken.RSQRBRACE): break exprval = self.expr() val.append(exprval) if self.debug: print(self.peek().__class__, self.peek()) if (self.peek().kind == EzhilToken.RSQRBRACE): break else: assert (self.peek().kind == EzhilToken.COMMA) self.dequeue() assert (self.peek().kind == EzhilToken.RSQRBRACE) list_end = self.dequeue() else: raise ParseException("Expected Number, found something " + str(tok)) self.dbg_msg("factor-returning: " + str(val)) return val