From 0955bca5bc0a410840430a8afb89f29522d2999e Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Fri, 5 Jun 2026 12:14:19 +0200 Subject: [PATCH] Updated closures --- crates/codegen/src/expr.rs | 45 +++++++++++++++---------- crates/parser/src/ast/expr.rs | 6 +++- crates/parser/src/grammar.pest | 7 ++-- crates/parser/src/parser/common/expr.rs | 20 +++++------ 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index 8cdbaca..fc4f41d 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -101,6 +101,32 @@ impl GenRust for Expression { cg.add(op); rhs.gen_rust(ctx, cg); } + + Expression::Closure { + return_type, + params, + body, + } => { + cg.add("|"); + for (i, arg) in params.iter().enumerate() { + if i > 0 { + cg.add(", "); + } + + arg.gen_rust(ctx, cg); + } + cg.add("| "); + + if let Some(ty) = return_type { + cg.add("-> "); + cg.add(&ty.get_rust()); + cg.add(" "); + + cg.ensure_brackets_expr(ctx, body); + } else { + body.gen_rust(ctx, cg); + } + } } if ensure_semicolon { @@ -114,30 +140,13 @@ impl GenRust for Expression { } impl GenRust for Prefix { - fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { + fn gen_rust(&self, _ctx: &mut Context, cg: &mut RustCodegen) { match self { Self::Deref => cg.add("*"), Self::Ref => cg.add("&"), Self::RefMut => cg.add("&mut "), Self::Not => cg.add("!"), Self::Neg => cg.add("-"), - Self::Closure(ty, args) => { - cg.add("|"); - for (i, arg) in args.iter().enumerate() { - if i > 0 { - cg.add(", "); - } - - arg.gen_rust(ctx, cg); - } - cg.add("| "); - - if let Some(ty) = ty { - cg.add("-> "); - cg.add(&ty.get_rust()); - cg.add(" "); - } - } } } } diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 969cf21..2f91ece 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -7,6 +7,11 @@ pub enum Expression { Literal(Literal), Path(ExprPath), Statement(Box), + Closure { + return_type: Option, + params: Vec, + body: Box, + }, Fix { initial: Box, prefixes: Vec, @@ -72,7 +77,6 @@ pub enum Prefix { Deref, Not, Neg, - Closure(Option, Vec), } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index e4f748d..ab6daaf 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -30,6 +30,7 @@ keyword = { | "false" | "dyn" | "loop" + | "fn" } identifier = @{ @@ -448,7 +449,7 @@ match_stmt = { // CLOSURES // ------------------------------------------------------ -closure = { type_expr? ~ "|" ~ param_list ~ "|" } +closure = { type_expr? ~ "fn" ~ "(" ~ param_list ~ ")" ~ expr } // ------------------------------------------------------ // TUPLES & ARRAYS @@ -490,6 +491,7 @@ expr_path = { primary = { control_flow + | closure | basic_stmt | literal | expr_path @@ -571,8 +573,7 @@ not_px = { "!" } neg_px = { "-" } prefix = { - closure - | deref_px + deref_px | mut_ref_px | ref_px | not_px diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index b3236d8..3834f1d 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -75,6 +75,16 @@ impl<'a> TryFrom> for Expression { )) } + Rule::closure => { + ast_expr!(Self::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::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())), @@ -108,16 +118,6 @@ impl<'a> TryFrom> for Prefix { Rule::ref_px => Self::Ref, Rule::not_px => Self::Not, Rule::neg_px => Self::Neg, - Rule::closure => { - let mut inner = pair.into_inner(); - - return ast_expr!(Self::Closure( - consume_rule(&mut inner, Rule::type_expr) - .map(TypeExpr::try_from) - .transpose(), - collect_recovered(inner.next().unwrap().into_inner()) - )); - } _ => return AstError::bug_unimplemented(pair), })