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)
def _whileStatement(self): condition = self._expression() self._consume(TokenType.DO, "Expect 'DO' after condition") body = self._bodyDeclaration(TokenType.ENDWHILE) self._consume(TokenType.ENDWHILE, "Expect 'ENDWHILE' at then end of the while statement.") return Statement.While(condition, body)
def _returnStatement(self): keyword = self._previous() value = None if not self._check(TokenType.SEMICOLON): value = self._expression() #self._consume(TokenType.SEMICOLON, "Expect ';' after return value.") return Statement.Return(keyword, value)
def _variableDeclaration(self): identifier = self._consume(TokenType.IDENTIFIER, "Expect variable identifier.") initializer = None if self._match([TokenType.LEFT_ARROW]): initializer = self._expression() #self._consume(TokenType.SEMICOLON, "Expect ';' after variable declaration.") return Statement.Variable(identifier, initializer)
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)
def _ifStatement(self): condition = self._or() self._consume(TokenType.THEN, "Expect 'THEN' after if statement condition.") thenBranch = [] elseBranch = None while not(self._check(TokenType.ENDIF) or self._check(TokenType.ELSE)) and not self._isAtEnd(): thenBranch.append(self._declaration()) if self._match([TokenType.ELSE]): elseBranch = self._bodyDeclaration(TokenType.ENDIF) self._consume(TokenType.ENDIF, "Expect 'ENDIF' at end of the if statement.") return Statement.If(condition, thenBranch, elseBranch)
def _functionDeclaration(self): identifier = self._consume(TokenType.IDENTIFIER, "Expect function identifier.") self._consume(TokenType.LEFT_PAREN, "Expect '(' after function identifier.") parameters = [] if not self._check(TokenType.RIGHT_PAREN): while True: if len(parameters) >= 8: self._error(self._peek(), "Cannot have more than 8 parameters.") parameters.append(self._consume(TokenType.IDENTIFIER, "Expect parameter identifier.")) if not self._match([TokenType.COMMA]): break self._consume(TokenType.RIGHT_PAREN, "Expect ')' after parameters.") body = self._bodyDeclaration(TokenType.ENDFUNCTION) self._consume(TokenType.ENDFUNCTION, "Expect 'ENDFUNCTION' at the end of the function.") return Statement.Function(identifier, parameters, body)
def _expressionStatement(self): expression = self._expression() #self._consume(TokenType.SEMICOLON, "Expect ';' after expression.") return Statement.Expression(expression)
def _outputStatement(self): value = self._expression() #self._consume(TokenType.SEMICOLON, "Expect ';' after output value.") return Statement.Output(value);