error system: statement

This commit is contained in:
2026-05-16 06:33:00 +02:00
parent 32c411ba78
commit a6e52b0191
2 changed files with 59 additions and 46 deletions
+12 -2
View File
@@ -47,14 +47,24 @@ impl<'a, F> AstError<'a, F> {
} }
} }
pub trait IntoErr<T> { pub trait IntoErr<T, FA, FR> {
fn get(self) -> T; fn get(self) -> T;
fn get_map(self, m: impl Fn(FA) -> FR) -> T;
} }
impl<'a, T, TE, TE2> IntoErr<AstResult<'a, T, TE2>> for AstResult<'a, T, TE> { impl<'a, T, TE, TE2> IntoErr<AstResult<'a, T, TE2>, TE, TE2> for AstResult<'a, T, TE> {
fn get(self) -> AstResult<'a, T, TE2> { fn get(self) -> AstResult<'a, T, TE2> {
self.map_err(AstError::get) 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 { pub trait GetLength {
+47 -44
View File
@@ -22,12 +22,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let condition = inner.next().unwrap().try_into().get()?; ast_expr!(StatementBranch {
let body = inner.next().unwrap().try_into().get()?; condition: inner.next().unwrap().try_into(),
body: inner.next().unwrap().try_into().map(Box::new),
Ok(StatementBranch {
condition,
body: Box::new(body),
}) })
} }
} }
@@ -39,62 +36,69 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
let rule = pair.as_rule(); let rule = pair.as_rule();
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
Ok(match rule { match rule {
Rule::statement => Statement::try_from(inner.next().unwrap())?, Rule::statement => Statement::try_from(inner.next().unwrap()),
Rule::expr_stmt => { 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 => { 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 => { Rule::if_stmt => {
let mut inner = inner.skip(2); let mut inner = inner.skip(2);
Statement::If { ast_expr!(Statement::If {
initial: StatementBranch::try_from(pair).get()?, initial: inner.next().unwrap().try_into(),
else_if: collect_recovered(inner.next().unwrap().into_inner()).get()?, else_if: collect_recovered(inner.next().unwrap().into_inner()),
else_branch: inner else_branch: inner
.next() .next()
.map(Statement::try_from) .map(Statement::try_from)
.transpose()? .transpose()
.map(Box::new), .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 { Rule::c_for_stmt => ast_expr!(Statement::CStyleFor {
init: Box::new(inner.next().unwrap().try_into().get()?), init: inner.next().unwrap().try_into().map(Box::new),
condition: inner.next().unwrap().try_into().get()?, condition: inner.next().unwrap().try_into(),
update: Box::new(inner.next().unwrap().try_into().get()?), update: inner.next().unwrap().try_into().map(Box::new),
body: Box::new(inner.next().unwrap().try_into().get()?), body: inner.next().unwrap().try_into().map(Box::new),
},
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::match_stmt => Statement::Match( Rule::for_stmt => ast_expr!(Statement::For {
inner.next().unwrap().try_into().get()?, 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 inner
.map(|match_itms| { .map(|match_itms| {
let mut match_inner = match_itms.into_inner(); let mut match_inner = match_itms.into_inner();
@@ -103,9 +107,8 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
Block::try_from(match_inner.next().unwrap()).get()?, Block::try_from(match_inner.next().unwrap()).get()?,
)) ))
}) })
.collect::<AstResult<'a, Vec<_>>>() .collect::<AstResult<'a, Vec<_>>>(),
.get()?, )),
),
Rule::unexpected_statement => { Rule::unexpected_statement => {
return Err(AstError { return Err(AstError {
@@ -117,6 +120,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
} }
_ => unimplemented!("{rule:#?}"), _ => unimplemented!("{rule:#?}"),
}) }
} }
} }