From 2549535e4badc35a188c3c17b995548b735ac878 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 25 Jun 2026 19:47:07 +0200 Subject: [PATCH] Updated codegen for class decl --- crates/codegen/src/class_decl.rs | 53 ++++++++++++++++++----------- crates/parser/src/ast/top_level.rs | 15 -------- crates/parser/src/semantics.rs | 2 +- mist-test/src/items/class_test.mist | 2 +- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index cf773b0..ce0fd09 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -51,7 +51,7 @@ impl ClassProcessedData { if matches!(method.item.visibility, Visibility::Public) { match &method.item.is_override { None => { - if method.item.is_using_self() { + if method.item.self_param.is_some() { v_table.push(method.item.name.clone()); } } @@ -263,7 +263,7 @@ impl ClassProcessedData { continue; } - if let TypeExpr::Ref { mutable, .. } = params.remove(0) { + if let Some((_, _, mutable)) = &method.item.self_param { method.gen_span(cg); cg.add_indented(&format!("{}::__m_", target_rust_path)); cg.add(&method.item.name.get_rust()); @@ -273,7 +273,7 @@ impl ClassProcessedData { 0, TypeExpr::Ref { lifetime: None, - mutable, + mutable: *mutable, ty: Box::new(get_type_from_path(&target_path)), }, ); @@ -396,7 +396,7 @@ impl ClassProcessedData { for method in &self.methods { match method.item.visibility { Visibility::Public => { - if method.item.is_using_self() { + if method.item.self_param.is_some() { if method.item.is_override.is_none() { gen_method_point(&method.item, ctx, cg); } @@ -500,12 +500,32 @@ fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern { } pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustCodegen) { - cg.add_indented(&format!( - "{}fn {}{}(", - method.visibility.get_rust(), - method.name.get_rust(), - method.generics.get_rust(), - )); + let mutable_self = if let Some((is_ref, lifetime, is_mut)) = &method.self_param { + cg.add_indented(&format!( + "{}fn {}{}(", + method.visibility.get_rust(), + method.name.get_rust(), + method.generics.get_rust(), + )); + + if *is_ref { + cg.add("&"); + } + + if let Some(lifetime) = lifetime { + cg.add(&format!("'{} ", lifetime.0)); + } + + if *is_mut { + cg.add("mut "); + } + + cg.add("self,"); + + *is_mut + } else { + panic!(); + }; let params = method .params @@ -553,14 +573,10 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC .filter_map(|v| v.type_) .collect(); - let TypeExpr::Ref { mutable, .. } = param_types.remove(0) else { - panic!("") - }; - param_types.insert( 0, TypeExpr::UnsafePtr { - mutable, + mutable: mutable_self, ty: Box::new(TypeExpr::Path( Path(vec![ Identifier(String::from("std")), @@ -575,16 +591,13 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.add(&TypeExpr::StaticFn(param_types, method.return_type.clone().map(Box::new)).get_rust()); cg.addln(" = std::mem::transmute(func_ptr);"); - if mutable { + if mutable_self { cg.add_indented("func(self as *mut Self as *const std::ffi::c_void"); } else { cg.add_indented("func(self as *const Self as *const std::ffi::c_void"); } - for (i, param) in ¶ms { - if *i == 0 { - continue; // self already fulfills it - } + for (_, param) in ¶ms { cg.add(", "); ctx.expr_ensure_semicolon = false; param.name.gen_rust(ctx, cg); diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index a93fcaf..d7d58ad 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -126,18 +126,3 @@ pub struct FieldDeclStmt { pub decl: FieldDecl, pub init: Option, } - -impl FunctionDecl { - pub fn is_using_self(&self) -> bool { - match self.params.0.get(0) { - Some(VarDecl { name, .. }) => { - if let Pattern::Path(_, v) = name { - v.0.len() == 1 && v.0[0].0 == "self" - } else { - false - } - } - _ => false, - } - } -} diff --git a/crates/parser/src/semantics.rs b/crates/parser/src/semantics.rs index 0b1a9aa..73d5a95 100644 --- a/crates/parser/src/semantics.rs +++ b/crates/parser/src/semantics.rs @@ -22,7 +22,7 @@ pub fn find_function_call<'a>( ) -> Option<&'a Spanned> { items.iter().find_map(|v| { if let ClassItem::Method(m) = v { - if m.item.is_using_self() && &m.item.name == name { + if m.item.self_param.is_some() && &m.item.name == name { Some(m) } else { None diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 1bb6f20..9cd2fd0 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -11,7 +11,7 @@ pub class Animal { "Unknown".to_string() } - pub void test_speak(&self) { + pub void test_speak<'a>(&'a self) { assert_eq!(self.speak(), "Woof!"); }