From 7a5e03afd6183e2d5e130276d65647b97c123ee0 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 10:39:41 +0200 Subject: [PATCH] Fixed constructor args --- crates/codegen/src/lib.rs | 8 +++- crates/codegen/src/top_level.rs | 52 +++++++++++++------------- crates/parser/src/ast/expr.rs | 2 +- crates/parser/src/grammar.pest | 6 ++- crates/parser/src/lib.rs | 8 ++++ crates/parser/src/parser/common/mod.rs | 11 +++++- 6 files changed, 57 insertions(+), 30 deletions(-) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 7618ebc..53e70e2 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -248,8 +248,12 @@ impl GenRust for Pattern { Self::Struct(path, inner) => { cg.add(&path.get_rust()); cg.add(" {"); - for pat in inner { - pat.gen_rust(ctx, cg); + for (name, pat) in inner { + cg.add(&name.get_rust()); + if let Some(pat) = pat { + cg.add(": "); + pat.gen_rust(ctx, cg); + } cg.add(","); } cg.add("}"); diff --git a/crates/codegen/src/top_level.rs b/crates/codegen/src/top_level.rs index 8547fa1..79da978 100644 --- a/crates/codegen/src/top_level.rs +++ b/crates/codegen/src/top_level.rs @@ -175,7 +175,27 @@ impl GenRust for (&Vec>, &Spanned) { self.1.item.generics.get_rust() )); - self.1.item.params.gen_rust(ctx, cg); + let params = self + .1 + .item + .params + .0 + .clone() + .into_iter() + .enumerate() + .map(|(idx, mut v)| { + v.name = construct_pattern(&v.name, idx); + (idx, v) + }) + .collect::>(); + + for (i, param) in ¶ms { + if *i > 0 { + cg.add(", "); + } + + param.gen_rust(ctx, cg); + } cg.addln(") -> Self {"); cg.indent += 1; @@ -196,21 +216,13 @@ impl GenRust for (&Vec>, &Spanned) { cg.add_indented(&format!("this.constructor(")); - for (i, param) in self - .1 - .item - .params - .0 - .iter() - .map(|v| expr_pattern(&v.name)) - .enumerate() - { + for (i, param) in params { if i > 0 { cg.add(", "); } ctx.expr_ensure_semicolon = false; - param.gen_rust(ctx, cg); + param.name.gen_rust(ctx, cg); } cg.addln(");"); @@ -246,21 +258,11 @@ impl GenRust for (&Vec>, &Spanned) { } } -pub fn expr_pattern(pat: &Pattern) -> Expression { +fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern { match pat { - Pattern::Literal(v) => Expression::Literal(v.clone()), - Pattern::Path(_, v) => Expression::Path(v.clone().into()), - Pattern::Tuple(items) => Expression::Literal(Literal::Tuple( - items.iter().map(|v| expr_pattern(&v)).collect(), - )), - Pattern::NamedTuple(path, items) => Expression::Fix { - initial: Box::new(Expression::Path(path.clone().into())), - prefixes: Vec::new(), - postfixes: vec![Postfix::Call( - items.iter().map(|v| expr_pattern(&v)).collect(), - )], - }, - Pattern::Struct(_, _) => unimplemented!(), + Pattern::Literal(v) => Pattern::Literal(v.clone()), + Pattern::Path(is_mut, v) => Pattern::Path(*is_mut, v.clone().into()), + _ => Pattern::Path(false, Path(vec![Identifier(format!("_{idx}"))])), } } diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 2146b38..b51e492 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -33,7 +33,7 @@ pub enum Literal { #[derive(Debug, Clone, Serialize)] pub enum Pattern { NamedTuple(Path, Vec>), - Struct(Path, Vec>), + Struct(Path, Vec<(Identifier, Option>)>), Tuple(Vec>), Literal(Literal), Path(bool, Path), diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 9bb6f51..ee78db8 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -146,8 +146,12 @@ named_tuple_pattern = { static_path ~ "[" ~ multi_pat_template ~ "]" } +struct_destruct = { + identifier ~ (":" ~ pattern)? +} + struct_pattern = { - static_path ~ "{" ~ multi_pat_template ~ "}" + static_path ~ "{" ~ (struct_destruct ~ ("," ~ struct_destruct)*)? ~ "}" } path_pattern = { diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 0a4824c..9e89836 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -77,6 +77,14 @@ macro_rules! ast_expr { analyzer.build(v) }}; + (( $($v:expr),* $(,)? )) => {{ + let mut analyzer = $crate::error::AstErrorAnalyzer(None); + + let v = ( $(analyzer.get($v).get()?),* ); + + analyzer.build(v) + }}; + ($($item:ident)::+) => { $($item)::+ }; diff --git a/crates/parser/src/parser/common/mod.rs b/crates/parser/src/parser/common/mod.rs index 59f0866..e626cae 100644 --- a/crates/parser/src/parser/common/mod.rs +++ b/crates/parser/src/parser/common/mod.rs @@ -71,7 +71,16 @@ impl<'a> TryFrom> for Pattern { Rule::struct_pattern => ast_expr!(Pattern::Struct( Path::try_from(inner.next().unwrap()), - collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)), + collect_recovered_map(inner, |v| { + let mut inner = v.into_inner(); + ast_expr!(( + Identifier::try_from(inner.next().unwrap()), + inner + .next() + .map(|v| Self::try_from(v).map(Box::new).get_map(Box::new)) + .transpose() + )) + }), )), Rule::literal => ast_expr!(Pattern::Literal(pair.try_into())),