From 76541040c9c2f25674de31819f48ddb12b5ee1d2 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 28 Jun 2026 05:45:13 +0200 Subject: [PATCH] Function types --- crates/codegen/src/fmt/mod.rs | 29 ++++++++++++++++++++++ crates/codegen/src/lib.rs | 31 +++++++++++++++++++++++- crates/parser/src/ast/mod.rs | 14 +++++++++++ crates/parser/src/grammar.pest | 24 +++++++++++++++++- crates/parser/src/parser/common/types.rs | 6 +++++ mist-test/src/main.mist | 2 ++ 6 files changed, 104 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/fmt/mod.rs b/crates/codegen/src/fmt/mod.rs index f549491..0dd8128 100644 --- a/crates/codegen/src/fmt/mod.rs +++ b/crates/codegen/src/fmt/mod.rs @@ -200,10 +200,39 @@ impl GetMist for TypeExpr { Self::Dyn(ty) => { format!("dyn {}", ty.get_mist()) } + Self::Fn { + kind, + return_type, + params, + } => { + format!( + "{} {}({})", + return_type.get_mist(), + kind.get_mist(), + params + .iter() + .map(TypeExpr::get_mist) + .collect::>() + .join(", ") + ) + } } } } +impl GetMist for FnKind { + fn get_mist(&self) -> String { + match self { + Self::Fn => "fn", + Self::UnsafeFn => "unsafe fn", + Self::FnClosure => "Fn", + Self::FnMut => "FnMut", + Self::FnOnce => "FnOnce", + } + .to_string() + } +} + impl GetMist for ExprPath { fn get_mist(&self) -> String { self.0 diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 9919ac3..cd11bf1 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -239,7 +239,6 @@ impl GetRust for TypeExpr { Self::UnsafePtr { mutable, ty } => { let mutable = if *mutable { "mut " } else { "const " }; format!("*{mutable}{}", ty.get_rust()) - } Self::Ref { @@ -262,10 +261,40 @@ impl GetRust for TypeExpr { Self::Dyn(ty) => { format!("dyn {}", ty.get_rust()) } + + Self::Fn { + kind, + return_type, + params, + } => { + format!( + "{} -> {}({})", + kind.get_rust(), + return_type.get_rust(), + params + .iter() + .map(TypeExpr::get_rust) + .collect::>() + .join(", ") + ) + } } } } +impl GetRust for FnKind { + fn get_rust(&self) -> String { + match self { + Self::Fn => "fn", + Self::UnsafeFn => "unsafe fn", + Self::FnClosure => "Fn", + Self::FnMut => "FnMut", + Self::FnOnce => "FnOnce", + } + .to_string() + } +} + impl GenRust for Pattern { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { diff --git a/crates/parser/src/ast/mod.rs b/crates/parser/src/ast/mod.rs index 5c61cb3..429c9c0 100644 --- a/crates/parser/src/ast/mod.rs +++ b/crates/parser/src/ast/mod.rs @@ -17,6 +17,15 @@ pub struct Identifier(pub String); #[derive(Debug, Clone, Serialize, Default)] pub struct ParamList(pub Vec); +#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] +pub enum FnKind { + Fn, + UnsafeFn, + FnClosure, + FnOnce, + FnMut, +} + #[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] pub enum TypeExpr { Ref { @@ -33,6 +42,11 @@ pub enum TypeExpr { StaticFn(Vec, Option>), Tuple(Vec), Lifetime(Identifier), + Fn { + kind: FnKind, + return_type: Box, + params: Vec, + }, } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index ad70449..4cfbbe1 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -111,12 +111,34 @@ ref_type = { mutable? ~ lifetime? ~ "&" } +fn_kind_fn = { "fn" } +fn_kind_unsafe = { "unsafe" ~ "fn" } +fn_kind_closure = { "Fn" } +fn_kind_once = { "FnOnce" } +fn_kind_mut = { "FnMut" } + +fn_kind = _{ + fn_kind_fn + | fn_kind_unsafe + | fn_kind_closure + | fn_kind_once + | fn_kind_mut +} + +fn_type = { + fn_kind ~ "(" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ")" +} + dyn_type = { "dyn" ~ type_expr } +void_type = { + "void" +} + type_expr = { - (path_type | tuple_type | dyn_type) ~ (unsafe_ref_type | ref_type)* + (void_type | path_type | tuple_type | dyn_type) ~ (unsafe_ref_type | ref_type | fn_type)* } lifetime = { diff --git a/crates/parser/src/parser/common/types.rs b/crates/parser/src/parser/common/types.rs index fbca7ea..64b032d 100644 --- a/crates/parser/src/parser/common/types.rs +++ b/crates/parser/src/parser/common/types.rs @@ -42,6 +42,10 @@ impl<'a> TryFrom> for TypeExpr { }; } + Rule::fn_type => { + + } + _ => AstError::bug_unimplemented(ref_pair)?, } } @@ -50,7 +54,9 @@ impl<'a> TryFrom> for TypeExpr { } Rule::lifetime => Ok(TypeExpr::Lifetime(inner.next().unwrap().try_into()?)), + Rule::void_type => Ok(TypeExpr::Tuple(Vec::new())), Rule::tuple_type => Ok(TypeExpr::Tuple(collect_recovered(inner)?)), + Rule::path_type => Ok(TypeExpr::Path( Path::try_from(inner.next().unwrap())?, inner.next().map(Generics::try_from).transpose()?, diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index e5fd2e4..689fc94 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -15,4 +15,6 @@ void main() items::impl_test::run_tests(); items::attribute_test::run_tests(); println!("\x1b[32m\nAll tests passed!\x1b[0m"); + + void fn() hello = () => {}; }