split off declarations from statements

added error for duplicate parameter names
This commit is contained in:
Moritz Gmeiner 2024-09-01 20:46:49 +02:00
commit 3066ba9032
2 changed files with 24 additions and 6 deletions

View file

@ -102,7 +102,7 @@ impl Parser {
while !me.token_iter.is_empty() && me.peek_token().token_type != TokenType::EOF { while !me.token_iter.is_empty() && me.peek_token().token_type != TokenType::EOF {
// statements.push(me.statement()?); // statements.push(me.statement()?);
match me.statement() { match me.declaration() {
Ok(stmt) => { Ok(stmt) => {
statements.push(stmt); statements.push(stmt);
} }
@ -167,15 +167,21 @@ impl Parser {
} }
} }
fn declaration(&mut self) -> ParserResult<Stmt> {
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<Stmt> { fn statement(&mut self) -> ParserResult<Stmt> {
match self.peek_token().token_type { match self.peek_token().token_type {
TokenType::Print => self.print_statement(), TokenType::Print => self.print_statement(),
TokenType::If => self.if_statement(), TokenType::If => self.if_statement(),
TokenType::While => self.while_statement(), TokenType::While => self.while_statement(),
TokenType::For => self.for_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::LeftBrace => self.block(),
TokenType::Break => { TokenType::Break => {
let code_pos = self.peek_token().code_pos; let code_pos = self.peek_token().code_pos;
@ -491,7 +497,17 @@ impl Parser {
while self.peek_token().token_type == TokenType::Comma { while self.peek_token().token_type == TokenType::Comma {
assert_eq!(self.next_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| { self.consume_token(TokenType::RightParen, |token| {
@ -510,7 +526,7 @@ impl Parser {
let mut statements = Vec::new(); let mut statements = Vec::new();
while self.peek_token().token_type != TokenType::RightBrace { 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 { if self.peek_token().token_type == TokenType::EOF {
ParserError::MissingRightBrace { ParserError::MissingRightBrace {
code_pos: self.peek_token().code_pos, code_pos: self.peek_token().code_pos,

View file

@ -46,4 +46,6 @@ pub enum ParserError {
ReturnInInit { code_pos: CodePos }, ReturnInInit { code_pos: CodePos },
#[error("ParserError: Missing method name after super")] #[error("ParserError: Missing method name after super")]
MissingMethodAfterSuper { code_pos: CodePos }, MissingMethodAfterSuper { code_pos: CodePos },
#[error("ParserError: duplicate parameter name at {code_pos}")]
DuplicateParameterName { code_pos: CodePos },
} }