Updated type parser #65
This commit is contained in:
@@ -2,67 +2,10 @@ use crate::{
|
|||||||
Rule,
|
Rule,
|
||||||
ast::*,
|
ast::*,
|
||||||
ast_ensure, ast_expr,
|
ast_ensure, ast_expr,
|
||||||
error::{AstError, IntoErr, collect_recovered},
|
error::{AstError, AstResult, IntoErr, collect_recovered},
|
||||||
parser::{consume_rule, listen_rule},
|
parser::{consume_rule, listen_rule},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypePostfix {
|
|
||||||
type Error = AstError<'a, Self>;
|
|
||||||
|
|
||||||
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::ref_type => {
|
|
||||||
let mutable = listen_rule(&mut inner, Rule::mutable);
|
|
||||||
let lifetime = consume_rule(&mut inner, Rule::lifetime)
|
|
||||||
.map(|pair| Identifier::try_from(pair.into_inner().next().unwrap()))
|
|
||||||
.transpose()
|
|
||||||
.get()?;
|
|
||||||
|
|
||||||
Ok(if mutable {
|
|
||||||
if let Some(lifetime) = lifetime {
|
|
||||||
TypePostfix::RefMutLifetime(lifetime)
|
|
||||||
} else {
|
|
||||||
TypePostfix::RefMut
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(lifetime) = lifetime {
|
|
||||||
TypePostfix::RefLifetime(lifetime)
|
|
||||||
} else {
|
|
||||||
TypePostfix::Ref
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Rule::dyn_type => Ok(TypePostfix::Dyn),
|
|
||||||
|
|
||||||
_ => AstError::bug_unimplemented(pair),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExprKind {
|
|
||||||
type Error = AstError<'a, Self>;
|
|
||||||
|
|
||||||
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_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))),
|
|
||||||
Rule::path_type => {
|
|
||||||
ast_expr!(TypeExprKind::Path(
|
|
||||||
Path::try_from(inner.next().unwrap()),
|
|
||||||
inner.next().map(Generics::try_from).transpose()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_ => AstError::bug_unimplemented(pair),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, Self>;
|
||||||
|
|
||||||
@@ -72,13 +15,27 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
|
|||||||
|
|
||||||
match rule {
|
match rule {
|
||||||
Rule::generic => Self::try_from(inner.next().unwrap()),
|
Rule::generic => Self::try_from(inner.next().unwrap()),
|
||||||
Rule::type_expr => ast_expr!(TypeExpr(
|
Rule::type_expr => inner.next().unwrap().try_into(),
|
||||||
inner.next().unwrap().try_into(),
|
Rule::lifetime => ast_expr!(TypeExpr::Lifetime(inner.next().unwrap().try_into())),
|
||||||
collect_recovered(inner),
|
|
||||||
)),
|
Rule::tuple_type => ast_expr!(TypeExpr::Tuple(collect_recovered(inner))),
|
||||||
Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
|
Rule::path_type => {
|
||||||
.get_map(TypeExpr::no_px)
|
ast_expr!(TypeExpr::Path(
|
||||||
.map(TypeExpr::no_px),
|
Path::try_from(inner.next().unwrap()),
|
||||||
|
inner.next().map(Generics::try_from).transpose()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule::ref_type => {
|
||||||
|
ast_expr!(TypeExpr::Ref {
|
||||||
|
lifetime: consume_rule(&mut inner, Rule::lifetime)
|
||||||
|
.map(|v| v.into_inner().next().map(Identifier::try_from))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.transpose(),
|
||||||
|
mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<bool>,
|
||||||
|
ty: TypeExpr::try_from(inner.next().unwrap()).map(Box::new),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
_ => AstError::bug_unimplemented(pair),
|
_ => AstError::bug_unimplemented(pair),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,21 +26,15 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
|
|||||||
let mutable = listen_rule(&mut param_inner, Rule::mutable);
|
let mutable = listen_rule(&mut param_inner, Rule::mutable);
|
||||||
let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
|
let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
|
||||||
let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
|
let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
|
||||||
|
let self_ty = TypeExpr::Path(Path(vec![Identifier(String::from("Self"))]), None);
|
||||||
|
|
||||||
VarDecl {
|
VarDecl {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
type_: Some(TypeExpr(
|
type_: Some(if is_ref {
|
||||||
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())]), None),
|
TypeExpr::Ref { lifetime: None, mutable, ty: Box::new(self_ty) }
|
||||||
if is_ref {
|
|
||||||
vec![if mutable {
|
|
||||||
TypePostfix::RefMut
|
|
||||||
} else {
|
} else {
|
||||||
TypePostfix::Ref
|
self_ty
|
||||||
}]
|
}),
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user