예제 #1
0
 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)
예제 #2
0
 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)
예제 #3
0
 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))
예제 #4
0
    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