Ejemplo n.º 1
0
 def test_parse_atoms(self):
     self.assertEqual(expr.parse('1'), True)
     self.assertEqual(expr.parse('0'), False)
     self.assertEqual(expr.parse('a'), expr.Variable(name='a'))
     self.assertEqual(expr.parse('ab'), expr.Variable(name='ab'))
     self.assertEqual(expr.parse('(a)'), expr.Variable(name='a'))
     self.assertEqual(expr.parse(' 1'), True)
     self.assertEqual(expr.parse('1 '), True)
Ejemplo n.º 2
0
 def test_parse_exprs(self):
     self.assertEqual(
         expr.parse('a&1&0'),
         expr.AndExpr(
             exprs=frozenset([expr.Variable(name='a'), True, False])))
     self.assertEqual(
         expr.parse('a|1|0'),
         expr.OrExpr(exprs=frozenset([expr.Variable(
             name='a'), True, False])))
     self.assertEqual(expr.parse('~a'),
                      expr.NotExpr(expr=expr.Variable(name='a')))
Ejemplo n.º 3
0
    def primary(self) -> e.Expr:
        if self.match(TokenType.FALSE):
            return e.Literal(False)
        if self.match(TokenType.TRUE):
            return e.Literal(True)
        if self.match(TokenType.NIL):
            return e.Literal(None)
        if self.match(TokenType.NUMBER, TokenType.STRING):
            return e.Literal(self.previous().literal)

        if self.match(TokenType.SUPER):
            keyword: Token = self.previous()
            self.consume(TokenType.DOT, "Expect '.' after 'super'.")
            method: Token = self.consume(TokenType.IDENTIFIER,
                                         "Expect superclass method name.")
            return e.Super(keyword, method)

        if self.match(TokenType.THIS):
            return e.This(self.previous())

        if self.match(TokenType.IDENTIFIER):
            return e.Variable(self.previous())

        if self.match(TokenType.LEFT_PAREN):
            expr: e.Expr = self.expression()
            self.consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.")
            return e.Grouping(expr)

        raise self.error(self.peek(), "Expect expression.")
Ejemplo n.º 4
0
 def _primary(self) -> ex.Expr:
     if self._match(TokenType.FALSE):
         return ex.Literal(False)
     if self._match(TokenType.TRUE):
         return ex.Literal(True)
     if self._match(TokenType.NIL):
         return ex.Literal(None)
     if self._match(TokenType.NUMBER, TokenType.STRING):
         return ex.Literal(self._previous.literal)
     if self._match(TokenType.SUPER):
         keyword = self._previous
         self._consume(TokenType.DOT, "Expect a '.' after 'super'.")
         method = self._consume(TokenType.IDENTIFIER,
                                'Expect superclass method name.')
         return ex.Super(keyword, method)
     if self._match(TokenType.THIS):
         return ex.This(self._previous)
     if self._match(TokenType.IDENTIFIER):
         return ex.Variable(self._previous)
     if self._match(TokenType.LEFT_PAREN):
         expr = self._expression()
         self._consume(TokenType.RIGHT_PAREN,
                       "Expect ')' after expression.")
         return ex.Grouping(expr)
     raise self._error(self._peek(), 'Expect expression.')
Ejemplo n.º 5
0
    def crement(self):
        isAdding = False
        if self.peek(-1).type == TokenType.PLUS_PLUS:
            isAdding = True

        identifier = self.peek(-2)

        if isAdding:
            tok = TokenType.PLUS
        else:
            tok = TokenType.MINUS
        val = 1

        return Expr.Assignment(
            Expr.Variable(identifier).name,
            Expr.Binary(Expr.Variable(identifier),
                        Token(tok, None, None, None), Expr.Literal(val)))
Ejemplo n.º 6
0
 def _class_declaration(self) -> st.Class:
     name = self._consume(TokenType.IDENTIFIER, 'Expect class name.')
     superclass = None
     if self._match(TokenType.LESS):
         self._consume(TokenType.IDENTIFIER, 'Expect superclass name.')
         superclass = ex.Variable(self._previous)
     self._consume(TokenType.LEFT_BRACE, "Expect '{' before class body.")
     methods = []
     while not self._check(TokenType.RIGHT_BRACE) and not self._is_at_end:
         methods.append(self._function('method'))
     self._consume(TokenType.RIGHT_BRACE, "Expect '}' after class body.")
     return st.Class(name, superclass, methods)
Ejemplo n.º 7
0
    def assignment(self):
        left = self.ternary()
        if self.match(TokenType.EQUAL):
            equals = self.peek(-1)
            value = self.assignment()
            if isinstance(left, Expr.Variable):
                return Expr.Assignment(left.name, value)
            self.error(equals, "Invalid assignment target.")

        elif self.match(TokenType.PLUS_EQUAL, TokenType.MINUS_EQUAL):
            tok = TokenType.MINUS
            if self.peek(-1).type == TokenType.PLUS_EQUAL:
                tok = TokenType.PLUS

            identifier = self.peek(-2)
            val = self.expression()

            return Expr.Assignment(
                Expr.Variable(identifier).name,
                Expr.Binary(Expr.Variable(identifier),
                            Token(tok, None, None, None), val))
        return left
Ejemplo n.º 8
0
    def classDeclaration(self) -> s.Stmt:
        name: Token = self.consume(TokenType.IDENTIFIER, "Expect class name.")
        superclass: Optional[e.Variable] = None
        if self.match(TokenType.LESS):
            self.consume(TokenType.IDENTIFIER, "Expect superclass name.")
            superclass = e.Variable(self.previous())

        self.consume(TokenType.LEFT_BRACE, "Expect '{' before class body.")

        methods: List[s.Function] = []
        while not self.check(TokenType.RIGHT_BRACE) and not self.isAtEnd():
            methods.append(self.function("method"))

        self.consume(TokenType.RIGHT_BRACE, "Expect '}' after class body.")

        return s.Class(name, superclass, methods)
Ejemplo n.º 9
0
    def primary(self):
        if self.match(TokenType.FALSE):
            return Expr.Literal(False)
        if self.match(TokenType.TRUE):
            return Expr.Literal(True)
        if self.match(TokenType.NIL):
            return Expr.Literal(None)
        if self.match(TokenType.NUMBER, TokenType.STRING):
            return Expr.Literal(self.peek(-1).literal)
        if self.match(TokenType.LEFT_PAREN):
            expr = self.expression()
            self.consume(TokenType.RIGHT_PAREN, "Missing ')' after expression")
            return Expr.Grouping(expr)
        if self.match(TokenType.IDENTIFIER):
            return Expr.Variable(self.peek(-1))

        raise self.error(self.peek(), "Requires an expression")
Ejemplo n.º 10
0
 def parse_atom(self):
     token = self.get_token
     if token.tag == Token.LPAREN:
         e = self.parse_expr()
         self.expect(Token.RPAREN)
         return e
     elif token.tag == Token.NUMBER:
         return E.NumberLit(token.value)
     elif token.tag == Token.ID:
         return E.Variable(token.value)
     elif token.tag == Token.LET:
         var = self.get_token
         assert (var.tag == Token.ID)
         self.expect(Token.ASSIGN)
         e1 = self.parse_expr()
         self.expect(Token.IN)
         e2 = self.parse_expr()
         self.expect(Token.END)
         return E.LetIn(var.value, e1, e2)