def for_statement(self): self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'.") # initializer = None if self.match(TokenType.SEMICOLON): initializer = None elif self.match(TokenType.VAR): initializer = self.var_declaration() else: initializer = self.expression_statement() condition = None if not self.check(TokenType.SEMICOLON): condition = self.expression() self.consume(TokenType.SEMICOLON, "Expect ';' after loop condition.") increment = None if not self.check(TokenType.RIGHT_PAREN): increment = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.") body = self.statement() if increment is not None: body = Stmt.Block([body, Stmt.Expression(increment)]) condition = SyntaxTree.Literal( True) if condition is None else condition body = Stmt.While(condition, body) if initializer is not None: body = Stmt.Block([initializer, body]) return body
def while_statement(self): self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'while'.") condition = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after condition.") body = self.statement() return Stmt.While(condition, body)
def var_declaration(self): name = self.consume(TokenType.IDENTIFIER, "Expect variable name.") initializer = None if self.match(TokenType.EQUAL): initializer = self.expression() self.consume(TokenType.SEMICOLON, "Expect ';' after variable declaration") return Stmt.Var(name, initializer)
def return_statement(self): keyword = self.previous() value = None if not self.check(TokenType.SEMICOLON): value = self.expression() self.consume(TokenType.SEMICOLON, "Expect ';' after return value.") return Stmt.Return(keyword, value)
def if_statement(self): self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'if'.") condition = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after if condition.") then_branch = self.statement() else_branch = None if self.match(TokenType.ELSE): else_branch = self.statement() return Stmt.If(condition, then_branch, else_branch)
def statement(self): if self.match(TokenType.FOR): return self.for_statement() elif self.match(TokenType.IF): return self.if_statement() elif self.match(TokenType.PRINT): return self.print_statement() elif self.match(TokenType.RETURN): return self.return_statement() elif self.match(TokenType.WHILE): return self.while_statement() elif self.match(TokenType.LEFT_BRACE): return Stmt.Block(self.block()) else: return self.expression_statement()
def class_declaration(self): name = self.consume(TokenType.IDENTIFIER, "Expected class name.") superclass = None if self.match(TokenType.LESS): self.consume(TokenType.IDENTIFIER, "Expected superclass name.") superclass = SyntaxTree.Variable(self.previous()) self.consume(TokenType.LEFT_BRACE, "Expected '{' 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, "Expected '}' after class body.") return Stmt.Class(name, superclass, methods)
def function(self, kind): name = self.consume(TokenType.IDENTIFIER, f"Expect {kind} name.") self.consume(TokenType.LEFT_PAREN, f"Expect '(' after {kind} name.") parameters = [] if not self.check(TokenType.RIGHT_PAREN): while True: if len(parameters) >= 255: self.error(self.peek(), "Cannot have more than 255 parameters.") parameters.append( self.consume(TokenType.IDENTIFIER, "Expected parameter name.")) if not self.match(TokenType.COMMA): break self.consume(TokenType.RIGHT_PAREN, "Expect ')' after parameters.") self.consume(TokenType.LEFT_BRACE, "Expect '{' before " + kind + " body.") body = self.block() return Stmt.Function(name, parameters, body)
def expression_statement(self): expression = self.expression() self.consume(TokenType.SEMICOLON, "Expected ';' after expression.") return Stmt.Expression(expression)
def print_statement(self): value = self.expression() self.consume(TokenType.SEMICOLON, "Expected ';' after value.") return Stmt.Print(value)