From 216c61228cf92f34146a65c6ce833fc92a202b4b Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Fri, 15 May 2026 12:09:30 +0200 Subject: [PATCH] Making a error recovery system --- mist-test/src/main.mist | 2 + parser/src/error.rs | 2 +- parser/src/lib.rs | 65 +++++++++++++++++++++++++++ parser/src/parser/common/statement.rs | 3 +- parser/src/parser/items/mod.rs | 3 +- 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 853e686..086ea97 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -12,4 +12,6 @@ void main() { app_instance.boot(); app_instance.run(); + + hi } \ No newline at end of file diff --git a/parser/src/error.rs b/parser/src/error.rs index a3bf8cc..0557cf9 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -108,7 +108,7 @@ where span: ast_err.span, error_code: ast_err.error_code, error_message: ast_err.error_message, - recovered: None, + recovered: Some(items), }), None => Ok(items), } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 5ab2bbf..3e0293f 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -26,3 +26,68 @@ pub fn parse<'a>(source: &'a str) -> Result, ParseError<'a, Vec {{ + let mut err = None; + + let v = $($item)::+ { + $( + $k: { + let r = $v.get(); + + if let Err(e) = r { + err = Some(e.clone().get()); + + if let Some(recovered) = e.recovered { + Ok(recovered) + } else { + Err(e) + } + } else { + r + } + }.get()? + ),* + }; + + if let Some(mut e) = err { + e.recovered = Some(v); + Err(e) + } else { + Ok(v) + } + }}; + + ($($item:ident)::+ ( $($v:expr),* $(,)? )) => {{ + let mut err = None; + + let v = $($item)::+ ( $({ + let r = $v.get(); + + if let Err(e) = r { + err = Some(e.clone().get()); + + if let Some(recovered) = e.recovered { + Ok(recovered) + } else { + Err(e) + } + } else { + r + } + }.get()?),* ); + + if let Some(mut e) = err { + e.recovered = Some(v); + Err(e) + } else { + Ok(v) + } + }}; + + ($($item:ident)::+) => { + $($item)::+ + }; +} diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 3f5afd5..77e1241 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -1,6 +1,7 @@ use crate::{ Rule, ast::*, + ast_expr, error::{AstError, AstResult, ErrorCode, GetParseError, collect_recovered}, parser::listen_rule, }; @@ -10,7 +11,7 @@ impl<'a> TryFrom> for Block { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { if pair.as_rule() == Rule::block { - Ok(Block(collect_recovered(pair.into_inner()).get()?)) + ast_expr!(Block(collect_recovered(pair.into_inner()))) } else { Err(AstError { span: pair.as_span(), diff --git a/parser/src/parser/items/mod.rs b/parser/src/parser/items/mod.rs index 9eba00e..bc5bf65 100644 --- a/parser/src/parser/items/mod.rs +++ b/parser/src/parser/items/mod.rs @@ -7,6 +7,7 @@ pub mod impl_decl; use crate::{ Rule, ast::*, + ast_expr, error::{AstError, GetParseError, collect_recovered}, parser::consume_rule, }; @@ -43,7 +44,7 @@ impl<'a> TryFrom> for TopLevelKind { Path::try_from(inner.next().unwrap()).get()?, ), - Rule::function_decl => TopLevelKind::FunctionDecl(pair.try_into().get()?), + Rule::function_decl => return ast_expr!(TopLevelKind::FunctionDecl(pair.try_into())), Rule::struct_decl => TopLevelKind::StructDecl { visibility: Visibility::try_from(&mut inner).get()?,