Merge pull request #87 from mist-go/rm-err-recovery

Remove: Error recovery
This commit is contained in:
2026-06-25 04:21:24 +02:00
committed by GitHub
16 changed files with 292 additions and 460 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ pub struct TranspiledFile {
#[derive(Debug)] #[derive(Debug)]
pub enum TranspileError<'a> { pub enum TranspileError<'a> {
Parse(mist_parser::error::ParseError<'a, Vec<mist_parser::ast::TopLevel>>), Parse(mist_parser::error::ParseError<'a>),
Semantic(Vec<mist_parser::semantics::SemanticError>), Semantic(Vec<mist_parser::semantics::SemanticError>),
} }
+1 -1
View File
@@ -186,7 +186,7 @@ std::io::Result<bool> is_source_newer(Path& source, Path& output) {
} }
pub enum TranspileError<'a> { pub enum TranspileError<'a> {
Parse(error::ParseError<'a, Vec<mist_parser::ast::TopLevel>>), Parse(error::ParseError<'a>),
Semantic(Vec<mist_parser::semantics::SemanticError>) Semantic(Vec<mist_parser::semantics::SemanticError>)
} }
+16 -74
View File
@@ -4,20 +4,19 @@ use pest::iterators::Pair;
use crate::Rule; use crate::Rule;
pub type AstResult<'a, T, ET = T> = Result<T, AstError<'a, ET>>; pub type AstResult<'a, T> = Result<T, AstError<'a>>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ParseError<'a, T> { pub enum ParseError<'a> {
PreAst(pest::error::Error<Rule>), PreAst(pest::error::Error<Rule>),
Ast(AstError<'a, T>), Ast(AstError<'a>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AstError<'a, T> { pub struct AstError<'a> {
pub span: pest::Span<'a>, pub span: pest::Span<'a>,
pub error_code: ErrorCode, pub error_code: ErrorCode,
pub error_message: String, pub error_message: String,
pub recovered: Option<T>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -27,30 +26,21 @@ pub enum ErrorCode {
Module, Module,
} }
impl<T> From<pest::error::Error<Rule>> for ParseError<'_, T> { impl From<pest::error::Error<Rule>> for ParseError<'_> {
fn from(value: pest::error::Error<Rule>) -> Self { fn from(value: pest::error::Error<Rule>) -> Self {
Self::PreAst(value) Self::PreAst(value)
} }
} }
impl<'a, T> From<AstError<'a, T>> for ParseError<'a, T> { impl<'a> From<AstError<'a>> for ParseError<'a> {
fn from(value: AstError<'a, T>) -> Self { fn from(value: AstError<'a>) -> Self {
Self::Ast(value) Self::Ast(value)
} }
} }
impl<'a, F> AstError<'a, F> { impl<'a> AstError<'a> {
pub fn get<T>(self) -> AstError<'a, T> {
AstError {
span: self.span,
error_code: self.error_code,
error_message: self.error_message,
recovered: None,
}
}
#[track_caller] #[track_caller]
pub fn bug_unimplemented<T>(pair: Pair<'a, Rule>) -> AstResult<'a, T, F> { pub fn bug_unimplemented<T>(pair: Pair<'a, Rule>) -> AstResult<'a, T> {
let loc = std::panic::Location::caller(); let loc = std::panic::Location::caller();
Err(Self { Err(Self {
@@ -62,7 +52,6 @@ impl<'a, F> AstError<'a, F> {
loc.file(), loc.file(),
loc.line(), loc.line(),
), ),
recovered: None,
}) })
} }
} }
@@ -72,21 +61,6 @@ pub trait IntoErr<T, FA, FR> {
fn get_map(self, m: impl Fn(FA) -> FR) -> T; fn get_map(self, m: impl Fn(FA) -> FR) -> T;
} }
impl<'a, T, TE, TE2> IntoErr<AstResult<'a, T, TE2>, 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 { pub trait GetLength {
fn len(&self) -> usize; fn len(&self) -> usize;
} }
@@ -97,24 +71,24 @@ impl<T, E> GetLength for Result<Vec<T>, E> {
} }
} }
pub fn collect_recovered<'a, T: Debug, ET>( pub fn collect_recovered<'a, T: Debug>(
pairs: impl Iterator<Item = pest::iterators::Pair<'a, Rule>>, pairs: impl Iterator<Item = pest::iterators::Pair<'a, Rule>>,
) -> AstResult<'a, Vec<T>, Vec<T>> ) -> AstResult<'a, Vec<T>>
where where
T: TryFrom<pest::iterators::Pair<'a, Rule>, Error = AstError<'a, ET>>, T: TryFrom<pest::iterators::Pair<'a, Rule>, Error = AstError<'a>>,
{ {
collect_recovered_map(pairs, T::try_from) collect_recovered_map(pairs, T::try_from)
} }
pub fn collect_recovered_map<'a, T: Debug, F, ET>( pub fn collect_recovered_map<'a, T: Debug, F>(
pairs: impl Iterator<Item = pest::iterators::Pair<'a, Rule>>, pairs: impl Iterator<Item = pest::iterators::Pair<'a, Rule>>,
f: F, f: F,
) -> AstResult<'a, Vec<T>, Vec<T>> ) -> AstResult<'a, Vec<T>>
where where
F: Fn(pest::iterators::Pair<'a, Rule>) -> AstResult<'a, T, ET>, F: Fn(pest::iterators::Pair<'a, Rule>) -> AstResult<'a, T>,
{ {
let mut items = Vec::new(); let mut items = Vec::new();
let mut last_error: Option<AstError<'a, ET>> = None; let mut last_error: Option<AstError<'a>> = None;
for pair in pairs { for pair in pairs {
match f(pair) { match f(pair) {
@@ -130,39 +104,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: Some(items),
}), }),
None => Ok(items), None => Ok(items),
} }
} }
pub struct AstErrorAnalyzer<'a, T>(pub Option<AstError<'a, T>>);
impl<'a, T> AstErrorAnalyzer<'a, T> {
pub fn get<V: Clone, V2: Clone + Into<V>>(
&mut self,
r: AstResult<'a, V, V2>,
) -> AstResult<'a, V, V2> {
if let Err(e) = r {
self.0 = Some(e.clone().get());
if let Some(recovered) = e.recovered {
Ok(recovered.into())
} else {
Err(e)
}
} else {
r
}
}
pub fn build(self, v: T) -> AstResult<'a, T> {
if let Some(mut e) = self.0 {
e.recovered = Some(v);
Err(e)
} else {
Ok(v)
}
}
}
+12 -70
View File
@@ -9,7 +9,7 @@ pub mod semantics;
use ast::*; use ast::*;
use crate::error::{IntoErr, ParseError}; use crate::error::ParseError;
#[derive(Parser)] #[derive(Parser)]
#[grammar = "./src/grammar.pest"] #[grammar = "./src/grammar.pest"]
@@ -20,45 +20,30 @@ pub struct Program {
pub items: Vec<TopLevel>, 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 pairs = MistParser::parse(Rule::program, source)?;
let mut statements = vec![]; let mut statements = vec![];
let mut analyzer = error::AstErrorAnalyzer(None);
for pair in pairs.next().unwrap().into_inner() { for pair in pairs.next().unwrap().into_inner() {
if pair.as_rule() != Rule::EOI { 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) { let (mod_attributes, items): (Vec<_>, Vec<_>) = statements
Ok(v) => { .into_iter()
let (mod_attributes, items): (Vec<_>, Vec<_>) = v .partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
.into_iter()
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
Ok(Program { Ok(Program {
items, items,
mod_attributes, 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>( pub fn parse_module<'a>(
source: &'a str, 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)?; let mut pairs = MistParser::parse(Rule::module_program, source)?;
if let Some(v) = pairs if let Some(v) = pairs
@@ -67,8 +52,7 @@ pub fn parse_module<'a>(
.into_inner() .into_inner()
.next() .next()
.map(TopLevel::try_from) .map(TopLevel::try_from)
.transpose() .transpose()?
.get()?
{ {
if let TopLevelKind::DeclareModule(vis, name) = &v.0.item { if let TopLevelKind::DeclareModule(vis, name) = &v.0.item {
Ok(Some((vis.clone(), name.clone()))) Ok(Some((vis.clone(), name.clone())))
@@ -90,49 +74,7 @@ macro_rules! ast_ensure {
span: $pair.as_span(), span: $pair.as_span(),
error_code: crate::error::ErrorCode::AstGenBug, error_code: crate::error::ErrorCode::AstGenBug,
error_message: format!("Possible bug: expected {:?}, got {:?}", $rule, $pair.as_rule()), error_message: format!("Possible bug: expected {:?}, got {:?}", $rule, $pair.as_rule()),
recovered: None,
}) })
} }
}; };
} }
#[macro_export]
macro_rules! ast_expr {
(use $r:expr, $($v:expr),* $(,)?) => {{
let mut analyzer = $crate::error::AstErrorAnalyzer(None);
$(
analyzer.get($v).get()?;
)*
analyzer.build($r)
}};
($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
let mut analyzer = $crate::error::AstErrorAnalyzer(None);
let v = $($item)::+ { $($k: analyzer.get($v).get()?),* };
analyzer.build(v)
}};
($($item:ident)::+ ( $($v:expr),* $(,)? )) => {{
let mut analyzer = $crate::error::AstErrorAnalyzer(None);
let v = $($item)::+ ( $(analyzer.get($v).get()?),* );
analyzer.build(v)
}};
(( $($v:expr),* $(,)? )) => {{
let mut analyzer = $crate::error::AstErrorAnalyzer(None);
let v = ( $(analyzer.get($v).get()?),* );
analyzer.build(v)
}};
($($item:ident)::+) => {
$($item)::+
};
}
+20 -21
View File
@@ -1,22 +1,21 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_expr, error::{AstError, collect_recovered},
error::{AstError, IntoErr, collect_recovered},
parser::consume_rule, parser::consume_rule,
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDeclStmt { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { match pair.as_rule() {
Rule::var_decl_statement => { Rule::var_decl_statement => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
ast_expr!(VarDeclStmt { Ok(VarDeclStmt {
decl: inner.next().unwrap().try_into(), decl: inner.next().unwrap().try_into()?,
init: inner.next().map(Expression::try_from).transpose() 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { match pair.as_rule() {
Rule::class_field => { Rule::class_field => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
ast_expr!(FieldDeclStmt { Ok(FieldDeclStmt {
decl: inner.next().unwrap().try_into(), decl: inner.next().unwrap().try_into()?,
init: inner.next().map(Expression::try_from).transpose(), 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { match pair.as_rule() {
Rule::var_decl | Rule::param => { Rule::var_decl | Rule::param => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
ast_expr!(VarDecl { Ok(VarDecl {
type_: consume_rule(&mut inner, Rule::type_expr) type_: consume_rule(&mut inner, Rule::type_expr)
.map(TypeExpr::try_from) .map(TypeExpr::try_from)
.transpose(), .transpose()?,
name: Pattern::try_from(inner.next().unwrap()), 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { match pair.as_rule() {
Rule::field => { Rule::field => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
ast_expr!(FieldDecl { Ok(FieldDecl {
visibility: Visibility::try_from(&mut inner), visibility: Visibility::try_from(&mut inner)?,
type_: TypeExpr::try_from(inner.next().unwrap()), type_: TypeExpr::try_from(inner.next().unwrap())?,
name: Identifier::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 { 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> { 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())?))
} }
} }
+58 -75
View File
@@ -1,15 +1,15 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure,
error::{AstError, AstResult, GetLength, IntoErr, collect_recovered, collect_recovered_map}, error::{AstError, collect_recovered, collect_recovered_map},
parser::consume_rule, parser::consume_rule,
}; };
use pest::pratt_parser::PrattParser; use pest::pratt_parser::PrattParser;
use std::sync::OnceLock; use std::sync::OnceLock;
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
@@ -27,10 +27,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
pratt pratt
.map_primary(|primary_pair| Expression::try_from(primary_pair)) .map_primary(|primary_pair| Expression::try_from(primary_pair))
.map_infix(|expr, op, rhs| { .map_infix(|expr, op, rhs| {
ast_expr!(Expression::Binary { Ok(Expression::Binary {
lhs: expr.map(Box::new).get_map(Box::new), lhs: expr.map(Box::new)?,
op: Ok(op.as_str().to_string()) as AstResult<'_, String>, op: op.as_str().to_string(),
rhs: rhs.map(Box::new).get_map(Box::new), rhs: rhs.map(Box::new)?,
}) })
}) })
.parse(inner) .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( let exp = Expression::try_from(
primary_pair.expect("Term must contain a primary expression"), 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 { if postfixes.len() > 0 || prefixes.len() > 0 {
ast_expr!(Expression::Fix { Ok(Expression::Fix {
initial: exp.map(Box::new), initial: Box::new(exp),
prefixes: prefixes, prefixes: prefixes,
postfixes: postfixes, postfixes: postfixes,
}) })
} else { } else {
ast_expr!(use exp?, prefixes, postfixes) Ok(exp)
} }
} }
Rule::tuple => { Rule::tuple => Ok(Expression::Literal(Literal::Tuple(collect_recovered(
ast_expr!(Expression::Literal( pair.into_inner(),
collect_recovered(pair.into_inner()) )?))),
.map(Literal::Tuple)
.get_map(Literal::Tuple)
))
}
Rule::closure => { Rule::closure => Ok(Expression::Closure {
ast_expr!(Expression::Closure { return_type: consume_rule(&mut inner, Rule::type_expr)
return_type: consume_rule(&mut inner, Rule::type_expr) .map(TypeExpr::try_from)
.map(TypeExpr::try_from) .transpose()?,
.transpose(), params: collect_recovered(inner.next().unwrap().into_inner())?,
params: collect_recovered(inner.next().unwrap().into_inner()), body: Box::new(Expression::try_from(inner.next().unwrap())?),
body: Expression::try_from(inner.next().unwrap()).map(Box::new), }),
})
}
Rule::array => { Rule::array => Ok(Expression::Array(collect_recovered(inner)?)),
ast_expr!(Expression::Array(collect_recovered(inner)))
}
Rule::array_repeat => { Rule::array_repeat => Ok(Expression::ArrayRepeat(
ast_expr!(Expression::ArrayRepeat( Box::new(Expression::try_from(inner.next().unwrap())?),
Expression::try_from(inner.next().unwrap()).map(Box::new), Box::new(Expression::try_from(inner.next().unwrap())?),
Expression::try_from(inner.next().unwrap()).map(Box::new) )),
))
}
Rule::primary => pair.into_inner().next().unwrap().try_into(), Rule::primary => pair.into_inner().next().unwrap().try_into(),
Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::static_path => Ok(Expression::Path(pair.try_into()?)),
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::literal => Ok(Expression::Literal(pair.try_into()?)),
Rule::expr_path => ast_expr!(Expression::Path(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 => ast_expr!( Rule::statement
Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new)) | Rule::basic_stmt
), | Rule::control_flow
| Rule::block
| Rule::unsafe_block => Ok(Expression::Statement(Box::new(pair.try_into()?))),
_ => AstError::bug_unimplemented(pair), _ => 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
Ok(match pair.as_rule() { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
@@ -136,34 +128,27 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
match rule { match rule {
Rule::postfix => Postfix::try_from(inner.next().unwrap()), Rule::postfix => Postfix::try_from(inner.next().unwrap()),
Rule::field_px => { Rule::field_px => Ok(Postfix::FieldAccess(
ast_expr!(Postfix::FieldAccess( inner.next().unwrap().try_into()?,
inner.next().unwrap().try_into(), inner.next().map(Generics::try_from).transpose()?,
inner.next().map(Generics::try_from).transpose() )),
))
}
Rule::tuple_field_px => { Rule::tuple_field_px => Ok(Postfix::TupleFieldAccess(
ast_expr!(Postfix::TupleFieldAccess( inner.next().unwrap().as_str().parse().unwrap_or(255_u8),
Ok(inner.next().unwrap().as_str().parse().unwrap_or(255_u8)) inner.next().map(Generics::try_from).transpose()?,
as AstResult<'_, 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(); let mut pi = p.into_inner();
Ok(( Ok((
Identifier::try_from(pi.next().unwrap())?, Identifier::try_from(pi.next().unwrap())?,
pi.next().map(Expression::try_from).transpose().get()?, pi.next().map(Expression::try_from).transpose()?,
)) ))
}))), })?)),
Rule::index_px => { Rule::index_px => Ok(Postfix::Index(Expression::try_from(inner.next().unwrap())?)),
ast_expr!(Postfix::Index(Expression::try_from(inner.next().unwrap())))
}
Rule::macro_call_paren => Ok(Postfix::MacroCall { Rule::macro_call_paren => Ok(Postfix::MacroCall {
inner: inner.as_str().to_string(), inner: inner.as_str().to_string(),
@@ -178,9 +163,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
delimiter: MacroDelimiter::Brace, delimiter: MacroDelimiter::Brace,
}), }),
Rule::as_px => { Rule::as_px => Ok(Postfix::As(inner.next().unwrap().try_into()?)),
ast_expr!(Postfix::As(inner.next().unwrap().try_into()))
}
Rule::try_px => Ok(Postfix::Try), 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::expr_path => { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::expr_path_segment => { ast_ensure!(pair, Rule::expr_path_segment => {
ast_expr!(ExprPathSegment { Ok(ExprPathSegment {
ident: Identifier::try_from(inner.next().unwrap()), ident: Identifier::try_from(inner.next().unwrap())?,
generics: inner.next().map(Generics::try_from).transpose(), generics: inner.next().map(Generics::try_from).transpose()?,
}) })
}) })
} }
+27 -28
View File
@@ -6,13 +6,13 @@ pub mod types;
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure,
error::{AstError, AstResult, IntoErr, collect_recovered, collect_recovered_map}, error::{AstError, collect_recovered, collect_recovered_map},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::identifier => { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { 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), _ => AstError::bug_unimplemented(pair),
} }
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Literal { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); 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::float => Literal::Float(pair.as_str().parse::<f64>().unwrap()),
Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()), Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()),
Rule::string_lit => Literal::String(inner.as_str().to_string()), 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), _ => return AstError::bug_unimplemented(pair),
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Pattern { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { 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) Self::try_from(v).map(Box::new)
}))), })?)),
Rule::named_tuple_pattern => ast_expr!(Pattern::NamedTuple( Rule::named_tuple_pattern => Ok(Pattern::NamedTuple(
Path::try_from(inner.next().unwrap()), Path::try_from(inner.next().unwrap())?,
collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)), collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new))?,
)), )),
Rule::struct_pattern => ast_expr!(Pattern::Struct( Rule::struct_pattern => Ok(Pattern::Struct(
Path::try_from(inner.next().unwrap()), Path::try_from(inner.next().unwrap())?,
collect_recovered_map(inner, |v| { collect_recovered_map(inner, |v| {
if v.as_rule() == Rule::etc_pattern { if v.as_rule() == Rule::etc_pattern {
return Ok(None); return Ok(None);
} }
let mut inner = v.into_inner(); let mut inner = v.into_inner();
Some(ast_expr!(( Ok(Some((
Identifier::try_from(inner.next().unwrap()), Identifier::try_from(inner.next().unwrap())?,
inner inner
.next() .next()
.map(|v| Self::try_from(v).map(Box::new).get_map(Box::new)) .map(|v| Self::try_from(v).map(Box::new))
.transpose() .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( Rule::path_pattern => Ok(Pattern::Path(
Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>, listen_rule(&mut inner, Rule::mutable),
inner.next().unwrap().try_into() inner.next().unwrap().try_into()?,
)), )),
Rule::etc_pattern => Ok(Pattern::Etc), 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 { 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> { fn try_from(pairs: &mut pest::iterators::Pairs<'a, Rule>) -> Result<Self, Self::Error> {
Ok(consume_rule(pairs, Rule::visibility) 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() { if let Some(path) = pair.into_inner().next() {
ast_expr!(Visibility::PublicTarget(Path::try_from(path))) Ok(Visibility::PublicTarget(Path::try_from(path)?))
} else { } else {
Ok(Visibility::Public) Ok(Visibility::Public)
} }
+42 -46
View File
@@ -1,42 +1,42 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, collect_recovered},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::block => { ast_ensure!(pair, Rule::block => {
ast_expr!(Block { Ok(Block {
statements: collect_recovered(inner.next().unwrap().into_inner()), statements: collect_recovered(inner.next().unwrap().into_inner())?,
soft_return: inner.next().map(Spanned::try_from).transpose(), soft_return: inner.next().map(Spanned::try_from).transpose()?,
}) })
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::statement_branch => { ast_ensure!(pair, Rule::statement_branch => {
ast_expr!(StatementBranch { Ok(StatementBranch {
condition: inner.next().unwrap().try_into(), condition: inner.next().unwrap().try_into()?,
body: inner.next().unwrap().try_into().map(Box::new), body: Box::new(inner.next().unwrap().try_into()?),
}) })
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); 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()) 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 => { Rule::return_stmt => Ok(Statement::Return(
ast_expr!(Statement::Return( inner.next().map(Expression::try_from).transpose()?,
inner.next().map(Expression::try_from).transpose() )),
))
}
Rule::break_stmt => Ok(Statement::Break), Rule::break_stmt => Ok(Statement::Break),
Rule::continue_stmt => Ok(Statement::Continue), Rule::continue_stmt => Ok(Statement::Continue),
Rule::if_stmt => { Rule::if_stmt => Ok(Statement::If {
ast_expr!(Statement::If { initial: inner.next().unwrap().try_into()?,
initial: inner.next().unwrap().try_into(), else_if: collect_recovered(inner.next().unwrap().into_inner())?,
else_if: collect_recovered(inner.next().unwrap().into_inner()), else_branch: inner.next().map(Block::try_from).transpose()?,
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::for_stmt => ast_expr!(Statement::For { Rule::while_stmt => Ok(Statement::While(inner.next().unwrap().try_into()?)),
pattern: inner.next().unwrap().try_into(),
iterator: inner.next().unwrap().try_into(), Rule::loop_stmt => Ok(Statement::Loop(inner.next().unwrap().try_into()?)),
body: 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( Rule::for_stmt => Ok(Statement::For {
inner.next().unwrap().try_into(), pattern: inner.next().unwrap().try_into()?,
collect_recovered(inner), 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), _ => 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut match_inner = pair.into_inner(); let mut match_inner = pair.into_inner();
Ok(MatchItem( Ok(MatchItem(
collect_recovered(match_inner.next().unwrap().into_inner()).get()?, collect_recovered(match_inner.next().unwrap().into_inner())?,
Expression::try_from(match_inner.next().unwrap()).get()?, Expression::try_from(match_inner.next().unwrap())?,
)) ))
} }
} }
+28 -33
View File
@@ -1,13 +1,13 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, collect_recovered},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); 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) lifetime: consume_rule(&mut ref_inner, Rule::ref_lifetime)
.map(|v| v.into_inner().next().map(Lifetime::try_from)) .map(|v| v.into_inner().next().map(Lifetime::try_from))
.unwrap_or_default() .unwrap_or_default()
.transpose() .transpose()?,
.get()?,
mutable: listen_rule(&mut ref_inner, Rule::mutable), mutable: listen_rule(&mut ref_inner, Rule::mutable),
ty: Box::new(ty), ty: Box::new(ty),
}; };
@@ -36,21 +35,17 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
Ok(ty) 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::tuple_type => Ok(TypeExpr::Tuple(collect_recovered(inner)?)),
Rule::path_type => { Rule::path_type => Ok(TypeExpr::Path(
ast_expr!(TypeExpr::Path( Path::try_from(inner.next().unwrap())?,
Path::try_from(inner.next().unwrap()), inner.next().map(Generics::try_from).transpose()?,
inner.next().map(Generics::try_from).transpose() )),
))
}
Rule::dyn_type => { Rule::dyn_type => Ok(TypeExpr::Dyn(
ast_expr!(TypeExpr::Dyn( TypeExpr::try_from(inner.next().unwrap()).map(Box::new)?,
TypeExpr::try_from(inner.next().unwrap()).map(Box::new), )),
))
}
_ => AstError::bug_unimplemented(pair), _ => 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let inner = pair.clone().into_inner(); let inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generics_decl => { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generic_decl => { ast_ensure!(pair, Rule::generic_decl => {
if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) { if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
ast_expr!(GenericDecl::Lifetime( Ok(GenericDecl::Lifetime(
pair.into_inner().next().unwrap().try_into(), pair.into_inner().next().unwrap().try_into()?,
)) ))
} else { } else {
ast_expr!(GenericDecl::Type( Ok(GenericDecl::Type(
inner.next().unwrap().try_into(), inner.next().unwrap().try_into()?,
collect_recovered(inner), 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let inner = pair.clone().into_inner(); let inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generics => { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::generic => { ast_ensure!(pair, Rule::generic => {
if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) { if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
ast_expr!(Generic::Lifetime( Ok(Generic::Lifetime(
pair.into_inner().next().unwrap().try_into(), pair.into_inner().next().unwrap().try_into()?,
)) ))
} else { } else {
ast_expr!(Generic::Type( Ok(Generic::Type(
inner.next().unwrap().try_into() inner.next().unwrap().try_into()?
)) ))
} }
}) })
+5 -5
View File
@@ -1,11 +1,11 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, collect_recovered},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() { match pair.as_rule() {
@@ -18,7 +18,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
// first item is always the path // first item is always the path
let path = inner.next().unwrap().try_into().get()?; let path = inner.next().unwrap().try_into()?;
// check what comes next // check what comes next
match inner.next() { match inner.next() {
@@ -32,7 +32,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
// #[path = literal] // #[path = literal]
Ok(Attribute::NameValue { Ok(Attribute::NameValue {
path, path,
value: next.try_into().get()?, value: next.try_into()?,
}) })
} }
@@ -40,7 +40,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
// #[path(...)] // #[path(...)]
Ok(Attribute::List { Ok(Attribute::List {
path, path,
items: collect_recovered(next.into_inner()).get()?, items: collect_recovered(next.into_inner())?,
}) })
} }
+9 -18
View File
@@ -1,48 +1,39 @@
use crate::{ use crate::{Rule, ast::*, error::AstError, parser::consume_rule};
Rule,
ast::*,
error::{AstError, IntoErr},
parser::consume_rule,
};
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassConstructor { 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> { 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();
Ok(Self { Ok(Self {
visibility: Visibility::try_from(&mut inner).get()?, visibility: Visibility::try_from(&mut inner)?,
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()?
.get()?
.unwrap_or_default(), .unwrap_or_default(),
params: consume_rule(&mut inner, Rule::param_list) params: consume_rule(&mut inner, Rule::param_list)
.map(ParamList::try_from) .map(ParamList::try_from)
.transpose() .transpose()?
.get()?
.unwrap_or_default(), .unwrap_or_default(),
body: inner.next().unwrap().try_into().get()?, body: inner.next().unwrap().try_into()?,
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassItem { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
match rule { match rule {
Rule::impl_decl | Rule::impl_for_decl => { Rule::impl_decl | Rule::impl_for_decl => Ok(ClassItem::ImplDecl(pair.try_into()?)),
Ok(ClassItem::ImplDecl(pair.try_into().get()?))
}
Rule::function_decl => Ok(ClassItem::Method(pair.try_into().get()?)), Rule::function_decl => Ok(ClassItem::Method(pair.try_into()?)),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
+8 -9
View File
@@ -1,31 +1,30 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, collect_recovered},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for EnumItem { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::enum_named => Ok(EnumItem::Named(inner.next().unwrap().try_into().get()?)), Rule::enum_named => Ok(EnumItem::Named(inner.next().unwrap().try_into()?)),
Rule::enum_tuple => Ok(EnumItem::Tuple( Rule::enum_tuple => Ok(EnumItem::Tuple(
inner.next().unwrap().try_into().get()?, inner.next().unwrap().try_into()?,
collect_recovered(inner.next().unwrap().into_inner()).get()?, collect_recovered(inner.next().unwrap().into_inner())?,
)), )),
Rule::enum_struct => Ok(EnumItem::Struct( Rule::enum_struct => Ok(EnumItem::Struct(
inner.next().unwrap().try_into().get()?, inner.next().unwrap().try_into()?,
inner inner
.next() .next()
.map(|pair| collect_recovered::<FieldDecl, FieldDecl>(pair.into_inner())) .map(|pair| collect_recovered::<FieldDecl>(pair.into_inner()))
.transpose() .transpose()?
.get()?
.unwrap_or_default(), .unwrap_or_default(),
)), )),
+15 -15
View File
@@ -1,29 +1,29 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure,
error::{self, AstError, AstResult, IntoErr}, error::{self, AstError, AstResult},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::function_decl => { ast_ensure!(pair, Rule::function_decl => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let visibility = Visibility::try_from(&mut inner); let visibility = Visibility::try_from(&mut inner)?;
let return_type = consume_rule(&mut inner, Rule::type_expr) let return_type = consume_rule(&mut inner, Rule::type_expr)
.map(TypeExpr::try_from) .map(TypeExpr::try_from)
.transpose(); .transpose()?;
let name = Identifier::try_from(inner.next().unwrap()); let name = Identifier::try_from(inner.next().unwrap())?;
let generics = consume_rule(&mut inner, Rule::generics_decl) let generics = consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.map(|v| v.unwrap_or_default()); .map(|v| v.unwrap_or_default())?;
let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| { let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
let mut param_inner = param.into_inner(); let mut param_inner = param.into_inner();
@@ -61,13 +61,13 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
Ok(params) Ok(params)
} }
}) })
.unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect()))); .unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())))?;
let is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose(); let is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose()?;
let body = inner.next().map(Block::try_from).transpose(); let body = inner.next().map(Block::try_from).transpose()?;
ast_expr!(Self { Ok(Self {
visibility: visibility, visibility: visibility,
is_override: is_override, is_override: is_override,
return_type: return_type, 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::override_kw => { 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 { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match pair.as_rule() { match pair.as_rule() {
Rule::ref_lifetime => inner.next().unwrap().try_into(), 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), Rule::unsafe_kw => Ok(Lifetime::Unsafe),
_ => error::AstError::bug_unimplemented(pair), _ => error::AstError::bug_unimplemented(pair),
} }
+9 -11
View File
@@ -1,12 +1,12 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, collect_recovered},
parser::consume_rule, parser::consume_rule,
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
@@ -16,23 +16,21 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl {
Rule::impl_for_decl => Ok(ImplDecl { Rule::impl_for_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()?
.get()?
.unwrap_or_default(), .unwrap_or_default(),
trait_: Some(inner.next().unwrap().try_into().get()?), trait_: Some(inner.next().unwrap().try_into()?),
target: inner.next().unwrap().try_into().get()?, target: inner.next().unwrap().try_into()?,
methods: collect_recovered(inner).get()?, methods: collect_recovered(inner)?,
}), }),
Rule::impl_decl => Ok(ImplDecl { Rule::impl_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()?
.get()?
.unwrap_or_default(), .unwrap_or_default(),
trait_: None, trait_: None,
target: inner.next().unwrap().try_into().get()?, target: inner.next().unwrap().try_into()?,
methods: collect_recovered(inner).get()?, methods: collect_recovered(inner)?,
}), }),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
+38 -41
View File
@@ -7,122 +7,119 @@ pub mod impl_decl;
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_expr, error::{AstError, collect_recovered},
error::{AstError, IntoErr, collect_recovered},
parser::consume_rule, parser::consume_rule,
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevel { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
let attributes = collect_recovered(inner.next().unwrap().into_inner()); let attributes = collect_recovered(inner.next().unwrap().into_inner())?;
ast_expr!(TopLevel( Ok(TopLevel(
inner inner
.next() .next()
.map(Spanned::try_from) .map(Spanned::try_from)
.unwrap_or_else(move || Ok(Spanned::new_pair(pair, TopLevelKind::ModAttribute))), .unwrap_or_else(move || Ok(Spanned::new_pair(pair, TopLevelKind::ModAttribute)))?,
attributes, attributes,
)) ))
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind { 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let rule = pair.as_rule(); let rule = pair.as_rule();
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::import => ast_expr!(TopLevelKind::Import( Rule::import => Ok(TopLevelKind::Import(
Visibility::try_from(&mut inner), Visibility::try_from(&mut inner)?,
Path::try_from(inner.next().unwrap()), 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), visibility: Visibility::try_from(&mut inner)?,
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into()?,
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .map(|v| v.unwrap_or_default())?,
fields: inner fields: inner
.next() .next()
.map(|pair| collect_recovered(pair.into_inner())) .map(|pair| collect_recovered(pair.into_inner()))
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .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), visibility: Visibility::try_from(&mut inner)?,
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into()?,
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .map(|v| v.unwrap_or_default())?,
inherits: consume_rule(&mut inner, Rule::expr_path) inherits: consume_rule(&mut inner, Rule::expr_path)
.map(ExprPath::try_from) .map(ExprPath::try_from)
.transpose(), .transpose()?,
fields: collect_recovered(inner.next().unwrap().into_inner()), fields: collect_recovered(inner.next().unwrap().into_inner())?,
constructor: consume_rule(&mut inner, Rule::class_constructor) constructor: consume_rule(&mut inner, Rule::class_constructor)
.map(Spanned::try_from) .map(Spanned::try_from)
.transpose(), .transpose()?,
items: collect_recovered(inner), items: collect_recovered(inner)?,
}), }),
Rule::enum_decl => ast_expr!(TopLevelKind::EnumDecl { Rule::enum_decl => Ok(TopLevelKind::EnumDecl {
visibility: Visibility::try_from(&mut inner), visibility: Visibility::try_from(&mut inner)?,
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into()?,
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .map(|v| v.unwrap_or_default())?,
fields: collect_recovered(inner), fields: collect_recovered(inner)?,
}), }),
Rule::declare_module => ast_expr!(TopLevelKind::DeclareModule( Rule::declare_module => Ok(TopLevelKind::DeclareModule(
Visibility::try_from(&mut inner), Visibility::try_from(&mut inner)?,
inner.next().unwrap().try_into(), inner.next().unwrap().try_into()?,
)), )),
Rule::impl_for_decl | Rule::impl_decl => { Rule::impl_for_decl | Rule::impl_decl => Ok(TopLevelKind::ImplDecl(pair.try_into()?)),
ast_expr!(TopLevelKind::ImplDecl(pair.try_into()))
}
Rule::trait_decl => ast_expr!(TopLevelKind::TraitDecl { Rule::trait_decl => Ok(TopLevelKind::TraitDecl {
visibility: Visibility::try_from(&mut inner), visibility: Visibility::try_from(&mut inner)?,
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into()?,
generics: consume_rule(&mut inner, Rule::generics_decl) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .map(|v| v.unwrap_or_default())?,
requirements: consume_rule(&mut inner, Rule::trait_requirements) requirements: consume_rule(&mut inner, Rule::trait_requirements)
.map(|pair| collect_recovered(pair.into_inner())) .map(|pair| collect_recovered(pair.into_inner()))
.transpose() .transpose()
.map(|v| v.unwrap_or_default()), .map(|v| v.unwrap_or_default())?,
items: collect_recovered(&mut inner), items: collect_recovered(&mut inner)?,
}), }),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
+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> 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> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let span = pair.as_span().start_pos().line_col(); 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 { Ok(Self {
line: span.0, line: span.0,
column: span.1, column: span.1,
item: pair.try_into().map_err(|err: AstError<'_, T>| AstError { item: pair.try_into()?,
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,
}),
})?,
}) })
} }
} }