From c606432be2d482e806e8970fe8ec750e9de6b34a Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 18 May 2025 18:28:57 -0500 Subject: [PATCH] Work to properly resolve imports. --- src/ast/mod.rs | 4 +++ src/name_analysis/gather.rs | 14 +++++++-- src/name_analysis/mod.rs | 10 ++----- src/name_analysis/resolve.rs | 27 ++++++++++++++++- src/name_analysis/symbol.rs | 49 ++++++++++++------------------- src/name_analysis/symbol_table.rs | 8 +++-- src/std_core/mod.rs | 40 ++++++++++++------------- 7 files changed, 86 insertions(+), 66 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 60bd899..f03728a 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -91,6 +91,10 @@ impl Identifier { pub fn symbol(&self) -> &Option { &self.symbol } + + pub fn symbol_mut(&mut self) -> Option { + self.symbol.clone() + } } #[derive(Debug)] diff --git a/src/name_analysis/gather.rs b/src/name_analysis/gather.rs index 6ee4ea6..9aa70ed 100644 --- a/src/name_analysis/gather.rs +++ b/src/name_analysis/gather.rs @@ -164,9 +164,17 @@ fn handle_use_statement_import( ); } drop(borrowed_identifier); - identifier - .borrow_mut() - .set_scope_id(symbol_table.current_scope_id()) + let mut mutable_borrowed_identifier = identifier.borrow_mut(); + mutable_borrowed_identifier.set_scope_id(symbol_table.current_scope_id()); + + let use_statement_symbol = symbol_table + .lookup( + &declared_name, + mutable_borrowed_identifier.scope_id().unwrap(), + ) + .unwrap(); + + mutable_borrowed_identifier.set_symbol(use_statement_symbol); } fn gather_use_statement( diff --git a/src/name_analysis/mod.rs b/src/name_analysis/mod.rs index c46c582..49acb4e 100644 --- a/src/name_analysis/mod.rs +++ b/src/name_analysis/mod.rs @@ -104,7 +104,7 @@ mod tests { ( "main.dm", indoc! {" - use std::core::{Array, String, println}; + use test::Greeter; fn main(args: Array) { println(\"Hello, World!\"); @@ -114,13 +114,9 @@ mod tests { ( "deps.dm", indoc! {" - ns std::core; + ns test; - pub class String {} - - pub class Array {} - - pub platform fn println(msg: String) -> Void; + pub class Greeter {} "}, ), ]); diff --git a/src/name_analysis/resolve.rs b/src/name_analysis/resolve.rs index d0e3826..0c20610 100644 --- a/src/name_analysis/resolve.rs +++ b/src/name_analysis/resolve.rs @@ -161,8 +161,33 @@ fn resolve_use_statement( todo!() } + let base_name = use_statement.base_name().to_string(); + match &use_statement.last { - UseStatementLast::Identifier(identifier) => {} + UseStatementLast::Identifier(identifier) => { + let borrowed_identifier = identifier.borrow(); + let declared_name = borrowed_identifier.name().to_string(); + let fqn = format!("{}::{}", &base_name, &declared_name); + let lookup_result = + symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap()); + drop(borrowed_identifier); + + if let Err(_) = lookup_result { + diagnostics.push( + Diagnostic::error() + .with_message(&format!("Unable to find symbol '{}'.", fqn)) + .with_label(Label::primary(use_statement.file_id, use_statement.range)), + ); + } else { + let mut mutable_borrowed_identifier = identifier.borrow_mut(); + let use_statement_symbol = mutable_borrowed_identifier + .symbol_mut() + .unwrap() + .unwrap_use_statement_symbol(); + let mut mutable_borrowed_use_statement_symbol = use_statement_symbol.borrow_mut(); + mutable_borrowed_use_statement_symbol.set_referenced_symbol(lookup_result.unwrap()) + } + } UseStatementLast::Identifiers(identifiers) => {} UseStatementLast::Star => panic!(), } diff --git a/src/name_analysis/symbol.rs b/src/name_analysis/symbol.rs index c974d0d..ecf444a 100644 --- a/src/name_analysis/symbol.rs +++ b/src/name_analysis/symbol.rs @@ -45,14 +45,14 @@ impl SourceDefinition { pub trait SymbolInner { fn declared_name(&self) -> &str; - fn definition(&self) -> &Option; + fn definition(&self) -> Option; } /* Symbol */ #[derive(Debug, Clone)] pub enum Symbol { - UseStatement(Rc), + UseStatement(Rc>), Module(Rc), Type(Rc), Function(Rc), @@ -61,20 +61,9 @@ pub enum Symbol { } impl Symbol { - pub fn name(&self) -> &str { + pub fn definition(&self) -> Option { match self { - Symbol::UseStatement(s) => s.declared_name(), - Symbol::Module(s) => s.declared_name(), - Symbol::Type(s) => s.declared_name(), - Symbol::Function(s) => s.declared_name(), - Symbol::Parameter(s) => s.declared_name(), - Symbol::Variable(s) => s.declared_name(), - } - } - - pub fn definition(&self) -> &Option { - match self { - Symbol::UseStatement(s) => s.definition(), + Symbol::UseStatement(s) => s.borrow().definition.clone(), Symbol::Module(s) => s.definition(), Symbol::Type(s) => s.definition(), Symbol::Function(s) => s.definition(), @@ -83,9 +72,9 @@ impl Symbol { } } - pub fn unwrap_use_statement_symbol(&self) -> &UseStatementSymbol { + pub fn unwrap_use_statement_symbol(&self) -> Rc> { match self { - Symbol::UseStatement(s) => s, + Symbol::UseStatement(s) => s.clone(), _ => panic!("unwrap_use_statement_symbol called on non-use statement symbol"), } } @@ -95,7 +84,7 @@ impl Display for Symbol { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use Symbol::*; match self { - UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol), + UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()), Module(module_symbol) => write!(f, "{}", module_symbol), Type(class_symbol) => write!(f, "{}", class_symbol), Function(function_symbol) => write!(f, "{}", function_symbol), @@ -139,8 +128,8 @@ impl SymbolInner for UseStatementSymbol { &self.declared_name } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } @@ -186,8 +175,8 @@ impl SymbolInner for ModuleSymbol { self.declared_name.as_str() } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } @@ -235,8 +224,8 @@ impl SymbolInner for TypeSymbol { &self.declared_name } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } @@ -288,8 +277,8 @@ impl SymbolInner for FunctionSymbol { self.declared_name.as_str() } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } @@ -325,8 +314,8 @@ impl SymbolInner for ParameterSymbol { &self.declared_name } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } @@ -364,8 +353,8 @@ impl SymbolInner for VariableSymbol { self.declared_name.as_str() } - fn definition(&self) -> &Option { - &self.definition + fn definition(&self) -> Option { + self.definition.clone() } } diff --git a/src/name_analysis/symbol_table.rs b/src/name_analysis/symbol_table.rs index 86aef8f..c23708f 100644 --- a/src/name_analysis/symbol_table.rs +++ b/src/name_analysis/symbol_table.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use crate::name_analysis::symbol::{ FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol, UseStatementSymbol, VariableSymbol, @@ -12,7 +13,7 @@ use std::rc::Rc; #[derive(Debug)] struct Scope { parent: Option, - use_statement_symbols: HashMap>, + use_statement_symbols: HashMap>>, module_symbols: HashMap>, type_symbols: HashMap>, function_symbols: HashMap>, @@ -42,6 +43,7 @@ impl Scope { .or_else(|| self.function_symbols.get(name).map(|s| Symbol::Function(s.clone()))) .or_else(|| self.type_symbols.get(name).map(|ts| Symbol::Type(ts.clone()))) .or_else(|| self.module_symbols.get(name).map(|ms| Symbol::Module(ms.clone()))) + .or_else(|| self.use_statement_symbols.get(name).map(|us| Symbol::UseStatement(us.clone()))) } fn get_module_symbol_by_declared_name(&self, name: &str) -> Option> { @@ -159,7 +161,7 @@ impl SymbolTable { } else { current_scope.use_statement_symbols.insert( use_statement_symbol.declared_name().to_string(), - Rc::new(use_statement_symbol), + Rc::new(RefCell::new(use_statement_symbol)), ); Ok(()) } @@ -287,7 +289,7 @@ impl Display for SymbolTable { for (i, scope) in self.scopes.iter().enumerate() { writeln!(f, "Scope {} {}", i, scope.debug_name)?; for (name, symbol) in &scope.use_statement_symbols { - writeln!(f, " {}({})", name, symbol)?; + writeln!(f, " {}({})", name, symbol.borrow())?; } for (name, symbol) in &scope.module_symbols { writeln!(f, " {}({})", name, symbol)?; diff --git a/src/std_core/mod.rs b/src/std_core/mod.rs index 4aeee04..4f031d1 100644 --- a/src/std_core/mod.rs +++ b/src/std_core/mod.rs @@ -1,27 +1,23 @@ -use crate::name_analysis::symbol::{FunctionSymbol, Symbol, TypeSymbol}; +use crate::name_analysis::symbol::{FunctionSymbol, TypeSymbol}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { - symbol_table.insert_type_symbol( - TypeSymbol::new("std::core:Array", "Array", true, None), - )?; - symbol_table.insert_function_symbol( - FunctionSymbol::new( - "std::core::println", - "println", - true, - true, - None, - ), - )?; - symbol_table.insert_function_symbol( - FunctionSymbol::new( - "std::core::print", - "print", - true, - true, - None, - ), - )?; + symbol_table.insert_type_symbol(TypeSymbol::new("std::core:Array", "Array", true, None))?; + // todo: make this primitive + symbol_table.insert_type_symbol(TypeSymbol::new("std::core::String", "String", true, None))?; + symbol_table.insert_function_symbol(FunctionSymbol::new( + "std::core::println", + "println", + true, + true, + None, + ))?; + symbol_table.insert_function_symbol(FunctionSymbol::new( + "std::core::print", + "print", + true, + true, + None, + ))?; Ok(()) }