diff --git a/src/syntax/binding.rs b/src/syntax/binding.rs index e9cd56a..f0e7b5e 100644 --- a/src/syntax/binding.rs +++ b/src/syntax/binding.rs @@ -1,10 +1,10 @@ use super::ast::var_binding::Binding; use super::utils::{parse_token_type, try_operator}; -use super::{expression, ParseResult, ParsingError}; +use super::{expression, ParsingError, ParsingResult}; use crate::error_handling::SyntaxError; use crate::lexic::token::{Token, TokenType}; -pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { +pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { let mut current_pos = pos; // TODO: Detect if the binding starts with a datatype @@ -23,7 +23,7 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult _ => (false, let_token, next_let), } } - _ => return ParseResult::Unmatched, + _ => return Err(ParsingError::Unmatched), } }; current_pos = next_pos; @@ -36,25 +36,25 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult Ok((t, n)) => (t, n), Err(ParsingError::Mismatch(token)) => { // The parser found a token, but it's not an identifier - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { error_start: token.position, error_end: token.get_end_position(), reason: "??".into(), - }); + })); } Err(ParsingError::Err(error)) => { - return ParseResult::Err(error); + return Err(ParsingError::Err(error)); } _ => { // The parser didn't find an Identifier after VAL/VAR - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: format!( "There should be an identifier after a `{}` token", if is_mutable { "val" } else { "var" } ), error_start: binding_token.position, error_end: binding_token.get_end_position(), - }); + })); } }; current_pos = next_pos; @@ -66,31 +66,31 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult Ok((t, _)) => t, Err(ParsingError::Mismatch(t)) => { // The parser found a token, but it's not the `=` operator - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: format!("There should be an equal sign `=` after the identifier"), error_start: t.position, error_end: t.get_end_position(), - }); + })); } _ => { // The parser didn't find the `=` operator after the identifier - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: format!("There should be an equal sign `=` after the identifier",), error_start: identifier.position, error_end: identifier.get_end_position(), - }); + })); } }; current_pos += 1; let (expression, next_pos) = match expression::try_parse(tokens, current_pos) { - ParseResult::Ok(exp, next) => (exp, next), + Ok((exp, next)) => (exp, next), _ => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected an expression after the equal `=` operator"), error_start: equal_operator.position, error_end: equal_operator.get_end_position(), - }); + })); } }; current_pos = next_pos; @@ -102,7 +102,7 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult is_mutable, }; - ParseResult::Ok(binding, current_pos) + Ok((binding, current_pos)) } #[cfg(test)] @@ -113,7 +113,7 @@ mod tests { #[test] fn should_parse_val_binding() { let tokens = get_tokens(&String::from("let identifier = 20")).unwrap(); - let ParseResult::Ok(binding, _) = try_parse(&tokens, 0) else { + let Ok((binding, _)) = try_parse(&tokens, 0) else { panic!() }; @@ -174,7 +174,7 @@ mod tests { let binding = try_parse(&tokens, 0); match binding { - ParseResult::Err(error) => { + Err(ParsingError::Err(error)) => { assert_eq!(0, error.error_start); assert_eq!(3, error.error_end); } @@ -190,7 +190,7 @@ mod tests { let binding = try_parse(&tokens, 0); match binding { - ParseResult::Err(error) => { + Err(ParsingError::Err(error)) => { assert_eq!(4, error.error_start); assert_eq!(7, error.error_end); } @@ -201,7 +201,7 @@ mod tests { let binding = try_parse(&tokens, 0); match binding { - ParseResult::Err(error) => { + Err(ParsingError::Err(error)) => { assert_eq!(4, error.error_start); assert_eq!(11, error.error_end); } @@ -215,7 +215,7 @@ mod tests { let binding = try_parse(&tokens, 0); match binding { - ParseResult::Err(error) => { + Err(ParsingError::Err(error)) => { assert_eq!(7, error.error_start); assert_eq!(14, error.error_end); } diff --git a/src/syntax/block.rs b/src/syntax/block.rs index ff4dbe0..7691378 100644 --- a/src/syntax/block.rs +++ b/src/syntax/block.rs @@ -3,19 +3,13 @@ use crate::{ lexic::token::{Token, TokenType}, }; -use super::{ast::Block, utils::parse_token_type, ParseResult, ParsingError}; +use super::{ast::Block, utils::parse_token_type, ParsingError, ParsingResult}; // Assumes that the token at `pos` is a { -pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { +pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { let mut current_pos = pos; - let (opening_brace, next_pos) = - match parse_token_type(tokens, current_pos, TokenType::LeftBrace) { - Ok((t, next)) => (t, next), - Err(ParsingError::Err(err)) => return ParseResult::Err(err), - Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t), - Err(ParsingError::Unmatched) => return ParseResult::Unmatched, - }; + let (opening_brace, next_pos) = parse_token_type(tokens, current_pos, TokenType::LeftBrace)?; current_pos = next_pos; // Parse block statements @@ -23,13 +17,12 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult // First statement match super::statement::try_parse(tokens, current_pos) { - ParseResult::Ok(statement, next_pos) => { + Ok((statement, next_pos)) => { current_pos = next_pos; statements.push(statement); } - ParseResult::Err(err) => return ParseResult::Err(err), - ParseResult::Unmatched => {} - ParseResult::Mismatch(_) => {} + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), + _ => {} } // More statements separated by new lines @@ -40,11 +33,11 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult current_pos += 1; match super::statement::try_parse(tokens, current_pos) { - ParseResult::Ok(statement, next_pos) => { + Ok((statement, next_pos)) => { current_pos = next_pos; statements.push(statement); } - ParseResult::Err(err) => return ParseResult::Err(err), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), _ => break, } } @@ -53,25 +46,25 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult let (_closing_brace, next_pos) = match parse_token_type(tokens, current_pos, TokenType::RightBrace) { Ok((t, next)) => (t, next), - Err(ParsingError::Err(err)) => return ParseResult::Err(err), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), Err(ParsingError::Mismatch(t)) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a closing brace after the block body."), error_start: t.position, error_end: t.get_end_position(), - }); + })); } Err(ParsingError::Unmatched) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a closing brace after the block body."), error_start: opening_brace.position, error_end: opening_brace.get_end_position(), - }); + })); } }; current_pos = next_pos; - ParseResult::Ok(Block { statements }, current_pos) + Ok((Block { statements }, current_pos)) } #[cfg(test)] @@ -85,7 +78,7 @@ mod tests { let block = parse_block(&tokens, 0); let block = match block { - ParseResult::Ok(p, _) => p, + ParsingResult::Ok((p, _)) => p, _ => panic!("Expected a block, got: {:?}", block), }; @@ -98,7 +91,7 @@ mod tests { let block = parse_block(&tokens, 0); let block = match block { - ParseResult::Ok(p, _) => p, + ParsingResult::Ok((p, _)) => p, _ => panic!("Expected a block, got: {:?}", block), }; @@ -111,7 +104,7 @@ mod tests { let block = parse_block(&tokens, 0); let block = match block { - ParseResult::Ok(p, _) => p, + ParsingResult::Ok((p, _)) => p, _ => { panic!("Expected a block, got: {:?}\n\n{:?}", block, tokens) } diff --git a/src/syntax/expression/comparison.rs b/src/syntax/expression/comparison.rs index 91cf25e..d456ceb 100644 --- a/src/syntax/expression/comparison.rs +++ b/src/syntax/expression/comparison.rs @@ -1,6 +1,6 @@ use crate::{ lexic::token::Token, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; /// Parses a factor expression. @@ -8,10 +8,10 @@ use crate::{ /// ```ebnf /// comparison = term, ((">" | ">=" | "<" | "<="), term)*; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { let (term, next_pos) = match super::term::try_parse(tokens, pos) { - ParseResult::Ok(expr, next_pos) => (expr, next_pos), - _ => return ParseResult::Unmatched, + Ok((expr, next_pos)) => (expr, next_pos), + _ => return Err(ParsingError::Unmatched), }; parse_many(tokens, next_pos, term) @@ -21,7 +21,7 @@ fn parse_many<'a>( tokens: &'a Vec, pos: usize, prev_expr: Expression<'a>, -) -> ParseResult<'a, Expression<'a>> { +) -> ParsingResult<'a, Expression<'a>> { // comparison = term, ((">" | ">=" | "<" | "<="), term)*; match tokens.get(pos) { @@ -32,7 +32,7 @@ fn parse_many<'a>( || token.value == ">=" => { match super::term::try_parse(tokens, pos + 1) { - ParseResult::Ok(expr, next_pos) => { + Ok((expr, next_pos)) => { let expr = Expression::BinaryOperator( Box::new(prev_expr), Box::new(expr), @@ -41,9 +41,9 @@ fn parse_many<'a>( parse_many(tokens, next_pos, expr) } - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), } } - _ => ParseResult::Ok(prev_expr, pos), + _ => Ok((prev_expr, pos)), } } diff --git a/src/syntax/expression/equality.rs b/src/syntax/expression/equality.rs index c88cb12..3d4a838 100644 --- a/src/syntax/expression/equality.rs +++ b/src/syntax/expression/equality.rs @@ -1,6 +1,6 @@ use crate::{ lexic::token::Token, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; /// Parses a factor expression. @@ -8,10 +8,10 @@ use crate::{ /// ```ebnf /// equality = comparison, (("==" | "!="), comparison )*; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { let (comparison, next_pos) = match super::comparison::try_parse(tokens, pos) { - ParseResult::Ok(expr, next_pos) => (expr, next_pos), - _ => return ParseResult::Unmatched, + Ok((expr, next_pos)) => (expr, next_pos), + _ => return Err(ParsingError::Unmatched), }; parse_many(tokens, next_pos, comparison) @@ -21,13 +21,13 @@ fn parse_many<'a>( tokens: &'a Vec, pos: usize, prev_expr: Expression<'a>, -) -> ParseResult<'a, Expression<'a>> { +) -> ParsingResult<'a, Expression<'a>> { // equality = comparison, (("==" | "!="), comparison )*; match tokens.get(pos) { Some(token) if token.value == "==" || token.value == "!=" => { match super::comparison::try_parse(tokens, pos + 1) { - ParseResult::Ok(expr, next_pos) => { + Ok((expr, next_pos)) => { let expr = Expression::BinaryOperator( Box::new(prev_expr), Box::new(expr), @@ -36,9 +36,9 @@ fn parse_many<'a>( parse_many(tokens, next_pos, expr) } - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), } } - _ => ParseResult::Ok(prev_expr, pos), + _ => Ok((prev_expr, pos)), } } diff --git a/src/syntax/expression/factor.rs b/src/syntax/expression/factor.rs index e82eb03..ace232f 100644 --- a/src/syntax/expression/factor.rs +++ b/src/syntax/expression/factor.rs @@ -1,6 +1,6 @@ use crate::{ lexic::token::Token, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; /// Parses a factor expression. @@ -8,10 +8,10 @@ use crate::{ /// ```ebnf /// factor = unary, (("/" | "*"), unary)*; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { let (unary, next_pos) = match super::unary::try_parse(tokens, pos) { - ParseResult::Ok(expr, next_pos) => (expr, next_pos), - _ => return ParseResult::Unmatched, + Ok((expr, next_pos)) => (expr, next_pos), + _ => return Err(ParsingError::Unmatched), }; parse_many(tokens, next_pos, unary) @@ -21,13 +21,13 @@ fn parse_many<'a>( tokens: &'a Vec, pos: usize, prev_expr: Expression<'a>, -) -> ParseResult<'a, Expression<'a>> { +) -> ParsingResult<'a, Expression<'a>> { // (("/" | "*"), unary)* match tokens.get(pos) { Some(token) if token.value == "/" || token.value == "*" => { match super::unary::try_parse(tokens, pos + 1) { - ParseResult::Ok(expr, next_pos) => { + Ok((expr, next_pos)) => { let expr = Expression::BinaryOperator( Box::new(prev_expr), Box::new(expr), @@ -36,9 +36,9 @@ fn parse_many<'a>( parse_many(tokens, next_pos, expr) } - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), } } - _ => ParseResult::Ok(prev_expr, pos), + _ => Ok((prev_expr, pos)), } } diff --git a/src/syntax/expression/function_call_expr.rs b/src/syntax/expression/function_call_expr.rs index 77e36f3..2480fff 100644 --- a/src/syntax/expression/function_call_expr.rs +++ b/src/syntax/expression/function_call_expr.rs @@ -3,7 +3,7 @@ use crate::{ syntax::{ ast::{functions::FunctionCall, Expression}, functions::arguments_list, - ParseResult, + ParsingError, ParsingResult, }, }; @@ -13,18 +13,18 @@ use crate::{ /// function call expr = primary, "(", (arguments list)?, ")" /// | primary; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { let (primary_expr, next_pos) = match super::primary::try_parse(tokens, pos) { - ParseResult::Ok(expr, next_pos) => (expr, next_pos), - _ => return ParseResult::Unmatched, + Ok((expr, next_pos)) => (expr, next_pos), + _ => return Err(ParsingError::Unmatched), }; // Parse arguments list let (arguments, next_pos) = match arguments_list::try_parse(tokens, next_pos) { - ParseResult::Ok(args, next) => (args, next), - ParseResult::Err(err) => return ParseResult::Err(err), + Ok((args, next)) => (args, next), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), _ => { - return ParseResult::Ok(primary_expr, next_pos); + return Ok((primary_expr, next_pos)); } }; @@ -33,7 +33,7 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { arguments: Box::new(arguments), }; - ParseResult::Ok(Expression::FunctionCall(fun_call), next_pos) + Ok((Expression::FunctionCall(fun_call), next_pos)) } #[cfg(test)] diff --git a/src/syntax/expression/mod.rs b/src/syntax/expression/mod.rs index db8684b..e93cd8b 100644 --- a/src/syntax/expression/mod.rs +++ b/src/syntax/expression/mod.rs @@ -1,4 +1,4 @@ -use super::{ast::Expression, ParseResult}; +use super::{ast::Expression, ParsingResult}; use crate::lexic::token::Token; mod comparison; @@ -10,8 +10,8 @@ mod term; mod unary; /// Expression is defined in the grammar. -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { - return equality::try_parse(tokens, pos); +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { + equality::try_parse(tokens, pos) } #[cfg(test)] diff --git a/src/syntax/expression/primary.rs b/src/syntax/expression/primary.rs index e235827..dda70ab 100644 --- a/src/syntax/expression/primary.rs +++ b/src/syntax/expression/primary.rs @@ -1,7 +1,7 @@ use super::super::utils::Tokenizer; use crate::{ lexic::token::{Token, TokenType}, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; /// This grammar may not be up to date. Refer to the spec for the latest grammar. @@ -9,35 +9,33 @@ use crate::{ /// ```ebnf /// primary = number | string | boolean | identifier | ("(", expression, ")"); /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { match tokens.get_significant(pos) { Some((token, token_pos)) => match token.token_type { - TokenType::Number => ParseResult::Ok(Expression::Number(&token.value), token_pos + 1), - TokenType::String => ParseResult::Ok(Expression::String(&token.value), token_pos + 1), + TokenType::Number => Ok((Expression::Number(&token.value), token_pos + 1)), + TokenType::String => Ok((Expression::String(&token.value), token_pos + 1)), TokenType::Identifier if token.value == "true" || token.value == "false" => { - ParseResult::Ok(Expression::Boolean(token.value == "true"), token_pos + 1) - } - TokenType::Identifier => { - ParseResult::Ok(Expression::Identifier(&token.value), token_pos + 1) + Ok((Expression::Boolean(token.value == "true"), token_pos + 1)) } + TokenType::Identifier => Ok((Expression::Identifier(&token.value), token_pos + 1)), TokenType::LeftParen => parse_parenthesized_expression(tokens, token_pos), - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), }, - None => ParseResult::Unmatched, + None => Err(ParsingError::Unmatched), } } -fn parse_parenthesized_expression(tokens: &Vec, pos: usize) -> ParseResult { +fn parse_parenthesized_expression(tokens: &Vec, pos: usize) -> ParsingResult { let expression = super::try_parse(tokens, pos + 1); match expression { - ParseResult::Ok(expression, next_pos) => match tokens.get(next_pos) { + Ok((expression, next_pos)) => match tokens.get(next_pos) { Some(token) => match token.token_type { - TokenType::RightParen => ParseResult::Ok(expression, next_pos + 1), - _ => ParseResult::Unmatched, + TokenType::RightParen => Ok((expression, next_pos + 1)), + _ => Err(ParsingError::Unmatched), }, - None => ParseResult::Unmatched, + None => Err(ParsingError::Unmatched), }, - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), } } @@ -52,7 +50,9 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::Number(value), _) => assert_eq!("40", format!("{}", value)), + Ok((Expression::Number(value), _)) => { + assert_eq!("40", format!("{}", value)) + } _ => panic!(), } } @@ -63,7 +63,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::String(value), _) => { + Ok((Expression::String(value), _)) => { assert_eq!("\"Hello\"", format!("{}", value)) } _ => panic!(), @@ -76,7 +76,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::Boolean(value), _) => assert!(value), + Ok((Expression::Boolean(value), _)) => assert!(value), _ => panic!(), } } @@ -87,7 +87,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::Identifier(value), _) => { + Ok((Expression::Identifier(value), _)) => { assert_eq!("someIdentifier", format!("{}", value)) } _ => panic!(), @@ -100,7 +100,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::Identifier(value), _) => { + Ok((Expression::Identifier(value), _)) => { assert_eq!("identifier", format!("{}", value)) } _ => panic!(), diff --git a/src/syntax/expression/term.rs b/src/syntax/expression/term.rs index 8b4ca55..f680a93 100644 --- a/src/syntax/expression/term.rs +++ b/src/syntax/expression/term.rs @@ -1,6 +1,6 @@ use crate::{ lexic::token::Token, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; /// Parses a factor expression. @@ -8,10 +8,10 @@ use crate::{ /// ```ebnf /// term = factor, (("-" | "+"), factor)*; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { let (factor, next_pos) = match super::factor::try_parse(tokens, pos) { - ParseResult::Ok(expr, next_pos) => (expr, next_pos), - _ => return ParseResult::Unmatched, + Ok((expr, next_pos)) => (expr, next_pos), + _ => return Err(ParsingError::Unmatched), }; parse_many(tokens, next_pos, factor) @@ -21,13 +21,13 @@ fn parse_many<'a>( tokens: &'a Vec, pos: usize, prev_expr: Expression<'a>, -) -> ParseResult<'a, Expression<'a>> { +) -> ParsingResult<'a, Expression<'a>> { // term = factor, (("-" | "+"), factor)*; match tokens.get(pos) { Some(token) if token.value == "+" || token.value == "-" => { match super::factor::try_parse(tokens, pos + 1) { - ParseResult::Ok(expr, next_pos) => { + Ok((expr, next_pos)) => { let expr = Expression::BinaryOperator( Box::new(prev_expr), Box::new(expr), @@ -36,9 +36,9 @@ fn parse_many<'a>( parse_many(tokens, next_pos, expr) } - _ => ParseResult::Unmatched, + _ => Err(ParsingError::Unmatched), } } - _ => ParseResult::Ok(prev_expr, pos), + _ => Ok((prev_expr, pos)), } } diff --git a/src/syntax/expression/unary.rs b/src/syntax/expression/unary.rs index 70ef553..b7ba49e 100644 --- a/src/syntax/expression/unary.rs +++ b/src/syntax/expression/unary.rs @@ -1,6 +1,6 @@ use crate::{ lexic::token::Token, - syntax::{ast::Expression, ParseResult}, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; use super::function_call_expr; @@ -11,15 +11,15 @@ use super::function_call_expr; /// unary = ("!" | "-"), expression /// | function call expr; /// ``` -pub fn try_parse(tokens: &Vec, pos: usize) -> ParseResult { +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { match tokens.get(pos) { Some(token) if token.value == "!" || token.value == "-" => { match super::try_parse(tokens, pos + 1) { - ParseResult::Ok(expression, next_pos) => ParseResult::Ok( + Ok((expression, next_pos)) => Ok(( Expression::UnaryOperator(&token.value, Box::new(expression)), next_pos, - ), - _ => ParseResult::Unmatched, + )), + _ => Err(ParsingError::Unmatched), } } _ => function_call_expr::try_parse(tokens, pos), @@ -37,7 +37,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::Identifier(value), _) => { + Ok((Expression::Identifier(value), _)) => { assert_eq!("identifier", format!("{}", value)) } _ => panic!(), @@ -50,7 +50,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::UnaryOperator(operator, expression), _) => { + Ok((Expression::UnaryOperator(operator, expression), _)) => { match (operator, *expression) { (op, Expression::Number(value)) => { assert_eq!(*op, "-"); @@ -69,7 +69,7 @@ mod tests { let expression = try_parse(&tokens, 0); match expression { - ParseResult::Ok(Expression::UnaryOperator(operator, expression), _) => { + Ok((Expression::UnaryOperator(operator, expression), _)) => { assert_eq!(*operator, "-"); match *expression { Expression::BinaryOperator(_, _, _) => { diff --git a/src/syntax/functions/arguments_list.rs b/src/syntax/functions/arguments_list.rs index 1592ed5..a873dd8 100644 --- a/src/syntax/functions/arguments_list.rs +++ b/src/syntax/functions/arguments_list.rs @@ -4,19 +4,19 @@ use crate::{ syntax::{ ast::{functions::ArgumentsList, Expression}, utils::parse_token_type, - ParseResult, ParsingError, + ParsingError, ParsingResult, }, }; -pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { +pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { let mut current_pos = pos; let (opening_paren, next_pos) = match parse_token_type(tokens, current_pos, TokenType::LeftParen) { Ok((t, next)) => (t, next), - Err(ParsingError::Err(err)) => return ParseResult::Err(err), - Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t), - Err(ParsingError::Unmatched) => return ParseResult::Unmatched, + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), + Err(ParsingError::Mismatch(t)) => return Err(ParsingError::Mismatch(t)), + Err(ParsingError::Unmatched) => return Err(ParsingError::Unmatched), }; current_pos = next_pos; @@ -24,10 +24,10 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult (expression, next_pos), - ParseResult::Err(error) => { + Ok((expression, next_pos)) => (expression, next_pos), + Err(ParsingError::Err(error)) => { // TODO: Write a more detailed error - return ParseResult::Err(error); + return Err(ParsingError::Err(error)); } _ => break, }; @@ -41,7 +41,7 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult return ParseResult::Err(err), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), Err(ParsingError::Mismatch(_)) => { // Something other than a comma was found. It must be a closing paren ) // Still, break the loop, assume there are no more arguments @@ -56,25 +56,25 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult (t, next), - Err(ParsingError::Err(err)) => return ParseResult::Err(err), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), Err(ParsingError::Mismatch(t)) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a closing paren after the function identifier."), error_start: t.position, error_end: t.get_end_position(), - }); + })); } Err(ParsingError::Unmatched) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a closing paren after the function identifier."), error_start: opening_paren.position, error_end: opening_paren.get_end_position(), - }); + })); } }; current_pos = next_pos; - ParseResult::Ok(ArgumentsList { arguments }, current_pos) + Ok((ArgumentsList { arguments }, current_pos)) } #[cfg(test)] @@ -87,7 +87,7 @@ mod tests { let tokens = get_tokens(&String::from("()")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(list, next) = fun_decl else { + let Ok((list, next)) = fun_decl else { panic!("Expected an unmatched result: {:?}", fun_decl); }; @@ -100,7 +100,7 @@ mod tests { let tokens = get_tokens(&String::from("( ) ")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(list, next) = fun_decl else { + let Ok((list, next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; @@ -113,7 +113,7 @@ mod tests { let tokens = get_tokens(&String::from("(\n \n)")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(list, next) = fun_decl else { + let Ok((list, next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; @@ -126,7 +126,7 @@ mod tests { let tokens = get_tokens(&String::from("(0)")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(arguments_list, next) = fun_decl else { + let Ok((arguments_list, next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; @@ -145,7 +145,7 @@ mod tests { let tokens = get_tokens(&String::from("(0, )")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(arguments_list, next) = fun_decl else { + let Ok((arguments_list, next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; @@ -163,7 +163,7 @@ mod tests { let tokens = get_tokens(&String::from("(\"Hello new world\", 322, )")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(arguments_list, _next) = fun_decl else { + let Ok((arguments_list, _next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; @@ -185,7 +185,7 @@ mod tests { let tokens = get_tokens(&String::from("(foo(), bar())")).unwrap(); let fun_decl = try_parse(&tokens, 0); - let ParseResult::Ok(arguments_list, _next) = fun_decl else { + let Ok((arguments_list, _next)) = fun_decl else { panic!("Expected a result, got: {:?}", fun_decl); }; diff --git a/src/syntax/functions/function_declaration.rs b/src/syntax/functions/function_declaration.rs index 45f4cf8..b96324c 100644 --- a/src/syntax/functions/function_declaration.rs +++ b/src/syntax/functions/function_declaration.rs @@ -5,7 +5,7 @@ use crate::{ }; use super::{ - super::{ast::FunctionDeclaration, block::parse_block, utils::parse_token_type, ParseResult}, + super::{ast::FunctionDeclaration, block::parse_block, utils::parse_token_type}, params_list::parse_params_list, }; @@ -61,18 +61,18 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult (block, next_pos), - ParseResult::Err(error) => { + Ok((block, next_pos)) => (block, next_pos), + Err(ParsingError::Err(error)) => { return Err(ParsingError::Err(error)); } - ParseResult::Mismatch(wrong_token) => { + Err(ParsingError::Mismatch(wrong_token)) => { return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a block after the function declaration."), error_start: wrong_token.position, error_end: wrong_token.get_end_position(), })); } - ParseResult::Unmatched => { + Err(ParsingError::Unmatched) => { return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected a block after the function declaration."), error_start: identifier.position, diff --git a/src/syntax/functions/params_list.rs b/src/syntax/functions/params_list.rs index 0bc0d53..b53c565 100644 --- a/src/syntax/functions/params_list.rs +++ b/src/syntax/functions/params_list.rs @@ -6,7 +6,7 @@ use crate::{ use super::super::{ ast::{Parameter, ParamsList}, - utils, ParseResult, + utils, }; pub fn parse_params_list<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { @@ -33,8 +33,8 @@ pub fn parse_params_list<'a>(tokens: &'a Vec, pos: usize) -> ParsingResul let mut parameters = Vec::::new(); loop { let (next_parameter, next_pos) = match parse_param_definition(tokens, current_pos) { - ParseResult::Ok(parameter, next_pos) => (parameter, next_pos), - ParseResult::Err(error) => { + Ok((parameter, next_pos)) => (parameter, next_pos), + Err(ParsingError::Err(error)) => { return Err(ParsingError::Err(error)); } _ => break, @@ -84,7 +84,7 @@ pub fn parse_params_list<'a>(tokens: &'a Vec, pos: usize) -> ParsingResul Ok((ParamsList {}, current_pos)) } -fn parse_param_definition<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { +fn parse_param_definition<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { // Parse a single parameter definition of the form: // - Type identifier // There will be more constructs in the future, like: @@ -97,12 +97,12 @@ fn parse_param_definition<'a>(tokens: &'a Vec, pos: usize) -> ParseResult match utils::parse_token_type(tokens, current_pos, TokenType::Datatype) { Ok((token, next)) => (token, next), Err(ParsingError::Err(err)) => { - return ParseResult::Err(err); + return Err(ParsingError::Err(err)); } // If there is no datatype this construction doesn't apply. // Return a mismatch and let the caller handle it - Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t), - Err(ParsingError::Unmatched) => return ParseResult::Unmatched, + Err(ParsingError::Mismatch(t)) => return Err(ParsingError::Mismatch(t)), + Err(ParsingError::Unmatched) => return Err(ParsingError::Unmatched), }; current_pos = next_pos; @@ -110,30 +110,30 @@ fn parse_param_definition<'a>(tokens: &'a Vec, pos: usize) -> ParseResult match utils::parse_token_type(tokens, current_pos, TokenType::Identifier) { Ok((token, next)) => (token, next), Err(ParsingError::Err(err)) => { - return ParseResult::Err(err); + return Err(ParsingError::Err(err)); } // However, if we fail to parse an identifier, it's an error Err(ParsingError::Mismatch(_)) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected an identifier for the parameter."), error_start: tokens[pos].position, error_end: tokens[pos].get_end_position(), - }); + })); } Err(ParsingError::Unmatched) => { - return ParseResult::Err(SyntaxError { + return Err(ParsingError::Err(SyntaxError { reason: String::from("Expected an identifier for the parameter."), error_start: tokens[pos].position, error_end: tokens[pos].get_end_position(), - }) + })) } }; - ParseResult::Ok( + Ok(( Parameter { identifier: &identifier.value, datatype: &datatype.value, }, next_pos, - ) + )) } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 2c1b966..44d3e77 100755 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -14,23 +14,6 @@ use ast::ModuleAST; use self::ast::TopLevelDeclaration; -#[derive(Debug)] -pub enum ParseResult<'a, A> { - /// The parsing was a success. The first element is the parsed construct, - /// the second element is the position of the next token to parse - Ok(A, usize), - /// The parsing failed past a point of no return. - /// - /// For example, when parsing a function declaration - /// the `fun` token is found, but then no identifier - Err(SyntaxError), - /// Some special value was expected, but something else was found. - /// The inside element is the something else found. - Mismatch(&'a Token), - /// This parsing didn't succeed, but it's not a fatal error. - Unmatched, -} - pub type ParsingResult<'a, A> = Result<(A, usize), ParsingError<'a>>; #[derive(Debug)] diff --git a/src/syntax/statement.rs b/src/syntax/statement.rs index ff449be..7d1a9da 100644 --- a/src/syntax/statement.rs +++ b/src/syntax/statement.rs @@ -4,26 +4,26 @@ use super::{ ast::{statement::Statement, Expression}, binding, expression::function_call_expr, - ParseResult, + ParsingError, ParsingResult, }; -pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { - None.or_else(|| match binding::try_parse(tokens, pos) { - ParseResult::Ok(b, next) => Some(ParseResult::Ok(Statement::Binding(b), next)), - ParseResult::Err(err) => Some(ParseResult::Err(err)), - _ => None, - }) - .or_else(|| match function_call_expr::try_parse(tokens, pos) { - ParseResult::Ok(f, next) => { - let Expression::FunctionCall(f) = f else { - return None; - }; - Some(ParseResult::Ok(Statement::FunctionCall(f), next)) - } - ParseResult::Err(err) => Some(ParseResult::Err(err)), - _ => None, - }) - .unwrap_or_else(|| ParseResult::Unmatched) +pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParsingResult { + // Try to parse a binding + match binding::try_parse(tokens, pos) { + Ok((b, next)) => return Ok((Statement::Binding(b), next)), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), + _ => {} + } + + // Try to parse a function call + match function_call_expr::try_parse(tokens, pos) { + Ok((Expression::FunctionCall(f), next)) => return Ok((Statement::FunctionCall(f), next)), + Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), + _ => {} + }; + + // Return unmatched + Err(ParsingError::Unmatched) } #[cfg(test)] @@ -37,7 +37,7 @@ mod tests { let statement = try_parse(&tokens, 0); let statement = match statement { - ParseResult::Ok(s, _) => s, + Ok((s, _)) => s, _ => panic!("Expected a statement"), }; @@ -54,7 +54,7 @@ mod tests { let statement = try_parse(&tokens, 0); let statement = match statement { - ParseResult::Ok(s, _) => s, + Ok((s, _)) => s, _ => panic!("Expected a statement"), }; diff --git a/src/syntax/utils.rs b/src/syntax/utils.rs index 6557b7f..b3f627d 100644 --- a/src/syntax/utils.rs +++ b/src/syntax/utils.rs @@ -54,7 +54,7 @@ pub fn parse_token_type( ) -> ParsingResult<&Token> { let mut current_pos = pos; - // Ignore all whitespace and newlines + // Ignore all whitespace, newlines and semicolons while let Some(t) = tokens.get(current_pos) { if t.token_type == TokenType::INDENT || t.token_type == TokenType::DEDENT