diff --git a/crates/analyzer/src/lib.rs b/crates/analyzer/src/lib.rs index 0ba2e7d..7602f4c 100644 --- a/crates/analyzer/src/lib.rs +++ b/crates/analyzer/src/lib.rs @@ -26,7 +26,7 @@ use crate::transpiler::{ static MARKER_COUNTER: AtomicU64 = AtomicU64::new(0); -const KEYWORDS: [&'static str; 22] = [ +const KEYWORDS: [&'static str; 23] = [ "if", "else", "for", @@ -49,6 +49,7 @@ const KEYWORDS: [&'static str; 22] = [ "override", "module ", "void ", + "virtual ", ]; fn keyword_completion_items() -> impl Iterator { @@ -1630,11 +1631,11 @@ fn mist_ify_completions(source: &str, pos: &Position, items: &mut Vec, methods: Vec>, v_table: Vec, - override_v_table: HashMap>>, + override_v_table: HashMap>>, } impl ClassProcessedData { @@ -51,7 +51,7 @@ impl ClassProcessedData { if matches!(method.item.visibility, Visibility::Public) { match &method.item.is_override { None => { - if method.item.self_param.is_some() { + if method.item.is_virtual && method.item.self_param.is_some() { v_table.push(method.item.name.clone()); } } @@ -64,7 +64,7 @@ impl ClassProcessedData { item: Vec::new(), }) .item - .push(method.item.name.clone()); + .push((method.item.name.clone(), method.item.is_virtual)); } } } @@ -191,13 +191,13 @@ impl ClassProcessedData { .as_ref() .unwrap_or(self.inherits.as_ref().unwrap()) .get_rust(); - for method_ident in &overriden_method_idents.item { + for (method_ident, is_virtual) in &overriden_method_idents.item { cg.add_indentedln(&format!( - "table[{}::__FN_{}] = {}::__m_{} as *const std::ffi::c_void;", + "table[{}::__FN_{}] = {}::{} as *const std::ffi::c_void;", base_class_path, method_ident.0.to_uppercase(), self.self_path.get_rust(), - method_ident.get_rust() + get_virtual_name(method_ident, *is_virtual) )); } } @@ -380,6 +380,7 @@ impl ClassProcessedData { column: constructor.column, item: FunctionDecl { visibility: constructor.item.visibility.clone(), + is_virtual: false, is_override: None, name: Identifier(String::from("constructor")), generics: constructor.item.generics.clone(), @@ -396,7 +397,7 @@ impl ClassProcessedData { for method in &self.methods { match method.item.visibility { Visibility::Public => { - if method.item.self_param.is_some() { + if method.item.is_virtual && method.item.self_param.is_some() { if method.item.is_override.is_none() { gen_method_point(&method.item, ctx, cg); } @@ -617,3 +618,11 @@ pub fn get_type_from_path(path: &ExprPath) -> TypeExpr { path.0.last().unwrap().generics.clone(), ) } + +pub fn get_virtual_name(name: &Identifier, is_virtual: bool) -> String { + if is_virtual { + format!("__m_{}", name.get_rust()) + } else { + name.get_rust() + } +} diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index 2e95aed..fd8427e 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -107,12 +107,13 @@ pub struct Override(pub Option); #[derive(Debug, Clone, Serialize)] pub struct FunctionDecl { pub visibility: Visibility, - pub is_override: Option, + pub is_virtual: bool, + pub return_type: Option, pub name: Identifier, pub generics: GenericsDecl, pub self_param: Option<(bool, Option, bool)>, pub params: ParamList, - pub return_type: Option, + pub is_override: Option, pub body: Option, } @@ -129,7 +130,6 @@ pub struct FieldDecl { pub visibility: Visibility, pub type_: TypeExpr, pub name: Identifier, - // pub tuple_names: Vec, } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 24b188b..a51c7e2 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -36,6 +36,7 @@ keyword = { | "override" | "const" | "type" + | "virtual" } identifier = @{ @@ -373,10 +374,12 @@ trait_decl = { // FUNCTIONS // ====================================================== +virtual_kw = { "virtual" } + override_kw = { "override" ~ ("(" ~ expr_path ~ ")")? } function_decl = { - visibility? ~ ("void" | type_expr) ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ override_kw? ~ (block | semicolon) + visibility? ~ virtual_kw? ~ ("void" | type_expr) ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ override_kw? ~ (block | semicolon) } // ====================================================== diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 7c7ac46..25ea082 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -14,6 +14,8 @@ impl<'a> TryFrom> for FunctionDecl { let mut inner = pair.into_inner(); let visibility = Visibility::try_from(&mut inner)?; + let is_virtual = listen_rule(&mut inner, Rule::virtual_kw); + let return_type = consume_rule(&mut inner, Rule::type_expr) .map(TypeExpr::try_from) .transpose()?; @@ -45,12 +47,13 @@ impl<'a> TryFrom> for FunctionDecl { Ok(Self { visibility: visibility, - is_override: is_override, + is_virtual: is_virtual, return_type: return_type, name: name, generics: generics, self_param: self_param, params: params, + is_override: is_override, body: body, }) }) diff --git a/crates/parser/src/semantics.rs b/crates/parser/src/semantics.rs index 5a21f9b..2457254 100644 --- a/crates/parser/src/semantics.rs +++ b/crates/parser/src/semantics.rs @@ -102,6 +102,28 @@ pub fn check_class_semantics<'a>(top_level: &TopLevel) -> Result<(), Vec