From eb2552b19a7453dbab4d7ca408dbb063263f343a Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 6 Jun 2026 22:20:32 +0200 Subject: [PATCH 01/17] Separated class decl --- crates/codegen/src/class_decl.rs | 223 +++++++++++++++++++++++++++++++ crates/codegen/src/lib.rs | 1 + crates/codegen/src/top_level.rs | 221 ++---------------------------- 3 files changed, 236 insertions(+), 209 deletions(-) create mode 100644 crates/codegen/src/class_decl.rs diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs new file mode 100644 index 0000000..9a19e0e --- /dev/null +++ b/crates/codegen/src/class_decl.rs @@ -0,0 +1,223 @@ +use mist_parser::ast::*; + +use crate::Context; + +use crate::{GenRust, GetRust, RustCodegen}; + +pub fn class_decl( + ctx: &mut Context, + cg: &mut RustCodegen, + + visibility: &Visibility, + name: &Identifier, + generics: &GenericsDecl, + inherits: &Option, + fields: &Vec>, + constructor: &Spanned, + items: &Vec, +) { + // Struct decl + cg.addln(&format!( + "{}struct {}{} {{", + visibility.get_rust(), + name.clone().get_rust(), + generics.clone().get_rust() + )); + cg.indent += 1; + + if let Some(inherits) = inherits { + cg.add_indented("pub _super: "); + cg.add(&inherits.get_rust()); + cg.addln(","); + } + + for field in fields.clone() { + cg.add_indentedln(&field.get_comment()); + cg.add_indentedln(&field.item.decl.get_rust()); + } + + cg.indent -= 1; + cg.addln("}\n"); + + // Constructor + cg.addln(&format!( + "impl{} {}{} {{", + generics.clone().get_rust(), + name.clone().get_rust(), + format!( + "<{}>", + generics + .clone() + .0 + .into_iter() + .map(|v| Generic::from(v).get_rust()) + .collect::>() + .join(", ") + ) + )); + cg.indent += 1; + + let constructor_comment = constructor.get_comment(); + + cg.add_indentedln("#[allow(invalid_value)]"); + cg.add_indentedln(&constructor_comment); + + (fields, constructor).gen_rust(ctx, cg); + + for item in items.clone() { + match item { + ClassItem::ImplDecl(_) => {} + ClassItem::Method(method) => method.gen_rust(ctx, cg), + } + } + + cg.indent -= 1; + cg.addln("}\n"); + + for item in items { + match item { + ClassItem::ImplDecl(impl_) => { + let mut impl_ = impl_.clone(); + + impl_.item.trait_ = Some(impl_.item.target); + impl_.item.target = TypeExpr::Path(Path(vec![name.clone()]), None); + + impl_.gen_rust(ctx, cg); + } + ClassItem::Method(_) => {} + } + } + + if let Some(inherits) = inherits { + cg.add("impl std::ops::Deref for "); + cg.add(&name.get_rust()); + + cg.addln(" {"); + cg.indent += 1; + + cg.add_indented("type Target = "); + cg.add(&inherits.get_rust()); + cg.addln(";"); + + cg.add_indentedln("fn deref(&self) -> &Self::Target {&self._super}"); + + cg.indent -= 1; + cg.addln("}"); + + // Mut + + cg.add("impl std::ops::DerefMut for "); + cg.add(&name.get_rust()); + + cg.addln(" {"); + cg.indent += 1; + + cg.add_indentedln("fn deref_mut(&mut self) -> &mut Self::Target {&mut self._super}"); + + cg.indent -= 1; + cg.addln("}"); + } +} + +impl GenRust for (&Vec>, &Spanned) { + fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { + cg.add_indented(&format!( + "{}fn new{}(", + self.1.item.visibility.get_rust(), + self.1.item.generics.get_rust() + )); + + 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; + + cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); + + for field in self.0 { + let comment = field.get_comment(); + + if let Some(init) = &field.item.init { + cg.add_indentedln(&comment); + + cg.add_indentedln(&format!("this.{} = ", field.item.decl.name.get_rust())); + + init.gen_rust(ctx, cg); + } + } + + cg.add_indented(&format!("this.constructor(")); + + for (i, param) in params { + if i > 0 { + cg.add(", "); + } + + ctx.expr_ensure_semicolon = false; + param.name.gen_rust(ctx, cg); + } + + cg.addln(");"); + + cg.add_indentedln("this"); + + cg.indent -= 1; + cg.add_indentedln("}\n"); + + let mut constructor_params = vec![VarDecl { + name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), + type_: Some(TypeExpr::Ref { + lifetime: None, + mutable: true, + ty: Box::new(TypeExpr::Path( + Path(vec![Identifier(String::from("Self"))]), + None, + )), + }), + }]; + + constructor_params.append(&mut self.1.item.params.0.clone()); + + Spanned { + line: self.1.line, + column: self.1.column, + item: FunctionDecl { + visibility: self.1.item.visibility.clone(), + name: Identifier(String::from("constructor")), + generics: self.1.item.generics.clone(), + params: ParamList(constructor_params), + return_type: Some(TypeExpr::Tuple(Vec::new())), + body: Some(self.1.item.body.clone()), + }, + } + .gen_rust(ctx, cg); + } +} + +fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern { + match pat { + 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/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 168b0af..2a14d0e 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -1,3 +1,4 @@ +pub mod class_decl; pub mod expr; pub mod statement; pub mod top_level; diff --git a/crates/codegen/src/top_level.rs b/crates/codegen/src/top_level.rs index 94073c5..1b2ff11 100644 --- a/crates/codegen/src/top_level.rs +++ b/crates/codegen/src/top_level.rs @@ -1,6 +1,6 @@ use mist_parser::ast::*; -use crate::Context; +use crate::{Context, class_decl}; use crate::{GenRust, GetRust, RustCodegen}; @@ -170,109 +170,6 @@ impl GenRust for TopLevel { } } -impl GenRust for (&Vec>, &Spanned) { - fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { - cg.add_indented(&format!( - "{}fn new{}(", - self.1.item.visibility.get_rust(), - self.1.item.generics.get_rust() - )); - - 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; - - cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); - - for field in self.0 { - let comment = field.get_comment(); - - if let Some(init) = &field.item.init { - cg.add_indentedln(&comment); - - cg.add_indentedln(&format!("this.{} = ", field.item.decl.name.get_rust())); - - init.gen_rust(ctx, cg); - } - } - - cg.add_indented(&format!("this.constructor(")); - - for (i, param) in params { - if i > 0 { - cg.add(", "); - } - - ctx.expr_ensure_semicolon = false; - param.name.gen_rust(ctx, cg); - } - - cg.addln(");"); - - cg.add_indentedln("this"); - - cg.indent -= 1; - cg.add_indentedln("}\n"); - - let mut constructor_params = vec![VarDecl { - name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), - type_: Some(TypeExpr::Ref { - lifetime: None, - mutable: true, - ty: Box::new(TypeExpr::Path( - Path(vec![Identifier(String::from("Self"))]), - None, - )), - }), - }]; - - constructor_params.append(&mut self.1.item.params.0.clone()); - - Spanned { - line: self.1.line, - column: self.1.column, - item: FunctionDecl { - visibility: self.1.item.visibility.clone(), - name: Identifier(String::from("constructor")), - generics: self.1.item.generics.clone(), - params: ParamList(constructor_params), - return_type: Some(TypeExpr::Tuple(Vec::new())), - body: Some(self.1.item.body.clone()), - }, - } - .gen_rust(ctx, cg); - } -} - -fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern { - match pat { - 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}"))])), - } -} - impl GenRust for TopLevelKind { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { @@ -365,111 +262,17 @@ impl GenRust for TopLevelKind { fields, constructor, items, - } => { - // Struct decl - cg.addln(&format!( - "{}struct {}{} {{", - visibility.get_rust(), - name.clone().get_rust(), - generics.clone().get_rust() - )); - cg.indent += 1; - - if let Some(inherits) = inherits { - cg.add_indented("pub _super: "); - cg.add(&inherits.get_rust()); - cg.addln(","); - } - - for field in fields.clone() { - cg.add_indentedln(&field.get_comment()); - cg.add_indentedln(&field.item.decl.get_rust()); - } - - cg.indent -= 1; - cg.addln("}\n"); - - // Constructor - cg.addln(&format!( - "impl{} {}{} {{", - generics.clone().get_rust(), - name.clone().get_rust(), - format!( - "<{}>", - generics - .clone() - .0 - .into_iter() - .map(|v| Generic::from(v).get_rust()) - .collect::>() - .join(", ") - ) - )); - cg.indent += 1; - - let constructor_comment = constructor.get_comment(); - - cg.add_indentedln("#[allow(invalid_value)]"); - cg.add_indentedln(&constructor_comment); - - (fields, constructor).gen_rust(ctx, cg); - - for item in items.clone() { - match item { - ClassItem::ImplDecl(_) => {} - ClassItem::Method(method) => method.gen_rust(ctx, cg), - } - } - - cg.indent -= 1; - cg.addln("}\n"); - - for item in items { - match item { - ClassItem::ImplDecl(impl_) => { - let mut impl_ = impl_.clone(); - - impl_.item.trait_ = Some(impl_.item.target); - impl_.item.target = TypeExpr::Path(Path(vec![name.clone()]), None); - - impl_.gen_rust(ctx, cg); - } - ClassItem::Method(_) => {} - } - } - - if let Some(inherits) = inherits { - cg.add("impl std::ops::Deref for "); - cg.add(&name.get_rust()); - - cg.addln(" {"); - cg.indent += 1; - - cg.add_indented("type Target = "); - cg.add(&inherits.get_rust()); - cg.addln(";"); - - cg.add_indentedln("fn deref(&self) -> &Self::Target {&self._super}"); - - cg.indent -= 1; - cg.addln("}"); - - // Mut - - cg.add("impl std::ops::DerefMut for "); - cg.add(&name.get_rust()); - - cg.addln(" {"); - cg.indent += 1; - - cg.add_indentedln( - "fn deref_mut(&mut self) -> &mut Self::Target {&mut self._super}", - ); - - cg.indent -= 1; - cg.addln("}"); - } - } + } => class_decl::class_decl( + ctx, + cg, + visibility, + name, + generics, + inherits, + fields, + constructor, + items, + ), } } } From 7229cfd9f556be07f5a3fbb94d5e804d7d300e58 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 6 Jun 2026 23:16:27 +0200 Subject: [PATCH 02/17] VTABLE OOP --- crates/codegen/src/class_decl.rs | 59 +++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 9a19e0e..9909b77 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -25,6 +25,8 @@ pub fn class_decl( )); cg.indent += 1; + cg.add_indentedln("pub _m_oop: (*const *const std::ffi::c_void, *mut std::ffi::c_void),"); + if let Some(inherits) = inherits { cg.add_indented("pub _super: "); cg.add(&inherits.get_rust()); @@ -57,6 +59,48 @@ pub fn class_decl( )); cg.indent += 1; + let methods = items + .clone() + .into_iter() + .filter_map(|item| match item { + ClassItem::ImplDecl(_) => None, + ClassItem::Method(method) => Some(method), + }) + .collect::>(); + + let v_table = methods + .iter() + .filter_map(|method| match method.item.visibility { + Visibility::Public => Some(method.item.name.clone()), + _ => None, + }) + .collect::>(); + + // V TABLE + { + cg.add_indentedln(&format!("pub const __V_COUNT: usize = {};", v_table.len())); + + for (i, method_name) in v_table.iter().enumerate() { + cg.add_indentedln(&format!( + "pub const __FN_{}: usize = {i};", + method_name.0.to_uppercase() + )); + } + + cg.add_indentedln("pub const __V_TABLE: [*const std::ffi::c_void; Self::__V_COUNT] = ["); + cg.indent += 1; + + for method_name in v_table { + cg.add_indented("Self::__m_"); + cg.add(&method_name.get_rust()); + cg.add(" as *const std::ffi::c_void"); + cg.addln(","); + } + + cg.indent -= 1; + cg.add_indentedln("];"); + } + let constructor_comment = constructor.get_comment(); cg.add_indentedln("#[allow(invalid_value)]"); @@ -64,11 +108,18 @@ pub fn class_decl( (fields, constructor).gen_rust(ctx, cg); - for item in items.clone() { - match item { - ClassItem::ImplDecl(_) => {} - ClassItem::Method(method) => method.gen_rust(ctx, cg), + for mut method in methods { + { + let body = method.item.body; + + method.item.body = Some(Block(Vec::new(), None)); + + method.gen_rust(ctx, cg); + method.item.body = body; } + + method.item.name.0.insert_str(0, "__m_"); + method.gen_rust(ctx, cg); } cg.indent -= 1; From 330beaea7575a0963e25f12f9719c53931162203 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 6 Jun 2026 23:50:40 +0200 Subject: [PATCH 03/17] Generating body --- crates/codegen/src/class_decl.rs | 61 +++++++++++++++++++- crates/codegen/src/statement.rs | 8 ++- crates/parser/src/ast/statement.rs | 10 ++-- crates/parser/src/grammar.pest | 4 +- crates/parser/src/parser/common/statement.rs | 9 ++- 5 files changed, 82 insertions(+), 10 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 9909b77..38a30f9 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -112,7 +112,66 @@ pub fn class_decl( { let body = method.item.body; - method.item.body = Some(Block(Vec::new(), None)); + method.item.body = Some(Block { + is_unsafe: false, + statements: Vec::new(), + soft_return: Some(Spanned { + line: 1, + column: 1, + item: Expression::Statement(Box::new(Statement::Block(Block { + is_unsafe: true, + statements: vec![Spanned { + line: 1, + column: 1, + item: Expression::Statement(Box::new(Statement::VarDecl( + VarDeclStmt { + decl: VarDecl { + name: Pattern::Path( + false, + Path(vec![Identifier(String::from("func_ptr"))]), + ), + type_: None, + }, + init: Some(Expression::Fix { + initial: Box::new(Expression::Path(ExprPath(vec![ + ExprPathSegment { + ident: Identifier(String::from("self")), + generics: None, + }, + ]))), + prefixes: vec![Prefix::Deref], + postfixes: vec![ + Postfix::FieldAccess( + Identifier(String::from("_m_oop")), + None, + ), + Postfix::TupleFieldAccess(0, None), + Postfix::FieldAccess( + Identifier(String::from("add")), + None, + ), + Postfix::Call(vec![Expression::Path(ExprPath(vec![ + ExprPathSegment { + ident: Identifier(String::from("Self")), + generics: None, + }, + ExprPathSegment { + ident: Identifier(format!( + "__FN_{}", + method.item.name.0.to_uppercase() + )), + generics: None, + }, + ]))]), + ], + }), + }, + ))), + }], + soft_return: None, + }))), + }), + }); method.gen_rust(ctx, cg); method.item.body = body; diff --git a/crates/codegen/src/statement.rs b/crates/codegen/src/statement.rs index fb2d3aa..601b20b 100644 --- a/crates/codegen/src/statement.rs +++ b/crates/codegen/src/statement.rs @@ -6,16 +6,20 @@ use crate::{GenRust, GetRust, RustCodegen}; impl GenRust for Block { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { + if self.is_unsafe { + cg.add("unsafe "); + } + cg.addln("{"); cg.indent += 1; - for stmt in &self.0 { + for stmt in &self.statements { ctx.expr_ensure_semicolon = true; stmt.gen_rust(ctx, cg); cg.addln(""); } - if let Some(soft_return) = &self.1 { + if let Some(soft_return) = &self.soft_return { ctx.expr_ensure_semicolon = false; soft_return.gen_rust(ctx, cg); cg.addln(""); diff --git a/crates/parser/src/ast/statement.rs b/crates/parser/src/ast/statement.rs index 412e2f0..e9b41a8 100644 --- a/crates/parser/src/ast/statement.rs +++ b/crates/parser/src/ast/statement.rs @@ -3,10 +3,12 @@ use serde::Serialize; use super::*; #[derive(Debug, Clone, Serialize, Default)] -pub struct Block( - pub Vec>, - pub Option>, -); +pub struct Block { + pub is_unsafe: bool, + + pub statements: Vec>, + pub soft_return: Option>, +} #[derive(Debug, Clone, Serialize)] pub enum StatementBody { diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index e4f33fb..e62dc58 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -63,6 +63,8 @@ static_path = { identifier ~ ("::" ~ identifier)* } +unsafe_kw = { "unsafe" } + // ====================================================== // PROGRAM // ====================================================== @@ -340,7 +342,7 @@ top_level = { // ====================================================== block = { - "{" ~ statement_list ~ expr? ~ "}" + unsafe_kw? ~ "{" ~ statement_list ~ expr? ~ "}" } statement_list = { diff --git a/crates/parser/src/parser/common/statement.rs b/crates/parser/src/parser/common/statement.rs index 5ca288e..1947928 100644 --- a/crates/parser/src/parser/common/statement.rs +++ b/crates/parser/src/parser/common/statement.rs @@ -2,7 +2,8 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, IntoErr, collect_recovered}, + error::{AstError, AstResult, IntoErr, collect_recovered}, + parser::listen_rule, }; impl<'a> TryFrom> for Block { @@ -12,7 +13,11 @@ impl<'a> TryFrom> for Block { let mut inner = pair.clone().into_inner(); ast_ensure!(pair, Rule::block => { - ast_expr!(Block(collect_recovered(inner.next().unwrap().into_inner()), inner.next().map(Spanned::try_from).transpose())) + ast_expr!(Block { + is_unsafe: Ok(listen_rule(&mut inner, Rule::unsafe_kw)) as AstResult, + statements: collect_recovered(inner.next().unwrap().into_inner()), + soft_return: inner.next().map(Spanned::try_from).transpose(), + }) }) } } From 5e5d22f3c54f1ede5a1095037b606195c67b9fa9 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sat, 6 Jun 2026 23:52:53 +0200 Subject: [PATCH 04/17] Added static fn type --- crates/codegen/src/lib.rs | 13 ++++++++----- crates/parser/src/ast/mod.rs | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 2a14d0e..b0d79de 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -176,11 +176,6 @@ impl GetRust for Identifier { impl GetRust for TypeExpr { fn get_rust(&self) -> String { match self { - // TypePostfix::Ref => format!("&"), - // TypePostfix::RefMut => format!("&mut "), - // TypePostfix::RefLifetime(lifetime) => format!("&'{} ", lifetime.get_rust()), - // TypePostfix::RefMutLifetime(lifetime) => format!("&'{} mut ", lifetime.get_rust()), - // TypePostfix::Dyn => format!("dyn "), Self::Path(path, generics) => { if let Some(generics) = generics { format!("{}{}", get_static_type_path(path), generics.get_rust()) @@ -197,6 +192,14 @@ impl GetRust for TypeExpr { .collect::>() .join(", ") ), + Self::StaticFn(types) => format!( + "fn({})", + types + .into_iter() + .map(|t| t.get_rust()) + .collect::>() + .join(", ") + ), Self::Ref { lifetime, diff --git a/crates/parser/src/ast/mod.rs b/crates/parser/src/ast/mod.rs index 6a975df..11014a3 100644 --- a/crates/parser/src/ast/mod.rs +++ b/crates/parser/src/ast/mod.rs @@ -26,6 +26,7 @@ pub enum TypeExpr { }, Dyn(Box), Path(Path, Option), + StaticFn(Vec), Tuple(Vec), Lifetime(Identifier), } From 7acef24e09b8b1d3e75aa017ba4f7cc8d6d7deb7 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 00:02:06 +0200 Subject: [PATCH 05/17] Plan for redo --- crates/codegen/src/class_decl.rs | 165 +++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 43 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 38a30f9..6a01d22 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -120,54 +120,133 @@ pub fn class_decl( column: 1, item: Expression::Statement(Box::new(Statement::Block(Block { is_unsafe: true, - statements: vec![Spanned { - line: 1, - column: 1, - item: Expression::Statement(Box::new(Statement::VarDecl( - VarDeclStmt { - decl: VarDecl { - name: Pattern::Path( - false, - Path(vec![Identifier(String::from("func_ptr"))]), - ), - type_: None, + statements: vec![ + Spanned { + line: 1, + column: 1, + item: Expression::Statement(Box::new(Statement::VarDecl( + VarDeclStmt { + decl: VarDecl { + name: Pattern::Path( + false, + Path(vec![Identifier(String::from("func_ptr"))]), + ), + type_: None, + }, + init: Some(Expression::Fix { + initial: Box::new(Expression::Path(ExprPath(vec![ + ExprPathSegment { + ident: Identifier(String::from("self")), + generics: None, + }, + ]))), + prefixes: vec![Prefix::Deref], + postfixes: vec![ + Postfix::FieldAccess( + Identifier(String::from("_m_oop")), + None, + ), + Postfix::TupleFieldAccess(0, None), + Postfix::FieldAccess( + Identifier(String::from("add")), + None, + ), + Postfix::Call(vec![Expression::Path(ExprPath( + vec![ + ExprPathSegment { + ident: Identifier(String::from("Self")), + generics: None, + }, + ExprPathSegment { + ident: Identifier(format!( + "__FN_{}", + method.item.name.0.to_uppercase() + )), + generics: None, + }, + ], + ))]), + ], + }), }, - init: Some(Expression::Fix { - initial: Box::new(Expression::Path(ExprPath(vec![ - ExprPathSegment { - ident: Identifier(String::from("self")), - generics: None, - }, - ]))), - prefixes: vec![Prefix::Deref], - postfixes: vec![ - Postfix::FieldAccess( - Identifier(String::from("_m_oop")), - None, + ))), + }, + Spanned { + line: 1, + column: 1, + item: Expression::Statement(Box::new(Statement::VarDecl( + VarDeclStmt { + decl: VarDecl { + name: Pattern::Path( + false, + Path(vec![Identifier(String::from("func"))]), ), - Postfix::TupleFieldAccess(0, None), - Postfix::FieldAccess( - Identifier(String::from("add")), - None, - ), - Postfix::Call(vec![Expression::Path(ExprPath(vec![ + type_: Some(TypeExpr::StaticFn( + method + .item + .params + .0 + .clone() + .into_iter() + .filter_map(|v| { + Some(match v.type_? { + TypeExpr::Ref { + lifetime, + mutable, + ty, + } => { + + } + + TypeExpr::Path(p, g) => { + if g.is_some() {} + } + + a => a, + }) + }) + .collect(), + )), + }, + init: Some(Expression::Fix { + initial: Box::new(Expression::Path(ExprPath(vec![ ExprPathSegment { - ident: Identifier(String::from("Self")), + ident: Identifier(String::from("self")), generics: None, }, - ExprPathSegment { - ident: Identifier(format!( - "__FN_{}", - method.item.name.0.to_uppercase() - )), - generics: None, - }, - ]))]), - ], - }), - }, - ))), - }], + ]))), + prefixes: vec![Prefix::Deref], + postfixes: vec![ + Postfix::FieldAccess( + Identifier(String::from("_m_oop")), + None, + ), + Postfix::TupleFieldAccess(0, None), + Postfix::FieldAccess( + Identifier(String::from("add")), + None, + ), + Postfix::Call(vec![Expression::Path(ExprPath( + vec![ + ExprPathSegment { + ident: Identifier(String::from("Self")), + generics: None, + }, + ExprPathSegment { + ident: Identifier(format!( + "__FN_{}", + method.item.name.0.to_uppercase() + )), + generics: None, + }, + ], + ))]), + ], + }), + }, + ))), + }, + ], soft_return: None, }))), }), From e7b4e65b71889342462f26157a3471ebe0861b2c Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 00:17:28 +0200 Subject: [PATCH 06/17] Working method point --- crates/codegen/src/class_decl.rs | 211 ++++++++++--------------------- 1 file changed, 66 insertions(+), 145 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 6a01d22..6a63a87 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -109,154 +109,15 @@ pub fn class_decl( (fields, constructor).gen_rust(ctx, cg); for mut method in methods { - { - let body = method.item.body; + match method.item.visibility { + Visibility::Public => { + gen_method_point(&method.item, ctx, cg); - method.item.body = Some(Block { - is_unsafe: false, - statements: Vec::new(), - soft_return: Some(Spanned { - line: 1, - column: 1, - item: Expression::Statement(Box::new(Statement::Block(Block { - is_unsafe: true, - statements: vec![ - Spanned { - line: 1, - column: 1, - item: Expression::Statement(Box::new(Statement::VarDecl( - VarDeclStmt { - decl: VarDecl { - name: Pattern::Path( - false, - Path(vec![Identifier(String::from("func_ptr"))]), - ), - type_: None, - }, - init: Some(Expression::Fix { - initial: Box::new(Expression::Path(ExprPath(vec![ - ExprPathSegment { - ident: Identifier(String::from("self")), - generics: None, - }, - ]))), - prefixes: vec![Prefix::Deref], - postfixes: vec![ - Postfix::FieldAccess( - Identifier(String::from("_m_oop")), - None, - ), - Postfix::TupleFieldAccess(0, None), - Postfix::FieldAccess( - Identifier(String::from("add")), - None, - ), - Postfix::Call(vec![Expression::Path(ExprPath( - vec![ - ExprPathSegment { - ident: Identifier(String::from("Self")), - generics: None, - }, - ExprPathSegment { - ident: Identifier(format!( - "__FN_{}", - method.item.name.0.to_uppercase() - )), - generics: None, - }, - ], - ))]), - ], - }), - }, - ))), - }, - Spanned { - line: 1, - column: 1, - item: Expression::Statement(Box::new(Statement::VarDecl( - VarDeclStmt { - decl: VarDecl { - name: Pattern::Path( - false, - Path(vec![Identifier(String::from("func"))]), - ), - type_: Some(TypeExpr::StaticFn( - method - .item - .params - .0 - .clone() - .into_iter() - .filter_map(|v| { - Some(match v.type_? { - TypeExpr::Ref { - lifetime, - mutable, - ty, - } => { - - } - - TypeExpr::Path(p, g) => { - if g.is_some() {} - } - - a => a, - }) - }) - .collect(), - )), - }, - init: Some(Expression::Fix { - initial: Box::new(Expression::Path(ExprPath(vec![ - ExprPathSegment { - ident: Identifier(String::from("self")), - generics: None, - }, - ]))), - prefixes: vec![Prefix::Deref], - postfixes: vec![ - Postfix::FieldAccess( - Identifier(String::from("_m_oop")), - None, - ), - Postfix::TupleFieldAccess(0, None), - Postfix::FieldAccess( - Identifier(String::from("add")), - None, - ), - Postfix::Call(vec![Expression::Path(ExprPath( - vec![ - ExprPathSegment { - ident: Identifier(String::from("Self")), - generics: None, - }, - ExprPathSegment { - ident: Identifier(format!( - "__FN_{}", - method.item.name.0.to_uppercase() - )), - generics: None, - }, - ], - ))]), - ], - }), - }, - ))), - }, - ], - soft_return: None, - }))), - }), - }); - - method.gen_rust(ctx, cg); - method.item.body = body; + method.item.name.0.insert_str(0, "__m_"); + } + _ => {} } - method.item.name.0.insert_str(0, "__m_"); method.gen_rust(ctx, cg); } @@ -410,3 +271,63 @@ fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern { _ => Pattern::Path(false, Path(vec![Identifier(format!("_{idx}"))])), } } + +pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustCodegen) { + cg.add(&format!( + "{}fn {}{}(", + method.visibility.get_rust(), + method.name.get_rust(), + method.generics.get_rust(), + )); + + for (i, param) in method.params.0.iter().enumerate() { + if i > 0 { + cg.add(", "); + } + + param.gen_rust(ctx, cg); + } + + cg.add(") "); + if let Some(return_type) = &method.return_type { + cg.add("-> "); + cg.add(&return_type.get_rust()); + } + + cg.addln("{"); + cg.indent += 1; + + cg.add_indentedln("unsafe {"); + cg.indent += 1; + + cg.add_indentedln(&format!( + "let func_ptr = *self._m_oop.0.add(Self::__FN_{});", + method.name.0.to_uppercase() + )); + + cg.add_indented("let func: "); + + let mut param_types: Vec = method + .params + .clone() + .0 + .into_iter() + .filter_map(|v| v.type_) + .collect(); + + param_types.remove(0); + + // param_types.insert(0, ); + + cg.add(&TypeExpr::StaticFn(param_types).get_rust()); + + cg.addln(" = std::mem::transmute(func_ptr);"); + + cg.add_indentedln("func(self._m_oop.1);"); + + cg.indent -= 1; + cg.add_indentedln("}"); + + cg.indent -= 1; + cg.add_indentedln("}"); +} From d0796aa5df3f8126e5e0b118d8f439349cfd29e2 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 00:30:27 +0200 Subject: [PATCH 07/17] Working param and return type fn type --- crates/codegen/src/class_decl.rs | 19 ++++++++++++++--- crates/codegen/src/lib.rs | 35 ++++++++++++++++++++++++-------- crates/parser/src/ast/mod.rs | 6 +++++- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 6a63a87..3008614 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -317,13 +317,26 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC param_types.remove(0); - // param_types.insert(0, ); + param_types.insert( + 0, + TypeExpr::UnsafePtr { + mutable: true, + ty: Box::new(TypeExpr::Path( + Path(vec![ + Identifier(String::from("std")), + Identifier(String::from("ffi")), + Identifier(String::from("c_void")), + ]), + None, + )), + }, + ); - cg.add(&TypeExpr::StaticFn(param_types).get_rust()); + cg.add(&TypeExpr::StaticFn(param_types, method.return_type.clone().map(Box::new)).get_rust()); cg.addln(" = std::mem::transmute(func_ptr);"); - cg.add_indentedln("func(self._m_oop.1);"); + cg.add_indentedln("func(self._m_oop.1)"); cg.indent -= 1; cg.add_indentedln("}"); diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index b0d79de..ea63d97 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -192,14 +192,33 @@ impl GetRust for TypeExpr { .collect::>() .join(", ") ), - Self::StaticFn(types) => format!( - "fn({})", - types - .into_iter() - .map(|t| t.get_rust()) - .collect::>() - .join(", ") - ), + Self::StaticFn(types, return_type) => { + if let Some(return_type) = return_type { + format!( + "fn({}) -> {}", + types + .into_iter() + .map(|t| t.get_rust()) + .collect::>() + .join(", "), + return_type.get_rust() + ) + } else { + format!( + "fn({})", + types + .into_iter() + .map(|t| t.get_rust()) + .collect::>() + .join(", "), + ) + } + } + + Self::UnsafePtr { mutable, ty } => { + let mutable = if *mutable { "mut " } else { "const " }; + format!("*{mutable}{}", ty.get_rust()) + } Self::Ref { lifetime, diff --git a/crates/parser/src/ast/mod.rs b/crates/parser/src/ast/mod.rs index 11014a3..89b12fb 100644 --- a/crates/parser/src/ast/mod.rs +++ b/crates/parser/src/ast/mod.rs @@ -24,9 +24,13 @@ pub enum TypeExpr { mutable: bool, ty: Box, }, + UnsafePtr { + mutable: bool, + ty: Box, + }, Dyn(Box), Path(Path, Option), - StaticFn(Vec), + StaticFn(Vec, Option>), Tuple(Vec), Lifetime(Identifier), } From 982b0bf4a544b462ff9545e3faa6b4e22796555c Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 00:38:14 +0200 Subject: [PATCH 08/17] Improved constructor --- crates/codegen/src/class_decl.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 3008614..1363248 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -199,10 +199,14 @@ impl GenRust for (&Vec>, &Spanned) { param.gen_rust(ctx, cg); } - cg.addln(") -> Self {"); + cg.addln(") -> Box {"); cg.indent += 1; - cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::::zeroed().assume_init() };"); + cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::::zeroed().assume_init() });"); + cg.add_indentedln("let this_ptr = &mut *this as *mut Self as *mut std::ffi::c_void;"); + cg.add_indentedln( + "this._m_oop = (&Self::__V_TABLE as *const *const std::ffi::c_void, this_ptr);", + ); for field in self.0 { let comment = field.get_comment(); From fafc03d5d8066e52ecb28f3b4d43badef0f31e43 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 00:40:22 +0200 Subject: [PATCH 09/17] Heap super --- crates/codegen/src/class_decl.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 1363248..3f4e607 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -28,9 +28,9 @@ pub fn class_decl( cg.add_indentedln("pub _m_oop: (*const *const std::ffi::c_void, *mut std::ffi::c_void),"); if let Some(inherits) = inherits { - cg.add_indented("pub _super: "); + cg.add_indented("pub _super: Box<"); cg.add(&inherits.get_rust()); - cg.addln(","); + cg.addln(">,"); } for field in fields.clone() { From 58e1f9ddd23ea1e0ebf16313c76308e2a79a3c36 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 01:18:14 +0200 Subject: [PATCH 10/17] Super VTable generation --- crates/codegen/src/class_decl.rs | 38 ++++++++++++++++++++-- crates/parser/src/ast/top_level.rs | 1 + crates/parser/src/grammar.pest | 5 ++- crates/parser/src/parser/items/function.rs | 2 ++ mist-test/src/items/class_test.mist | 4 +++ 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 3f4e607..9dae552 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -71,7 +71,7 @@ pub fn class_decl( let v_table = methods .iter() .filter_map(|method| match method.item.visibility { - Visibility::Public => Some(method.item.name.clone()), + Visibility::Public => Some((method.item.name.clone(), method.item.is_override)), _ => None, }) .collect::>(); @@ -83,14 +83,14 @@ pub fn class_decl( for (i, method_name) in v_table.iter().enumerate() { cg.add_indentedln(&format!( "pub const __FN_{}: usize = {i};", - method_name.0.to_uppercase() + method_name.0.0.to_uppercase() )); } cg.add_indentedln("pub const __V_TABLE: [*const std::ffi::c_void; Self::__V_COUNT] = ["); cg.indent += 1; - for method_name in v_table { + for (method_name, _) in &v_table { cg.add_indented("Self::__m_"); cg.add(&method_name.get_rust()); cg.add(" as *const std::ffi::c_void"); @@ -101,6 +101,37 @@ pub fn class_decl( cg.add_indentedln("];"); } + // Super V Table + if let Some(inherits) = inherits { + cg.add_indented(&format!( + "pub const __SUPER_V_TABLE: [*const std::ffi::c_void; {}", + inherits.get_rust() + )); + + cg.addln("::__V_COUNT] = {"); + cg.indent += 1; + + cg.add_indented("let mut table = "); + cg.add(&inherits.get_rust()); + cg.addln("::__V_TABLE;"); + + for (name, is_override) in v_table { + if is_override { + cg.add_indentedln(&format!( + "table[{}::__FN_{}] = Self::__m_{} as *const std::ffi::c_void;", + inherits.get_rust(), + name.0.to_uppercase(), + name.get_rust() + )); + } + } + + cg.add_indentedln("table"); + + cg.indent -= 1; + cg.add_indentedln("};"); + } + let constructor_comment = constructor.get_comment(); cg.add_indentedln("#[allow(invalid_value)]"); @@ -257,6 +288,7 @@ impl GenRust for (&Vec>, &Spanned) { column: self.1.column, item: FunctionDecl { visibility: self.1.item.visibility.clone(), + is_override: false, name: Identifier(String::from("constructor")), generics: self.1.item.generics.clone(), params: ParamList(constructor_params), diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index dd29e9b..f6fe296 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -94,6 +94,7 @@ pub struct ClassConstructor { #[derive(Debug, Clone, Serialize)] pub struct FunctionDecl { pub visibility: Visibility, + pub is_override: bool, pub name: Identifier, pub generics: GenericsDecl, pub params: ParamList, diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index e62dc58..3c20825 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -32,6 +32,7 @@ keyword = { | "loop" | "fn" | "unsafe" + | "override" } identifier = @{ @@ -324,8 +325,10 @@ trait_decl = { // FUNCTIONS // ====================================================== +override_kw = { "override" } + function_decl = { - visibility? ~ "fn" ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ type_expr? ~ (block | semicolon) + visibility? ~ override_kw? ~ "fn" ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ type_expr? ~ (block | semicolon) } // ====================================================== diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 3919cce..4e68469 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -13,6 +13,7 @@ impl<'a> TryFrom> for FunctionDecl { ast_ensure!(pair, Rule::function_decl => { let mut inner = pair.into_inner(); let visibility = Visibility::try_from(&mut inner); + let is_override: AstResult = Ok(listen_rule(&mut inner, Rule::override_kw)); let name = Identifier::try_from(inner.next().unwrap()); let generics = consume_rule(&mut inner, Rule::generics_decl) @@ -66,6 +67,7 @@ impl<'a> TryFrom> for FunctionDecl { ast_expr!(Self { visibility: visibility, + is_override: is_override, return_type: return_type, name: name, generics: generics, diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 7c44635..9ca0f16 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -42,6 +42,10 @@ class NamedCounter : Counter { pub fn get_name(*self) String { self.name.clone() } + + pub override fn increment(*mut self) { + println!("OK!!"); + } } pub fn test_class_inherit() { From 1977bd59be97f12a413bd94654b4229d832a518e Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 01:32:00 +0200 Subject: [PATCH 11/17] VTable update --- crates/codegen/src/class_decl.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 9dae552..27e86d3 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -137,7 +137,7 @@ pub fn class_decl( cg.add_indentedln("#[allow(invalid_value)]"); cg.add_indentedln(&constructor_comment); - (fields, constructor).gen_rust(ctx, cg); + (fields, constructor, inherits.is_some()).gen_rust(ctx, cg); for mut method in methods { match method.item.visibility { @@ -200,7 +200,13 @@ pub fn class_decl( } } -impl GenRust for (&Vec>, &Spanned) { +impl GenRust + for ( + &Vec>, + &Spanned, + bool, + ) +{ fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { cg.add_indented(&format!( "{}fn new{}(", @@ -264,6 +270,10 @@ impl GenRust for (&Vec>, &Spanned) { cg.addln(");"); + if self.2 { + cg.add("this._super._m_oop.0 = &Self::__SUPER_V_TABLE as *const *const std::ffi::c_void;"); + } + cg.add_indentedln("this"); cg.indent -= 1; From e70e81349719160064f21c35570a15e040140ddc Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 01:57:09 +0200 Subject: [PATCH 12/17] Working inheritance #68 --- crates/codegen/src/class_decl.rs | 8 +++- mist-test/src/items/class_test.mist | 69 ++++++++--------------------- 2 files changed, 24 insertions(+), 53 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 27e86d3..c8d9fbe 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -142,7 +142,9 @@ pub fn class_decl( for mut method in methods { match method.item.visibility { Visibility::Public => { - gen_method_point(&method.item, ctx, cg); + if !method.item.is_override { + gen_method_point(&method.item, ctx, cg); + } method.item.name.0.insert_str(0, "__m_"); } @@ -271,7 +273,9 @@ impl GenRust cg.addln(");"); if self.2 { - cg.add("this._super._m_oop.0 = &Self::__SUPER_V_TABLE as *const *const std::ffi::c_void;"); + cg.add_indentedln( + "this._super._m_oop.0 = &Self::__SUPER_V_TABLE as *const *const std::ffi::c_void;", + ); } cg.add_indentedln("this"); diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 9ca0f16..71cbfcf 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -1,62 +1,29 @@ -pub class Counter { - pub count i32; - - pub constructor(start i32) { - self.count = start; - } - - pub fn increment(*mut self) { - self.count++; - } - - pub fn get(*self) i32 { - self.count - } -} - -pub fn test_class_create() { - let c = Counter::new(0); - assert_eq!(c.get(), 0); -} - -pub fn test_class_method() { - let mut c = Counter::new(5); - c.increment(); - assert_eq!(c.get(), 6); -} - -pub fn test_class_field_access() { - let c = Counter::new(42); - assert_eq!(c.count, 42); -} - -class NamedCounter : Counter { +pub class Animal { pub name String; - pub constructor(start i32, name String) { - self._super = Counter::new(start); - - self.name = name; + constructor() { + self.name = "Rex".to_string(); } - pub fn get_name(*self) String { - self.name.clone() - } - - pub override fn increment(*mut self) { - println!("OK!!"); + pub fn speak(*self) { + println!("Unknown"); } } -pub fn test_class_inherit() { - let nc = NamedCounter::new(10, "test".to_string()); - assert_eq!(nc.get_name(), "test"); - assert_eq!(nc.count, 10); +pub class Dog : Animal { + constructor() { + unsafe { + std::ptr::write(&mut self._super, Animal::new()); + } + } + + pub override fn speak(*self) { + println!("Woof!"); + } } pub fn run_tests() { - test_class_create(); - test_class_method(); - test_class_field_access(); - test_class_inherit(); + let dawg = Dog::new(); + + dawg.speak(); } From fa4a7ee4c768e3b3a8a9be0f0ef254209ae41425 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 03:36:02 +0200 Subject: [PATCH 13/17] Super and super --- crates/codegen/src/class_decl.rs | 16 ++++++++++++++++ crates/codegen/src/expr.rs | 26 +++++++++++++++++++++++++- crates/codegen/src/lib.rs | 6 ++++++ mist-test/src/items/class_test.mist | 2 +- 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index c8d9fbe..c00bbb1 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -16,6 +16,10 @@ pub fn class_decl( constructor: &Spanned, items: &Vec, ) { + if let Some(inherits) = inherits { + ctx.expr_super = Some(get_type_path(inherits)); + } + // Struct decl cg.addln(&format!( "{}struct {}{} {{", @@ -200,6 +204,8 @@ pub fn class_decl( cg.indent -= 1; cg.addln("}"); } + + ctx.expr_super = None; } impl GenRust @@ -394,3 +400,13 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.indent -= 1; cg.add_indentedln("}"); } + +pub fn get_type_path(ty: &TypeExpr) -> Path { + match ty { + TypeExpr::Path(p, _) => p.clone(), + TypeExpr::Dyn(v) => get_type_path(v), + TypeExpr::Ref { ty, .. } => get_type_path(ty), + TypeExpr::UnsafePtr { ty, .. } => get_type_path(ty), + _ => unimplemented!(), + } +} diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index fbfdfe8..9cf5171 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -12,6 +12,30 @@ impl GetRust for ExprPath { .collect::>() .join("::") } + + fn get_rust_ctx(&self, cx: &mut Context) -> String { + let mut a = self.clone(); + + if let Some(path) = &cx.expr_super { + if self.0[0].ident.0 == "super" { + a.0[0].ident.0 = String::from("self._super"); + } else if self.0[0].ident.0 == "Super" { + a.0[0].ident = path.0[0].clone(); + + if path.0.len() > 1 { + a.0.splice( + 1..1, + path.0.clone().into_iter().skip(1).map(|v| ExprPathSegment { + ident: v, + generics: None, + }), + ); + } + } + } + + a.get_rust() + } } impl GetRust for ExprPathSegment { @@ -63,7 +87,7 @@ impl GenRust for Expression { }; match self { - Expression::Path(path) => cg.add(&path.get_rust()), + Expression::Path(path) => cg.add(&path.get_rust_ctx(ctx)), Expression::Literal(literal) => literal.gen_rust(ctx, cg), Expression::Statement(stmt) => stmt.gen_rust(ctx, cg), Expression::Array(values) => { diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index ea63d97..a1d74cb 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -7,6 +7,7 @@ use mist_parser::ast::*; pub struct Context { pub expr_ensure_semicolon: bool, + pub expr_super: Option, } pub trait GenRust { @@ -15,6 +16,10 @@ pub trait GenRust { pub trait GetRust { fn get_rust(&self) -> String; + fn get_rust_ctx(&self, cx: &mut Context) -> String { + let _ = cx; + self.get_rust() + } } #[derive(Default)] @@ -57,6 +62,7 @@ impl RustCodegen { pub fn generate(&mut self, toplevels: Vec) -> String { let mut ctx = Context { expr_ensure_semicolon: true, + expr_super: None, }; for tl in toplevels { diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 71cbfcf..9d88134 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -13,7 +13,7 @@ pub class Animal { pub class Dog : Animal { constructor() { unsafe { - std::ptr::write(&mut self._super, Animal::new()); + std::ptr::write(&mut super, Super::new()); } } From 206b2fa41429e3330a0862fff9ca654c1b9142dc Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 03:38:10 +0200 Subject: [PATCH 14/17] super edge case --- crates/codegen/src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index 9cf5171..e4e2701 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -17,7 +17,7 @@ impl GetRust for ExprPath { let mut a = self.clone(); if let Some(path) = &cx.expr_super { - if self.0[0].ident.0 == "super" { + if self.0[0].ident.0 == "super" && self.0.len() == 1 { a.0[0].ident.0 = String::from("self._super"); } else if self.0[0].ident.0 == "Super" { a.0[0].ident = path.0[0].clone(); From 9001c1c3e2431b9a63d58ad71246c13bdb618c67 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 03:40:23 +0200 Subject: [PATCH 15/17] Removed void --- crates/codegen/src/lib.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index a1d74cb..f6c466b 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -184,9 +184,9 @@ impl GetRust for TypeExpr { match self { Self::Path(path, generics) => { if let Some(generics) = generics { - format!("{}{}", get_static_type_path(path), generics.get_rust()) + format!("{}{}", path.get_rust(), generics.get_rust()) } else { - get_static_type_path(path) + path.get_rust() } } Self::Lifetime(name) => format!("'{}", name.get_rust()), @@ -247,16 +247,6 @@ impl GetRust for TypeExpr { } } -pub fn get_static_type_path(path: &Path) -> String { - let rust_path = path.get_rust(); - - if rust_path == "void" { - format!("()") - } else { - rust_path - } -} - impl GenRust for Pattern { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { From 27e78dc3771675452b55181328739da1a7096783 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 09:49:30 +0200 Subject: [PATCH 16/17] Improved safety --- crates/codegen/src/class_decl.rs | 8 ++++---- mist-test/src/items/class_test.mist | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index c00bbb1..8fa1fe3 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -29,7 +29,7 @@ pub fn class_decl( )); cg.indent += 1; - cg.add_indentedln("pub _m_oop: (*const *const std::ffi::c_void, *mut std::ffi::c_void),"); + cg.add_indentedln("pub _m_oop: (&'static [*const std::ffi::c_void; Self::__V_COUNT], *mut std::ffi::c_void),"); if let Some(inherits) = inherits { cg.add_indented("pub _super: Box<"); @@ -250,7 +250,7 @@ impl GenRust cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::::zeroed().assume_init() });"); cg.add_indentedln("let this_ptr = &mut *this as *mut Self as *mut std::ffi::c_void;"); cg.add_indentedln( - "this._m_oop = (&Self::__V_TABLE as *const *const std::ffi::c_void, this_ptr);", + "this._m_oop = (&Self::__V_TABLE, this_ptr);", ); for field in self.0 { @@ -280,7 +280,7 @@ impl GenRust if self.2 { cg.add_indentedln( - "this._super._m_oop.0 = &Self::__SUPER_V_TABLE as *const *const std::ffi::c_void;", + "this._super._m_oop.0 = &Self::__SUPER_V_TABLE;", ); } @@ -357,7 +357,7 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC cg.indent += 1; cg.add_indentedln(&format!( - "let func_ptr = *self._m_oop.0.add(Self::__FN_{});", + "let func_ptr = self._m_oop.0[Self::__FN_{}];", method.name.0.to_uppercase() )); diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 9d88134..b95f19d 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -8,6 +8,10 @@ pub class Animal { pub fn speak(*self) { println!("Unknown"); } + + pub fn test_speak(*self) { + self.speak(); + } } pub class Dog : Animal { @@ -25,5 +29,5 @@ pub class Dog : Animal { pub fn run_tests() { let dawg = Dog::new(); - dawg.speak(); + dawg.test_speak(); } From 3e7863afed656daa46f354e1ca17e3f936a0664a Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 7 Jun 2026 10:24:13 +0200 Subject: [PATCH 17/17] V table type checking --- crates/codegen/src/class_decl.rs | 76 ++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/crates/codegen/src/class_decl.rs b/crates/codegen/src/class_decl.rs index 8fa1fe3..73f7713 100644 --- a/crates/codegen/src/class_decl.rs +++ b/crates/codegen/src/class_decl.rs @@ -16,9 +16,13 @@ pub fn class_decl( constructor: &Spanned, items: &Vec, ) { - if let Some(inherits) = inherits { - ctx.expr_super = Some(get_type_path(inherits)); - } + let inherits = if let Some(inherits) = inherits { + let path = get_type_path(inherits); + ctx.expr_super = Some(path.clone()); + Some((inherits, path)) + } else { + None + }; // Struct decl cg.addln(&format!( @@ -29,9 +33,11 @@ pub fn class_decl( )); cg.indent += 1; - cg.add_indentedln("pub _m_oop: (&'static [*const std::ffi::c_void; Self::__V_COUNT], *mut std::ffi::c_void),"); + cg.add_indentedln( + "pub _m_oop: (&'static [*const std::ffi::c_void; Self::__V_COUNT], *mut std::ffi::c_void),", + ); - if let Some(inherits) = inherits { + if let Some((inherits, _)) = inherits { cg.add_indented("pub _super: Box<"); cg.add(&inherits.get_rust()); cg.addln(">,"); @@ -106,7 +112,7 @@ pub fn class_decl( } // Super V Table - if let Some(inherits) = inherits { + if let Some((inherits, inherit_path)) = &inherits { cg.add_indented(&format!( "pub const __SUPER_V_TABLE: [*const std::ffi::c_void; {}", inherits.get_rust() @@ -134,6 +140,54 @@ pub fn class_decl( cg.indent -= 1; cg.add_indentedln("};"); + + cg.add_indentedln("const fn __test_vt() {"); + cg.indent += 1; + + for i in &methods { + if i.item.is_override { + let mut params = i + .item + .params + .clone() + .0 + .into_iter() + .filter_map(|v| v.type_) + .collect::>(); + + if params.len() == 0 { + continue; + } + + match params.remove(0) { + TypeExpr::Ref { mutable, .. } => { + cg.add_indented(&inherit_path.get_rust()); + cg.add("::__m_"); + cg.add(&i.item.name.get_rust()); + cg.add(" as "); + + params.insert( + 0, + TypeExpr::Ref { + lifetime: None, + mutable: mutable, + ty: Box::new((*inherits).clone()), + }, + ); + + cg.add( + &TypeExpr::StaticFn(params, i.item.return_type.clone().map(Box::new)) + .get_rust(), + ); + cg.addln(";"); + } + _ => {} + } + } + } + + cg.indent -= 1; + cg.add_indentedln("}"); } let constructor_comment = constructor.get_comment(); @@ -175,7 +229,7 @@ pub fn class_decl( } } - if let Some(inherits) = inherits { + if let Some((inherits, _)) = inherits { cg.add("impl std::ops::Deref for "); cg.add(&name.get_rust()); @@ -249,9 +303,7 @@ impl GenRust cg.add_indentedln("let mut this = Box::new(unsafe { std::mem::MaybeUninit::::zeroed().assume_init() });"); cg.add_indentedln("let this_ptr = &mut *this as *mut Self as *mut std::ffi::c_void;"); - cg.add_indentedln( - "this._m_oop = (&Self::__V_TABLE, this_ptr);", - ); + cg.add_indentedln("this._m_oop = (&Self::__V_TABLE, this_ptr);"); for field in self.0 { let comment = field.get_comment(); @@ -279,9 +331,7 @@ impl GenRust cg.addln(");"); if self.2 { - cg.add_indentedln( - "this._super._m_oop.0 = &Self::__SUPER_V_TABLE;", - ); + cg.add_indentedln("this._super._m_oop.0 = &Self::__SUPER_V_TABLE;"); } cg.add_indentedln("this");