deimos-lang/dmc-lib/src/symbol_table/helpers.rs

242 lines
7.4 KiB
Rust

use crate::scope::Scope;
use crate::scope::block_scope::BlockScope;
use crate::scope::class_body_scope::ClassBodyScope;
use crate::scope::class_scope::ClassScope;
use crate::scope::function_scope::FunctionScope;
use crate::scope::module_scope::ModuleScope;
use crate::symbol::Symbol;
use crate::symbol::class_symbol::ClassSymbol;
use crate::symbol::expressible_symbol::ExpressibleSymbol;
use crate::symbol::field_symbol::FieldSymbol;
use crate::symbol::function_symbol::FunctionSymbol;
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
use crate::symbol::parameter_symbol::ParameterSymbol;
use crate::symbol::type_symbol::TypeSymbol;
use crate::symbol::variable_symbol::VariableSymbol;
use std::collections::HashMap;
use std::rc::Rc;
fn find_class_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::Class(symbol.clone()))
}
fn find_generic_parameter_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<GenericParameterSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::GenericParameter(symbol.clone()))
}
fn find_field_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<FieldSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::Field(symbol.clone()))
}
fn find_function_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<FunctionSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::Function(symbol.clone()))
}
fn find_parameter_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<ParameterSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::Parameter(symbol.clone()))
}
fn find_variable_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<VariableSymbol>>,
name: &str,
) -> Option<Symbol> {
symbols
.get(name)
.map(|symbol| Symbol::Variable(symbol.clone()))
}
/* Expressible symbol refs */
fn find_class_expressible_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
name: &str,
) -> Option<ExpressibleSymbol> {
symbols
.get(name)
.map(|symbol| ExpressibleSymbol::Class(symbol.clone()))
}
fn find_field_expressible_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<FieldSymbol>>,
name: &str,
) -> Option<ExpressibleSymbol> {
symbols
.get(name)
.map(|symbol| ExpressibleSymbol::Field(symbol.clone()))
}
fn find_function_expressible_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<FunctionSymbol>>,
name: &str,
) -> Option<ExpressibleSymbol> {
symbols
.get(name)
.map(|symbol| ExpressibleSymbol::Function(symbol.clone()))
}
fn find_parameter_expressible_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<ParameterSymbol>>,
name: &str,
) -> Option<ExpressibleSymbol> {
symbols
.get(name)
.map(|symbol| ExpressibleSymbol::Parameter(symbol.clone()))
}
fn find_variable_expressible_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<VariableSymbol>>,
name: &str,
) -> Option<ExpressibleSymbol> {
symbols
.get(name)
.map(|symbol| ExpressibleSymbol::Variable(symbol.clone()))
}
/* Find type symbols */
fn find_class_type_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
name: &str,
) -> Option<TypeSymbol> {
symbols
.get(name)
.map(|symbol| TypeSymbol::Class(symbol.clone()))
}
fn find_generic_parameter_type_symbol_ref(
symbols: &HashMap<Rc<str>, Rc<GenericParameterSymbol>>,
name: &str,
) -> Option<TypeSymbol> {
symbols
.get(name)
.map(|symbol| TypeSymbol::GenericParameter(symbol.clone()))
}
/* Public helper functions */
/* Various find in functions */
pub fn find_in_module_by_name(module_scope: &ModuleScope, name: &str) -> Option<Symbol> {
find_function_symbol_ref(&module_scope.function_symbols(), name)
.or_else(|| find_class_symbol_ref(&module_scope.class_symbols(), name))
}
pub fn find_in_class_by_name(class_scope: &ClassScope, name: &str) -> Option<Symbol> {
find_generic_parameter_symbol_ref(&class_scope.generic_parameter_symbols(), name)
}
pub fn find_in_class_body_by_name(class_body_scope: &ClassBodyScope, name: &str) -> Option<Symbol> {
find_class_symbol_ref(&class_body_scope.class_symbols(), name)
.or_else(|| find_function_symbol_ref(&class_body_scope.function_symbols(), name))
.or_else(|| find_field_symbol_ref(&class_body_scope.field_symbols(), name))
}
pub fn find_in_function_by_name(function_scope: &FunctionScope, name: &str) -> Option<Symbol> {
find_parameter_symbol_ref(&function_scope.parameter_symbols(), name)
}
pub fn find_in_block_by_name(block_scope: &BlockScope, name: &str) -> Option<Symbol> {
find_variable_symbol_ref(&block_scope.variable_symbols(), name)
}
/* Find expressible */
fn find_expressible_in_module_by_name(
module_scope: &ModuleScope,
name: &str,
) -> Option<ExpressibleSymbol> {
find_class_expressible_symbol_ref(&module_scope.class_symbols(), name)
.or_else(|| find_function_expressible_symbol_ref(&module_scope.function_symbols(), name))
}
fn find_expressible_in_class_body_by_name(
class_body_scope: &ClassBodyScope,
name: &str,
) -> Option<ExpressibleSymbol> {
find_class_expressible_symbol_ref(&class_body_scope.class_symbols(), name)
.or_else(|| {
find_function_expressible_symbol_ref(&class_body_scope.function_symbols(), name)
})
.or_else(|| find_field_expressible_symbol_ref(&class_body_scope.field_symbols(), name))
}
fn find_expressible_in_function_by_name(
function_scope: &FunctionScope,
name: &str,
) -> Option<ExpressibleSymbol> {
find_parameter_expressible_symbol_ref(function_scope.parameter_symbols(), name)
}
fn find_expressible_in_block_by_name(
block_scope: &BlockScope,
name: &str,
) -> Option<ExpressibleSymbol> {
find_variable_expressible_symbol_ref(block_scope.variable_symbols(), name)
}
pub fn find_expressible_symbol(scope: &Scope, name: &str) -> Option<ExpressibleSymbol> {
match scope {
Scope::Module(module_scope) => find_expressible_in_module_by_name(module_scope, name),
Scope::Class(_) => None,
Scope::ClassBody(class_body_scope) => {
find_expressible_in_class_body_by_name(class_body_scope, name)
}
Scope::Function(function_scope) => {
find_expressible_in_function_by_name(function_scope, name)
}
Scope::Block(block_scope) => find_expressible_in_block_by_name(block_scope, name),
}
}
/* Find type */
fn find_type_symbol_in_module(module_scope: &ModuleScope, name: &str) -> Option<TypeSymbol> {
find_class_type_symbol_ref(&module_scope.class_symbols(), name)
}
fn find_type_symbol_in_class_body(
class_body_scope: &ClassBodyScope,
name: &str,
) -> Option<TypeSymbol> {
find_class_type_symbol_ref(&class_body_scope.class_symbols(), name)
}
fn find_type_symbol_in_class(class_scope: &ClassScope, name: &str) -> Option<TypeSymbol> {
find_generic_parameter_type_symbol_ref(&class_scope.generic_parameter_symbols(), name)
}
pub fn find_type_symbol(scope: &Scope, name: &str) -> Option<TypeSymbol> {
match scope {
Scope::Module(module_scope) => find_type_symbol_in_module(module_scope, name),
Scope::Class(class_scope) => find_type_symbol_in_class(class_scope, name),
Scope::ClassBody(class_body_scope) => {
find_type_symbol_in_class_body(class_body_scope, name)
}
_ => None,
}
}