fix(parser): ignore newlines instead of using them as statement terminators
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user