From a6e52b0191b854586439755b6d5fdd62efc57165 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 16 May 2026 06:33:00 +0200 Subject: [PATCH] error system: statement --- parser/src/error.rs | 14 ++++- parser/src/parser/common/statement.rs | 91 ++++++++++++++------------- 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/parser/src/error.rs b/parser/src/error.rs index e9fc2dd..03c60d2 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -47,14 +47,24 @@ impl<'a, F> AstError<'a, F> { } } -pub trait IntoErr { +pub trait IntoErr { fn get(self) -> T; + fn get_map(self, m: impl Fn(FA) -> FR) -> T; } -impl<'a, T, TE, TE2> IntoErr> for AstResult<'a, T, TE> { +impl<'a, T, TE, TE2> IntoErr, TE, TE2> for AstResult<'a, T, TE> { fn get(self) -> AstResult<'a, T, TE2> { self.map_err(AstError::get) } + + fn get_map(self, m: impl Fn(TE) -> TE2) -> AstResult<'a, T, TE2> { + self.map_err(|e| AstError { + span: e.span, + error_code: e.error_code, + error_message: e.error_message, + recovered: e.recovered.map(m), + }) + } } pub trait GetLength { diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 3bd8e9c..5dd84b2 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -22,12 +22,9 @@ impl<'a> TryFrom> for StatementBranch { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { let mut inner = pair.into_inner(); - let condition = inner.next().unwrap().try_into().get()?; - let body = inner.next().unwrap().try_into().get()?; - - Ok(StatementBranch { - condition, - body: Box::new(body), + ast_expr!(StatementBranch { + condition: inner.next().unwrap().try_into(), + body: inner.next().unwrap().try_into().map(Box::new), }) } } @@ -39,62 +36,69 @@ impl<'a> TryFrom> for Statement { let rule = pair.as_rule(); let mut inner = pair.clone().into_inner(); - Ok(match rule { - Rule::statement => Statement::try_from(inner.next().unwrap())?, + match rule { + Rule::statement => Statement::try_from(inner.next().unwrap()), Rule::expr_stmt => { - Statement::Expression(Expression::try_from(inner.next().unwrap()).get()?) + ast_expr!(Statement::Expression(inner.next().unwrap().try_into())) } - Rule::block => Statement::Block(pair.try_into().get()?), + Rule::block => ast_expr!(Statement::Block(pair.try_into())), - Rule::var_decl_statement => Statement::VarDecl(VarDeclStmt::try_from(pair).get()?), + Rule::var_decl_statement => { + ast_expr!(Statement::VarDecl(inner.next().unwrap().try_into())) + } Rule::return_stmt => { - Statement::Return(inner.next().map(Expression::try_from).transpose().get()?) + ast_expr!(Statement::Return( + inner.next().map(Expression::try_from).transpose() + )) } - Rule::break_stmt => Statement::Break, + Rule::break_stmt => Ok(Statement::Break), - Rule::continue_stmt => Statement::Continue, + Rule::continue_stmt => Ok(Statement::Continue), Rule::if_stmt => { let mut inner = inner.skip(2); - Statement::If { - initial: StatementBranch::try_from(pair).get()?, - else_if: collect_recovered(inner.next().unwrap().into_inner()).get()?, + ast_expr!(Statement::If { + initial: inner.next().unwrap().try_into(), + else_if: collect_recovered(inner.next().unwrap().into_inner()), else_branch: inner .next() .map(Statement::try_from) - .transpose()? - .map(Box::new), - } + .transpose() + .map(|v| v.map(Box::new)) + .get_map(|v| { Some(Box::new(v)) }), + }) } - Rule::while_stmt => Statement::While(pair.try_into().get()?), + Rule::while_stmt => ast_expr!(Statement::While(pair.try_into())), - Rule::c_for_stmt => Statement::CStyleFor { - init: Box::new(inner.next().unwrap().try_into().get()?), - condition: inner.next().unwrap().try_into().get()?, - update: Box::new(inner.next().unwrap().try_into().get()?), - body: Box::new(inner.next().unwrap().try_into().get()?), - }, - - Rule::for_stmt => Statement::For { - mutable: listen_rule(&mut inner, Rule::mutable), - pattern: inner.next().unwrap().try_into().get()?, - iterator: inner.next().unwrap().try_into().get()?, - body: Box::new(Statement::try_from(inner.next().unwrap())?), - }, - - Rule::assign_statement => Statement::VarAssign(VarAssignStmt { - target: inner.next().unwrap().try_into().get()?, - value: inner.next().unwrap().try_into().get()?, + Rule::c_for_stmt => ast_expr!(Statement::CStyleFor { + init: inner.next().unwrap().try_into().map(Box::new), + condition: inner.next().unwrap().try_into(), + update: inner.next().unwrap().try_into().map(Box::new), + body: inner.next().unwrap().try_into().map(Box::new), }), - Rule::match_stmt => Statement::Match( - inner.next().unwrap().try_into().get()?, + Rule::for_stmt => ast_expr!(Statement::For { + mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>, + pattern: inner.next().unwrap().try_into(), + iterator: inner.next().unwrap().try_into(), + body: inner.next().unwrap().try_into().map(Box::new), + }), + + Rule::assign_statement => ast_expr!(VarAssignStmt { + target: inner.next().unwrap().try_into(), + value: inner.next().unwrap().try_into(), + }) + .map(Statement::VarAssign) + .get_map(Statement::VarAssign), + + Rule::match_stmt => ast_expr!(Statement::Match( + inner.next().unwrap().try_into(), inner .map(|match_itms| { let mut match_inner = match_itms.into_inner(); @@ -103,9 +107,8 @@ impl<'a> TryFrom> for Statement { Block::try_from(match_inner.next().unwrap()).get()?, )) }) - .collect::>>() - .get()?, - ), + .collect::>>(), + )), Rule::unexpected_statement => { return Err(AstError { @@ -117,6 +120,6 @@ impl<'a> TryFrom> for Statement { } _ => unimplemented!("{rule:#?}"), - }) + } } }