Fix: Generics decl not working

This commit is contained in:
2026-05-17 19:21:10 +02:00
parent 7fe91b8e36
commit 1d4473906f
5 changed files with 66 additions and 64 deletions
+2 -2
View File
@@ -34,8 +34,8 @@ pub fn parse<'a>(source: &'a str) -> Result<Vec<TopLevel>, ParseError<'a, Vec<To
#[macro_export] #[macro_export]
macro_rules! ast_ensure { macro_rules! ast_ensure {
($pair:expr, $rule:expr => $body:block) => { ($pair:expr, $rule:expr $(, $rules:expr)* => $body:block) => {
if $pair.as_rule() == $rule if $pair.as_rule() == $rule $(|| $pair.as_rule() == $rules)*
$body $body
else { else {
Err(AstError { Err(AstError {
+1 -1
View File
@@ -14,7 +14,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassConstructor {
Ok(Self { Ok(Self {
visibility: Visibility::try_from(&mut inner).get()?, visibility: Visibility::try_from(&mut inner).get()?,
generics: consume_rule(&mut inner, Rule::generics) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.get()? .get()?
+52 -50
View File
@@ -1,7 +1,7 @@
use crate::{ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_expr, ast_ensure, ast_expr,
error::{AstError, AstResult, IntoErr, collect_recovered}, error::{AstError, AstResult, IntoErr, collect_recovered},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
@@ -10,64 +10,66 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
type Error = AstError<'a, Self>; type Error = AstError<'a, Self>;
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, Rule::method, Rule::method_no_body => {
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 = TypeExpr::try_from(inner.next().unwrap()); let return_type = TypeExpr::try_from(inner.next().unwrap());
let name = Identifier::try_from(inner.next().unwrap()); let name = Identifier::try_from(inner.next().unwrap());
let generics = consume_rule(&mut inner, Rule::generics) 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();
let name = Pattern::Id(Identifier(String::from("self"))); let name = Pattern::Id(Identifier(String::from("self")));
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);
VarDecl { VarDecl {
mutable: mutable && !is_ref, mutable: mutable && !is_ref,
name: name.clone(), name: name.clone(),
type_: Some(TypeExpr( type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])), TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),
if is_ref { if is_ref {
vec![if mutable { vec![if mutable {
TypePostfix::RefMut TypePostfix::RefMut
} else {
TypePostfix::Ref
}]
} else { } else {
TypePostfix::Ref Vec::new()
}] },
} else { )),
Vec::new()
},
)),
}
});
let params = consume_rule(&mut inner, Rule::param_list)
.map({
let self_param = self_param.clone();
|params_pair| -> AstResult<'a, ParamList> {
let mut params = ParamList::try_from(params_pair)?;
if let Some(x) = self_param {
params.0.insert(0, x);
}
Ok(params)
} }
});
let params = consume_rule(&mut inner, Rule::param_list)
.map({
let self_param = self_param.clone();
|params_pair| -> AstResult<'a, ParamList> {
let mut params = ParamList::try_from(params_pair)?;
if let Some(x) = self_param {
params.0.insert(0, x);
}
Ok(params)
}
})
.unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())));
let body = inner.next().map(Block::try_from).transpose();
ast_expr!(Self {
visibility: visibility,
return_type: return_type,
name: name,
generics: generics,
params: params,
body: body,
}) })
.unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())));
let body = inner.next().map(Block::try_from).transpose();
ast_expr!(Self {
visibility: visibility,
return_type: return_type,
name: name,
generics: generics,
params: params,
body: body,
}) })
} }
} }
+2 -2
View File
@@ -14,7 +14,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl {
match rule { match rule {
Rule::impl_for_decl => Ok(ImplDecl { Rule::impl_for_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.get()? .get()?
@@ -25,7 +25,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ImplDecl {
}), }),
Rule::impl_decl => Ok(ImplDecl { Rule::impl_decl => Ok(ImplDecl {
generics: consume_rule(&mut inner, Rule::generics) generics: consume_rule(&mut inner, Rule::generics_decl)
.map(GenericsDecl::try_from) .map(GenericsDecl::try_from)
.transpose() .transpose()
.get()? .get()?
+9 -9
View File
@@ -8,7 +8,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_expr, ast_expr,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, AstResult, IntoErr, collect_recovered},
parser::consume_rule, parser::consume_rule,
}; };
@@ -50,7 +50,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into(),
generics: consume_rule(&mut inner, Rule::generics) 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()),
@@ -67,7 +67,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into(),
generics: consume_rule(&mut inner, Rule::generics) 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()),
@@ -84,7 +84,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
name: inner.next().unwrap().try_into(), name: inner.next().unwrap().try_into(),
generics: consume_rule(&mut inner, Rule::generics) 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()),
@@ -101,23 +101,23 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
ast_expr!(TopLevelKind::ImplDecl(pair.try_into())) ast_expr!(TopLevelKind::ImplDecl(pair.try_into()))
} }
Rule::trait_decl => ast_expr!(TopLevelKind::TraitDecl { Rule::trait_decl => dbg!(ast_expr!(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) 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::<TypeExpr, TypeExpr>(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(inner), items: Ok(Vec::new()) as AstResult<'_, Vec<_>>,
}), })),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }