From 2dfd8e8a295a44ce87eacfb99533d524b1ff0dcb Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 21 Aug 2026 16:38:30 -0500 Subject: [PATCH] Finish parser refactor, simplifying code and diagnostics handling. --- dm/src/repl.rs | 12 +- dmc-lib/src/lib.rs | 18 +- dmc-lib/src/parser.rs | 1198 ++++++++++++----------------------------- 3 files changed, 366 insertions(+), 862 deletions(-) diff --git a/dm/src/repl.rs b/dm/src/repl.rs index a4a607a..c0d75b3 100644 --- a/dm/src/repl.rs +++ b/dm/src/repl.rs @@ -105,14 +105,10 @@ fn compile_statement( register_count: usize, constants_table: &mut ConstantsTable, ) -> Result { - let maybe_statement = parse_statement(input); - if !maybe_statement.is_ok() { - Err(maybe_statement.into_diagnostics()) + let parse_result = parse_statement(input); + if !parse_result.is_ok() { + Err(parse_result.1) } else { - session.compile_statement( - &maybe_statement.into_inner(), - register_count, - constants_table, - ) + session.compile_statement(&parse_result.0.unwrap(), register_count, constants_table) } } diff --git a/dmc-lib/src/lib.rs b/dmc-lib/src/lib.rs index 27494c8..7826411 100644 --- a/dmc-lib/src/lib.rs +++ b/dmc-lib/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(option_zip)] + use crate::ast::statement::Statement; use crate::constants_table::ConstantsTable; use crate::diagnostic::Diagnostics; @@ -5,7 +7,7 @@ use crate::ir::compile_dvm_function; use crate::ir::ir_variable::{IrStackFrameVariables, IrVariable, IrVariableInfo}; use crate::lowering::util::to_ir_type_info; use crate::lowering::{lower_to_ir_compilation_unit, lower_to_ir_synthetic_function}; -use crate::parser::parse_compilation_unit; +use crate::parser::{ParseResult, parse_compilation_unit}; use crate::semantic_analysis::symbol::SymbolId; use crate::semantic_analysis::{analyze_compilation_unit, analyze_statement}; use dvm_lib::vm::function::Function; @@ -39,14 +41,14 @@ pub fn compile_compilation_unit( register_count: usize, constants_table: &mut ConstantsTable, ) -> Result { - let (compilation_unit, diagnostics) = parse_compilation_unit(input, None); - if !diagnostics.is_empty() { - return Err(diagnostics); - } + let ParseResult(compilation_unit, mut parse_diagnostics) = parse_compilation_unit(input, None); + let mut analysis_diagnostics = analyze_compilation_unit(&compilation_unit, analysis_context); - let diagnostics = analyze_compilation_unit(&compilation_unit, analysis_context); - if !diagnostics.is_empty() { - return Err(diagnostics); + if !parse_diagnostics.is_empty() || !analysis_diagnostics.is_empty() { + let mut all_diagnostics = Vec::new(); + all_diagnostics.append(&mut parse_diagnostics); + all_diagnostics.append(&mut analysis_diagnostics); + return Err(all_diagnostics); } let lower_to_ir_result = lower_to_ir_compilation_unit(&compilation_unit, analysis_context); diff --git a/dmc-lib/src/parser.rs b/dmc-lib/src/parser.rs index 7712832..3640fd5 100644 --- a/dmc-lib/src/parser.rs +++ b/dmc-lib/src/parser.rs @@ -1,4 +1,5 @@ use crate::FileId; +use crate::ast::NodeId; use crate::ast::assign_statement::AssignStatement; use crate::ast::binary_expression::{BinaryExpression, BinaryOperation}; use crate::ast::call::Call; @@ -27,125 +28,18 @@ use crate::source_range::SourceRange; use crate::token::{Token, TokenKind}; use std::str::FromStr; -#[deprecated] -pub type ParseResult = (T, Diagnostics); - -pub struct ParseResult2 { - t: T, - diagnostics: Diagnostics, -} - -impl ParseResult2 { - pub fn new(t: T, diagnostics: Diagnostics) -> Self { - Self { t, diagnostics } - } - - fn to_maybe_parse_result(self) -> MaybeParseResult { - MaybeParseResult::some(self.t, self.diagnostics) - } -} - -pub struct MaybeParseResult { - t: Option, - diagnostics: Diagnostics, -} - -impl MaybeParseResult { - fn some(t: T, diagnostics: Diagnostics) -> Self { - Self { - t: Some(t), - diagnostics, - } - } - - fn none(diagnostics: Diagnostics) -> Self { - Self { - t: None, - diagnostics, - } - } - - fn push_diagnostic(&mut self, diagnostic: Diagnostic) { - self.diagnostics.push(diagnostic); - } - - fn append_diagnostics(&mut self, diagnostics: &mut Diagnostics) { - self.diagnostics.append(diagnostics); - } - - fn with_diagnostics(mut self, mut diagnostics: Diagnostics) -> Self { - self.diagnostics.append(&mut diagnostics); - self - } +pub struct ParseResult(pub T, pub Diagnostics); +impl ParseResult { pub fn is_ok(&self) -> bool { - self.t.is_some() && self.diagnostics.is_empty() + self.1.is_empty() } - fn map(self, f: impl FnOnce(T) -> R) -> MaybeParseResult { + pub fn to_result(self) -> Result { if self.is_ok() { - let t = self.t.unwrap(); - MaybeParseResult::some(f(t), self.diagnostics) + Ok(self.0) } else { - MaybeParseResult::none(self.diagnostics) - } - } - - fn flat_map(mut self, f: impl FnOnce(T) -> MaybeParseResult) -> MaybeParseResult { - if self.is_ok() { - let t = self.t.unwrap(); - let mut r = f(t); - r.append_diagnostics(&mut self.diagnostics); - r - } else { - MaybeParseResult::none(self.diagnostics) - } - } - - fn zip_map(mut self, mut other: MaybeParseResult, f: impl FnOnce(T, T) -> T) -> Self { - if self.is_ok() && other.is_ok() { - let t0 = self.t.take().unwrap(); - let t1 = other.t.take().unwrap(); - MaybeParseResult::some(f(t0, t1), self.diagnostics) - } else { - let mut result = MaybeParseResult::none(self.diagnostics); - result.diagnostics.append(&mut other.diagnostics); - result - } - } - - pub fn take_inner(&mut self) -> T { - if !self.is_ok() { - panic!("Attempt to take non-Ok MaybeParseResult inner"); - } - self.t.take().unwrap() - } - - pub fn into_inner(self) -> T { - if !self.is_ok() { - panic!("Attempt to take non-Ok MaybeParseResult inner"); - } - self.t.unwrap() - } - - pub fn take_diagnostics(&mut self) -> Diagnostics { - std::mem::take(&mut self.diagnostics) - } - - pub fn into_diagnostics(self) -> Diagnostics { - self.diagnostics - } - - pub fn diagnostics(&self) -> &Diagnostics { - &self.diagnostics - } -} - -impl Default for MaybeParseResult { - fn default() -> Self { - Self { - t: None, - diagnostics: Diagnostics::new(), + Err(self.1) } } } @@ -154,12 +48,7 @@ pub fn get_compilation_unit( input: &str, file_id: Option, ) -> Result { - let (compilation_unit, diagnostics) = parse_compilation_unit(input, file_id); - if diagnostics.is_empty() { - Ok(compilation_unit) - } else { - Err(diagnostics) - } + parse_compilation_unit(input, file_id).to_result() } pub fn parse_compilation_unit( @@ -167,29 +56,20 @@ pub fn parse_compilation_unit( file_id: Option, ) -> ParseResult { let mut parser = Parser::new(input); - let mut diagnostics = Vec::new(); - diagnostics.append(&mut parser.advance()); - let (compilation_unit, mut ds) = parser.compilation_unit(file_id); - diagnostics.append(&mut ds); - (compilation_unit, diagnostics) + parser.advance(); + parser.compilation_unit(file_id) } -pub fn parse_statement(input: &str) -> MaybeParseResult { +pub fn parse_statement(input: &str) -> ParseResult> { let mut parser = Parser::new(input); - let mut diagnostics = Diagnostics::new(); - diagnostics.append(&mut parser.advance()); - let mut maybe_statement = parser.statement(); - maybe_statement.append_diagnostics(&mut diagnostics); - maybe_statement + parser.advance(); + ParseResult(parser.statement(), parser.diagnostics) } -pub fn parse_expression(input: &str) -> MaybeParseResult { +pub fn parse_expression(input: &str) -> ParseResult> { let mut parser = Parser::new(input); - let mut diagnostics = Vec::new(); - diagnostics.append(&mut parser.advance()); - let mut maybe_expression = parser.expression(); - maybe_expression.append_diagnostics(&mut diagnostics); - maybe_expression + parser.advance(); + ParseResult(parser.expression(), parser.diagnostics) } macro_rules! matches_expression_first { @@ -241,12 +121,37 @@ macro_rules! matches_type_use_first { }; } +fn join_kinds(kinds: &[TokenKind]) -> String { + kinds + .iter() + .map(|kind| format!("{:?}", kind)) + .collect::>() + .join(", ") +} + +fn get_expected_but_found(kinds: &[TokenKind], found: &Token) -> Diagnostic { + Diagnostic::new( + &format!("Unexpected token: {:?}.", found.kind()), + found.start(), + found.end(), + ) + .with_error_code(PARSE_ERROR) + .with_primary_label_message(&format!("Expected {}.", join_kinds(kinds))) +} + +fn get_expected_but_found_eoi(kinds: &[TokenKind], position: usize) -> Diagnostic { + Diagnostic::new("Unexpected end-of-input.", position, position) + .with_error_code(PARSE_ERROR) + .with_primary_label_message(&format!("Expected {}.", join_kinds(kinds))) +} + struct Parser<'a> { input: &'a str, lexer: Lexer<'a>, current: Option, lookahead: Option, - node_id: usize, + current_node_id: NodeId, + diagnostics: Diagnostics, } impl<'a> Parser<'a> { @@ -256,15 +161,13 @@ impl<'a> Parser<'a> { lexer: Lexer::new(input), current: None, lookahead: None, - node_id: 0, + current_node_id: 0, + diagnostics: Diagnostics::new(), } } - #[must_use] - fn advance_until(&mut self, token_kinds: &[TokenKind]) -> Diagnostics { - let mut diagnostics = Vec::new(); + fn advance_until(&mut self, token_kinds: &[TokenKind]) { while self.current.is_some() { - diagnostics.append(&mut self.advance()); match &self.current { None => { // reached eoi @@ -276,14 +179,10 @@ impl<'a> Parser<'a> { } } } - diagnostics } - #[must_use] - fn advance(&mut self) -> Diagnostics { - #[must_use] - fn fetch(lexer: &mut Lexer) -> (Option, Diagnostics) { - let mut diagnostics = vec![]; + fn advance(&mut self) { + fn fetch(lexer: &mut Lexer, diagnostics: &mut Diagnostics) -> Option { let mut maybe_token: Option = None; while let Some(lexer_result) = lexer.next() { match lexer_result { @@ -310,97 +209,56 @@ impl<'a> Parser<'a> { } } } - (maybe_token, diagnostics) + maybe_token } - let mut diagnostics = Vec::new(); - if self.lookahead.is_some() { // we've advanced at least once self.current = self.lookahead.take(); - let (lookahead, mut ds) = fetch(&mut self.lexer); - self.lookahead = lookahead; - diagnostics.append(&mut ds); + self.lookahead = fetch(&mut self.lexer, &mut self.diagnostics); } else if self.lookahead.is_none() && self.current.is_some() { // we're on the last token self.current = None; } else { // we've not yet advanced, so fetch both - let (current, mut ds) = fetch(&mut self.lexer); - self.current = current; - diagnostics.append(&mut ds); - - let (lookahead, mut ds) = fetch(&mut self.lexer); - self.lookahead = lookahead; - diagnostics.append(&mut ds); + self.current = fetch(&mut self.lexer, &mut self.diagnostics); + self.lookahead = fetch(&mut self.lexer, &mut self.diagnostics); } - - diagnostics } - fn join_kinds(kinds: &[TokenKind]) -> String { - kinds - .iter() - .map(|kind| format!("{:?}", kind)) - .collect::>() - .join(", ") - } - - fn get_expected_but_found(kinds: &[TokenKind], found: &Token) -> Diagnostic { - Diagnostic::new( - &format!("Unexpected token: {:?}.", found.kind()), - found.start(), - found.end(), - ) - .with_error_code(PARSE_ERROR) - .with_primary_label_message(&format!("Expected {}.", Self::join_kinds(kinds))) - } - - fn get_expected_but_found_eoi(kinds: &[TokenKind], position: usize) -> Diagnostic { - Diagnostic::new("Unexpected end-of-input.", position, position) - .with_error_code(PARSE_ERROR) - .with_primary_label_message(&format!("Expected {}.", Self::join_kinds(kinds))) - } - - #[must_use] - fn expect_advance(&mut self, token_kind: TokenKind) -> (Option, Diagnostics) { + fn expect_advance(&mut self, token_kind: TokenKind) -> Option { match self.current.take() { - None => ( - None, - vec![Self::get_expected_but_found_eoi( - &[token_kind], - self.input.len(), - )], - ), + None => { + self.diagnostics + .push(get_expected_but_found_eoi(&[token_kind], self.input.len())); + None + } Some(token) => { - let mut diagnostics = Vec::new(); if token.kind() == token_kind { - diagnostics.append(&mut self.advance()); - (Some(token), diagnostics) + self.advance(); + Some(token) } else { - ( - None, - vec![Self::get_expected_but_found(&[token_kind], &token)], - ) + self.diagnostics + .push(get_expected_but_found(&[token_kind], &token)); + None } } } } - #[must_use] fn expect_immediately_after_advance( &mut self, token_kind: TokenKind, previous_token: &Token, - ) -> (Option, Diagnostics) { - let (maybe_matched, mut diagnostics) = self.expect_advance(token_kind); + ) -> Option { + let maybe_matched = self.expect_advance(token_kind); match maybe_matched { - None => (None, diagnostics), + None => None, Some(matched) => { if matched.start() == previous_token.end() { - (Some(matched), diagnostics) + Some(matched) } else { - diagnostics.push( + self.diagnostics.push( Diagnostic::new( &format!( "Expected {:?} immediately after previous token.", @@ -411,7 +269,7 @@ impl<'a> Parser<'a> { ) .with_error_code(PARSE_ERROR), ); - (None, diagnostics) + None } } } @@ -419,7 +277,7 @@ impl<'a> Parser<'a> { fn peek_current(&self, token_kind: TokenKind) -> bool { match &self.current { - None => panic!("Unexpected end of input."), + None => panic!("BUG: peeked when current is None"), Some(token) => token.kind() == token_kind, } } @@ -432,9 +290,9 @@ impl<'a> Parser<'a> { self.sample_input(token.start(), token.end()) } - fn next_node_id(&mut self) -> usize { - let node_id = self.node_id; - self.node_id += 1; + fn next_node_id(&mut self) -> NodeId { + let node_id = self.current_node_id; + self.current_node_id += 1; node_id } @@ -443,36 +301,28 @@ impl<'a> Parser<'a> { let mut extern_functions: Vec = vec![]; let mut classes: Vec = vec![]; - let mut diagnostics = vec![]; - while self.current.is_some() { 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( + self.module_level_declaration( &mut functions, &mut extern_functions, &mut classes, ); - diagnostics.append(&mut ds); } _ => { - diagnostics.push(Self::get_expected_but_found( + self.diagnostics.push(get_expected_but_found( &[TokenKind::Fn, TokenKind::Extern, TokenKind::Class], current, )); - diagnostics.append(&mut self.advance_until(&[ - TokenKind::Fn, - TokenKind::Extern, - TokenKind::Class, - ])); } } } - ( + ParseResult( CompilationUnit::new(file_id, functions, extern_functions, classes), - diagnostics, + std::mem::take(&mut self.diagnostics), ) } @@ -481,93 +331,65 @@ impl<'a> Parser<'a> { functions: &mut Vec, extern_functions: &mut Vec, classes: &mut Vec, - ) -> ParseResult<()> { - let mut diagnostics = Vec::new(); + ) { let current = match self.current.as_ref() { None => { - diagnostics.push(Self::get_expected_but_found_eoi( + self.diagnostics.push(get_expected_but_found_eoi( &[TokenKind::Fn, TokenKind::Extern, TokenKind::Class], self.input.len(), )); - return ((), diagnostics); + return; } Some(current) => current, }; match current.kind() { TokenKind::Fn => { - let maybe_function = self.function(); - if maybe_function.is_ok() { - functions.push(maybe_function.into_inner()); - } else { - diagnostics.append(&mut maybe_function.into_diagnostics()); + if let Some(function) = self.function() { + functions.push(function); } } TokenKind::Extern => { - let (maybe_extern_function, mut ds) = self.extern_function(); - diagnostics.append(&mut ds); - if let Some(extern_function) = maybe_extern_function { + if let Some(extern_function) = self.extern_function() { extern_functions.push(extern_function); } } TokenKind::Class => { - let maybe_class = self.class(); - if maybe_class.is_ok() { - classes.push(maybe_class.into_inner()); - } else { - diagnostics.append(&mut maybe_class.into_diagnostics()); + if let Some(class) = self.class() { + classes.push(class); } } _ => unreachable!(), } - - ((), diagnostics) } - fn function(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn function(&mut self) -> Option { let is_public = if self.current.is_some() && self.peek_current(TokenKind::Public) { - diagnostics.append(&mut self.advance()); // pub + self.advance(); // pub true } else { false }; - let (_, mut ds) = self.expect_advance(TokenKind::Fn); - diagnostics.append(&mut ds); - - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::LeftParentheses); - diagnostics.append(&mut ds); - - let (parameters, mut ds) = self.parameter_list(); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::RightParentheses); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::Fn); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); + self.expect_advance(TokenKind::LeftParentheses); + let parameters = self.parameter_list(); + self.expect_advance(TokenKind::RightParentheses); let return_type = if self.current.is_some() && self.peek_current(TokenKind::RightArrow) { - let (maybe_type_use, mut ds) = self.return_type(); - diagnostics.append(&mut ds); - maybe_type_use + self.return_type() } else { None }; let mut statements = vec![]; while self.current.is_some() && !self.peek_current(TokenKind::End) { - let maybe_statement = self.statement(); - if maybe_statement.is_ok() { - statements.push(maybe_statement.into_inner()); - } else { - diagnostics.append(&mut maybe_statement.into_diagnostics()); + if let Some(statement) = self.statement() { + statements.push(statement); } } - let (_, mut ds) = self.expect_advance(TokenKind::End); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::End); if let Some(identifier) = maybe_identifier { let function = Function::new( @@ -579,38 +401,23 @@ impl<'a> Parser<'a> { return_type, statements, ); - MaybeParseResult::some(function, diagnostics) + Some(function) } else { - MaybeParseResult::none(diagnostics) + None } } - fn extern_function(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); - - let (_, mut ds) = self.expect_advance(TokenKind::Extern); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::Fn); - diagnostics.append(&mut ds); - - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::LeftParentheses); - diagnostics.append(&mut ds); - - let (parameters, mut ds) = self.parameter_list(); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::RightParentheses); - diagnostics.append(&mut ds); - - let (return_type, mut ds) = self.return_type(); - diagnostics.append(&mut ds); + fn extern_function(&mut self) -> Option { + self.expect_advance(TokenKind::Extern); + self.expect_advance(TokenKind::Fn); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); + self.expect_advance(TokenKind::LeftParentheses); + let parameters = self.parameter_list(); + self.expect_advance(TokenKind::RightParentheses); + let maybe_return_type = self.return_type(); if let Some(identifier) = maybe_identifier - && let Some(type_use) = return_type + && let Some(type_use) = maybe_return_type { let extern_function = ExternFunction::new( self.next_node_id(), @@ -619,29 +426,21 @@ impl<'a> Parser<'a> { parameters, type_use, ); - (Some(extern_function), diagnostics) + Some(extern_function) } else { - (None, diagnostics) + None } } - fn class(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); + fn class(&mut self) -> Option { + self.expect_advance(TokenKind::Class); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); - let (_, mut ds) = self.expect_advance(TokenKind::Class); - diagnostics.append(&mut ds); - - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); - - let generic_parameters: Vec = - if self.current.is_some() && self.peek_current(TokenKind::Lt) { - let (gps, mut ds) = self.generic_parameters(); - diagnostics.append(&mut ds); - gps - } else { - Vec::new() - }; + let generic_parameters = if self.current.is_some() && self.peek_current(TokenKind::Lt) { + self.generic_parameters() + } else { + Vec::new() + }; let mut fields = vec![]; let mut functions = vec![]; @@ -651,40 +450,26 @@ impl<'a> Parser<'a> { match self.current.as_ref().unwrap().kind() { // checked in loop TokenKind::Public => { - let (_, mut ds) = - self.public_class_member(&mut fields, &mut functions, &mut constructor); - diagnostics.append(&mut ds); + self.public_class_member(&mut fields, &mut functions, &mut constructor); } TokenKind::Mut | TokenKind::Identifier => { - let maybe_field = self.field(); - if maybe_field.is_ok() { - fields.push(maybe_field.into_inner()); - } else { - diagnostics.append(&mut maybe_field.into_diagnostics()); + if let Some(field) = self.field() { + fields.push(field); } } TokenKind::Fn => { - let maybe_function = self.function(); - if maybe_function.is_ok() { - functions.push(maybe_function.into_inner()); - } else { - diagnostics.append(&mut maybe_function.into_diagnostics()); + if let Some(function) = self.function() { + functions.push(function); } } TokenKind::Ctor => { - let maybe_constructor = self.constructor(); - if maybe_constructor.is_ok() { - constructor.replace(maybe_constructor.into_inner()); - } else { - diagnostics.append(&mut maybe_constructor.into_diagnostics()); - } + constructor = self.constructor(); } _ => unreachable!(), } } - let (_, mut ds) = self.expect_advance(TokenKind::End); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::End); if let Some(identifier) = maybe_identifier { let class = Class::new( @@ -696,41 +481,31 @@ impl<'a> Parser<'a> { fields, functions, ); - MaybeParseResult::some(class, diagnostics) + Some(class) } else { - MaybeParseResult::none(diagnostics) + None } } - fn parameter_list(&mut self) -> ParseResult> { + fn parameter_list(&mut self) -> Vec { let mut parameters = vec![]; - let mut diagnostics = vec![]; while self.current.is_some() && self.peek_current(TokenKind::Identifier) { - let (maybe_parameter, mut ds) = self.parameter(); - diagnostics.append(&mut ds); - if let Some(parameter) = maybe_parameter { + if let Some(parameter) = self.parameter() { parameters.push(parameter); } if self.current.is_some() && self.peek_current(TokenKind::Comma) { - diagnostics.append(&mut self.advance()); + self.advance(); } } - - (parameters, diagnostics) + parameters } - fn parameter(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); + fn parameter(&mut self) -> Option { + let maybe_identifier = self.expect_advance(TokenKind::Identifier); + self.expect_advance(TokenKind::Colon); - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::Colon); - diagnostics.append(&mut ds); - - let (maybe_type_use, mut ds) = self.type_use(); - diagnostics.append(&mut ds); + let maybe_type_use = self.type_use(); if let Some(identifier) = maybe_identifier && let Some(type_use) = maybe_type_use @@ -741,50 +516,32 @@ impl<'a> Parser<'a> { SourceRange::new(identifier.start(), identifier.end()), type_use, ); - (Some(parameter), diagnostics) + Some(parameter) } else { - (None, diagnostics) + None } } - fn return_type(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); - let (_, mut ds) = self.expect_advance(TokenKind::RightArrow); - diagnostics.append(&mut ds); - let (maybe_type_use, mut ds) = self.type_use(); - diagnostics.append(&mut ds); - (maybe_type_use, diagnostics) + fn return_type(&mut self) -> Option { + self.expect_advance(TokenKind::RightArrow); + self.type_use() } - fn type_use(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); - + fn type_use(&mut self) -> Option { if self.current.is_some() { let current = self.current.as_ref().unwrap(); // loop checks for Some - return match current.kind() { + match current.kind() { TokenKind::LeftSquare => { - diagnostics.append(&mut self.advance()); // [ - let (inner_type_use, mut ds) = self.type_use(); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::RightSquare); - diagnostics.append(&mut ds); - todo!() } TokenKind::Identifier => { - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); let generic_arguments = if self.current.is_some() && self.peek_current(TokenKind::Lt) { - diagnostics.append(&mut self.advance()); // < - let (generic_arguments, mut ds) = self.generic_arguments_list(); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::Gt); // > - diagnostics.append(&mut ds); - + self.advance(); // < + let generic_arguments = self.generic_arguments_list(); + self.expect_advance(TokenKind::Gt); // > generic_arguments } else { vec![] @@ -797,110 +554,96 @@ impl<'a> Parser<'a> { SourceRange::new(identifier.start(), identifier.end()), generic_arguments, ); - (Some(type_use), diagnostics) + Some(type_use) } else { - (None, diagnostics) + None } } _ => { - diagnostics.push(Self::get_expected_but_found( + self.diagnostics.push(get_expected_but_found( &[TokenKind::LeftSquare, TokenKind::Identifier], current, )); - (None, diagnostics) + None } - }; + } + } else { + self.diagnostics.push(get_expected_but_found_eoi( + &[TokenKind::LeftSquare, TokenKind::Identifier], + self.input.len(), + )); + None } - diagnostics.push(Self::get_expected_but_found_eoi( - &[TokenKind::LeftSquare, TokenKind::Identifier], - self.input.len(), - )); - (None, diagnostics) } - fn generic_arguments_list(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); + fn generic_arguments_list(&mut self) -> Vec { let mut generic_arguments: Vec = vec![]; - 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 { + if let Some(type_use) = self.type_use() { generic_arguments.push(type_use); } if self.current.is_some() && self.peek_current(TokenKind::Comma) { - diagnostics.append(&mut self.advance()); // comma + self.advance(); // comma } else { break; } } - - (generic_arguments, diagnostics) + generic_arguments } - fn generic_parameters(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); - - let (_, mut ds) = self.expect_advance(TokenKind::Lt); - diagnostics.append(&mut ds); + fn generic_parameters(&mut self) -> Vec { + self.expect_advance(TokenKind::Lt); let mut parameters: Vec = vec![]; while self.current.is_some() && self.peek_current(TokenKind::Identifier) { - let (maybe_generic_parameter, mut ds) = self.generic_parameter(); - diagnostics.append(&mut ds); - if let Some(generic_parameter) = maybe_generic_parameter { + if let Some(generic_parameter) = self.generic_parameter() { parameters.push(generic_parameter); } if self.current.is_some() && self.peek_current(TokenKind::Plus) { - diagnostics.append(&mut self.advance()); // + + self.advance(); // + } else { break; } } - let (_, mut ds) = self.expect_advance(TokenKind::Gt); - diagnostics.append(&mut ds); - (parameters, diagnostics) + self.expect_advance(TokenKind::Gt); + parameters } - fn generic_parameter(&mut self) -> ParseResult> { - let mut diagnostics = Vec::new(); - let (identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); + fn generic_parameter(&mut self) -> Option { + let maybe_identifier = self.expect_advance(TokenKind::Identifier); let mut extends_list: Vec = vec![]; if self.current.is_some() && self.peek_current(TokenKind::Colon) { - diagnostics.append(&mut self.advance()); // : + self.advance(); // : 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 { + if let Some(type_use) = self.type_use() { extends_list.push(type_use); } if self.current.is_some() && self.peek_current(TokenKind::Comma) { - diagnostics.append(&mut self.advance()); // , + self.advance(); // , } else { break; } } } - if let Some(identifier) = identifier { + if let Some(identifier) = maybe_identifier { let generic_parameter = GenericParameter::new( self.token_text(&identifier), SourceRange::new(identifier.start(), identifier.end()), extends_list, ); - (Some(generic_parameter), diagnostics) + Some(generic_parameter) } else { - (None, diagnostics) + None } } @@ -908,38 +651,28 @@ impl<'a> Parser<'a> { &mut self, fields: &mut Vec, functions: &mut Vec, - constructor: &mut Option, - ) -> ParseResult<()> { - let mut diagnostics = Vec::new(); + maybe_constructor: &mut Option, + ) { if self.lookahead.is_some() { match self.lookahead.as_ref().unwrap().kind() { TokenKind::Mut | TokenKind::Identifier => { - let maybe_field = self.field(); - if maybe_field.is_ok() { - fields.push(maybe_field.into_inner()); - } else { - diagnostics.append(&mut maybe_field.into_diagnostics()); + if let Some(field) = self.field() { + fields.push(field); } } TokenKind::Fn => { - let maybe_function = self.function(); - if maybe_function.is_ok() { - functions.push(maybe_function.into_inner()); - } else { - diagnostics.append(&mut maybe_function.into_diagnostics()); + if let Some(function) = self.function() { + functions.push(function); } } TokenKind::Ctor => { - let maybe_constructor = self.constructor(); - if maybe_constructor.is_ok() { - constructor.replace(maybe_constructor.into_inner()); - } else { - diagnostics.append(&mut maybe_constructor.into_diagnostics()); + if let Some(constructor) = self.constructor() { + maybe_constructor.replace(constructor); } } _ => { let lookahead = self.lookahead.as_ref().unwrap(); - diagnostics.push(Self::get_expected_but_found( + self.diagnostics.push(get_expected_but_found( &[TokenKind::Mut, TokenKind::Identifier, TokenKind::Fn], lookahead, )); @@ -947,61 +680,46 @@ impl<'a> Parser<'a> { } } else { let current = self.current.as_ref().unwrap(); - diagnostics.push(Self::get_expected_but_found( + self.diagnostics.push(get_expected_but_found( &[TokenKind::Mut, TokenKind::Identifier, TokenKind::Fn], current, )); } - - ((), diagnostics) } - fn constructor(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn constructor(&mut self) -> Option { let is_public = if self.current.is_some() && self.peek_current(TokenKind::Public) { - diagnostics.append(&mut self.advance()); + self.advance(); true } else { false }; - let (ctor_keyword, mut ds) = self.expect_advance(TokenKind::Ctor); - diagnostics.append(&mut ds); - - let (_, mut ds) = self.expect_advance(TokenKind::LeftParentheses); - diagnostics.append(&mut ds); + let maybe_ctor_kw = self.expect_advance(TokenKind::Ctor); + self.expect_advance(TokenKind::LeftParentheses); let parameters = if self.current.is_some() && self.peek_current(TokenKind::Identifier) { - let (parameters, mut ds) = self.parameter_list(); - diagnostics.append(&mut ds); - parameters + self.parameter_list() } else { vec![] }; - let (_, mut ds) = self.expect_advance(TokenKind::RightParentheses); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::RightParentheses); // statements let mut statements: Vec = vec![]; - let mut diagnostics: Vec = vec![]; while self.current.is_some() && matches_statement_first!(self.current.as_ref().unwrap().kind()) { - let maybe_statement = self.statement(); - if maybe_statement.is_ok() { - statements.push(maybe_statement.into_inner()); - } else { - diagnostics.append(&mut maybe_statement.into_diagnostics()) + if let Some(statement) = self.statement() { + statements.push(statement); } } - let (_, mut ds) = self.expect_advance(TokenKind::End); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::End); - if let Some(ctor_keyword) = ctor_keyword { + if let Some(ctor_keyword) = maybe_ctor_kw { let constructor = Constructor::new( self.next_node_id(), is_public, @@ -1009,92 +727,66 @@ impl<'a> Parser<'a> { parameters, statements, ); - MaybeParseResult::some(constructor, diagnostics) + Some(constructor) } else { - MaybeParseResult::none(diagnostics) + None } } - fn field(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn field(&mut self) -> Option { let is_public = if self.current.is_some() && self.peek_current(TokenKind::Public) { - diagnostics.append(&mut self.advance()); + self.advance(); true } else { false }; let is_mut = if self.current.is_some() && self.peek_current(TokenKind::Mut) { - diagnostics.append(&mut self.advance()); + self.advance(); true } else { false }; - let (identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); - let declared_type = if self.current.is_some() && self.peek_current(TokenKind::Colon) { - diagnostics.append(&mut self.advance()); // colon - let (type_use, mut ds) = self.type_use(); - diagnostics.append(&mut ds); - type_use + let maybe_declared_type = if self.current.is_some() && self.peek_current(TokenKind::Colon) { + self.advance(); // colon + self.type_use() } else { None }; - let initializer = if self.current.is_some() && self.peek_current(TokenKind::Equals) { - diagnostics.append(&mut self.advance()); // equals - let maybe_expression = self.expression(); - Some(maybe_expression) + let maybe_initializer = if self.current.is_some() && self.peek_current(TokenKind::Equals) { + self.advance(); // equals + self.expression() } else { None }; - if let Some(identifier) = identifier { - if let Some(maybe_initializer) = initializer { - maybe_initializer - .map(|expression| { - Field::new( - self.next_node_id(), - self.token_text(&identifier), - SourceRange::new(identifier.start(), identifier.end()), - is_public, - is_mut, - declared_type, - Some(expression), - ) - }) - .with_diagnostics(diagnostics) - } else { - MaybeParseResult::some( - Field::new( - self.next_node_id(), - self.token_text(&identifier), - SourceRange::new(identifier.start(), identifier.end()), - is_public, - is_mut, - declared_type, - None, - ), - diagnostics, - ) - } + if let Some(identifier) = maybe_identifier { + Some(Field::new( + self.next_node_id(), + self.token_text(&identifier), + SourceRange::new(identifier.start(), identifier.end()), + is_public, + is_mut, + maybe_declared_type, + maybe_initializer, + )) } else { - MaybeParseResult::none(diagnostics) + None } } - fn statement(&mut self) -> MaybeParseResult { + fn statement(&mut self) -> Option { let current = match self.current.as_ref() { None => { - let mut ds = Diagnostics::new(); - ds.push(Self::get_expected_but_found_eoi( + self.diagnostics.push(get_expected_but_found_eoi( &STATEMENT_FIRSTS, self.input.len(), )); - return MaybeParseResult::none(ds); + return None; } Some(current) => current, }; @@ -1106,31 +798,25 @@ impl<'a> Parser<'a> { } } - fn let_statement(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - - let (_, mut ds) = self.expect_advance(TokenKind::Let); - diagnostics.append(&mut ds); + fn let_statement(&mut self) -> Option { + self.expect_advance(TokenKind::Let); let is_mut = if self.current.is_some() && self.peek_current(TokenKind::Mut) { - diagnostics.append(&mut self.advance()); + self.advance(); true } else { false }; - let (maybe_identifier, mut ds) = self.expect_advance(TokenKind::Identifier); - diagnostics.append(&mut ds); + let maybe_identifier = self.expect_advance(TokenKind::Identifier); - let (_, mut ds) = self.expect_advance(TokenKind::Equals); - diagnostics.append(&mut ds); + self.expect_advance(TokenKind::Equals); - let mut maybe_expression = self.expression(); + let maybe_expression = self.expression(); let identifier = match maybe_identifier { None => { - diagnostics.append(&mut maybe_expression.take_diagnostics()); - return MaybeParseResult::none(diagnostics); + return None; } Some(identifier) => identifier, }; @@ -1146,306 +832,166 @@ impl<'a> Parser<'a> { }) } - fn expression_statement_or_assign_statement(&mut self) -> MaybeParseResult { - let base = self.expression(); + fn expression_statement_or_assign_statement(&mut self) -> Option { + let expression = self.expression(); if self.current.is_some() && self.peek_current(TokenKind::Equals) { - base.flat_map(|expression| { + expression.and_then(|expression| { self.assign_rhs(expression) .map(|assign_statement| Statement::Assign(assign_statement)) }) } else { - base.map(|expression| Statement::Expression(ExpressionStatement::new(expression))) + expression.map(|expression| Statement::Expression(ExpressionStatement::new(expression))) } } - fn assign_rhs(&mut self, destination: Expression) -> MaybeParseResult { - let (_, mut ds) = self.expect_advance(TokenKind::Equals); - let mut expression = self.expression(); - expression.append_diagnostics(&mut ds); - expression.map(|expression| AssignStatement::new(destination, expression)) + fn assign_rhs(&mut self, destination: Expression) -> Option { + self.expect_advance(TokenKind::Equals); + let maybe_expression = self.expression(); + maybe_expression.map(|expression| AssignStatement::new(destination, expression)) } - fn expression(&mut self) -> MaybeParseResult { + fn expression(&mut self) -> Option { if self.current.is_some() { if matches_expression_first!(self.current.as_ref().unwrap().kind()) { self.bitwise_or_expression() } else { - let diagnostic = Self::get_expected_but_found( + self.diagnostics.push(get_expected_but_found( &EXPRESSION_FIRSTS, self.current.as_ref().unwrap(), - ); - MaybeParseResult::none(vec![diagnostic]) + )); + None } } else { - let diagnostic = Self::get_expected_but_found_eoi(&EXPRESSION_FIRSTS, 0); - MaybeParseResult::none(vec![diagnostic]) + self.diagnostics + .push(get_expected_but_found_eoi(&EXPRESSION_FIRSTS, 0)); + None } } - fn bitwise_or_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); + fn zip_binary_expression( + &mut self, + left: Option, + right: Option, + operation: BinaryOperation, + ) -> Option { + left.zip_with(right, |lhs, rhs| { + let source_range = + SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); + Expression::Binary(BinaryExpression::new( + self.next_node_id(), + lhs, + rhs, + operation, + source_range, + )) + }) + } + fn bitwise_or_expression(&mut self) -> Option { let mut base = self.bitwise_xor_expression(); - while self.current.is_some() && self.peek_current(TokenKind::Bar) { - diagnostics.append(&mut self.advance()); // | + self.advance(); // | let rhs = self.bitwise_xor_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::BitwiseOr, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::BitwiseOr); } - - base.append_diagnostics(&mut diagnostics); base } - fn bitwise_xor_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn bitwise_xor_expression(&mut self) -> Option { let mut base = self.bitwise_and_expression(); - while self.current.is_some() && self.peek_current(TokenKind::Caret) { - diagnostics.append(&mut self.advance()); // ^ + self.advance(); // ^ let rhs = self.bitwise_and_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::BitwiseXor, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::BitwiseXor); } - - base.append_diagnostics(&mut diagnostics); base } - fn bitwise_and_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn bitwise_and_expression(&mut self) -> Option { let mut base = self.shift_expression(); - while self.current.is_some() && self.peek_current(TokenKind::Ampersand) { - diagnostics.append(&mut self.advance()); // & + self.advance(); // & let rhs = self.shift_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::BitwiseAnd, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::BitwiseAnd); } - - base.append_diagnostics(&mut diagnostics); base } - fn shift_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn shift_expression(&mut self) -> Option { let mut base = self.additive_expression(); - if !base.is_ok() { - return base; - } - while self.current.is_some() { let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Lt => { let previous_cloned = current.clone(); - diagnostics.append(&mut self.advance()); // first < - let (_, mut ds) = - self.expect_immediately_after_advance(TokenKind::Lt, &previous_cloned); // second < - diagnostics.append(&mut ds); + self.advance(); // first < + self.expect_immediately_after_advance(TokenKind::Lt, &previous_cloned); // second < let rhs = self.additive_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::LeftShift, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::LeftShift); } TokenKind::Gt => { let previous_cloned = current.clone(); - diagnostics.append(&mut self.advance()); // first > - let (_, mut ds) = - self.expect_immediately_after_advance(TokenKind::Gt, &previous_cloned); // second > - diagnostics.append(&mut ds); + self.advance(); // first > + self.expect_immediately_after_advance(TokenKind::Gt, &previous_cloned); // second > let rhs = self.additive_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::RightShift, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::RightShift); } _ => break, } } - - base.append_diagnostics(&mut diagnostics); base } - fn additive_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn additive_expression(&mut self) -> Option { let mut base = self.multiplicative_expression(); - if !base.is_ok() { - return base; - } - while self.current.is_some() { let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Plus => { - diagnostics.append(&mut self.advance()); // plus + self.advance(); // plus let rhs = self.multiplicative_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::Add, - source_range, - )) - }) + base = self.zip_binary_expression(base, rhs, BinaryOperation::Add); } TokenKind::Minus => { - diagnostics.append(&mut self.advance()); // minus + self.advance(); // minus let rhs = self.multiplicative_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::Subtract, - source_range, - )) - }) + base = self.zip_binary_expression(base, rhs, BinaryOperation::Subtract); } _ => break, } } - - base.append_diagnostics(&mut diagnostics); base } - fn multiplicative_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn multiplicative_expression(&mut self) -> Option { let mut base = self.prefix_expression(); - if !base.is_ok() { - return base; - } - while self.current.is_some() { let current = self.current.as_ref().unwrap(); match current.kind() { TokenKind::Star => { - diagnostics.append(&mut self.advance()); // multiply + self.advance(); // multiply let rhs = self.prefix_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::Multiply, - source_range, - )) - }) + base = self.zip_binary_expression(base, rhs, BinaryOperation::Multiply); } TokenKind::Slash => { - diagnostics.append(&mut self.advance()); // slash + self.advance(); // slash let rhs = self.prefix_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::Divide, - source_range, - )) - }) + base = self.zip_binary_expression(base, rhs, BinaryOperation::Divide); } TokenKind::Modulo => { - diagnostics.append(&mut self.advance()); // modulo + self.advance(); // modulo let rhs = self.prefix_expression(); - - base = base.zip_map(rhs, |lhs, rhs| { - let source_range = - SourceRange::new(lhs.source_range().start(), rhs.source_range().end()); - - Expression::Binary(BinaryExpression::new( - self.next_node_id(), - lhs, - rhs, - BinaryOperation::Modulo, - source_range, - )) - }); + base = self.zip_binary_expression(base, rhs, BinaryOperation::Modulo); } _ => break, } } - - base.append_diagnostics(&mut diagnostics); base } - fn prefix_expression(&mut self) -> MaybeParseResult { - let mut diagnostics = Vec::new(); - + fn prefix_expression(&mut self) -> Option { // first, collect all consecutive operators let mut operator_tokens = vec![]; while self.current.is_some() { @@ -1453,7 +999,7 @@ impl<'a> Parser<'a> { match current.kind() { TokenKind::Minus => { operator_tokens.push(current.clone()); // unfortunately necessary - diagnostics.append(&mut self.advance()); + self.advance(); } _ => break, } @@ -1463,7 +1009,6 @@ impl<'a> Parser<'a> { // the parser is currently just after the prefix operators, so we need a suffix expression // as a base let mut base = self.suffix_expression(); - while let Some(operator_token) = operator_tokens.pop() { match operator_token.kind() { TokenKind::Minus => { @@ -1482,119 +1027,93 @@ impl<'a> Parser<'a> { _ => unreachable!(), } } - - base.append_diagnostics(&mut diagnostics); base } - fn suffix_expression(&mut self) -> MaybeParseResult { - let mut base = self.expression_base(); - if !base.is_ok() { - return base; - } - - while self.current.is_some() { - let current = self.current.as_ref().unwrap(); - match current.kind() { - TokenKind::LeftParentheses => { - let call = self.call(base.take_inner()); - base = call - .to_maybe_parse_result() - .map(|call| Expression::Call(call)) + fn suffix_expression(&mut self) -> Option { + if let Some(mut expression) = self.expression_base() { + while self.current.is_some() { + let current = self.current.as_ref().unwrap(); + match current.kind() { + TokenKind::LeftParentheses => { + expression = Expression::Call(self.call(expression)); + } + _ => break, } - _ => break, } + Some(expression) + } else { + None } - - base } - fn expression_base(&mut self) -> MaybeParseResult { + fn expression_base(&mut self) -> Option { let current = match self.current.as_ref() { + Some(current) => current, None => { - let mut result = MaybeParseResult::default(); - result.push_diagnostic(Self::get_expected_but_found_eoi( + self.diagnostics.push(get_expected_but_found_eoi( &EXPRESSION_FIRSTS, self.input.len(), )); - return result; + return None; } - Some(current) => current, }; - let mut diagnostics = Vec::new(); match current.kind() { TokenKind::IntegerLiteral => { let raw = self.token_text(¤t); let source_range = SourceRange::new(current.start(), current.end()); - diagnostics.append(&mut self.advance()); - MaybeParseResult::some( - Expression::Integer(IntegerLiteral::new( - self.next_node_id(), - i32::from_str(raw).unwrap(), - source_range, - )), - diagnostics, - ) + self.advance(); + Some(Expression::Integer(IntegerLiteral::new( + self.next_node_id(), + i32::from_str(raw).unwrap(), + source_range, + ))) } TokenKind::DoubleLiteral => { let raw = self.token_text(¤t); let source_range = SourceRange::new(current.start(), current.end()); - diagnostics.append(&mut self.advance()); - MaybeParseResult::some( - Expression::Double(DoubleLiteral::new( - self.next_node_id(), - f64::from_str(raw).unwrap(), - source_range, - )), - diagnostics, - ) + self.advance(); + Some(Expression::Double(DoubleLiteral::new( + self.next_node_id(), + f64::from_str(raw).unwrap(), + source_range, + ))) } TokenKind::String => { let with_quotes = self.token_text(¤t); let source_range = SourceRange::new(current.start(), current.end()); - diagnostics.append(&mut self.advance()); - MaybeParseResult::some( - Expression::String(StringLiteral::new( - self.next_node_id(), - &with_quotes[1..with_quotes.len() - 1], - source_range, - )), - diagnostics, - ) + self.advance(); + Some(Expression::String(StringLiteral::new( + self.next_node_id(), + &with_quotes[1..with_quotes.len() - 1], + source_range, + ))) } TokenKind::Identifier => { let declared_name = self.token_text(¤t); let source_range = SourceRange::new(current.start(), current.end()); - diagnostics.append(&mut self.advance()); - MaybeParseResult::some( - Expression::Identifier(Identifier::new( - self.next_node_id(), - declared_name, - source_range, - )), - diagnostics, - ) + self.advance(); + Some(Expression::Identifier(Identifier::new( + self.next_node_id(), + declared_name, + source_range, + ))) } _ => unreachable!("Unreachable token type found: {:?}", current.kind()), } } - fn call(&mut self, callee: Expression) -> ParseResult2 { - let mut diagnostics = Vec::new(); - let (_, mut ds) = self.expect_advance(TokenKind::LeftParentheses); - diagnostics.append(&mut ds); + fn call(&mut self, callee: Expression) -> Call { + self.expect_advance(TokenKind::LeftParentheses); let mut arguments = vec![]; if let Some(current) = &self.current { if matches_expression_first!(current.kind()) { - let (mut expressions, mut ds) = self.expression_list(); - arguments.append(&mut expressions); - diagnostics.append(&mut ds); + arguments = self.expression_list(); } } - let (maybe_right_parenthesis, mut ds) = self.expect_advance(TokenKind::RightParentheses); - diagnostics.append(&mut ds); + let maybe_right_parenthesis = self.expect_advance(TokenKind::RightParentheses); let source_range = if let Some(token) = maybe_right_parenthesis { SourceRange::new(callee.source_range().start(), token.end()) @@ -1603,34 +1122,21 @@ impl<'a> Parser<'a> { SourceRange::new(callee.source_range().start(), callee.source_range().end()) }; - ParseResult2::new( - Call::new(self.next_node_id(), callee, arguments, source_range), - diagnostics, - ) + Call::new(self.next_node_id(), callee, arguments, source_range) } - fn expression_list(&mut self) -> ParseResult> { + fn expression_list(&mut self) -> Vec { let mut expressions = vec![]; - let mut diagnostics = Vec::new(); - - let maybe_expression = self.expression(); - if maybe_expression.is_ok() { - expressions.push(maybe_expression.into_inner()); - } else { - diagnostics.append(&mut maybe_expression.into_diagnostics()); + if let Some(expression) = self.expression() { + expressions.push(expression); } - while self.current.is_some() && self.peek_current(TokenKind::Comma) { - diagnostics.append(&mut self.advance()); // comma - let maybe_expression = self.expression(); - if maybe_expression.is_ok() { - expressions.push(maybe_expression.into_inner()); - } else { - diagnostics.append(&mut maybe_expression.into_diagnostics()); + self.advance(); + if let Some(expression) = self.expression() { + expressions.push(expression); } } - - (expressions, diagnostics) + expressions } } @@ -1639,9 +1145,9 @@ mod smoke_tests { use super::*; fn smoke_test(input: &str) { - let (_, diagnostics) = parse_compilation_unit(input, None); - if !diagnostics.is_empty() { - eprintln!("{:#?}", diagnostics); + let parse_result = parse_compilation_unit(input, None); + if !parse_result.is_ok() { + eprintln!("{:#?}", parse_result.1); panic!("There were diagnostics during parsing"); } } @@ -1858,19 +1364,19 @@ mod concrete_tests { } fn assert_compilation_unit(input: &str) -> CompilationUnit { - let (compilation_unit, diagnostics) = parse_compilation_unit(input, None); - if !diagnostics.is_empty() { - report_diagnostics(&diagnostics); + let parse_result = parse_compilation_unit(input, None); + if !parse_result.is_ok() { + report_diagnostics(&parse_result.1); } - compilation_unit + parse_result.0 } fn assert_expression(input: &str) -> Expression { - let maybe_expression = parse_expression(input); - if maybe_expression.is_ok() { - maybe_expression.into_inner() + let parse_result = parse_expression(input); + if parse_result.is_ok() { + parse_result.0.unwrap() } else { - report_diagnostics(maybe_expression.diagnostics()); + report_diagnostics(&parse_result.1); } }