Refactoring of name-analysis.

This commit is contained in:
Jesse Brault 2025-05-19 09:53:08 -05:00
parent c606432be2
commit abb7aab3a4
8 changed files with 374 additions and 215 deletions

View File

@ -1,17 +1,11 @@
ns greeter ns greeter;
fn main(x: String) { class Array<T> {}
let x = 'Hello';
let y = 'World'; class String {}
{
let test = 'test'; platform fn println(msg: Any) -> Void;
let x = 'x';
let y = 'y'; fn main(args: Array<String>) {
let z = 'z'; println(args);
let test = 'oops.';
};
} }
pub mod test {
}

View File

@ -57,12 +57,18 @@ pub enum SuffixUnaryOperator {
/* Names */ /* Names */
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SavedSymbol {
Declaration(Symbol),
Linking(Symbol),
}
#[derive(Debug)]
pub struct Identifier { pub struct Identifier {
pub name: String, pub name: String,
pub file_id: usize, pub file_id: usize,
pub range: Range<usize>, pub range: Range<usize>,
scope_id: Option<usize>, scope_id: Option<usize>,
symbol: Option<Symbol>, saved_symbol: Option<SavedSymbol>,
} }
impl Identifier { impl Identifier {
@ -72,7 +78,7 @@ impl Identifier {
file_id, file_id,
range, range,
scope_id: None, scope_id: None,
symbol: None, saved_symbol: None,
} }
} }
@ -84,16 +90,12 @@ impl Identifier {
self.scope_id self.scope_id
} }
pub fn set_symbol(&mut self, symbol: Symbol) { pub fn set_saved_symbol(&mut self, saved_symbol: SavedSymbol) {
self.symbol = Some(symbol); self.saved_symbol = Some(saved_symbol);
} }
pub fn symbol(&self) -> &Option<Symbol> { pub fn saved_symbol(&self) -> Option<SavedSymbol> {
&self.symbol self.saved_symbol.clone()
}
pub fn symbol_mut(&mut self) -> Option<Symbol> {
self.symbol.clone()
} }
} }
@ -465,8 +467,6 @@ pub struct UseStatement {
pub last: UseStatementLast, pub last: UseStatementLast,
pub file_id: usize, pub file_id: usize,
pub range: Range<usize>, pub range: Range<usize>,
scope_id: Option<usize>,
symbol: Option<Symbol>,
} }
pub struct UseStatementImport<'a> { pub struct UseStatementImport<'a> {
@ -487,8 +487,6 @@ impl UseStatement {
last, last,
file_id, file_id,
range, range,
scope_id: None,
symbol: None,
} }
} }
@ -519,22 +517,6 @@ impl UseStatement {
_ => false, _ => false,
} }
} }
pub fn set_scope_id(&mut self, scope_id: usize) {
self.scope_id = Some(scope_id);
}
pub fn scope_id(&self) -> Option<usize> {
self.scope_id
}
pub fn set_symbol(&mut self, symbol: Symbol) {
self.symbol = Some(symbol);
}
pub fn symbol(&self) -> &Option<Symbol> {
&self.symbol
}
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -6,6 +6,7 @@ use crate::name_analysis::symbol::*;
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
use codespan_reporting::diagnostic::{Diagnostic, Label}; use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::cell::RefCell; use std::cell::RefCell;
use std::ops::DerefMut;
use std::range::Range; use std::range::Range;
use std::rc::Rc; use std::rc::Rc;
@ -41,6 +42,10 @@ fn handle_insert_error(
} }
} }
fn gather_identifier(identifier: &mut Identifier, symbol_table: &mut SymbolTable) {
identifier.set_scope_id(symbol_table.current_scope_id());
}
fn gather_fully_qualified_name( fn gather_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName, fully_qualified_name: &mut FullyQualifiedName,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
@ -153,28 +158,30 @@ fn handle_use_statement_import(
&declared_name, &declared_name,
Some(identifier.clone()), Some(identifier.clone()),
)); ));
if let Err(err) = insert_result {
handle_insert_error( match insert_result {
err, Ok(use_statement_symbol) => {
&declared_name, drop(borrowed_identifier);
borrowed_identifier.file_id,
borrowed_identifier.range, let mut mutable_borrowed_identifier = identifier.borrow_mut();
"Use statement",
diagnostics, gather_identifier(mutable_borrowed_identifier.deref_mut(), symbol_table);
);
mutable_borrowed_identifier.set_saved_symbol(SavedSymbol::Linking(
Symbol::UseStatement(use_statement_symbol),
));
}
Err(err) => {
handle_insert_error(
err,
&declared_name,
borrowed_identifier.file_id,
borrowed_identifier.range,
"Use statement",
diagnostics,
);
}
} }
drop(borrowed_identifier);
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( fn gather_use_statement(
@ -321,30 +328,55 @@ fn gather_function_definition(
Some(&function.identifier), Some(&function.identifier),
)); ));
if let Err(err) = insert_result { match insert_result {
handle_insert_error( Ok(function_symbol) => {
err, function
&declared_name, .identifier
function.identifier.file_id, .set_scope_id(symbol_table.current_scope_id());
function.identifier.range,
"function/variable", symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
diagnostics,
) let parameters_result = gather_parameters(
&mut function.parameters,
symbol_table,
fqn_context,
diagnostics,
);
match parameters_result {
Some(parameter_symbols) => {
function_symbol
.borrow_mut()
.set_parameters(parameter_symbols);
}
None => {}
}
gather_return_type(
&mut function.return_type,
symbol_table,
fqn_context,
diagnostics,
);
symbol_table.push_scope(&format!("FunctionBodyScope({})", resolved_name));
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
symbol_table.pop_scope(); // body
symbol_table.pop_scope(); // parameters
}
Err(err) => {
handle_insert_error(
err,
&declared_name,
function.identifier.file_id,
function.identifier.range,
"function/variable",
diagnostics,
);
}
} }
function
.identifier
.set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!("FunctionScope({})", resolved_name));
gather_parameters(
&mut function.parameters,
symbol_table,
fqn_context,
diagnostics,
);
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
symbol_table.pop_scope();
} }
fn gather_platform_function_definition( fn gather_platform_function_definition(
@ -364,31 +396,56 @@ fn gather_platform_function_definition(
Some(&platform_function_declaration.identifier), Some(&platform_function_declaration.identifier),
)); ));
if let Err(err) = insert_result { match insert_result {
handle_insert_error( Ok(function_symbol) => {
err, let declared_name_as_string =
&declared_name, platform_function_declaration.identifier.name().to_string();
platform_function_declaration.identifier.file_id,
platform_function_declaration.identifier.range, platform_function_declaration
"(Platform-) Function", .identifier
diagnostics, .set_scope_id(symbol_table.current_scope_id());
);
symbol_table.push_scope(&format!(
"FunctionParameterScope({})",
declared_name_as_string
));
let parameter_symbols_result = gather_parameters(
&mut platform_function_declaration.parameters,
symbol_table,
fqn_context,
diagnostics,
);
match parameter_symbols_result {
Some(parameter_symbols) => {
function_symbol
.borrow_mut()
.set_parameters(parameter_symbols);
}
None => {}
}
gather_return_type(
&mut platform_function_declaration.return_type,
symbol_table,
fqn_context,
diagnostics,
);
symbol_table.pop_scope();
}
Err(err) => {
handle_insert_error(
err,
&declared_name,
platform_function_declaration.identifier.file_id,
platform_function_declaration.identifier.range,
"(Platform-) Function",
diagnostics,
);
}
} }
let declared_name_as_string = platform_function_declaration.identifier.name().to_string();
platform_function_declaration
.identifier
.set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!("FunctionScope({})", declared_name_as_string));
gather_parameters(
&mut platform_function_declaration.parameters,
symbol_table,
fqn_context,
diagnostics,
);
symbol_table.pop_scope();
} }
fn gather_parameters( fn gather_parameters(
@ -396,10 +453,12 @@ fn gather_parameters(
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext, fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) -> Option<Vec<Rc<ParameterSymbol>>> {
for parameter in &mut parameters.0 { parameters
gather_parameter(parameter, symbol_table, fqn_context, diagnostics); .0
} .iter_mut()
.map(|parameter| gather_parameter(parameter, symbol_table, fqn_context, diagnostics))
.collect()
} }
fn gather_parameter( fn gather_parameter(
@ -407,7 +466,7 @@ fn gather_parameter(
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext, fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) -> Option<Rc<ParameterSymbol>> {
let parameter_name = parameter.identifier.name(); let parameter_name = parameter.identifier.name();
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new( let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
@ -415,27 +474,63 @@ fn gather_parameter(
Some(&parameter.identifier), Some(&parameter.identifier),
)); ));
if let Err(err) = insert_result { match insert_result {
handle_insert_error( Ok(parameter_symbol) => {
err, parameter
&parameter_name, .identifier
parameter.identifier.file_id, .set_scope_id(symbol_table.current_scope_id());
parameter.identifier.range,
"function/variable", gather_type_use(
diagnostics, &mut parameter.type_use,
) symbol_table,
fqn_context,
diagnostics,
);
Some(parameter_symbol)
}
Err(err) => {
handle_insert_error(
err,
&parameter_name,
parameter.identifier.file_id,
parameter.identifier.range,
"function/variable",
diagnostics,
);
None
}
} }
}
parameter fn gather_return_type(
.identifier return_type: &mut ReturnType,
.set_scope_id(symbol_table.current_scope_id()); symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_type_use( gather_type_use(
&mut parameter.type_use, &mut return_type.declared_type,
symbol_table, symbol_table,
fqn_context, fqn_context,
diagnostics, diagnostics,
) );
gather_references(
&mut return_type.references,
symbol_table,
fqn_context,
diagnostics,
);
}
fn gather_references(
references: &mut References,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for identifier in &mut references.0 {
gather_identifier(identifier, symbol_table);
}
} }
fn gather_function_body( fn gather_function_body(
@ -673,7 +768,7 @@ fn gather_object_access(
gather_expression(index_expression, symbol_table, diagnostics); gather_expression(index_expression, symbol_table, diagnostics);
} }
ObjectNavigation::Identifier(identifier) => { ObjectNavigation::Identifier(identifier) => {
identifier.set_scope_id(symbol_table.current_scope_id()); gather_identifier(identifier, symbol_table);
} }
} }
} }

View File

@ -105,10 +105,6 @@ mod tests {
"main.dm", "main.dm",
indoc! {" indoc! {"
use test::Greeter; use test::Greeter;
fn main(args: Array<String>) {
println(\"Hello, World!\");
}
"}, "},
), ),
( (
@ -123,4 +119,18 @@ mod tests {
assert_no_diagnostics(sources); assert_no_diagnostics(sources);
} }
#[test]
fn sees_std_core_println() {
let sources: HashMap<&str, &str> = HashMap::from([(
"main.dm",
indoc! {"
fn main(args: Array<String>) {
println(args)
}
"},
)]);
assert_no_diagnostics(sources);
}
} }

View File

@ -3,6 +3,9 @@ use crate::ast::*;
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
use codespan_reporting::diagnostic::{Diagnostic, Label}; use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::cell::RefCell;
use std::range::Range;
use std::rc::Rc;
fn resolve_fully_qualified_name( fn resolve_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName, fully_qualified_name: &mut FullyQualifiedName,
@ -152,44 +155,74 @@ fn resolve_references(
} }
} }
fn handle_use_statement_identifier(
identifier: &Rc<RefCell<Identifier>>,
base_name: &str,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
file_id: usize,
error_range: Range<usize>,
) {
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());
match lookup_result {
Ok(referenced_symbol) => match borrowed_identifier.saved_symbol() {
Some(saved_symbol) => match saved_symbol {
SavedSymbol::Linking(symbol) => {
let use_statement_symbol = symbol.unwrap_use_statement_symbol();
use_statement_symbol
.borrow_mut()
.set_referenced_symbol(referenced_symbol);
}
_ => panic!("Expected to find SavedSymbol::Linking."),
},
None => panic!("Expected to find saved_symbol"),
},
Err(_) => {
diagnostics.push(
Diagnostic::error()
.with_message(&format!("Unable to find symbol '{}'.", fqn))
.with_label(Label::primary(file_id, error_range)),
);
}
}
}
fn resolve_use_statement( fn resolve_use_statement(
use_statement: &mut UseStatement, use_statement: &mut UseStatement,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
if use_statement.is_star() {
todo!()
}
let base_name = use_statement.base_name().to_string(); let base_name = use_statement.base_name().to_string();
match &use_statement.last { match &use_statement.last {
UseStatementLast::Identifier(identifier) => { UseStatementLast::Identifier(identifier) => {
let borrowed_identifier = identifier.borrow(); handle_use_statement_identifier(
let declared_name = borrowed_identifier.name().to_string(); identifier,
let fqn = format!("{}::{}", &base_name, &declared_name); &base_name,
let lookup_result = symbol_table,
symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap()); diagnostics,
drop(borrowed_identifier); use_statement.file_id,
use_statement.range,
if let Err(_) = lookup_result { );
diagnostics.push( }
Diagnostic::error() UseStatementLast::Identifiers(identifiers) => {
.with_message(&format!("Unable to find symbol '{}'.", fqn)) for identifier in identifiers {
.with_label(Label::primary(use_statement.file_id, use_statement.range)), handle_use_statement_identifier(
); identifier,
} else { &base_name,
let mut mutable_borrowed_identifier = identifier.borrow_mut(); symbol_table,
let use_statement_symbol = mutable_borrowed_identifier diagnostics,
.symbol_mut() use_statement.file_id,
.unwrap() identifier.borrow().range,
.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 => todo!(),
UseStatementLast::Star => panic!(),
} }
} }

View File

@ -1,5 +1,5 @@
use std::cell::RefCell;
use crate::ast::{Identifier, UseStatement}; use crate::ast::{Identifier, UseStatement};
use std::cell::RefCell;
use std::fmt::Display; use std::fmt::Display;
use std::range::Range; use std::range::Range;
use std::rc::Rc; use std::rc::Rc;
@ -17,7 +17,7 @@ impl SourceDefinition {
range: identifier.range, range: identifier.range,
} }
} }
pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self { pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self {
let borrowed = identifier.borrow(); let borrowed = identifier.borrow();
SourceDefinition { SourceDefinition {
@ -55,7 +55,7 @@ pub enum Symbol {
UseStatement(Rc<RefCell<UseStatementSymbol>>), UseStatement(Rc<RefCell<UseStatementSymbol>>),
Module(Rc<ModuleSymbol>), Module(Rc<ModuleSymbol>),
Type(Rc<TypeSymbol>), Type(Rc<TypeSymbol>),
Function(Rc<FunctionSymbol>), Function(Rc<RefCell<FunctionSymbol>>),
Parameter(Rc<ParameterSymbol>), Parameter(Rc<ParameterSymbol>),
Variable(Rc<VariableSymbol>), Variable(Rc<VariableSymbol>),
} }
@ -63,15 +63,15 @@ pub enum Symbol {
impl Symbol { impl Symbol {
pub fn definition(&self) -> Option<SourceDefinition> { pub fn definition(&self) -> Option<SourceDefinition> {
match self { match self {
Symbol::UseStatement(s) => s.borrow().definition.clone(), Symbol::UseStatement(s) => s.borrow().definition(),
Symbol::Module(s) => s.definition(), Symbol::Module(s) => s.definition(),
Symbol::Type(s) => s.definition(), Symbol::Type(s) => s.definition(),
Symbol::Function(s) => s.definition(), Symbol::Function(s) => s.borrow().definition(),
Symbol::Parameter(s) => s.definition(), Symbol::Parameter(s) => s.definition(),
Symbol::Variable(s) => s.definition(), Symbol::Variable(s) => s.definition(),
} }
} }
pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> { pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> {
match self { match self {
Symbol::UseStatement(s) => s.clone(), Symbol::UseStatement(s) => s.clone(),
@ -87,7 +87,7 @@ impl Display for Symbol {
UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()), UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()),
Module(module_symbol) => write!(f, "{}", module_symbol), Module(module_symbol) => write!(f, "{}", module_symbol),
Type(class_symbol) => write!(f, "{}", class_symbol), Type(class_symbol) => write!(f, "{}", class_symbol),
Function(function_symbol) => write!(f, "{}", function_symbol), Function(function_symbol) => write!(f, "{}", function_symbol.borrow()),
Parameter(parameter_symbol) => write!(f, "{}", parameter_symbol), Parameter(parameter_symbol) => write!(f, "{}", parameter_symbol),
Variable(variable_symbol) => write!(f, "{}", variable_symbol), Variable(variable_symbol) => write!(f, "{}", variable_symbol),
} }
@ -101,11 +101,15 @@ pub struct UseStatementSymbol {
pub fqn: String, pub fqn: String,
pub declared_name: String, pub declared_name: String,
definition: Option<SourceDefinition>, definition: Option<SourceDefinition>,
referenced_symbol: Option<Box<Symbol>> referenced_symbol: Option<Box<Symbol>>,
} }
impl UseStatementSymbol { impl UseStatementSymbol {
pub fn new(fqn: &str, declared_name: &str, identifier: Option<Rc<RefCell<Identifier>>>) -> Self { pub fn new(
fqn: &str,
declared_name: &str,
identifier: Option<Rc<RefCell<Identifier>>>,
) -> Self {
UseStatementSymbol { UseStatementSymbol {
fqn: fqn.to_string(), fqn: fqn.to_string(),
declared_name: declared_name.to_string(), declared_name: declared_name.to_string(),
@ -143,7 +147,6 @@ impl Display for UseStatementSymbol {
} }
} }
/* Module */ /* Module */
#[derive(Debug)] #[derive(Debug)]
@ -201,7 +204,12 @@ pub struct TypeSymbol {
} }
impl TypeSymbol { impl TypeSymbol {
pub fn new(fqn: &str, declared_name: &str, is_public: bool, identifier: Option<&Identifier>) -> Self { pub fn new(
fqn: &str,
declared_name: &str,
is_public: bool,
identifier: Option<&Identifier>,
) -> Self {
TypeSymbol { TypeSymbol {
fqn: fqn.to_string(), fqn: fqn.to_string(),
declared_name: declared_name.to_string(), declared_name: declared_name.to_string(),
@ -248,6 +256,8 @@ pub struct FunctionSymbol {
is_public: bool, is_public: bool,
is_platform: bool, is_platform: bool,
definition: Option<SourceDefinition>, definition: Option<SourceDefinition>,
parameters: Vec<Rc<ParameterSymbol>>,
return_type: Option<Rc<TypeSymbol>>,
} }
impl FunctionSymbol { impl FunctionSymbol {
@ -264,19 +274,53 @@ impl FunctionSymbol {
is_public, is_public,
is_platform, is_platform,
definition: identifier.map(SourceDefinition::from_identifier), definition: identifier.map(SourceDefinition::from_identifier),
parameters: Vec::new(),
return_type: None,
} }
} }
pub fn with_parameters(self, parameters: Vec<ParameterSymbol>) -> Self {
Self {
fqn: self.fqn,
declared_name: self.declared_name,
is_public: self.is_public,
is_platform: self.is_platform,
definition: self.definition,
parameters: parameters.into_iter().map(|parameter| Rc::new(parameter)).collect(),
return_type: self.return_type,
}
}
pub fn with_return_type(self, return_type: TypeSymbol) -> Self {
Self {
fqn: self.fqn,
declared_name: self.declared_name,
is_public: self.is_public,
is_platform: self.is_platform,
definition: self.definition,
parameters: self.parameters,
return_type: Some(Rc::new(return_type)),
}
}
pub fn fqn(&self) -> &str { pub fn fqn(&self) -> &str {
&self.fqn &self.fqn
} }
pub fn set_parameters(&mut self, parameters: Vec<Rc<ParameterSymbol>>) {
self.parameters = parameters;
}
pub fn set_return_type(&mut self, return_type: Rc<TypeSymbol>) {
self.return_type = Some(return_type);
}
} }
impl SymbolInner for FunctionSymbol { impl SymbolInner for FunctionSymbol {
fn declared_name(&self) -> &str { fn declared_name(&self) -> &str {
self.declared_name.as_str() self.declared_name.as_str()
} }
fn definition(&self) -> Option<SourceDefinition> { fn definition(&self) -> Option<SourceDefinition> {
self.definition.clone() self.definition.clone()
} }
@ -313,7 +357,7 @@ impl SymbolInner for ParameterSymbol {
fn declared_name(&self) -> &str { fn declared_name(&self) -> &str {
&self.declared_name &self.declared_name
} }
fn definition(&self) -> Option<SourceDefinition> { fn definition(&self) -> Option<SourceDefinition> {
self.definition.clone() self.definition.clone()
} }
@ -321,11 +365,7 @@ impl SymbolInner for ParameterSymbol {
impl Display for ParameterSymbol { impl Display for ParameterSymbol {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(f, "ParameterSymbol({})", self.declared_name)
f,
"ParameterSymbol({})",
self.declared_name
)
} }
} }
@ -352,7 +392,7 @@ impl SymbolInner for VariableSymbol {
fn declared_name(&self) -> &str { fn declared_name(&self) -> &str {
self.declared_name.as_str() self.declared_name.as_str()
} }
fn definition(&self) -> Option<SourceDefinition> { fn definition(&self) -> Option<SourceDefinition> {
self.definition.clone() self.definition.clone()
} }

View File

@ -16,7 +16,7 @@ struct Scope {
use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>, use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>,
module_symbols: HashMap<String, Rc<ModuleSymbol>>, module_symbols: HashMap<String, Rc<ModuleSymbol>>,
type_symbols: HashMap<String, Rc<TypeSymbol>>, type_symbols: HashMap<String, Rc<TypeSymbol>>,
function_symbols: HashMap<String, Rc<FunctionSymbol>>, function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>, parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
variable_symbols: HashMap<String, Rc<VariableSymbol>>, variable_symbols: HashMap<String, Rc<VariableSymbol>>,
debug_name: String, debug_name: String,
@ -57,7 +57,7 @@ impl Scope {
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> { fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
for function_symbol in self.function_symbols.values() { for function_symbol in self.function_symbols.values() {
if function_symbol.fqn() == fqn { if function_symbol.borrow().fqn() == fqn {
return Some(Symbol::Function(function_symbol.clone())); return Some(Symbol::Function(function_symbol.clone()));
} }
} }
@ -71,7 +71,7 @@ impl Scope {
fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> { fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
for function_symbol in self.function_symbols.values() { for function_symbol in self.function_symbols.values() {
if function_symbol.declared_name() == declared_name { if function_symbol.borrow().declared_name() == declared_name {
return Some(Symbol::Function(function_symbol.clone())); return Some(Symbol::Function(function_symbol.clone()));
} }
} }
@ -152,18 +152,21 @@ impl SymbolTable {
pub fn insert_use_statement_symbol( pub fn insert_use_statement_symbol(
&mut self, &mut self,
use_statement_symbol: UseStatementSymbol, use_statement_symbol: UseStatementSymbol,
) -> Result<(), SymbolInsertError> { ) -> Result<Rc<RefCell<UseStatementSymbol>>, SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = if let Some(defined_symbol) =
current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name()) current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name())
{ {
Err(SymbolAlreadyDefined(defined_symbol)) Err(SymbolAlreadyDefined(defined_symbol))
} else { } else {
let declared_name = use_statement_symbol.declared_name().to_string();
let to_insert = Rc::new(RefCell::new(use_statement_symbol));
let to_return = to_insert.clone();
current_scope.use_statement_symbols.insert( current_scope.use_statement_symbols.insert(
use_statement_symbol.declared_name().to_string(), declared_name,
Rc::new(RefCell::new(use_statement_symbol)), to_insert,
); );
Ok(()) Ok(to_return)
} }
} }
@ -203,36 +206,41 @@ impl SymbolTable {
pub fn insert_function_symbol( pub fn insert_function_symbol(
&mut self, &mut self,
function_symbol: FunctionSymbol, function_symbol: FunctionSymbol,
) -> Result<(), SymbolInsertError> { ) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = if let Some(defined_symbol) =
current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name()) current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name())
{ {
Err(SymbolAlreadyDefined(defined_symbol)) Err(SymbolAlreadyDefined(defined_symbol))
} else { } else {
let declared_name = function_symbol.declared_name().to_string();
let to_insert = Rc::new(RefCell::new(function_symbol));
let to_return = to_insert.clone();
current_scope.function_symbols.insert( current_scope.function_symbols.insert(
function_symbol.declared_name().to_string(), declared_name,
Rc::new(function_symbol), to_insert
); );
Ok(()) Ok(to_return)
} }
} }
pub fn insert_parameter_symbol( pub fn insert_parameter_symbol(
&mut self, &mut self,
parameter_symbol: ParameterSymbol, parameter_symbol: ParameterSymbol,
) -> Result<(), SymbolInsertError> { ) -> Result<Rc<ParameterSymbol>, SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = if let Some(defined_symbol) =
current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name()) current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name())
{ {
Err(SymbolAlreadyDefined(defined_symbol)) Err(SymbolAlreadyDefined(defined_symbol))
} else { } else {
let to_insert = Rc::new(parameter_symbol);
let to_return = to_insert.clone();
current_scope.parameter_symbols.insert( current_scope.parameter_symbols.insert(
parameter_symbol.declared_name().to_string(), to_insert.declared_name().to_string(),
Rc::new(parameter_symbol), to_insert,
); );
Ok(()) Ok(to_return)
} }
} }
@ -298,6 +306,9 @@ impl Display for SymbolTable {
writeln!(f, " {}({})", name, symbol)?; writeln!(f, " {}({})", name, symbol)?;
} }
for (name, symbol) in &scope.function_symbols { for (name, symbol) in &scope.function_symbols {
writeln!(f, " {}({})", name, symbol.borrow())?;
}
for (name, symbol) in &scope.parameter_symbols {
writeln!(f, " {}({})", name, symbol)?; writeln!(f, " {}({})", name, symbol)?;
} }
for (name, symbol) in &scope.variable_symbols { for (name, symbol) in &scope.variable_symbols {

View File

@ -1,23 +1,17 @@
use crate::name_analysis::symbol::{FunctionSymbol, TypeSymbol}; use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol, TypeSymbol};
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { 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_type_symbol(TypeSymbol::new("std::core:Array", "Array", true, None))?;
// todo: make this primitive // todo: make this primitive
symbol_table.insert_type_symbol(TypeSymbol::new("std::core::String", "String", true, None))?; symbol_table.insert_type_symbol(TypeSymbol::new("std::core::String", "String", true, None))?;
symbol_table.insert_function_symbol(FunctionSymbol::new( symbol_table.insert_function_symbol(
"std::core::println", FunctionSymbol::new("std::core::println", "println", true, true, None)
"println", .with_parameters(vec![ParameterSymbol::new("msg", None)]),
true, )?;
true, symbol_table.insert_function_symbol(
None, FunctionSymbol::new("std::core::print", "print", true, true, None)
))?; .with_parameters(vec![ParameterSymbol::new("msg", None)]),
symbol_table.insert_function_symbol(FunctionSymbol::new( )?;
"std::core::print",
"print",
true,
true,
None,
))?;
Ok(()) Ok(())
} }