Removed error recovery from common

This commit is contained in:
2026-06-25 04:08:31 +02:00
parent 6cc46751f9
commit ae60aee85c
13 changed files with 212 additions and 268 deletions
+6 -23
View File
@@ -9,7 +9,7 @@ pub mod semantics;
use ast::*;
use crate::error::{IntoErr, ParseError};
use crate::error::ParseError;
#[derive(Parser)]
#[grammar = "./src/grammar.pest"]
@@ -20,22 +20,18 @@ pub struct Program {
pub items: Vec<TopLevel>,
}
pub fn parse<'a>(source: &'a str) -> Result<Program, ParseError<'a, Vec<TopLevel>>> {
pub fn parse<'a>(source: &'a str) -> Result<Program, ParseError<'a>> {
let mut pairs = MistParser::parse(Rule::program, source)?;
let mut statements = vec![];
let mut analyzer = error::AstErrorAnalyzer(None);
for pair in pairs.next().unwrap().into_inner() {
if pair.as_rule() != Rule::EOI {
statements.push(analyzer.get(TopLevel::try_from(pair)).get()?);
statements.push(TopLevel::try_from(pair)?);
}
}
match analyzer.build(statements) {
Ok(v) => {
let (mod_attributes, items): (Vec<_>, Vec<_>) = v
let (mod_attributes, items): (Vec<_>, Vec<_>) = statements
.into_iter()
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
@@ -44,21 +40,10 @@ pub fn parse<'a>(source: &'a str) -> Result<Program, ParseError<'a, Vec<TopLevel
mod_attributes,
})
}
Err(e) => {
let rec = e.recovered.clone();
let mut e2 = e.get();
e2.recovered = rec;
Err(ParseError::Ast(e2))
}
}
}
pub fn parse_module<'a>(
source: &'a str,
) -> Result<Option<(Visibility, Identifier)>, ParseError<'a, Option<(Visibility, Identifier)>>> {
) -> Result<Option<(Visibility, Identifier)>, ParseError<'a>> {
let mut pairs = MistParser::parse(Rule::module_program, source)?;
if let Some(v) = pairs
@@ -67,8 +52,7 @@ pub fn parse_module<'a>(
.into_inner()
.next()
.map(TopLevel::try_from)
.transpose()
.get()?
.transpose()?
{
if let TopLevelKind::DeclareModule(vis, name) = &v.0.item {
Ok(Some((vis.clone(), name.clone())))
@@ -90,7 +74,6 @@ macro_rules! ast_ensure {
span: $pair.as_span(),
error_code: crate::error::ErrorCode::AstGenBug,
error_message: format!("Possible bug: expected {:?}, got {:?}", $rule, $pair.as_rule()),
recovered: None,
})
}
};
+20 -21
View File
@@ -1,22 +1,21 @@
use crate::{
Rule,
ast::*,
ast_expr,
error::{AstError, IntoErr, collect_recovered},
error::{AstError, collect_recovered},
parser::consume_rule,
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDeclStmt {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::var_decl_statement => {
let mut inner = pair.into_inner();
ast_expr!(VarDeclStmt {
decl: inner.next().unwrap().try_into(),
init: inner.next().map(Expression::try_from).transpose()
Ok(VarDeclStmt {
decl: inner.next().unwrap().try_into()?,
init: inner.next().map(Expression::try_from).transpose()?,
})
}
@@ -26,16 +25,16 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDeclStmt {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FieldDeclStmt {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::class_field => {
let mut inner = pair.into_inner();
ast_expr!(FieldDeclStmt {
decl: inner.next().unwrap().try_into(),
init: inner.next().map(Expression::try_from).transpose(),
Ok(FieldDeclStmt {
decl: inner.next().unwrap().try_into()?,
init: inner.next().map(Expression::try_from).transpose()?,
})
}
@@ -45,18 +44,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FieldDeclStmt {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::var_decl | Rule::param => {
let mut inner = pair.into_inner();
ast_expr!(VarDecl {
Ok(VarDecl {
type_: consume_rule(&mut inner, Rule::type_expr)
.map(TypeExpr::try_from)
.transpose(),
name: Pattern::try_from(inner.next().unwrap()),
.transpose()?,
name: Pattern::try_from(inner.next().unwrap())?,
})
}
@@ -66,17 +65,17 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDecl {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FieldDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::field => {
let mut inner = pair.into_inner();
ast_expr!(FieldDecl {
visibility: Visibility::try_from(&mut inner),
type_: TypeExpr::try_from(inner.next().unwrap()),
name: Identifier::try_from(inner.next().unwrap()),
Ok(FieldDecl {
visibility: Visibility::try_from(&mut inner)?,
type_: TypeExpr::try_from(inner.next().unwrap())?,
name: Identifier::try_from(inner.next().unwrap())?,
})
}
@@ -86,9 +85,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FieldDecl {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ParamList {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
Ok(ParamList(collect_recovered(pair.into_inner()).get()?))
Ok(ParamList(collect_recovered(pair.into_inner())?))
}
}
+56 -73
View File
@@ -1,15 +1,15 @@
use crate::{
Rule,
ast::*,
ast_ensure, ast_expr,
error::{AstError, AstResult, GetLength, IntoErr, collect_recovered, collect_recovered_map},
ast_ensure,
error::{AstError, collect_recovered, collect_recovered_map},
parser::consume_rule,
};
use pest::pratt_parser::PrattParser;
use std::sync::OnceLock;
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
@@ -27,10 +27,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
pratt
.map_primary(|primary_pair| Expression::try_from(primary_pair))
.map_infix(|expr, op, rhs| {
ast_expr!(Expression::Binary {
lhs: expr.map(Box::new).get_map(Box::new),
op: Ok(op.as_str().to_string()) as AstResult<'_, String>,
rhs: rhs.map(Box::new).get_map(Box::new),
Ok(Expression::Binary {
lhs: expr.map(Box::new)?,
op: op.as_str().to_string(),
rhs: rhs.map(Box::new)?,
})
})
.parse(inner)
@@ -50,59 +50,51 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
}
}
let prefixes = collect_recovered::<Prefix, Prefix>(prefix_pairs.into_iter());
let prefixes = collect_recovered::<Prefix>(prefix_pairs.into_iter())?;
let exp = Expression::try_from(
primary_pair.expect("Term must contain a primary expression"),
);
let postfixes = collect_recovered::<Postfix, Postfix>(postfix_pairs.into_iter());
)?;
let postfixes = collect_recovered::<Postfix>(postfix_pairs.into_iter())?;
if postfixes.len() > 0 || prefixes.len() > 0 {
ast_expr!(Expression::Fix {
initial: exp.map(Box::new),
Ok(Expression::Fix {
initial: Box::new(exp),
prefixes: prefixes,
postfixes: postfixes,
})
} else {
ast_expr!(use exp?, prefixes, postfixes)
Ok(exp)
}
}
Rule::tuple => {
ast_expr!(Expression::Literal(
collect_recovered(pair.into_inner())
.map(Literal::Tuple)
.get_map(Literal::Tuple)
))
}
Rule::tuple => Ok(Expression::Literal(Literal::Tuple(collect_recovered(
pair.into_inner(),
)?))),
Rule::closure => {
ast_expr!(Expression::Closure {
Rule::closure => Ok(Expression::Closure {
return_type: consume_rule(&mut inner, Rule::type_expr)
.map(TypeExpr::try_from)
.transpose(),
params: collect_recovered(inner.next().unwrap().into_inner()),
body: Expression::try_from(inner.next().unwrap()).map(Box::new),
})
}
.transpose()?,
params: collect_recovered(inner.next().unwrap().into_inner())?,
body: Box::new(Expression::try_from(inner.next().unwrap())?),
}),
Rule::array => {
ast_expr!(Expression::Array(collect_recovered(inner)))
}
Rule::array => Ok(Expression::Array(collect_recovered(inner)?)),
Rule::array_repeat => {
ast_expr!(Expression::ArrayRepeat(
Expression::try_from(inner.next().unwrap()).map(Box::new),
Expression::try_from(inner.next().unwrap()).map(Box::new)
))
}
Rule::array_repeat => Ok(Expression::ArrayRepeat(
Box::new(Expression::try_from(inner.next().unwrap())?),
Box::new(Expression::try_from(inner.next().unwrap())?),
)),
Rule::primary => pair.into_inner().next().unwrap().try_into(),
Rule::static_path => ast_expr!(Expression::Path(pair.try_into())),
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())),
Rule::statement | Rule::basic_stmt | Rule::control_flow | Rule::block | Rule::unsafe_block => ast_expr!(
Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new))
),
Rule::static_path => Ok(Expression::Path(pair.try_into()?)),
Rule::literal => Ok(Expression::Literal(pair.try_into()?)),
Rule::expr_path => Ok(Expression::Path(pair.try_into()?)),
Rule::statement
| Rule::basic_stmt
| Rule::control_flow
| Rule::block
| Rule::unsafe_block => Ok(Expression::Statement(Box::new(pair.try_into()?))),
_ => AstError::bug_unimplemented(pair),
}
@@ -110,7 +102,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Prefix {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
Ok(match pair.as_rule() {
@@ -127,7 +119,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Prefix {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
@@ -136,34 +128,27 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
match rule {
Rule::postfix => Postfix::try_from(inner.next().unwrap()),
Rule::field_px => {
ast_expr!(Postfix::FieldAccess(
inner.next().unwrap().try_into(),
inner.next().map(Generics::try_from).transpose()
))
}
Rule::field_px => Ok(Postfix::FieldAccess(
inner.next().unwrap().try_into()?,
inner.next().map(Generics::try_from).transpose()?,
)),
Rule::tuple_field_px => {
ast_expr!(Postfix::TupleFieldAccess(
Ok(inner.next().unwrap().as_str().parse().unwrap_or(255_u8))
as AstResult<'_, u8>,
inner.next().map(Generics::try_from).transpose(),
))
}
Rule::tuple_field_px => Ok(Postfix::TupleFieldAccess(
inner.next().unwrap().as_str().parse().unwrap_or(255_u8),
inner.next().map(Generics::try_from).transpose()?,
)),
Rule::call_px => ast_expr!(Postfix::Call(collect_recovered(inner))),
Rule::call_px => Ok(Postfix::Call(collect_recovered(inner)?)),
Rule::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| {
Rule::struct_px => Ok(Postfix::StructCall(collect_recovered_map(inner, |p| {
let mut pi = p.into_inner();
Ok((
Identifier::try_from(pi.next().unwrap())?,
pi.next().map(Expression::try_from).transpose().get()?,
pi.next().map(Expression::try_from).transpose()?,
))
}))),
})?)),
Rule::index_px => {
ast_expr!(Postfix::Index(Expression::try_from(inner.next().unwrap())))
}
Rule::index_px => Ok(Postfix::Index(Expression::try_from(inner.next().unwrap())?)),
Rule::macro_call_paren => Ok(Postfix::MacroCall {
inner: inner.as_str().to_string(),
@@ -178,9 +163,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
delimiter: MacroDelimiter::Brace,
}),
Rule::as_px => {
ast_expr!(Postfix::As(inner.next().unwrap().try_into()))
}
Rule::as_px => Ok(Postfix::As(inner.next().unwrap().try_into()?)),
Rule::try_px => Ok(Postfix::Try),
@@ -193,25 +176,25 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ExprPath {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::expr_path => {
ast_expr!(ExprPath(collect_recovered(pair.into_inner())))
Ok(ExprPath(collect_recovered(pair.into_inner())?))
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ExprPathSegment {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::expr_path_segment => {
ast_expr!(ExprPathSegment {
ident: Identifier::try_from(inner.next().unwrap()),
generics: inner.next().map(Generics::try_from).transpose(),
Ok(ExprPathSegment {
ident: Identifier::try_from(inner.next().unwrap())?,
generics: inner.next().map(Generics::try_from).transpose()?,
})
})
}
+27 -28
View File
@@ -6,13 +6,13 @@ pub mod types;
use crate::{
Rule,
ast::*,
ast_ensure, ast_expr,
error::{AstError, AstResult, IntoErr, collect_recovered, collect_recovered_map},
ast_ensure,
error::{AstError, collect_recovered, collect_recovered_map},
parser::{consume_rule, listen_rule},
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::identifier => {
@@ -22,18 +22,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Path {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::static_path => Ok(Path(collect_recovered(pair.into_inner()).get()?)),
Rule::static_path => Ok(Path(collect_recovered(pair.into_inner())?)),
_ => AstError::bug_unimplemented(pair),
}
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Literal {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
@@ -46,53 +46,52 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Literal {
Rule::float => Literal::Float(pair.as_str().parse::<f64>().unwrap()),
Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()),
Rule::string_lit => Literal::String(inner.as_str().to_string()),
Rule::tuple => Literal::Tuple(collect_recovered(inner).get()?),
Rule::tuple => Literal::Tuple(collect_recovered(inner)?),
_ => return AstError::bug_unimplemented(pair),
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Pattern {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
let mut inner = pair.clone().into_inner();
match rule {
Rule::tuple_pattern => ast_expr!(Pattern::Tuple(collect_recovered_map(inner, |v| {
Rule::tuple_pattern => Ok(Pattern::Tuple(collect_recovered_map(inner, |v| {
Self::try_from(v).map(Box::new)
}))),
})?)),
Rule::named_tuple_pattern => ast_expr!(Pattern::NamedTuple(
Path::try_from(inner.next().unwrap()),
collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)),
Rule::named_tuple_pattern => Ok(Pattern::NamedTuple(
Path::try_from(inner.next().unwrap())?,
collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new))?,
)),
Rule::struct_pattern => ast_expr!(Pattern::Struct(
Path::try_from(inner.next().unwrap()),
Rule::struct_pattern => Ok(Pattern::Struct(
Path::try_from(inner.next().unwrap())?,
collect_recovered_map(inner, |v| {
if v.as_rule() == Rule::etc_pattern {
return Ok(None);
}
let mut inner = v.into_inner();
Some(ast_expr!((
Identifier::try_from(inner.next().unwrap()),
Ok(Some((
Identifier::try_from(inner.next().unwrap())?,
inner
.next()
.map(|v| Self::try_from(v).map(Box::new).get_map(Box::new))
.transpose()
.map(|v| Self::try_from(v).map(Box::new))
.transpose()?,
)))
.transpose()
}),
})?,
)),
Rule::literal => ast_expr!(Pattern::Literal(pair.try_into())),
Rule::literal => Ok(Pattern::Literal(pair.try_into()?)),
Rule::path_pattern => ast_expr!(Pattern::Path(
Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
inner.next().unwrap().try_into()
Rule::path_pattern => Ok(Pattern::Path(
listen_rule(&mut inner, Rule::mutable),
inner.next().unwrap().try_into()?,
)),
Rule::etc_pattern => Ok(Pattern::Etc),
@@ -103,13 +102,13 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Pattern {
}
impl<'a> TryFrom<&mut pest::iterators::Pairs<'a, Rule>> for Visibility {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pairs: &mut pest::iterators::Pairs<'a, Rule>) -> Result<Self, Self::Error> {
Ok(consume_rule(pairs, Rule::visibility)
.map(|pair| -> Result<Visibility, AstError<'a, Self>> {
.map(|pair| -> Result<Visibility, AstError<'a>> {
if let Some(path) = pair.into_inner().next() {
ast_expr!(Visibility::PublicTarget(Path::try_from(path)))
Ok(Visibility::PublicTarget(Path::try_from(path)?))
} else {
Ok(Visibility::Public)
}
+42 -46
View File
@@ -1,42 +1,42 @@
use crate::{
Rule,
ast::*,
ast_ensure, ast_expr,
error::{AstError, IntoErr, collect_recovered},
ast_ensure,
error::{AstError, collect_recovered},
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::block => {
ast_expr!(Block {
statements: collect_recovered(inner.next().unwrap().into_inner()),
soft_return: inner.next().map(Spanned::try_from).transpose(),
Ok(Block {
statements: collect_recovered(inner.next().unwrap().into_inner())?,
soft_return: inner.next().map(Spanned::try_from).transpose()?,
})
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::statement_branch => {
ast_expr!(StatementBranch {
condition: inner.next().unwrap().try_into(),
body: inner.next().unwrap().try_into().map(Box::new),
Ok(StatementBranch {
condition: inner.next().unwrap().try_into()?,
body: Box::new(inner.next().unwrap().try_into()?),
})
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
@@ -47,50 +47,46 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
Statement::try_from(inner.next().unwrap())
}
Rule::unsafe_block => ast_expr!(Statement::UnsafeBlock(inner.next().unwrap().try_into())),
Rule::unsafe_block => Ok(Statement::UnsafeBlock(inner.next().unwrap().try_into()?)),
Rule::block => ast_expr!(Statement::Block(pair.try_into())),
Rule::block => Ok(Statement::Block(pair.try_into()?)),
Rule::var_decl_statement => ast_expr!(Statement::VarDecl(pair.try_into())),
Rule::var_decl_statement => Ok(Statement::VarDecl(pair.try_into()?)),
Rule::return_stmt => {
ast_expr!(Statement::Return(
inner.next().map(Expression::try_from).transpose()
))
}
Rule::return_stmt => Ok(Statement::Return(
inner.next().map(Expression::try_from).transpose()?,
)),
Rule::break_stmt => Ok(Statement::Break),
Rule::continue_stmt => Ok(Statement::Continue),
Rule::if_stmt => {
ast_expr!(Statement::If {
initial: inner.next().unwrap().try_into(),
else_if: collect_recovered(inner.next().unwrap().into_inner()),
else_branch: inner.next().map(Block::try_from).transpose(),
})
}
Rule::while_stmt => ast_expr!(Statement::While(inner.next().unwrap().try_into())),
Rule::loop_stmt => ast_expr!(Statement::Loop(inner.next().unwrap().try_into())),
Rule::c_for_stmt => ast_expr!(Statement::CStyleFor {
init: inner.next().unwrap().try_into(),
condition: inner.next().unwrap().try_into(),
update: inner.next().unwrap().try_into(),
body: inner.next().unwrap().try_into(),
Rule::if_stmt => Ok(Statement::If {
initial: inner.next().unwrap().try_into()?,
else_if: collect_recovered(inner.next().unwrap().into_inner())?,
else_branch: inner.next().map(Block::try_from).transpose()?,
}),
Rule::for_stmt => ast_expr!(Statement::For {
pattern: inner.next().unwrap().try_into(),
iterator: inner.next().unwrap().try_into(),
body: inner.next().unwrap().try_into(),
Rule::while_stmt => Ok(Statement::While(inner.next().unwrap().try_into()?)),
Rule::loop_stmt => Ok(Statement::Loop(inner.next().unwrap().try_into()?)),
Rule::c_for_stmt => Ok(Statement::CStyleFor {
init: inner.next().unwrap().try_into()?,
condition: inner.next().unwrap().try_into()?,
update: inner.next().unwrap().try_into()?,
body: inner.next().unwrap().try_into()?,
}),
Rule::match_stmt => ast_expr!(Statement::Match(
inner.next().unwrap().try_into(),
collect_recovered(inner),
Rule::for_stmt => Ok(Statement::For {
pattern: inner.next().unwrap().try_into()?,
iterator: inner.next().unwrap().try_into()?,
body: inner.next().unwrap().try_into()?,
}),
Rule::match_stmt => Ok(Statement::Match(
inner.next().unwrap().try_into()?,
collect_recovered(inner)?,
)),
_ => AstError::bug_unimplemented(pair),
@@ -99,14 +95,14 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for MatchItem {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut match_inner = pair.into_inner();
Ok(MatchItem(
collect_recovered(match_inner.next().unwrap().into_inner()).get()?,
Expression::try_from(match_inner.next().unwrap()).get()?,
collect_recovered(match_inner.next().unwrap().into_inner())?,
Expression::try_from(match_inner.next().unwrap())?,
))
}
}
+28 -33
View File
@@ -1,13 +1,13 @@
use crate::{
Rule,
ast::*,
ast_ensure, ast_expr,
error::{AstError, IntoErr, collect_recovered},
ast_ensure,
error::{AstError, collect_recovered},
parser::{consume_rule, listen_rule},
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
@@ -27,8 +27,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
lifetime: consume_rule(&mut ref_inner, Rule::ref_lifetime)
.map(|v| v.into_inner().next().map(Lifetime::try_from))
.unwrap_or_default()
.transpose()
.get()?,
.transpose()?,
mutable: listen_rule(&mut ref_inner, Rule::mutable),
ty: Box::new(ty),
};
@@ -36,21 +35,17 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
Ok(ty)
}
Rule::lifetime => ast_expr!(TypeExpr::Lifetime(inner.next().unwrap().try_into())),
Rule::lifetime => Ok(TypeExpr::Lifetime(inner.next().unwrap().try_into()?)),
Rule::tuple_type => ast_expr!(TypeExpr::Tuple(collect_recovered(inner))),
Rule::path_type => {
ast_expr!(TypeExpr::Path(
Path::try_from(inner.next().unwrap()),
inner.next().map(Generics::try_from).transpose()
))
}
Rule::tuple_type => Ok(TypeExpr::Tuple(collect_recovered(inner)?)),
Rule::path_type => Ok(TypeExpr::Path(
Path::try_from(inner.next().unwrap())?,
inner.next().map(Generics::try_from).transpose()?,
)),
Rule::dyn_type => {
ast_expr!(TypeExpr::Dyn(
TypeExpr::try_from(inner.next().unwrap()).map(Box::new),
))
}
Rule::dyn_type => Ok(TypeExpr::Dyn(
TypeExpr::try_from(inner.next().unwrap()).map(Box::new)?,
)),
_ => AstError::bug_unimplemented(pair),
}
@@ -58,32 +53,32 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generics_decl => {
ast_expr!(GenericsDecl(collect_recovered(inner)))
Ok(GenericsDecl(collect_recovered(inner)?))
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generic_decl => {
if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
ast_expr!(GenericDecl::Lifetime(
pair.into_inner().next().unwrap().try_into(),
Ok(GenericDecl::Lifetime(
pair.into_inner().next().unwrap().try_into()?,
))
} else {
ast_expr!(GenericDecl::Type(
inner.next().unwrap().try_into(),
collect_recovered(inner),
Ok(GenericDecl::Type(
inner.next().unwrap().try_into()?,
collect_recovered(inner)?,
))
}
})
@@ -91,31 +86,31 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericDecl {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generics {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generics => {
ast_expr!(Generics(collect_recovered(inner)))
Ok(Generics(collect_recovered(inner)?))
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generic {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generic => {
if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
ast_expr!(Generic::Lifetime(
pair.into_inner().next().unwrap().try_into(),
Ok(Generic::Lifetime(
pair.into_inner().next().unwrap().try_into()?,
))
} else {
ast_expr!(Generic::Type(
inner.next().unwrap().try_into()
Ok(Generic::Type(
inner.next().unwrap().try_into()?
))
}
})
+1 -1
View File
@@ -5,7 +5,7 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
+2 -2
View File
@@ -6,7 +6,7 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassConstructor {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.into_inner();
@@ -32,7 +32,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassConstructor {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassItem {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
+1 -1
View File
@@ -5,7 +5,7 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for EnumItem {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
+6 -6
View File
@@ -7,7 +7,7 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::function_decl => {
@@ -67,7 +67,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
let body = inner.next().map(Block::try_from).transpose();
ast_expr!(Self {
Ok(Self {
visibility: visibility,
is_override: is_override,
return_type: return_type,
@@ -81,24 +81,24 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Override {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::override_kw => {
ast_expr!(Override(pair.into_inner().next().map(ExprPath::try_from).transpose()))
Ok(Override(pair.into_inner().next().map(ExprPath::try_from).transpose()))
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Lifetime {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
match pair.as_rule() {
Rule::ref_lifetime => inner.next().unwrap().try_into(),
Rule::lifetime => ast_expr!(Lifetime::Lifetime(inner.next().unwrap().try_into())),
Rule::lifetime => Ok(Lifetime::Lifetime(inner.next().unwrap().try_into())),
Rule::unsafe_kw => Ok(Lifetime::Unsafe),
_ => error::AstError::bug_unimplemented(pair),
}
+1 -1
View File
@@ -6,7 +6,7 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
+11 -13
View File
@@ -13,14 +13,14 @@ use crate::{
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevel {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
let attributes = collect_recovered(inner.next().unwrap().into_inner());
ast_expr!(TopLevel(
Ok(TopLevel(
inner
.next()
.map(Spanned::try_from)
@@ -31,21 +31,21 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevel {
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule();
let mut inner = pair.clone().into_inner();
match rule {
Rule::import => ast_expr!(TopLevelKind::Import(
Rule::import => Ok(TopLevelKind::Import(
Visibility::try_from(&mut inner),
Path::try_from(inner.next().unwrap()),
)),
Rule::function_decl => ast_expr!(TopLevelKind::FunctionDecl(pair.try_into())),
Rule::function_decl => Ok(TopLevelKind::FunctionDecl(pair.try_into())),
Rule::struct_decl => ast_expr!(TopLevelKind::StructDecl {
Rule::struct_decl => Ok(TopLevelKind::StructDecl {
visibility: Visibility::try_from(&mut inner),
name: inner.next().unwrap().try_into(),
@@ -62,7 +62,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
.map(|v| v.unwrap_or_default()),
}),
Rule::class_decl => ast_expr!(TopLevelKind::ClassDecl {
Rule::class_decl => Ok(TopLevelKind::ClassDecl {
visibility: Visibility::try_from(&mut inner),
name: inner.next().unwrap().try_into(),
@@ -85,7 +85,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
items: collect_recovered(inner),
}),
Rule::enum_decl => ast_expr!(TopLevelKind::EnumDecl {
Rule::enum_decl => Ok(TopLevelKind::EnumDecl {
visibility: Visibility::try_from(&mut inner),
name: inner.next().unwrap().try_into(),
@@ -98,16 +98,14 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
fields: collect_recovered(inner),
}),
Rule::declare_module => ast_expr!(TopLevelKind::DeclareModule(
Rule::declare_module => Ok(TopLevelKind::DeclareModule(
Visibility::try_from(&mut inner),
inner.next().unwrap().try_into(),
)),
Rule::impl_for_decl | Rule::impl_decl => {
ast_expr!(TopLevelKind::ImplDecl(pair.try_into()))
}
Rule::impl_for_decl | Rule::impl_decl => Ok(TopLevelKind::ImplDecl(pair.try_into())),
Rule::trait_decl => ast_expr!(TopLevelKind::TraitDecl {
Rule::trait_decl => Ok(TopLevelKind::TraitDecl {
visibility: Visibility::try_from(&mut inner),
name: inner.next().unwrap().try_into(),
+3 -12
View File
@@ -40,10 +40,10 @@ impl<T> Spanned<T> {
}
}
impl<'a, T: TryFrom<pest::iterators::Pair<'a, Rule>, Error = AstError<'a, T>>>
impl<'a, T: TryFrom<pest::iterators::Pair<'a, Rule>, Error = AstError<'a>>>
TryFrom<pest::iterators::Pair<'a, Rule>> for Spanned<T>
{
type Error = AstError<'a, Self>;
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let span = pair.as_span().start_pos().line_col();
@@ -51,16 +51,7 @@ impl<'a, T: TryFrom<pest::iterators::Pair<'a, Rule>, Error = AstError<'a, T>>>
Ok(Self {
line: span.0,
column: span.1,
item: pair.try_into().map_err(|err: AstError<'_, T>| AstError {
span: err.span,
error_code: err.error_code,
error_message: err.error_message,
recovered: err.recovered.map(|v| Spanned {
line: span.0,
column: span.1,
item: v,
}),
})?,
item: pair.try_into()?,
})
}
}