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)]
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>),
}
+1 -1
View File
@@ -186,7 +186,7 @@ std::io::Result<bool> is_source_newer(Path& source, Path& output) {
}
pub enum TranspileError<'a> {
Parse(error::ParseError<'a, Vec<mist_parser::ast::TopLevel>>),
Parse(error::ParseError<'a>),
Semantic(Vec<mist_parser::semantics::SemanticError>)
}
+16 -74
View File
@@ -4,20 +4,19 @@ use pest::iterators::Pair;
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)]
pub enum ParseError<'a, T> {
pub enum ParseError<'a> {
PreAst(pest::error::Error<Rule>),
Ast(AstError<'a, T>),
Ast(AstError<'a>),
}
#[derive(Debug, Clone)]
pub struct AstError<'a, T> {
pub struct AstError<'a> {
pub span: pest::Span<'a>,
pub error_code: ErrorCode,
pub error_message: String,
pub recovered: Option<T>,
}
#[derive(Debug, Clone)]
@@ -27,30 +26,21 @@ pub enum ErrorCode {
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 {
Self::PreAst(value)
}
}
impl<'a, T> From<AstError<'a, T>> for ParseError<'a, T> {
fn from(value: AstError<'a, T>) -> Self {
impl<'a> From<AstError<'a>> for ParseError<'a> {
fn from(value: AstError<'a>) -> Self {
Self::Ast(value)
}
}
impl<'a, F> AstError<'a, F> {
pub fn get<T>(self) -> AstError<'a, T> {
AstError {
span: self.span,
error_code: self.error_code,
error_message: self.error_message,
recovered: None,
}
}
impl<'a> AstError<'a> {
#[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();
Err(Self {
@@ -62,7 +52,6 @@ impl<'a, F> AstError<'a, F> {
loc.file(),
loc.line(),
),
recovered: None,
})
}
}
@@ -72,21 +61,6 @@ pub trait IntoErr<T, FA, FR> {
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 {
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>>,
) -> AstResult<'a, Vec<T>, Vec<T>>
) -> AstResult<'a, Vec<T>>
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)
}
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>>,
f: F,
) -> AstResult<'a, Vec<T>, Vec<T>>
) -> AstResult<'a, Vec<T>>
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 last_error: Option<AstError<'a, ET>> = None;
let mut last_error: Option<AstError<'a>> = None;
for pair in pairs {
match f(pair) {
@@ -130,39 +104,7 @@ where
span: ast_err.span,
error_code: ast_err.error_code,
error_message: ast_err.error_message,
recovered: Some(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 crate::error::{IntoErr, ParseError};
use crate::error::ParseError;
#[derive(Parser)]
#[grammar = "./src/grammar.pest"]
@@ -20,45 +20,30 @@ 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
.into_iter()
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
let (mod_attributes, items): (Vec<_>, Vec<_>) = statements
.into_iter()
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
Ok(Program {
items,
mod_attributes,
})
}
Err(e) => {
let rec = e.recovered.clone();
let mut e2 = e.get();
e2.recovered = rec;
Err(ParseError::Ast(e2))
}
}
Ok(Program {
items,
mod_attributes,
})
}
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,49 +74,7 @@ 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,
})
}
};
}
#[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::{
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())?))
}
}
+58 -75
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 {
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),
})
}
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: 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()?
))
}
})
+5 -5
View File
@@ -1,11 +1,11 @@
use crate::{
Rule,
ast::*,
error::{AstError, IntoErr, collect_recovered},
error::{AstError, collect_recovered},
};
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() {
@@ -18,7 +18,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
let mut inner = pair.into_inner();
// 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
match inner.next() {
@@ -32,7 +32,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Attribute {
// #[path = literal]
Ok(Attribute::NameValue {
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(...)]
Ok(Attribute::List {
path,
items: collect_recovered(next.into_inner()).get()?,
items: collect_recovered(next.into_inner())?,
})
}
+9 -18
View File
@@ -1,48 +1,39 @@
use crate::{
Rule,
ast::*,
error::{AstError, IntoErr},
parser::consume_rule,
};
use crate::{Rule, ast::*, error::AstError, parser::consume_rule};
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();
Ok(Self {
visibility: Visibility::try_from(&mut inner).get()?,
visibility: Visibility::try_from(&mut inner)?,
generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from)
.transpose()
.get()?
.transpose()?
.unwrap_or_default(),
params: consume_rule(&mut inner, Rule::param_list)
.map(ParamList::try_from)
.transpose()
.get()?
.transpose()?
.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 {
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();
match rule {
Rule::impl_decl | Rule::impl_for_decl => {
Ok(ClassItem::ImplDecl(pair.try_into().get()?))
}
Rule::impl_decl | Rule::impl_for_decl => Ok(ClassItem::ImplDecl(pair.try_into()?)),
Rule::function_decl => Ok(ClassItem::Method(pair.try_into().get()?)),
Rule::function_decl => Ok(ClassItem::Method(pair.try_into()?)),
_ => AstError::bug_unimplemented(pair),
}
+8 -9
View File
@@ -1,31 +1,30 @@
use crate::{
Rule,
ast::*,
error::{AstError, IntoErr, collect_recovered},
error::{AstError, collect_recovered},
};
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();
let mut inner = pair.clone().into_inner();
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(
inner.next().unwrap().try_into().get()?,
collect_recovered(inner.next().unwrap().into_inner()).get()?,
inner.next().unwrap().try_into()?,
collect_recovered(inner.next().unwrap().into_inner())?,
)),
Rule::enum_struct => Ok(EnumItem::Struct(
inner.next().unwrap().try_into().get()?,
inner.next().unwrap().try_into()?,
inner
.next()
.map(|pair| collect_recovered::<FieldDecl, FieldDecl>(pair.into_inner()))
.transpose()
.get()?
.map(|pair| collect_recovered::<FieldDecl>(pair.into_inner()))
.transpose()?
.unwrap_or_default(),
)),
+15 -15
View File
@@ -1,29 +1,29 @@
use crate::{
Rule,
ast::*,
ast_ensure, ast_expr,
error::{self, AstError, AstResult, IntoErr},
ast_ensure,
error::{self, AstError, AstResult},
parser::{consume_rule, listen_rule},
};
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 => {
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)
.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)
.map(GenericsDecl::try_from)
.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 mut param_inner = param.into_inner();
@@ -61,13 +61,13 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
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,
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),
}
+9 -11
View File
@@ -1,12 +1,12 @@
use crate::{
Rule,
ast::*,
error::{AstError, IntoErr, collect_recovered},
error::{AstError, collect_recovered},
parser::consume_rule,
};
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();
@@ -16,23 +16,21 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl {
Rule::impl_for_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from)
.transpose()
.get()?
.transpose()?
.unwrap_or_default(),
trait_: Some(inner.next().unwrap().try_into().get()?),
target: inner.next().unwrap().try_into().get()?,
methods: collect_recovered(inner).get()?,
trait_: Some(inner.next().unwrap().try_into()?),
target: inner.next().unwrap().try_into()?,
methods: collect_recovered(inner)?,
}),
Rule::impl_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from)
.transpose()
.get()?
.transpose()?
.unwrap_or_default(),
trait_: None,
target: inner.next().unwrap().try_into().get()?,
methods: collect_recovered(inner).get()?,
target: inner.next().unwrap().try_into()?,
methods: collect_recovered(inner)?,
}),
_ => AstError::bug_unimplemented(pair),
+38 -41
View File
@@ -7,122 +7,119 @@ pub mod impl_decl;
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 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());
let attributes = collect_recovered(inner.next().unwrap().into_inner())?;
ast_expr!(TopLevel(
Ok(TopLevel(
inner
.next()
.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,
))
}
}
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(
Visibility::try_from(&mut inner),
Path::try_from(inner.next().unwrap()),
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 {
visibility: Visibility::try_from(&mut inner),
Rule::struct_decl => Ok(TopLevelKind::StructDecl {
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)
.map(GenericsDecl::try_from)
.transpose()
.map(|v| v.unwrap_or_default()),
.map(|v| v.unwrap_or_default())?,
fields: inner
.next()
.map(|pair| collect_recovered(pair.into_inner()))
.transpose()
.map(|v| v.unwrap_or_default()),
.map(|v| v.unwrap_or_default())?,
}),
Rule::class_decl => ast_expr!(TopLevelKind::ClassDecl {
visibility: Visibility::try_from(&mut inner),
Rule::class_decl => Ok(TopLevelKind::ClassDecl {
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)
.map(GenericsDecl::try_from)
.transpose()
.map(|v| v.unwrap_or_default()),
.map(|v| v.unwrap_or_default())?,
inherits: consume_rule(&mut inner, Rule::expr_path)
.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)
.map(Spanned::try_from)
.transpose(),
.transpose()?,
items: collect_recovered(inner),
items: collect_recovered(inner)?,
}),
Rule::enum_decl => ast_expr!(TopLevelKind::EnumDecl {
visibility: Visibility::try_from(&mut inner),
Rule::enum_decl => Ok(TopLevelKind::EnumDecl {
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)
.map(GenericsDecl::try_from)
.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(
Visibility::try_from(&mut inner),
inner.next().unwrap().try_into(),
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 {
visibility: Visibility::try_from(&mut inner),
Rule::trait_decl => Ok(TopLevelKind::TraitDecl {
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)
.map(GenericsDecl::try_from)
.transpose()
.map(|v| v.unwrap_or_default()),
.map(|v| v.unwrap_or_default())?,
requirements: consume_rule(&mut inner, Rule::trait_requirements)
.map(|pair| collect_recovered(pair.into_inner()))
.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),
+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()?,
})
}
}