diff --git a/dmc-lib/src/ast/call.rs b/dmc-lib/src/ast/call.rs index bd3dd86..37ce077 100644 --- a/dmc-lib/src/ast/call.rs +++ b/dmc-lib/src/ast/call.rs @@ -1,4 +1,5 @@ use crate::ast::expression::Expression; +use crate::ast::fqn_util::fqn_parts_to_string; use crate::ast::ir_builder::IrBuilder; use crate::diagnostic::Diagnostic; use crate::ir::ir_call::IrCall; @@ -186,7 +187,7 @@ impl Call { let callable_symbol = self.get_callee_symbol(); match callable_symbol { CallableSymbol::Function(function_symbol) => IrCall::new( - function_symbol.borrow().declared_name_owned(), + fqn_parts_to_string(function_symbol.borrow().fqn_parts()), arguments, function_symbol.borrow().is_extern(), ), @@ -197,7 +198,7 @@ impl Call { .cloned() .expect("Default constructors not supported yet."); IrCall::new( - constructor_symbol.borrow().declared_name_owned(), + fqn_parts_to_string(constructor_symbol.borrow().fqn_parts()), arguments, false, ) diff --git a/dmc-lib/src/ast/class.rs b/dmc-lib/src/ast/class.rs index d2834b0..b5927e4 100644 --- a/dmc-lib/src/ast/class.rs +++ b/dmc-lib/src/ast/class.rs @@ -1,5 +1,6 @@ use crate::ast::constructor::Constructor; use crate::ast::field::Field; +use crate::ast::fqn_context::FqnContext; use crate::ast::function::Function; use crate::diagnostic::{Diagnostic, SecondaryLabel}; use crate::ir::ir_function::IrFunction; @@ -40,7 +41,11 @@ impl Class { pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, + fqn_context: &mut FqnContext, ) -> Result<(), Vec> { + // 0. Push class name on fqn + fqn_context.push(self.declared_name.clone()); + // 1. insert class symbol let to_insert = ClassSymbol::new( &self.declared_name, @@ -94,7 +99,8 @@ impl Class { // 4. gather constructor if let Some(constructor) = &mut self.constructor { - let constructor_symbol = constructor.gather_declared_names(symbol_table)?; + let constructor_symbol = + constructor.gather_declared_names(symbol_table, fqn_context)?; self.class_symbol .as_mut() .unwrap() @@ -108,7 +114,11 @@ impl Class { .functions .iter_mut() .map(|function| { - function.gather_declared_names(symbol_table, self.class_symbol.as_ref()) + function.gather_declared_names( + symbol_table, + fqn_context, + self.class_symbol.as_ref(), + ) }) .filter_map(Result::err) .flatten() @@ -121,6 +131,9 @@ impl Class { // 6. pop scope symbol_table.pop_scope(); + // 7. pop fqn part + fqn_context.pop(); + Ok(()) } diff --git a/dmc-lib/src/ast/compilation_unit.rs b/dmc-lib/src/ast/compilation_unit.rs index c9cde06..0d73d6d 100644 --- a/dmc-lib/src/ast/compilation_unit.rs +++ b/dmc-lib/src/ast/compilation_unit.rs @@ -1,5 +1,6 @@ use crate::ast::class::Class; use crate::ast::extern_function::ExternFunction; +use crate::ast::fqn_context::FqnContext; use crate::ast::function::Function; use crate::diagnostic::Diagnostic; use crate::ir::ir_function::IrFunction; @@ -42,24 +43,26 @@ impl CompilationUnit { ) -> Result<(), Vec> { symbol_table.push_module_scope("compilation_unit_scope"); + let mut fqn_context = FqnContext::new(); // in the future, we'll push the pkg/ns on here let mut diagnostics: Vec = vec![]; + self.functions .iter_mut() - .map(|f| f.gather_declared_names(symbol_table, None)) + .map(|f| f.gather_declared_names(symbol_table, &fqn_context, None)) .filter_map(Result::err) .flatten() .for_each(|diagnostic| diagnostics.push(diagnostic)); self.extern_functions .iter_mut() - .map(|f| f.gather_declared_names(symbol_table)) + .map(|f| f.gather_declared_names(symbol_table, &fqn_context)) .filter_map(Result::err) .flatten() .for_each(|diagnostic| diagnostics.push(diagnostic)); self.classes .iter_mut() - .map(|c| c.gather_declared_names(symbol_table)) + .map(|c| c.gather_declared_names(symbol_table, &mut fqn_context)) .filter_map(Result::err) .flatten() .for_each(|diagnostic| diagnostics.push(diagnostic)); diff --git a/dmc-lib/src/ast/constructor.rs b/dmc-lib/src/ast/constructor.rs index 2b409f4..b27b18a 100644 --- a/dmc-lib/src/ast/constructor.rs +++ b/dmc-lib/src/ast/constructor.rs @@ -1,4 +1,6 @@ use crate::ast::field::Field; +use crate::ast::fqn_context::FqnContext; +use crate::ast::fqn_util::fqn_parts_to_string; use crate::ast::ir_builder::IrBuilder; use crate::ast::parameter::Parameter; use crate::ast::statement::Statement; @@ -55,9 +57,14 @@ impl Constructor { pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, + fqn_context: &FqnContext, ) -> Result>, Vec> { // insert constructor symbol - let to_insert = ConstructorSymbol::new(self.ctor_keyword_source_range.clone(), false); + let to_insert = ConstructorSymbol::new( + self.ctor_keyword_source_range.clone(), + fqn_context.resolve("ctor"), // ctor is a keyword at the language level, should not be callable via normal means + false, + ); let constructor_symbol = symbol_table .insert_constructor_symbol(to_insert) @@ -277,8 +284,15 @@ impl Constructor { let entry_block = ir_builder.get_block(entry_block_id); IrFunction::new( - format!("{}::ctor", class_symbol.borrow().declared_name()).into(), // fake function symbol - &ir_parameters, // make params + fqn_parts_to_string( + class_symbol + .borrow() + .constructor_symbol() + .unwrap() + .borrow() + .fqn_parts(), + ), // fake function symbol + &ir_parameters, // make params &TypeInfo::ClassInstance(class_symbol.clone()), entry_block.clone(), ) diff --git a/dmc-lib/src/ast/extern_function.rs b/dmc-lib/src/ast/extern_function.rs index 6026b0f..1495fd1 100644 --- a/dmc-lib/src/ast/extern_function.rs +++ b/dmc-lib/src/ast/extern_function.rs @@ -1,3 +1,4 @@ +use crate::ast::fqn_context::FqnContext; use crate::ast::parameter::Parameter; use crate::ast::type_use::TypeUse; use crate::diagnostic::Diagnostic; @@ -39,12 +40,14 @@ impl ExternFunction { pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, + fqn_context: &FqnContext, ) -> Result<(), Vec> { let mut diagnostics = vec![]; let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new( &self.declared_name, self.declared_name_source_range.clone(), + fqn_context.resolve(self.declared_name()), true, )); diff --git a/dmc-lib/src/ast/fqn_context.rs b/dmc-lib/src/ast/fqn_context.rs new file mode 100644 index 0000000..ee39d8c --- /dev/null +++ b/dmc-lib/src/ast/fqn_context.rs @@ -0,0 +1,25 @@ +use std::rc::Rc; + +pub struct FqnContext { + parts: Vec>, +} + +impl FqnContext { + pub fn new() -> Self { + Self { parts: vec![] } + } + + pub fn push(&mut self, part: Rc) { + self.parts.push(part); + } + + pub fn pop(&mut self) { + self.parts.pop(); + } + + pub fn resolve(&self, name: &str) -> Vec> { + let mut result = self.parts.clone(); + result.push(name.into()); + result + } +} diff --git a/dmc-lib/src/ast/fqn_util.rs b/dmc-lib/src/ast/fqn_util.rs new file mode 100644 index 0000000..d9b78c2 --- /dev/null +++ b/dmc-lib/src/ast/fqn_util.rs @@ -0,0 +1,6 @@ +use std::rc::Rc; + +#[inline] +pub fn fqn_parts_to_string(parts: &[Rc]) -> Rc { + parts.join("::").into() +} diff --git a/dmc-lib/src/ast/function.rs b/dmc-lib/src/ast/function.rs index 6f63f8c..c799421 100644 --- a/dmc-lib/src/ast/function.rs +++ b/dmc-lib/src/ast/function.rs @@ -1,3 +1,5 @@ +use crate::ast::fqn_context::FqnContext; +use crate::ast::fqn_util::fqn_parts_to_string; use crate::ast::ir_builder::IrBuilder; use crate::ast::parameter::Parameter; use crate::ast::statement::Statement; @@ -7,9 +9,9 @@ use crate::ir::ir_function::IrFunction; use crate::ir::ir_parameter::IrParameter; use crate::ir::ir_parameter_or_variable::IrParameterOrVariable; use crate::source_range::SourceRange; +use crate::symbol::Symbol; use crate::symbol::class_symbol::ClassSymbol; use crate::symbol::function_symbol::FunctionSymbol; -use crate::symbol::Symbol; use crate::symbol_table::{SymbolInsertError, SymbolTable}; use crate::type_info::TypeInfo; use std::cell::RefCell; @@ -57,6 +59,7 @@ impl Function { pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, + fqn_context: &FqnContext, class_context: Option<&Rc>>, ) -> Result<(), Vec> { let mut diagnostics = vec![]; @@ -69,6 +72,7 @@ impl Function { let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new( self.declared_name(), self.declared_name_source_range.clone(), + fqn_context.resolve(self.declared_name()), false, )); @@ -304,11 +308,7 @@ impl Function { let entry_block = builder.get_block(entry_block_id).clone(); IrFunction::new( - self.function_symbol - .as_ref() - .unwrap() - .borrow() - .declared_name_owned(), // ok for now... but we need to start using the fqn + fqn_parts_to_string(self.function_symbol.as_ref().unwrap().borrow().fqn_parts()), builder.parameters(), return_type_info, entry_block, diff --git a/dmc-lib/src/ast/mod.rs b/dmc-lib/src/ast/mod.rs index 234768e..8d52256 100644 --- a/dmc-lib/src/ast/mod.rs +++ b/dmc-lib/src/ast/mod.rs @@ -9,6 +9,8 @@ pub mod expression_statement; pub mod extern_function; pub mod field; pub mod fqn; +pub mod fqn_context; +mod fqn_util; pub mod function; pub mod identifier; pub mod integer_literal; diff --git a/dmc-lib/src/symbol/constructor_symbol.rs b/dmc-lib/src/symbol/constructor_symbol.rs index 057e719..cb3425c 100644 --- a/dmc-lib/src/symbol/constructor_symbol.rs +++ b/dmc-lib/src/symbol/constructor_symbol.rs @@ -6,19 +6,29 @@ use std::rc::Rc; pub struct ConstructorSymbol { ctor_keyword_source_range: SourceRange, + fqn_parts: Vec>, is_extern: bool, parameters: Option>>>, } impl ConstructorSymbol { - pub fn new(ctor_keyword_source_range: SourceRange, is_extern: bool) -> Self { + pub fn new( + ctor_keyword_source_range: SourceRange, + fqn_parts: Vec>, + is_extern: bool, + ) -> Self { Self { ctor_keyword_source_range, + fqn_parts, is_extern, parameters: None, } } + pub fn fqn_parts(&self) -> &[Rc] { + &self.fqn_parts + } + pub fn set_parameters(&mut self, parameters: Vec>>) { self.parameters = Some(parameters); } diff --git a/dmc-lib/src/symbol/function_symbol.rs b/dmc-lib/src/symbol/function_symbol.rs index 74c7974..44249f0 100644 --- a/dmc-lib/src/symbol/function_symbol.rs +++ b/dmc-lib/src/symbol/function_symbol.rs @@ -8,6 +8,7 @@ use std::rc::Rc; pub struct FunctionSymbol { declared_name: Rc, declared_name_source_range: SourceRange, + fqn_parts: Vec>, is_extern: bool, parameters: Option>>>, return_type: Option, @@ -17,17 +18,23 @@ impl FunctionSymbol { pub fn new( declared_name: &str, declared_name_source_range: SourceRange, + fqn_parts: Vec>, is_extern: bool, ) -> Self { Self { declared_name: declared_name.into(), declared_name_source_range, + fqn_parts, is_extern, parameters: None, return_type: None, } } + pub fn fqn_parts(&self) -> &[Rc] { + &self.fqn_parts + } + pub fn set_parameters(&mut self, parameters: Vec>>) { self.parameters = Some(parameters); }