Merge pull request #87 from mist-go/rm-err-recovery
Remove: Error recovery
This commit is contained in:
@@ -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>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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,22 +20,18 @@ 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) => {
|
|
||||||
let (mod_attributes, items): (Vec<_>, Vec<_>) = v
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
|
.partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute));
|
||||||
|
|
||||||
@@ -44,21 +40,10 @@ pub fn parse<'a>(source: &'a str) -> Result<Program, ParseError<'a, Vec<TopLevel
|
|||||||
mod_attributes,
|
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)::+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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())?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: Expression::try_from(inner.next().unwrap()).map(Box::new),
|
body: Box::new(Expression::try_from(inner.next().unwrap())?),
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
|
|
||||||
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()?,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()?
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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())?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}),
|
|
||||||
})?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user