diff --git a/dmc-lib/src/parser.rs b/dmc-lib/src/parser.rs index 639c4be..189b96d 100644 --- a/dmc-lib/src/parser.rs +++ b/dmc-lib/src/parser.rs @@ -71,16 +71,6 @@ pub fn parse_expression(input: &str) -> ParseResult { (expression, diagnostics) } -#[deprecated] -pub fn parse_let_statement(input: &str) -> ParseResult> { - let mut parser = Parser::new(input); - let mut diagnostics = Vec::new(); - diagnostics.append(&mut parser.advance()); - let (let_statement, mut ds) = parser.let_statement(); - diagnostics.append(&mut ds); - (let_statement, diagnostics) -} - macro_rules! matches_expression_first { ( $token_kind : expr ) => { matches!( @@ -96,12 +86,34 @@ macro_rules! matches_expression_first { }; } +const EXPRESSION_FIRSTS: [TokenKind; 7] = [ + TokenKind::IntegerLiteral, + TokenKind::DoubleLiteral, + TokenKind::LongLiteral, + TokenKind::String, + TokenKind::Minus, + TokenKind::SelfKw, + TokenKind::Identifier, +]; + macro_rules! matches_statement_first { ( $token_kind : expr ) => { matches!($token_kind, TokenKind::Let) || matches_expression_first!($token_kind) }; } +const STATEMENT_FIRSTS: [TokenKind; 8] = { + let mut firsts: [TokenKind; 8] = [TokenKind::Let; 8]; + + let mut i = 0; + while i < EXPRESSION_FIRSTS.len() { + firsts[i + 1] = EXPRESSION_FIRSTS[i]; + i += 1; + } + + firsts +}; + macro_rules! matches_type_use_first { ( $token_kind: expr ) => { matches!($token_kind, TokenKind::LeftSquare | TokenKind::Identifier) @@ -291,15 +303,6 @@ impl<'a> Parser<'a> { } } - fn get_current(&self) -> &Token { - match &self.current { - None => { - panic!("Unexpected end of input"); - } - Some(token) => token, - } - } - fn sample_input(&self, start: usize, end: usize) -> &'a str { &self.input[start..end] } @@ -322,7 +325,7 @@ impl<'a> Parser<'a> { let mut diagnostics = vec![]; while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); // loop checks for Some match current.kind() { TokenKind::Fn | TokenKind::Extern | TokenKind::Class => { let (_, mut ds) = self.module_level_declaration( @@ -359,7 +362,16 @@ impl<'a> Parser<'a> { classes: &mut Vec, ) -> ParseResult<()> { let mut diagnostics = Vec::new(); - let current = self.get_current(); + let current = match self.current.as_ref() { + None => { + diagnostics.push(Self::get_expected_but_found_eoi( + &[TokenKind::Fn, TokenKind::Extern, TokenKind::Class], + self.input.len(), + )); + return ((), diagnostics); + } + Some(current) => current, + }; match current.kind() { TokenKind::Fn => { let (maybe_function, mut ds) = self.function(); @@ -512,7 +524,8 @@ impl<'a> Parser<'a> { let mut maybe_constructor: Option = None; while self.current.is_some() && !self.peek_current(TokenKind::End) { - match self.get_current().kind() { + match self.current.as_ref().unwrap().kind() { + // checked in loop TokenKind::Public => { let (_, mut ds) = self.public_class_member( &mut fields, @@ -623,7 +636,7 @@ impl<'a> Parser<'a> { let mut diagnostics = Vec::new(); if self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); // loop checks for Some return match current.kind() { TokenKind::LeftSquare => { diagnostics.append(&mut self.advance()); // [ @@ -685,7 +698,9 @@ impl<'a> Parser<'a> { let mut diagnostics = Vec::new(); let mut generic_arguments: Vec = vec![]; - while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) { + while self.current.is_some() + && matches_type_use_first!(self.current.as_ref().unwrap().kind()) + { let (type_use, mut ds) = self.type_use(); diagnostics.append(&mut ds); if let Some(type_use) = type_use { @@ -736,7 +751,9 @@ impl<'a> Parser<'a> { let mut extends_list: Vec = vec![]; if self.current.is_some() && self.peek_current(TokenKind::Colon) { diagnostics.append(&mut self.advance()); // : - while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) { + while self.current.is_some() + && matches_type_use_first!(self.current.as_ref().unwrap().kind()) + { let (maybe_type_use, mut ds) = self.type_use(); diagnostics.append(&mut ds); if let Some(type_use) = maybe_type_use { @@ -925,7 +942,17 @@ impl<'a> Parser<'a> { } fn statement(&mut self) -> ParseResult> { - let current = self.get_current(); + let current = match self.current.as_ref() { + None => { + let mut ds = Diagnostics::new(); + ds.push(Self::get_expected_but_found_eoi( + &STATEMENT_FIRSTS, + self.input.len(), + )); + return (None, ds); + } + Some(current) => current, + }; match current.kind() { TokenKind::Let => { let (maybe_let_statement, diagnostics) = self.let_statement(); @@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> { diagnostics.append(&mut ds); while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Lt => { let previous_cloned = current.clone(); @@ -1142,7 +1169,7 @@ impl<'a> Parser<'a> { diagnostics.append(&mut ds); while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Plus => { diagnostics.append(&mut self.advance()); // plus @@ -1187,7 +1214,7 @@ impl<'a> Parser<'a> { diagnostics.append(&mut ds); while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Star => { diagnostics.append(&mut self.advance()); // multiply @@ -1246,7 +1273,7 @@ impl<'a> Parser<'a> { // first, collect all consecutive operators let mut operator_tokens = vec![]; while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Minus => { operator_tokens.push(current.clone()); // unfortunately necessary @@ -1285,7 +1312,7 @@ impl<'a> Parser<'a> { diagnostics.append(&mut ds); while self.current.is_some() { - let current = self.get_current(); + let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::LeftParentheses => { let (call, mut ds) = self.call(base); @@ -1300,7 +1327,17 @@ impl<'a> Parser<'a> { } fn expression_base(&mut self) -> ParseResult { - let current = self.get_current(); + let current = match self.current.as_ref() { + None => { + let mut ds = Diagnostics::new(); + ds.push(Self::get_expected_but_found_eoi( + &EXPRESSION_FIRSTS, + self.input.len(), + )); + return (todo!(), ds); + } + Some(current) => current, + }; let mut diagnostics = Vec::new(); match current.kind() { TokenKind::IntegerLiteral => {