Work on functions and parameter name resolution.
This commit is contained in:
parent
9b83a531ca
commit
12a3a61156
@ -1,7 +1,7 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
||||||
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
|
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameter,
|
||||||
PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement,
|
Parameters, PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement,
|
||||||
UseStatementIdentifier, UseStatementPrefix,
|
UseStatementIdentifier, UseStatementPrefix,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
@ -14,7 +14,7 @@ use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::name_analysis::util::{
|
use crate::name_analysis::util::{
|
||||||
format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts,
|
format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts,
|
||||||
};
|
};
|
||||||
@ -243,8 +243,6 @@ fn na_p1_function(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
|
||||||
|
|
||||||
let to_insert = FunctionSymbol::new(
|
let to_insert = FunctionSymbol::new(
|
||||||
&symbol_table.resolve_fqn(Rc::from(function.identifier().name())),
|
&symbol_table.resolve_fqn(Rc::from(function.identifier().name())),
|
||||||
function.is_public(),
|
function.is_public(),
|
||||||
@ -253,8 +251,26 @@ fn na_p1_function(
|
|||||||
);
|
);
|
||||||
let function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
let function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
||||||
Ok(function_symbol) => {
|
Ok(function_symbol) => {
|
||||||
{
|
Some(function_symbol)
|
||||||
let mut as_ref_mut = function_symbol.borrow_mut();
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
function.identifier().name(),
|
||||||
|
function.identifier().file_id(),
|
||||||
|
function.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if function_symbol.is_some() {
|
||||||
|
let mut as_ref_mut = function_symbol.as_ref().unwrap().borrow_mut();
|
||||||
|
|
||||||
|
// push a scope for this function
|
||||||
|
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
||||||
|
|
||||||
// generics
|
// generics
|
||||||
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
|
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
|
||||||
|
|
||||||
@ -271,22 +287,14 @@ fn na_p1_function(
|
|||||||
if let Some(type_symbol) = return_type {
|
if let Some(type_symbol) = return_type {
|
||||||
as_ref_mut.set_return_type(type_symbol);
|
as_ref_mut.set_return_type(type_symbol);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Some(function_symbol)
|
symbol_table.push_scope(&format!("FunctionBodyScope {}", function.identifier().name()));
|
||||||
}
|
|
||||||
Err(symbol_insert_error) => {
|
na_p1_function_body(function.function_body_mut(), symbol_table, diagnostics);
|
||||||
handle_insert_error(
|
|
||||||
symbol_insert_error,
|
|
||||||
function.identifier().name(),
|
|
||||||
function.identifier().file_id(),
|
|
||||||
function.identifier().range(),
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
|
||||||
function_symbol
|
function_symbol
|
||||||
}
|
}
|
||||||
@ -296,7 +304,40 @@ fn na_p1_parameters(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Vec<Rc<RefCell<ParameterSymbol>>> {
|
) -> Vec<Rc<RefCell<ParameterSymbol>>> {
|
||||||
todo!()
|
parameters
|
||||||
|
.parameters_mut()
|
||||||
|
.map(|parameter| na_p1_parameter(parameter, symbol_table, diagnostics))
|
||||||
|
.filter(Option::is_some)
|
||||||
|
.map(Option::unwrap)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_parameter(
|
||||||
|
parameter: &mut Parameter,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<Rc<RefCell<ParameterSymbol>>> {
|
||||||
|
let parameter_type_symbol = na_p1_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
|
||||||
|
let to_insert = ParameterSymbol::new(
|
||||||
|
parameter.identifier().name(),
|
||||||
|
Some(SourceDefinition::from_identifier(parameter.identifier())),
|
||||||
|
parameter_type_symbol,
|
||||||
|
);
|
||||||
|
match symbol_table.insert_parameter_symbol(to_insert) {
|
||||||
|
Ok(parameter_symbol) => {
|
||||||
|
Some(parameter_symbol)
|
||||||
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
parameter.identifier().name(),
|
||||||
|
parameter.identifier().file_id(),
|
||||||
|
parameter.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn na_p1_return_type(
|
fn na_p1_return_type(
|
||||||
@ -430,5 +471,19 @@ fn na_p1_function_body(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
match function_body {
|
||||||
|
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||||
|
// no-op, resolve in pass 2
|
||||||
|
}
|
||||||
|
FunctionBody::FunctionEqualsBody(equals_body) => {
|
||||||
|
// see below
|
||||||
|
}
|
||||||
|
FunctionBody::FunctionBlockBody(block_body) => {
|
||||||
|
// we need to do all insertion/resolution in pass 2, because we
|
||||||
|
// might call functions/use classes/etc from the same compilation
|
||||||
|
// unit which haven't been defined yet. So the strategy is to set
|
||||||
|
// the scope id for the body and then in pass 2, set the symbol
|
||||||
|
// table's current scope to that id.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,6 +71,8 @@ mod tests {
|
|||||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::name_analysis::symbol::use_symbol::StarUseSymbol;
|
||||||
|
|
||||||
fn parse_compilation_units<'a>(
|
fn parse_compilation_units<'a>(
|
||||||
files: &mut SimpleFiles<&'a str, &'a str>,
|
files: &mut SimpleFiles<&'a str, &'a str>,
|
||||||
@ -189,4 +191,26 @@ mod tests {
|
|||||||
)]);
|
)]);
|
||||||
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sees_println() {
|
||||||
|
let sources = HashMap::from([(
|
||||||
|
"main.dm",
|
||||||
|
"
|
||||||
|
fn main(args: Array<String>)
|
||||||
|
println args
|
||||||
|
end
|
||||||
|
"
|
||||||
|
)]);
|
||||||
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
let global_std_core_use = StarUseSymbol::new(
|
||||||
|
&[Rc::from("std"), Rc::from("core")],
|
||||||
|
None
|
||||||
|
);
|
||||||
|
symbol_table.insert_star_use_symbol(global_std_core_use)
|
||||||
|
.expect("Failed to insert star use symbol.");
|
||||||
|
|
||||||
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std/core symbols.");
|
||||||
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -35,8 +36,10 @@ impl ClassMemberSymbol {
|
|||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
impl Symbol for ClassMemberSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/name_analysis/symbol/lv_symbol.rs
Normal file
28
src/name_analysis/symbol/lv_symbol.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
|
|
||||||
|
pub enum LVSymbol {
|
||||||
|
ClassMember(Rc<RefCell<ClassMemberSymbol>>),
|
||||||
|
Parameter(Rc<RefCell<ParameterSymbol>>),
|
||||||
|
Variable(Rc<RefCell<VariableSymbol>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LVSymbol {
|
||||||
|
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
|
||||||
|
match self {
|
||||||
|
LVSymbol::ClassMember(class_member_symbol) => {
|
||||||
|
class_member_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
LVSymbol::Parameter(parameter_symbol) => {
|
||||||
|
parameter_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
LVSymbol::Variable(variable_symbol) => {
|
||||||
|
variable_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ pub mod class_symbol;
|
|||||||
pub mod function_symbol;
|
pub mod function_symbol;
|
||||||
pub mod generic_type_symbol;
|
pub mod generic_type_symbol;
|
||||||
pub mod interface_symbol;
|
pub mod interface_symbol;
|
||||||
|
pub mod lv_symbol;
|
||||||
pub mod module_level_symbol;
|
pub mod module_level_symbol;
|
||||||
pub mod module_symbol;
|
pub mod module_symbol;
|
||||||
pub mod parameter_symbol;
|
pub mod parameter_symbol;
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: String,
|
declared_name: Rc<str>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
type_symbol: Option<TypeSymbol>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
}
|
}
|
||||||
@ -14,8 +16,8 @@ impl ParameterSymbol {
|
|||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
type_symbol: Option<TypeSymbol>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParameterSymbol {
|
Self {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: Rc::from(declared_name),
|
||||||
source_definition,
|
source_definition,
|
||||||
type_symbol,
|
type_symbol,
|
||||||
}
|
}
|
||||||
@ -25,7 +27,13 @@ impl ParameterSymbol {
|
|||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.declared_name.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol for ParameterSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -9,7 +10,11 @@ pub struct VariableSymbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VariableSymbol {
|
impl VariableSymbol {
|
||||||
pub fn new(declared_name: &str, is_mutable: bool, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(
|
||||||
|
declared_name: &str,
|
||||||
|
is_mutable: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
VariableSymbol {
|
VariableSymbol {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
is_mutable,
|
is_mutable,
|
||||||
@ -24,8 +29,10 @@ impl VariableSymbol {
|
|||||||
pub fn is_mutable(&self) -> bool {
|
pub fn is_mutable(&self) -> bool {
|
||||||
self.is_mutable
|
self.is_mutable
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
impl Symbol for VariableSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
@ -112,6 +113,10 @@ impl SymbolTable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_module(&mut self, fqn_parts: &[&str]) {
|
||||||
|
self.symbol_tree.register_module_by_fqn_parts(fqn_parts);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_usable_symbols_by_base_fqn(
|
pub fn find_usable_symbols_by_base_fqn(
|
||||||
&self,
|
&self,
|
||||||
fqn_parts: &[Rc<str>],
|
fqn_parts: &[Rc<str>],
|
||||||
@ -205,6 +210,23 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_parameter_symbol(
|
||||||
|
&mut self,
|
||||||
|
parameter_symbol: ParameterSymbol,
|
||||||
|
) -> Result<Rc<RefCell<ParameterSymbol>>, SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) = self
|
||||||
|
.current_scope()
|
||||||
|
.find_lv_symbol(parameter_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
|
} else {
|
||||||
|
let inserted = self
|
||||||
|
.current_scope_mut()
|
||||||
|
.insert_parameter_symbol(parameter_symbol);
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lookup_type(&self, declared_name: &str) -> Result<TypeSymbol, SymbolLookupError> {
|
pub fn lookup_type(&self, declared_name: &str) -> Result<TypeSymbol, SymbolLookupError> {
|
||||||
let mut current_scope: Option<&Scope> = Some(self.current_scope());
|
let mut current_scope: Option<&Scope> = Some(self.current_scope());
|
||||||
while let Some(scope) = current_scope.take() {
|
while let Some(scope) = current_scope.take() {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::lv_symbol::LVSymbol;
|
||||||
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
@ -26,9 +27,9 @@ pub struct Scope {
|
|||||||
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
||||||
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
|
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
|
||||||
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
|
parameter_symbols: HashMap<Rc<str>, Rc<RefCell<ParameterSymbol>>>,
|
||||||
variable_symbols: HashMap<Rc<str>, VariableSymbol>,
|
variable_symbols: HashMap<Rc<str>, Rc<RefCell<VariableSymbol>>>,
|
||||||
class_member_symbols: HashMap<Rc<str>, ClassMemberSymbol>,
|
class_member_symbols: HashMap<Rc<str>, Rc<RefCell<ClassMemberSymbol>>>,
|
||||||
debug_name: String,
|
debug_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,11 +127,22 @@ impl Scope {
|
|||||||
self.class_symbols.get(declared_name)
|
self.class_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_generic_type_symbol(&mut self, symbol: GenericTypeSymbol) -> Rc<RefCell<GenericTypeSymbol>> {
|
pub fn insert_generic_type_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: GenericTypeSymbol,
|
||||||
|
) -> Rc<RefCell<GenericTypeSymbol>> {
|
||||||
let key = symbol.declared_name_owned();
|
let key = symbol.declared_name_owned();
|
||||||
insert_symbol!(self.generic_symbols, symbol, key)
|
insert_symbol!(self.generic_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_parameter_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: ParameterSymbol,
|
||||||
|
) -> Rc<RefCell<ParameterSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.parameter_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
||||||
self.module_symbols
|
self.module_symbols
|
||||||
.get(declared_name)
|
.get(declared_name)
|
||||||
@ -168,6 +180,22 @@ impl Scope {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_lv_symbol(&self, declared_name: &str) -> Option<LVSymbol> {
|
||||||
|
self.class_member_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|class_member_symbol| LVSymbol::ClassMember(class_member_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.parameter_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|parameter_symbol| LVSymbol::Parameter(parameter_symbol.clone()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.variable_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|variable_symbol| LVSymbol::Variable(variable_symbol.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn debug_name(&self) -> &str {
|
pub fn debug_name(&self) -> &str {
|
||||||
&self.debug_name
|
&self.debug_name
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,6 +63,15 @@ impl SymbolTree {
|
|||||||
self.recurse_register_module(&module_symbol.borrow().fqn_parts());
|
self.recurse_register_module(&module_symbol.borrow().fqn_parts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_module_by_fqn_parts(&mut self, fqn_parts: &[&str]) {
|
||||||
|
self.recurse_register_module(
|
||||||
|
&fqn_parts
|
||||||
|
.iter()
|
||||||
|
.map(|part| Rc::from(*part))
|
||||||
|
.collect::<Vec<Rc<str>>>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn recurse_register_module(&mut self, fqn_parts: &[Rc<str>]) {
|
fn recurse_register_module(&mut self, fqn_parts: &[Rc<str>]) {
|
||||||
if fqn_parts.len() == 0 {
|
if fqn_parts.len() == 0 {
|
||||||
panic!("Unable to register module fqn with no parts.")
|
panic!("Unable to register module fqn with no parts.")
|
||||||
|
|||||||
@ -7,11 +7,16 @@ use std::cell::RefCell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
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.register_module(&["std"]);
|
||||||
|
symbol_table.register_module(&["std", "core"]);
|
||||||
|
|
||||||
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
||||||
|
|
||||||
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(
|
let println_msg_symbol = ParameterSymbol::new(
|
||||||
TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)
|
"msg",
|
||||||
));
|
None,
|
||||||
|
Some(TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)),
|
||||||
|
);
|
||||||
|
|
||||||
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
||||||
&symbol_table.resolve_fqn(Rc::from("println")),
|
&symbol_table.resolve_fqn(Rc::from("println")),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user