diff options
| -rw-r--r-- | src/error.rs | 110 | ||||
| -rw-r--r-- | src/interpret/operator.rs | 32 | ||||
| -rw-r--r-- | src/interpret/walker.rs | 108 | ||||
| -rw-r--r-- | src/main.rs | 11 | ||||
| -rw-r--r-- | src/parse/macros.rs | 4 | ||||
| -rw-r--r-- | src/parse/parser.rs | 85 |
6 files changed, 205 insertions, 145 deletions
diff --git a/src/error.rs b/src/error.rs index 227a4b0..ed92355 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,10 +1,14 @@ -use crate::{interpret::walker::WalkerError, lex::token::Location, parse::parser::ParserError}; +use crate::{ + interpret::walker::WalkerError, + lex::token::Location, + parse::parser::{ParserError, ParserErrorLocation}, +}; use colored::Colorize; use std::fmt::Display; -pub struct RHError { - pub at: ErrorLocation, - pub kind: RHErrorKind, +pub enum RHError { + Parse(ParserError), + Run(WalkerError), } impl RHError { @@ -16,16 +20,6 @@ impl RHError { } } -pub enum RHErrorKind { - Parse(ParserError), - Run(WalkerError), -} - -pub enum ErrorLocation { - Specific(Location), - Eof, -} - pub struct RHErrorWithSource<'source> { error: RHError, source: &'source str, @@ -33,45 +27,27 @@ pub struct RHErrorWithSource<'source> { impl Display for RHErrorWithSource<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let (error_title, error_string) = match &self.error.kind { - RHErrorKind::Parse(parser_error) => ( + let (error_title, error_string) = match &self.error { + RHError::Parse(parser_error) => ( "Encountered error during parsing", - format!("{}", parser_error), + format!("{}", parser_error.kind), ), - RHErrorKind::Run(walker_error) => { - ("Encountered runtime error", format!("{}", walker_error)) - } - }; - - let weird_source_error_msg = - "Found error but could not get it's location in source, how does this even happen?"; - - let (line_number, line_column, source_line) = match self.error.at { - ErrorLocation::Specific(location) => ( - location.row, - location.col, - self.source - .lines() - .nth(location.row) - .expect(weird_source_error_msg), + RHError::Run(walker_error) => ( + "Encountered runtime error", + format!("{}", walker_error.kind), ), - ErrorLocation::Eof => { - let lines = self.source.lines(); - let (line_count, _) = lines.size_hint(); - let last_line = lines.last().expect(weird_source_error_msg); - - (line_count, last_line.len(), last_line) - } }; - let arrow_pad_len = line_column + 3 + line_number.to_string().len(); + let at = MappedErrorLocation::new(self); + + let arrow_pad_len = at.line_column + 3 + at.line_number.to_string().len(); writeln!(f, "{} {}:\n", " Error ".on_red(), error_title)?; writeln!( f, "{}{}", - format!("{} | ", line_number).dimmed(), - source_line + format!("{} | ", at.line_number).dimmed(), + at.source_line )?; writeln!(f, "{}{}", " ".repeat(arrow_pad_len), "^".red())?; writeln!(f, "{}", error_string)?; @@ -79,3 +55,51 @@ impl Display for RHErrorWithSource<'_> { Ok(()) } } + +pub struct MappedErrorLocation<'s> { + line_number: usize, + line_column: usize, + source_line: &'s str, +} + +impl<'s> MappedErrorLocation<'s> { + const SOURCE_MISSING_ERROR_LOCATION: &'static str = + "Found error but could not get it's location in source, how does this even happen?"; + + fn new(from: &'s RHErrorWithSource<'s>) -> MappedErrorLocation<'s> { + match &from.error { + RHError::Parse(error) => match &error.at { + ParserErrorLocation::Specific(at) => Self::at_location(from, at), + ParserErrorLocation::Eof => Self::last_line(from), + }, + RHError::Run(error) => Self::at_location(from, &error.at), + } + } + + fn last_line(from: &'s RHErrorWithSource<'s>) -> MappedErrorLocation<'s> { + let lines = from.source.lines(); + let (line_count, _) = lines.size_hint(); + let last_line = lines.last().expect(Self::SOURCE_MISSING_ERROR_LOCATION); + + MappedErrorLocation { + line_number: line_count, + line_column: last_line.len(), + source_line: last_line, + } + } + + fn at_location( + from: &'s RHErrorWithSource<'s>, + location: &'s Location, + ) -> MappedErrorLocation<'s> { + MappedErrorLocation { + line_number: location.row, + line_column: location.col, + source_line: from + .source + .lines() + .nth(location.row) + .expect(Self::SOURCE_MISSING_ERROR_LOCATION), + } + } +} diff --git a/src/interpret/operator.rs b/src/interpret/operator.rs index 42c501e..057f942 100644 --- a/src/interpret/operator.rs +++ b/src/interpret/operator.rs @@ -1,14 +1,13 @@ use thiserror::Error; use crate::{ - error::{RHError, RHErrorKind}, parse::ast::expression::{Expression, ExpressionKind}, types::bag::TypeBag, }; use super::{ value::{Value, ValueKind}, - walker::{Walker, WalkerError}, + walker::{Walker, WalkerError, WalkerErrorKind}, }; pub struct ValueOperator<'types> { @@ -224,11 +223,11 @@ impl<'t> ValueOperator<'t> { } } - pub fn call(&self, val: &Value, arguments: Vec<Value>) -> Result<Value, WalkerError> { + pub fn call(&self, val: &Value, arguments: Vec<Value>) -> Result<Value, CallError> { let called = match &val.kind { ValueKind::Fn(i) => i, _ => { - return Err(WalkerError::OperationError(OperationError::CallableType( + return Err(CallError::BeforeCall(OperationError::CallableType( val.clone(), ))) } @@ -253,9 +252,10 @@ impl<'t> ValueOperator<'t> { let parameters = &called.node.header.parameters; if parameters.len() != arguments.len() { - return Err(WalkerError::OperationError( - OperationError::WrongArgumentCount(parameters.len(), arguments.len()), - )); + return Err(CallError::BeforeCall(OperationError::WrongArgumentCount( + parameters.len(), + arguments.len(), + ))); } for (argument, parameter) in arguments.into_iter().zip(parameters.iter()) { @@ -276,19 +276,21 @@ impl<'t> ValueOperator<'t> { let result = walker.walk_expression(&body_expression); match result { - Err(RHError { - kind: RHErrorKind::Run(err), - .. - }) => match err { - WalkerError::Return(returned_value) => Ok(returned_value), - _ => Err(err), - }, - Err(_) => panic!("Walker returned non-walker error."), Ok(result) => Ok(result), + Err(WalkerError { + kind: WalkerErrorKind::Return(returned_value), + .. + }) => Ok(returned_value), + Err(x) => Err(CallError::InsideFunction(x)), } } } +pub enum CallError { + BeforeCall(OperationError), + InsideFunction(WalkerError), +} + #[derive(Error, Debug)] pub enum OperationError { #[error("Can't add value '{0}' of type '{}' to value '{1}' of type '{}'.", .0.type_name(), .1.type_name())] diff --git a/src/interpret/walker.rs b/src/interpret/walker.rs index 52f68c8..7c86780 100644 --- a/src/interpret/walker.rs +++ b/src/interpret/walker.rs @@ -1,7 +1,6 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; use crate::{ - error::{ErrorLocation, RHError, RHErrorKind}, interpret::{ operator::ValueOperator, value::{FnValue, ValueKind}, @@ -21,7 +20,7 @@ use crate::{ use thiserror::Error; use super::{ - operator::OperationError, + operator::{CallError, OperationError}, scope::{ScopeChain, ScopeError}, value::Value, }; @@ -44,7 +43,7 @@ impl Walker { Walker { scope, types } } - pub fn walk(&mut self, program: &Program) -> Result<(), RHError> { + pub fn walk(&mut self, program: &Program) -> Result<(), WalkerError> { self.scope.nest(); for statement in program.statements.iter() { self.walk_statement(statement)?; @@ -52,7 +51,7 @@ impl Walker { Ok(()) } - fn walk_statement(&mut self, statement: &Statement) -> Result<Option<Value>, RHError> { + fn walk_statement(&mut self, statement: &Statement) -> Result<Option<Value>, WalkerError> { let result = match &statement.kind { StatementKind::Expression(node) => { self.walk_expression(node)?; @@ -66,9 +65,9 @@ impl Walker { // FIXME: Returns are always expected to have a return even though `return;` is valid. StatementKind::Return(node) => { // If there's a function running above us it will catch this error. - return Err(walker_error( + return Err(WalkerError::new( statement.at, - WalkerError::Return(self.walk_expression(node)?), + WalkerErrorKind::Return(self.walk_expression(node)?), )); } StatementKind::Break(node) => { @@ -78,18 +77,24 @@ impl Walker { None }; // If there's a loop above us it will catch this error. - return Err(walker_error(statement.at, WalkerError::LoopBreak(returned))); + return Err(WalkerError::new( + statement.at, + WalkerErrorKind::LoopBreak(returned), + )); } // Same here. StatementKind::Continue => { - return Err(walker_error(statement.at, WalkerError::LoopContinue)); + return Err(WalkerError::new( + statement.at, + WalkerErrorKind::LoopContinue, + )); } }; Ok(result) } - pub fn walk_expression(&mut self, node: &Expression) -> Result<Value, RHError> { + pub fn walk_expression(&mut self, node: &Expression) -> Result<Value, WalkerError> { match &node.kind { ExpressionKind::Binary { left, op, right } => { // Assignment @@ -104,7 +109,9 @@ impl Walker { let left_value = self.walk_expression(left)?; let is_left_true = match left_value.kind { ValueKind::Bool(bool) => bool, - _ => return Err(walker_error(left.at, WalkerError::WrongAndOrType)), + _ => { + return Err(WalkerError::new(left.at, WalkerErrorKind::WrongAndOrType)) + } }; if let BinOp::And = op.kind { @@ -138,7 +145,7 @@ impl Walker { BinOp::Lte => exe.gte(right, left), _ => unreachable!(), } - .map_err(|err| walker_error(op.at, WalkerError::OperationError(err))) + .map_err(|err| WalkerError::new(op.at, WalkerErrorKind::OperationError(err))) } ExpressionKind::Unary { op, right } => { let value = self.walk_expression(right)?; @@ -149,7 +156,7 @@ impl Walker { UnOp::Minus => exe.neg(value), UnOp::Not => exe.not(value), } - .map_err(|err| walker_error(op.at, WalkerError::OperationError(err))) + .map_err(|err| WalkerError::new(op.at, WalkerErrorKind::OperationError(err))) } ExpressionKind::Call(node) => { let called = self.walk_expression(&node.called)?; @@ -160,8 +167,15 @@ impl Walker { } let exe = ValueOperator::new(&self.types); - exe.call(&called, argument_values) - .map_err(|err| walker_error(node.at, err)) + + match exe.call(&called, argument_values) { + Ok(value) => Ok(value), + Err(CallError::BeforeCall(op_err)) => Err(WalkerError::new( + node.at, + WalkerErrorKind::OperationError(op_err), + )), + Err(CallError::InsideFunction(err)) => Err(err), + } } ExpressionKind::ArrayAccess(node) => { let array = self.walk_expression(&node.array)?; @@ -169,7 +183,7 @@ impl Walker { let exe = ValueOperator::new(&self.types); exe.subscript(array, index) - .map_err(|err| walker_error(node.at, WalkerError::OperationError(err))) + .map_err(|err| WalkerError::new(node.at, WalkerErrorKind::OperationError(err))) } ExpressionKind::MemberAccess(_) => todo!("Structures not implemented yet."), ExpressionKind::Group(node) => self.walk_expression(node), @@ -228,9 +242,9 @@ impl Walker { return self.walk_block(&conditional.block); } } else { - return Err(walker_error( + return Err(WalkerError::new( conditional.at, - WalkerError::WrongIfConditionType, + WalkerErrorKind::WrongIfConditionType, )); } } @@ -250,27 +264,26 @@ impl Walker { return Ok(Value::void(&self.types)); } } else { - return Err(walker_error( + return Err(WalkerError::new( condition.at, - WalkerError::WrongLoopConditionType, + WalkerErrorKind::WrongLoopConditionType, )); } } match self.walk_block(&loop_node.body) { - Err(RHError { - kind: RHErrorKind::Run(err), - at: ErrorLocation::Specific(at), - }) => match err { - WalkerError::LoopBreak(loop_value) => { - return Ok(loop_value.unwrap_or(Value::void(&self.types))); - } - // Do nothing for continue and continue looping of course, you dummy. - WalkerError::LoopContinue => {} - // This is probably an actual error. - _ => return Err(walker_error(at, err)), - }, - Err(_) => panic!("Walker returned non-walker error."), + Err(WalkerError { + kind: WalkerErrorKind::LoopBreak(loop_value), + .. + }) => return Ok(loop_value.unwrap_or(Value::void(&self.types))), + // Do nothing for continue and continue looping of course, you dummy. + Err(WalkerError { + kind: WalkerErrorKind::LoopContinue, + .. + }) => {} + // This is probably an actual error. + Err(x) => return Err(x), + // Do nothing with values returned from loops for now. _ => {} } } @@ -278,11 +291,11 @@ impl Walker { ExpressionKind::Identifier(ident) => self .scope .get_var(ident, &self.types) - .map_err(|err| walker_error(node.at, WalkerError::ScopeError(err))), + .map_err(|err| WalkerError::new(node.at, WalkerErrorKind::ScopeError(err))), } } - fn walk_block(&mut self, block: &BlockExpression) -> Result<Value, RHError> { + fn walk_block(&mut self, block: &BlockExpression) -> Result<Value, WalkerError> { self.scope.nest(); for statement in block.statements.iter() { @@ -305,7 +318,7 @@ impl Walker { lvalue: &Expression, rvalue: &Expression, is_constant: bool, - ) -> Result<Value, RHError> { + ) -> Result<Value, WalkerError> { // Maybe other expressions could also be l-values, but these are fine for now. match &lvalue.kind { ExpressionKind::MemberAccess(_) => todo!("Structures not implemented yet."), @@ -317,30 +330,37 @@ impl Walker { let exe = ValueOperator::new(&self.types); exe.subscript_assign(&mut array, index, value) - .map_err(|err| walker_error(node.at, WalkerError::OperationError(err))) + .map_err(|err| WalkerError::new(node.at, WalkerErrorKind::OperationError(err))) } ExpressionKind::Identifier(ident) => { let value = self.walk_expression(rvalue)?; self.scope .set_var(ident, value.clone(), is_constant) - .map_err(|err| walker_error(lvalue.at, WalkerError::ScopeError(err)))?; + .map_err(|err| WalkerError::new(lvalue.at, WalkerErrorKind::ScopeError(err)))?; return Ok(value); } - _ => Err(walker_error(lvalue.at, WalkerError::NonLValueAssignment)), + _ => Err(WalkerError::new( + lvalue.at, + WalkerErrorKind::NonLValueAssignment, + )), } } } -// This assumes walker errors are always at a specific error location. -fn walker_error(at: Location, walker_error: WalkerError) -> RHError { - RHError { - at: ErrorLocation::Specific(at), - kind: RHErrorKind::Run(walker_error), +#[derive(Debug)] +pub struct WalkerError { + pub kind: WalkerErrorKind, + pub at: Location, +} + +impl WalkerError { + fn new(at: Location, kind: WalkerErrorKind) -> Self { + WalkerError { at, kind } } } #[derive(Error, Debug)] -pub enum WalkerError { +pub enum WalkerErrorKind { #[error("Loop expressions can only take boolean values as conditions.")] WrongLoopConditionType, #[error("If and Elif expressions can only take boolean values as conditions.")] diff --git a/src/main.rs b/src/main.rs index a670f92..d3c460c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,10 +29,10 @@ fn file(filename: impl AsRef<Path>) { let lexer = Lexer::new(&contents); let mut parser = Parser::new(lexer); - let node = handle_error(parser.parse(), &contents); + let node = handle_error(parser.parse().map_err(RHError::Parse), &contents); let mut walker = Walker::root(); - handle_error(walker.walk(&node), &contents); + handle_error(walker.walk(&node).map_err(RHError::Run), &contents); } fn repl() { @@ -54,8 +54,11 @@ fn repl() { let lexer = Lexer::new(input_buffer.trim()); let mut parser = Parser::new(lexer); - let node = handle_error(parser.expression(), &input_buffer); - let result = handle_error(walker.walk_expression(&node), &input_buffer); + let node = handle_error(parser.expression().map_err(RHError::Parse), &input_buffer); + let result = handle_error( + walker.walk_expression(&node).map_err(RHError::Run), + &input_buffer, + ); println!("🥕: {:?}\n", result); } diff --git a/src/parse/macros.rs b/src/parse/macros.rs index 9cf995c..aad6144 100644 --- a/src/parse/macros.rs +++ b/src/parse/macros.rs @@ -16,13 +16,13 @@ macro_rules! consume { if let Token {kind: $( $kind )|+, ..} = token { Ok(token) } else { - Err(parser_error(ErrorLocation::Specific(token.location), ParserError::UnexpectedToken { + Err(ParserError::new(ParserErrorLocation::Specific(token.location), ParserErrorKind::UnexpectedToken { received: token.kind, expected: merge_token_names!($($kind),+), })) } } else { - Err(parser_error(ErrorLocation::Eof, ParserError::UnexpectedEof { + Err(ParserError::new(ParserErrorLocation::Eof, ParserErrorKind::UnexpectedEof { expected: merge_token_names!($($kind),+), })) } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 19f26b1..f19dcf1 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -7,8 +7,8 @@ use super::ast::nodes::{ }; use super::ast::statement::{Statement, StatementKind}; use super::ast::Program; -use crate::error::{ErrorLocation, RHError, RHErrorKind}; use crate::lex::lexer::Lexer; +use crate::lex::token::Location; use crate::lex::token::TokenKind::{self, *}; use crate::parse::ast::nodes::{ ArrayAccessExpression, BlockExpression, CallExpression, ConditionalBlockNode, FnExpression, @@ -28,7 +28,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { } } - pub fn parse(&mut self) -> Result<Program, RHError> { + pub fn parse(&mut self) -> Result<Program, ParserError> { let mut statements = Vec::new(); while !check!(self, Eof) { @@ -38,7 +38,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(Program { statements }) } - fn statement(&mut self) -> Result<Statement, RHError> { + fn statement(&mut self) -> Result<Statement, ParserError> { let token = self.tokens.peek().expect("Expected token."); match token.kind { KeywordPrint => self.print_statement(), @@ -49,7 +49,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { } } - fn return_statement(&mut self) -> Result<Statement, RHError> { + fn return_statement(&mut self) -> Result<Statement, ParserError> { let return_token = consume!(self, KeywordReturn)?; let expression = self.expression()?; consume!(self, SemiColon)?; @@ -59,7 +59,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn break_statement(&mut self) -> Result<Statement, RHError> { + fn break_statement(&mut self) -> Result<Statement, ParserError> { let break_token = consume!(self, KeywordBreak)?; let returned_on_break = if consume_if!(self, SemiColon).is_none() { let expression = self.expression()?; @@ -74,7 +74,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn continue_statement(&mut self) -> Result<Statement, RHError> { + fn continue_statement(&mut self) -> Result<Statement, ParserError> { let continue_token = consume!(self, KeywordContinue)?; consume!(self, SemiColon)?; Ok(Statement { @@ -83,7 +83,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn print_statement(&mut self) -> Result<Statement, RHError> { + fn print_statement(&mut self) -> Result<Statement, ParserError> { let print_token = consume!(self, KeywordPrint)?; let expression = self.expression()?; consume!(self, SemiColon)?; @@ -93,7 +93,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn expression_statement(&mut self) -> Result<Statement, RHError> { + fn expression_statement(&mut self) -> Result<Statement, ParserError> { let expression = self.expression()?; consume!(self, SemiColon)?; Ok(Statement { @@ -102,11 +102,11 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - pub fn expression(&mut self) -> Result<Expression, RHError> { + pub fn expression(&mut self) -> Result<Expression, ParserError> { self.assignment_expression() } - fn assignment_expression(&mut self) -> Result<Expression, RHError> { + fn assignment_expression(&mut self) -> Result<Expression, ParserError> { // Parse any expressions as l-values for now. let left = self.or_expression()?; @@ -126,7 +126,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { } } - fn or_expression(&mut self) -> Result<Expression, RHError> { + fn or_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.and_expression()?; while let Some(op) = consume_if!(self, OpAnd) { @@ -145,7 +145,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn and_expression(&mut self) -> Result<Expression, RHError> { + fn and_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.equality_expression()?; while let Some(op) = consume_if!(self, OpOr) { @@ -164,7 +164,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn equality_expression(&mut self) -> Result<Expression, RHError> { + fn equality_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.comparison_expression()?; while let Some(op) = consume_if!(self, OpEq | OpNeq) { @@ -183,7 +183,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn comparison_expression(&mut self) -> Result<Expression, RHError> { + fn comparison_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.term_expression()?; while let Some(op) = consume_if!(self, OpGt | OpGte | OpLt | OpLte) { @@ -202,7 +202,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn term_expression(&mut self) -> Result<Expression, RHError> { + fn term_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.factor_expression()?; while let Some(op) = consume_if!(self, OpPlus | OpMinus) { @@ -221,7 +221,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn factor_expression(&mut self) -> Result<Expression, RHError> { + fn factor_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.unary_expression()?; while let Some(op) = consume_if!(self, OpSlash | OpStar) { @@ -240,7 +240,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn unary_expression(&mut self) -> Result<Expression, RHError> { + fn unary_expression(&mut self) -> Result<Expression, ParserError> { let expression = if check!(self, OpPlus | OpMinus | OpNot) { let op_token = self.tokens.next().unwrap(); @@ -258,7 +258,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(expression) } - fn postfix_expression(&mut self) -> Result<Expression, RHError> { + fn postfix_expression(&mut self) -> Result<Expression, ParserError> { let mut left = self.unit_expression()?; while let Some(token) = consume_if!(self, GroupOpen | ArrayOpen | Dot) { @@ -312,7 +312,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(left) } - fn unit_expression(&mut self) -> Result<Expression, RHError> { + fn unit_expression(&mut self) -> Result<Expression, ParserError> { if let Some(token) = self.tokens.peek() { let location = token.location; @@ -334,9 +334,9 @@ impl<T: Iterator<Item = Token>> Parser<T> { KeywordFn => Ok(ExpressionKind::FnLiteral(Box::new(self.function()?))), KeywordIf => Ok(ExpressionKind::If(Box::new(self.conditional()?))), KeywordLoop => Ok(ExpressionKind::Loop(Box::new(self.repeating()?))), - _ => Err(parser_error( - ErrorLocation::Specific(token.location), - ParserError::UnexpectedToken { + _ => Err(ParserError::new( + ParserErrorLocation::Specific(token.location), + ParserErrorKind::UnexpectedToken { received: token.kind.clone(), expected: merge_token_names!( Int(_), @@ -359,9 +359,9 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(Expression { at: location, kind }) } else { - Err(parser_error( - ErrorLocation::Eof, - ParserError::UnexpectedEof { + Err(ParserError::new( + ParserErrorLocation::Eof, + ParserErrorKind::UnexpectedEof { // Well sure this works. expected: "expression".into(), }, @@ -369,14 +369,14 @@ impl<T: Iterator<Item = Token>> Parser<T> { } } - fn group(&mut self) -> Result<Expression, RHError> { + fn group(&mut self) -> Result<Expression, ParserError> { consume!(self, GroupOpen)?; let expression = self.expression()?; consume!(self, GroupClose)?; Ok(expression) } - fn array(&mut self) -> Result<ArrayExpression, RHError> { + fn array(&mut self) -> Result<ArrayExpression, ParserError> { let array_token = consume!(self, ArrayOpen)?; let mut elements = Vec::new(); @@ -395,7 +395,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn str(&mut self) -> Result<StrExpression, RHError> { + fn str(&mut self) -> Result<StrExpression, ParserError> { let mut parts = Vec::new(); let str_token = consume!(self, StrOpen)?; @@ -429,7 +429,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn function(&mut self) -> Result<FnExpression, RHError> { + fn function(&mut self) -> Result<FnExpression, ParserError> { let fn_token = consume!(self, KeywordFn)?; let header = { @@ -485,7 +485,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn conditional(&mut self) -> Result<IfExpression, RHError> { + fn conditional(&mut self) -> Result<IfExpression, ParserError> { let if_token = consume!(self, KeywordIf)?; let mut conditionals = Vec::new(); @@ -524,7 +524,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn repeating(&mut self) -> Result<LoopExpression, RHError> { + fn repeating(&mut self) -> Result<LoopExpression, ParserError> { let loop_token = consume!(self, KeywordLoop)?; let condition = if consume_if!(self, KeywordIf).is_some() { @@ -542,7 +542,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { }) } - fn generic_block(&mut self) -> Result<BlockExpression, RHError> { + fn generic_block(&mut self) -> Result<BlockExpression, ParserError> { let block_token = consume!(self, BlockOpen)?; let mut statements = Vec::new(); @@ -582,15 +582,26 @@ impl<T: Iterator<Item = Token>> Parser<T> { } } -fn parser_error(at: ErrorLocation, parse_error: ParserError) -> RHError { - RHError { - at, - kind: RHErrorKind::Parse(parse_error), +#[derive(Debug)] +pub enum ParserErrorLocation { + Specific(Location), + Eof, +} + +#[derive(Debug)] +pub struct ParserError { + pub kind: ParserErrorKind, + pub at: ParserErrorLocation, +} + +impl ParserError { + fn new(at: ParserErrorLocation, kind: ParserErrorKind) -> Self { + Self { at, kind } } } #[derive(Error, Debug)] -pub enum ParserError { +pub enum ParserErrorKind { #[error("Received unexpected '{received}', expected: {expected}.'")] UnexpectedToken { received: TokenKind, |
