fix(parser): ignore newlines instead of using them as statement terminators

This commit is contained in:
2026-02-06 20:58:00 +01:00
parent 14341471b7
commit dde5453e75

View File

@@ -12,7 +12,7 @@ from src.token import Token, TokenType
class Parser:
IGNORE: set[TokenType] = {
TokenType.WHITESPACE, TokenType.COMMENT
TokenType.WHITESPACE, TokenType.COMMENT, TokenType.NEWLINE
}
STATEMENT_BOUNDARY: set[TokenType] = {
@@ -31,16 +31,10 @@ class Parser:
def parse(self) -> list[Stmt]:
statements: list[Stmt] = []
self.skip_newlines()
while not self.is_at_end():
statements.append(self.declaration())
self.skip_newlines()
return statements
def skip_newlines(self):
while self.check(TokenType.NEWLINE):
self.advance()
def is_at_end(self) -> bool:
return self.peek().type == TokenType.EOF
@@ -122,7 +116,6 @@ class Parser:
initializer: Optional[Expr] = None
if self.match(TokenType.EQUAL):
initializer = self.expression()
self.expect_eol("Expected end of line after variable initialization")
return LetStmt(name, initializer)
def statement(self) -> Stmt:
@@ -208,19 +201,22 @@ class Parser:
def return_stmt(self) -> Stmt:
keyword: Token = self.previous()
value: Optional[Expr] = None
if not self.check(TokenType.NEWLINE) and not self.is_at_end():
if not self.check(TokenType.RIGHT_BRACE) and not self.is_at_end():
value = self.expression()
self.expect_eol("Expected end of line after return statement.")
if not self.is_at_end() and not self.check(TokenType.RIGHT_BRACE):
self.error(keyword, "Return must be the last statement in a function.")
return ReturnStmt(keyword, value)
def break_stmt(self) -> Stmt:
keyword: Token = self.previous()
self.expect_eol("Expected end of line after break statement.")
if not self.is_at_end() and not self.check(TokenType.RIGHT_BRACE):
self.error(keyword, "Break must be the last statement in a block.")
return BreakStmt(keyword)
def continue_stmt(self) -> Stmt:
keyword: Token = self.previous()
self.expect_eol("Expected end of line after continue statement.")
if not self.is_at_end() and not self.check(TokenType.RIGHT_BRACE):
self.error(keyword, "Continue must be the last statement in a block.")
return ContinueStmt(keyword)
def while_stmt(self) -> Stmt:
@@ -230,9 +226,7 @@ class Parser:
def block_stmt(self) -> list[Stmt]:
statements: list[Stmt] = []
self.skip_newlines()
while not self.check(TokenType.RIGHT_BRACE) and not self.is_at_end():
self.skip_newlines()
statements.append(self.declaration())
self.consume(TokenType.RIGHT_BRACE, "Expected '}' after block.")
@@ -240,7 +234,6 @@ class Parser:
def expression_stmt(self) -> Stmt:
value: Expr = self.expression()
self.expect_eol("Expected end of line after expression")
return ExpressionStmt(value)
def expression(self) -> Expr: