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() {