Example #1
0
    def _assignment(self):
        expression = self._or()

        if self._match([TokenType.LEFT_ARROW]):
            leftArrow = self._previous()
            value = self._assignment()
            if isinstance(expression, Expression.Variable):
                identifier = expression.getIdentifier()
                return Expression.Assign(identifier, value)
            elif isinstance(expression, Expression.Get):
                return Expression.Set(expression.getObject(), expression.getIdentifier(), value)
            elif isinstance(expression, Expression.GetIndex):
                return Expression.SetIndex(expression.getObject(), expression.getIndices(), expression.getBrackets(), value)

            self._error(leftArrow, "Invalid assignment target.")
        return expression
Example #2
0
    def _unary(self):
        if self._match([TokenType.NOT, TokenType.MINUS]):
            operator = self._previous()
            right = self._unary()
            return Expression.Unary(operator, right)

        return self._index()
Example #3
0
    def _or(self):
        expression = self._and()
        while self._match([TokenType.OR]):
            operator = self._previous()
            right = self._and() #check this line!
            expression = Expression.Logical(expression, operator, right)

        return expression
Example #4
0
    def _twoDimensionalArithmetic(self):
        expression = self._unary()

        while self._match([TokenType.SLASH, TokenType.STAR]):
            operator = self._previous()
            right = self._unary()
            expression = Expression.Binary(expression, operator, right)

        return expression
Example #5
0
    def _oneDimensionalArithmetic(self):
        expression = self._twoDimensionalArithmetic()

        while self._match([TokenType.PLUS, TokenType.MINUS]):
            operator = self._previous()
            right = self._twoDimensionalArithmetic()
            expression = Expression.Binary(expression, operator, right)

        return expression
Example #6
0
    def _comparison(self):
        expression = self._oneDimensionalArithmetic()

        while self._match([TokenType.LESS, TokenType.GREATER, TokenType.LESS_EQUAL, TokenType.GREATER_EQUAL]):
            operator = self._previous()
            right = self._oneDimensionalArithmetic()
            expression = Expression.Binary(expression, operator, right)

        return expression
Example #7
0
    def _equality(self):
        expression = self._comparison()

        while self._match([TokenType.NOT_EQUAL, TokenType.EQUAL]):
            operator = self._previous()
            right = self._comparison()
            expression = Expression.Binary(expression, operator, right)

        return expression
Example #8
0
    def _and(self):
        expression = self._equality()

        while self._match([TokenType.AND]):
            operator = self._previous()
            right = self._equality()
            expression = Expression.Logical(expression, operator, right)

        return expression
Example #9
0
 def _finishFunctionCall(self, caller):
     arguments = []
     if not self._check(TokenType.RIGHT_PAREN):
         while True:
             if len(arguments) >= 8:
                 self._error(self._peek(), "Cannot have more than 8 arguments.")
             arguments.append(self._expression())
             if not self._match([TokenType.COMMA]):
                 break
     parantheses = self._consume(TokenType.RIGHT_PAREN, "Expect ')' after arguments.")
     return Expression.Call(caller, parantheses, arguments)
Example #10
0
    def _forStatement(self):
        if self._match([TokenType.VAR]):
            identifier = self._consume(TokenType.IDENTIFIER, "Expect variable identifier.")
            self._consume(TokenType.LEFT_ARROW, "Expect '<-' after variable identifier.")
            expression = self._expression()

            initializer = Statement.Variable(identifier, expression)
        else:
            raise self._error(self._peek(), "Expect a variable declaration after 'FOR'.")

        self._consume(TokenType.TO, "Expect 'TO' after varable declaration.")
        right = self._oneDimensionalArithmetic()

        condition = Expression.Binary(
            Expression.Variable(identifier),
            Token(TokenType.LESS_EQUAL, "<=", None, "NULL", -1),
            right
        )

        increment = Expression.Assign(identifier, Expression.Binary(
            Expression.Variable(identifier),
            Token(TokenType.PLUS, "+", None, "NULL", -1),
            Expression.Literal(1.0)
        ))

        self._consume(TokenType.DO, "Expect 'DO' at end of for loop initialization.")

        body = self._bodyDeclaration(TokenType.ENDFOR)
        self._consume(TokenType.ENDFOR, "Expect 'ENDFOR' at end of the for loop.")
        body.append(Statement.Expression(increment))

        return Statement.For(initializer, condition, body)
Example #11
0
    def _functionCall(self):
        expression = self._primary()

        while True:
            if self._match([TokenType.LEFT_PAREN]):
                expression = self._finishFunctionCall(expression)
            elif self._match([TokenType.DOT]):
                identifier = self._consume(TokenType.IDENTIFIER, "Expect property identifier after '.'.")
                expression = Expression.Get(expression, identifier)
            else:
                break

        return expression
Example #12
0
    def _classDeclaration(self):
        identifier = self._consume(TokenType.IDENTIFIER, "Expect class identifier.")
        superClass = None

        if self._match([TokenType.INHERITS]):
            self._consume(TokenType.IDENTIFIER, "Expect superclass identifier.")
            superClass = Expression.Variable(self._previous())

        methods = []
        while not self._check(TokenType.ENDCLASS) and not self._isAtEnd():
            if self._match([TokenType.FUNCTION]):
                methods.append(self._functionDeclaration())

        self._consume(TokenType.ENDCLASS, "Expect 'ENDCLASS' after class body.")
        return Statement.Class(identifier, superClass, methods)
Example #13
0
    def _primary(self):
        if self._match([TokenType.FALSE]):
            return Expression.Literal(False)

        if self._match([TokenType.TRUE]):
            return Expression.Literal(True)

        if self._match([TokenType.NULL]):
            return Expression.Literal(None)

        if self._match([TokenType.NUMBER, TokenType.STRING]):
            return Expression.Literal(self._previous().getLiteral())

        if self._match([TokenType.SUPER]):
            keyword = self._previous()
            self._consume(TokenType.DOT, "Expect '.' after 'SUPER'.")
            method = self._consume(TokenType.IDENTIFIER, "Expect super class method name.")
            return Expression.Super(keyword, method)

        if self._match([TokenType.THIS]):
            return Expression.This(self._previous())

        if self._match([TokenType.LEFT_BRACE]):
            values = []
            while True:
                values.append(self._expression())
                if not self._match([TokenType.COMMA]):
                    break
            self._consume(TokenType.RIGHT_BRACE, "Expect '}' after values.")
            return Expression.List(values)

        if self._match([TokenType.IDENTIFIER]):
            return Expression.Variable(self._previous())

        if self._match([TokenType.LEFT_PAREN]):
            expression = self._expression()
            self._consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.")
            return Expression.Grouping(expression)

        raise self._error(self._peek(), "Expect expression.")
Example #14
0
    def _index(self):
        expression = self._functionCall()

        if self._match([TokenType.LEFT_SQUARE]):
            indices = []
            while True:
                if not self._peek().getType() in [TokenType.IDENTIFIER, TokenType.NUMBER]:
                    self._error(self._peek(), "Expect identifier or number for index value.")

                indices.append(self._expression())
                if not self._match([TokenType.COMMA]):
                    break


            brackets = self._consume(TokenType.RIGHT_SQUARE, "Expect ']' after index value.")
            return Expression.GetIndex(expression, indices, brackets)

        return expression