From 3066ba9032f8e538698ae4685d81bdf1490e9cf8 Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Sun, 1 Sep 2024 20:46:49 +0200 Subject: [PATCH] split off declarations from statements added error for duplicate parameter names --- frontend/src/parser/_parser.rs | 28 ++++++++++++++++++++++------ frontend/src/parser/error.rs | 2 ++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/frontend/src/parser/_parser.rs b/frontend/src/parser/_parser.rs index 8f4558c..a0eeba6 100644 --- a/frontend/src/parser/_parser.rs +++ b/frontend/src/parser/_parser.rs @@ -102,7 +102,7 @@ impl Parser { while !me.token_iter.is_empty() && me.peek_token().token_type != TokenType::EOF { // statements.push(me.statement()?); - match me.statement() { + match me.declaration() { Ok(stmt) => { statements.push(stmt); } @@ -167,15 +167,21 @@ impl Parser { } } + fn declaration(&mut self) -> ParserResult { + match self.peek_token().token_type { + TokenType::Var => self.var_declaration(), + TokenType::Class => self.class_declaration(), + TokenType::Fun => self.fun_declaration(), + _ => self.statement(), + } + } + fn statement(&mut self) -> ParserResult { match self.peek_token().token_type { TokenType::Print => self.print_statement(), TokenType::If => self.if_statement(), TokenType::While => self.while_statement(), TokenType::For => self.for_statement(), - TokenType::Var => self.var_declaration(), - TokenType::Class => self.class_declaration(), - TokenType::Fun => self.fun_declaration(), TokenType::LeftBrace => self.block(), TokenType::Break => { let code_pos = self.peek_token().code_pos; @@ -491,7 +497,17 @@ impl Parser { while self.peek_token().token_type == TokenType::Comma { assert_eq!(self.next_token().token_type, TokenType::Comma); - param_names.push(self.identifier("Expected parameter name")?); + let code_pos = self.peek_token().code_pos; + + let name = self.identifier("Expected parameter name")?; + + for param in param_names.iter() { + if &name == param { + return Err(ParserError::DuplicateParameterName { code_pos }); + } + } + + param_names.push(name); } self.consume_token(TokenType::RightParen, |token| { @@ -510,7 +526,7 @@ impl Parser { let mut statements = Vec::new(); while self.peek_token().token_type != TokenType::RightBrace { - let statement = self.statement().map_err(|err| { + let statement = self.declaration().map_err(|err| { if self.peek_token().token_type == TokenType::EOF { ParserError::MissingRightBrace { code_pos: self.peek_token().code_pos, diff --git a/frontend/src/parser/error.rs b/frontend/src/parser/error.rs index a801790..49ab93b 100644 --- a/frontend/src/parser/error.rs +++ b/frontend/src/parser/error.rs @@ -46,4 +46,6 @@ pub enum ParserError { ReturnInInit { code_pos: CodePos }, #[error("ParserError: Missing method name after super")] MissingMethodAfterSuper { code_pos: CodePos }, + #[error("ParserError: duplicate parameter name at {code_pos}")] + DuplicateParameterName { code_pos: CodePos }, }