Making a error recovery system
This commit is contained in:
@@ -12,4 +12,6 @@ void main() {
|
|||||||
|
|
||||||
app_instance.boot();
|
app_instance.boot();
|
||||||
app_instance.run();
|
app_instance.run();
|
||||||
|
|
||||||
|
hi
|
||||||
}
|
}
|
||||||
+1
-1
@@ -108,7 +108,7 @@ where
|
|||||||
span: ast_err.span,
|
span: ast_err.span,
|
||||||
error_code: ast_err.error_code,
|
error_code: ast_err.error_code,
|
||||||
error_message: ast_err.error_message,
|
error_message: ast_err.error_message,
|
||||||
recovered: None,
|
recovered: Some(items),
|
||||||
}),
|
}),
|
||||||
None => Ok(items),
|
None => Ok(items),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,68 @@ pub fn parse<'a>(source: &'a str) -> Result<Vec<TopLevel>, ParseError<'a, Vec<To
|
|||||||
|
|
||||||
Ok(statements)
|
Ok(statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! ast_expr {
|
||||||
|
($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
|
||||||
|
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)::+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Rule,
|
Rule,
|
||||||
ast::*,
|
ast::*,
|
||||||
|
ast_expr,
|
||||||
error::{AstError, AstResult, ErrorCode, GetParseError, collect_recovered},
|
error::{AstError, AstResult, ErrorCode, GetParseError, collect_recovered},
|
||||||
parser::listen_rule,
|
parser::listen_rule,
|
||||||
};
|
};
|
||||||
@@ -10,7 +11,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
|
|||||||
|
|
||||||
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> {
|
||||||
if pair.as_rule() == Rule::block {
|
if pair.as_rule() == Rule::block {
|
||||||
Ok(Block(collect_recovered(pair.into_inner()).get()?))
|
ast_expr!(Block(collect_recovered(pair.into_inner())))
|
||||||
} else {
|
} else {
|
||||||
Err(AstError {
|
Err(AstError {
|
||||||
span: pair.as_span(),
|
span: pair.as_span(),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub mod impl_decl;
|
|||||||
use crate::{
|
use crate::{
|
||||||
Rule,
|
Rule,
|
||||||
ast::*,
|
ast::*,
|
||||||
|
ast_expr,
|
||||||
error::{AstError, GetParseError, collect_recovered},
|
error::{AstError, GetParseError, collect_recovered},
|
||||||
parser::consume_rule,
|
parser::consume_rule,
|
||||||
};
|
};
|
||||||
@@ -43,7 +44,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
|
|||||||
Path::try_from(inner.next().unwrap()).get()?,
|
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 {
|
Rule::struct_decl => TopLevelKind::StructDecl {
|
||||||
visibility: Visibility::try_from(&mut inner).get()?,
|
visibility: Visibility::try_from(&mut inner).get()?,
|
||||||
|
|||||||
Reference in New Issue
Block a user