diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index 2b51f26..c6fa873 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -85,7 +85,7 @@ impl GenRust for Expression { prefixes, postfixes, } => { - cg.add(&prefixes.get_rust()); + prefixes.gen_rust(ctx, cg); initial.gen_rust(ctx, cg); cg.add(&Some(prefixes).get_rust()); for postfix in postfixes { @@ -110,23 +110,41 @@ impl GenRust for Expression { } } -impl GetRust for Prefix { - fn get_rust(&self) -> String { +impl GenRust for Prefix { + fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { - Self::Deref => "*", - Self::Ref => "&", - Self::RefMut => "&mut ", - Self::Not => "!", - Self::New(_) => "", - Self::Neg => "-", + Self::Deref => cg.add("*"), + Self::Ref => cg.add("&"), + Self::RefMut => cg.add("&mut "), + Self::Not => cg.add("!"), + Self::New(_) => 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(" "); + } + } } - .to_string() } } -impl GetRust for Vec { - fn get_rust(&self) -> String { - self.into_iter().map(Prefix::get_rust).collect() +impl GenRust for Vec { + fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { + for prefix in self { + prefix.gen_rust(ctx, cg); + } } } diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 75583e0..1c6eb6b 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -62,6 +62,7 @@ pub enum Prefix { New(Option), Not, Neg, + Closure(Option, Vec), } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 5a87ca1..94803f2 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -436,6 +436,12 @@ match_stmt = { // EXPRESSIONS // ====================================================== +// ------------------------------------------------------ +// CLOSURES +// ------------------------------------------------------ + +closure = { type_expr? ~ "|" ~ param_list ~ "|" } + // ------------------------------------------------------ // TUPLES & ARRAYS // ------------------------------------------------------ @@ -549,7 +555,8 @@ not_px = { "!" } neg_px = { "-" } prefix = { - deref_px + closure + | deref_px | mut_ref_px | ref_px | new_px diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index de33878..feb1e24 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -3,6 +3,7 @@ use crate::{ ast::*, ast_ensure, ast_expr, error::{AstError, AstResult, GetLength, IntoErr, collect_recovered, collect_recovered_map}, + parser::consume_rule, }; use pest::pratt_parser::PrattParser; use std::sync::OnceLock; @@ -104,6 +105,16 @@ impl<'a> TryFrom> for Prefix { ), 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), }) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 3729e97..d0e58d0 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -9,4 +9,8 @@ void main() { app_instance.boot(); app_instance.run(); -} \ No newline at end of file +} + +void do_stuff() { + vec!(1, 2, 3).into_iter().map(Option |var v| {Some(v)}).collect::>(); +}