Refactor name-analysis SymbolTable, etc.
This commit is contained in:
parent
1f5d17ef79
commit
54882b187c
@ -2,10 +2,43 @@ use crate::ast::ast_node::{AstNode, AstNodeRef};
|
|||||||
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix};
|
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::use_symbol::StarUseStatementSymbol;
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol::UseStatementSymbol;
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::range::Range;
|
||||||
|
|
||||||
|
fn handle_insert_error(
|
||||||
|
err: SymbolInsertError,
|
||||||
|
error_symbol_name: &str,
|
||||||
|
error_file_id: usize,
|
||||||
|
error_range: Range<usize>,
|
||||||
|
symbol_types: &str,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match err {
|
||||||
|
SymbolInsertError::SymbolAlreadyDefined(s) => {
|
||||||
|
let mut diagnostic = Diagnostic::error()
|
||||||
|
.with_message(format!(
|
||||||
|
"{} symbol '{}' already defined in the current scope.",
|
||||||
|
symbol_types, error_symbol_name,
|
||||||
|
))
|
||||||
|
.with_label(
|
||||||
|
Label::primary(error_file_id, error_range)
|
||||||
|
.with_message("Symbol duplicated here."),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(source_definition) = s.definition() {
|
||||||
|
diagnostic = diagnostic.with_label(
|
||||||
|
Label::secondary(source_definition.file_id(), source_definition.range())
|
||||||
|
.with_message("Symbol defined here."),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics.push(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn gather_identifier(
|
fn gather_identifier(
|
||||||
identifier: &Identifier,
|
identifier: &Identifier,
|
||||||
@ -15,27 +48,61 @@ fn gather_identifier(
|
|||||||
identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id());
|
identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gather_concrete_use_symbol(base_fqn: &str, identifier: &Identifier, symbol_table: &mut SymbolTable, diagnostics: &mut Vec<DmDiagnostic>) {
|
||||||
|
let symbol = ConcreteUseSymbol::new(
|
||||||
|
base_fqn,
|
||||||
|
identifier.name(),
|
||||||
|
Some(SourceDefinition::from_identifier(identifier)),
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = symbol_table.insert_concrete_use_symbol(symbol) {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&base_fqn,
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
"Use Statement",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn gather_use_statement(
|
fn gather_use_statement(
|
||||||
use_statement: &UseStatement,
|
use_statement: &UseStatement,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let mut fully_qualified_name = String::new();
|
let base_fqn = use_statement
|
||||||
for prefix in use_statement.prefixes() {
|
.prefixes()
|
||||||
fully_qualified_name.push_str(&format!("{}::", prefix.identifier().name()));
|
.map(|prefix| prefix.identifier().name())
|
||||||
}
|
.collect::<Vec<_>>()
|
||||||
|
.join("::");
|
||||||
|
|
||||||
match use_statement.suffix() {
|
match use_statement.suffix() {
|
||||||
UseStatementSuffix::Identifier(identifier) => {}
|
UseStatementSuffix::Identifier(identifier) => {
|
||||||
|
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
UseStatementSuffix::Star => {
|
UseStatementSuffix::Star => {
|
||||||
let symbol_inner = StarUseStatementSymbol::new(
|
let symbol = StarUseSymbol::new(
|
||||||
&fully_qualified_name,
|
&base_fqn,
|
||||||
Some(SourceDefinition::from_use_statement(use_statement)),
|
Some(SourceDefinition::from_use_statement(use_statement)),
|
||||||
);
|
);
|
||||||
let symbol = UseStatementSymbol::Star(symbol_inner);
|
let insert_result = symbol_table.insert_star_use_symbol(symbol);
|
||||||
symbol_table.insert_use_statement_symbol(symbol);
|
if let Err(error) = insert_result {
|
||||||
todo!()
|
handle_insert_error(
|
||||||
|
error,
|
||||||
|
&base_fqn,
|
||||||
|
use_statement.file_id(),
|
||||||
|
use_statement.range(),
|
||||||
|
"Use Statement",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UseStatementSuffix::UseList(use_list) => {
|
||||||
|
for identifier in use_list.identifiers() {
|
||||||
|
gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UseStatementSuffix::UseList(use_list) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
src/name_analysis/symbol/class_member_symbol.rs
Normal file
45
src/name_analysis/symbol/class_member_symbol.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ClassMemberSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
is_field: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassMemberSymbol {
|
||||||
|
pub fn new(
|
||||||
|
declared_name: &str,
|
||||||
|
is_field: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_field,
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_field(&self) -> bool {
|
||||||
|
self.is_field
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ClassMemberSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ClassMemberSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("is_field", &self.is_field)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/name_analysis/symbol/function_symbol.rs
Normal file
101
src/name_analysis/symbol/function_symbol.rs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct FunctionSymbol {
|
||||||
|
fqn: String,
|
||||||
|
declared_name: String,
|
||||||
|
is_public: bool,
|
||||||
|
is_platform: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
parameters: Vec<ParameterSymbol>,
|
||||||
|
return_type: Option<ConcreteTypeSymbol>, // todo: can we use TypeSymbol?
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FunctionSymbol {
|
||||||
|
pub fn without_parameters_or_return_type(
|
||||||
|
fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
is_public: bool,
|
||||||
|
is_platform: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> FunctionSymbol {
|
||||||
|
FunctionSymbol {
|
||||||
|
fqn: fqn.to_string(),
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_public,
|
||||||
|
is_platform,
|
||||||
|
source_definition,
|
||||||
|
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,
|
||||||
|
source_definition: self.source_definition,
|
||||||
|
parameters,
|
||||||
|
return_type: self.return_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self {
|
||||||
|
Self {
|
||||||
|
fqn: self.fqn,
|
||||||
|
declared_name: self.declared_name,
|
||||||
|
is_public: self.is_public,
|
||||||
|
is_platform: self.is_platform,
|
||||||
|
source_definition: self.source_definition,
|
||||||
|
parameters: self.parameters,
|
||||||
|
return_type: Some(return_type),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fqn(&self) -> &str {
|
||||||
|
&self.fqn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_public(&self) -> bool {
|
||||||
|
self.is_public
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_platform(&self) -> bool {
|
||||||
|
self.is_platform
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameters(&self) -> &[ParameterSymbol] {
|
||||||
|
&self.parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn return_type(&self) -> Option<&ConcreteTypeSymbol> {
|
||||||
|
self.return_type.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for FunctionSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("FunctionSymbol")
|
||||||
|
.field("fqn", &self.fqn)
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("is_public", &self.is_public)
|
||||||
|
.field("is_platform", &self.is_platform)
|
||||||
|
.field("parameters", &self.parameters)
|
||||||
|
.field("return_type", &self.return_type)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,445 +1,46 @@
|
|||||||
pub(super) mod source_definition;
|
pub(crate) mod class_member_symbol;
|
||||||
pub(super) mod use_symbol;
|
pub(crate) mod function_symbol;
|
||||||
|
pub(crate) mod module_symbol;
|
||||||
|
pub(crate) mod parameter_symbol;
|
||||||
|
pub(crate) mod source_definition;
|
||||||
|
pub(crate) mod type_symbol;
|
||||||
|
pub(crate) mod use_symbol;
|
||||||
|
pub(crate) mod variable_symbol;
|
||||||
|
|
||||||
use crate::ast::node::Identifier;
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
|
use class_member_symbol::ClassMemberSymbol;
|
||||||
|
use function_symbol::FunctionSymbol;
|
||||||
|
use module_symbol::ModuleSymbol;
|
||||||
|
use parameter_symbol::ParameterSymbol;
|
||||||
use source_definition::SourceDefinition;
|
use source_definition::SourceDefinition;
|
||||||
use std::cell::RefCell;
|
use std::fmt::{Debug, Display};
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use type_symbol::TypeSymbol;
|
||||||
|
use variable_symbol::VariableSymbol;
|
||||||
pub trait SymbolInner {
|
|
||||||
fn declared_name(&self) -> &str;
|
|
||||||
fn definition(&self) -> Option<SourceDefinition>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Symbol */
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Symbol {
|
pub enum Symbol {
|
||||||
UseStatement(Rc<RefCell<UseStatementSymbol>>),
|
ConcreteUse(ConcreteUseSymbol),
|
||||||
Module(Rc<ModuleSymbol>),
|
StarUse(StarUseSymbol),
|
||||||
Type(Rc<TypeSymbol>),
|
Module(ModuleSymbol),
|
||||||
Function(Rc<RefCell<FunctionSymbol>>),
|
Type(TypeSymbol),
|
||||||
Parameter(Rc<ParameterSymbol>),
|
Function(FunctionSymbol),
|
||||||
Variable(Rc<VariableSymbol>),
|
Parameter(ParameterSymbol),
|
||||||
ClassMember(Rc<ClassMemberSymbol>),
|
Variable(VariableSymbol),
|
||||||
|
ClassMember(ClassMemberSymbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
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(),
|
Symbol::ConcreteUse(concrete) => concrete.source_definition(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::StarUse(star) => star.source_definition(),
|
||||||
Symbol::Type(s) => match s.deref() {
|
Symbol::Module(module) => module.source_definition(),
|
||||||
TypeSymbol::Concrete(cts) => cts.definition(),
|
Symbol::Type(type_symbol) => type_symbol.source_definition(),
|
||||||
TypeSymbol::Generic(gts) => gts.definition(),
|
Symbol::Function(function_symbol) => function_symbol.source_definition(),
|
||||||
},
|
Symbol::Parameter(parameter_symbol) => parameter_symbol.source_definition(),
|
||||||
Symbol::Function(s) => s.borrow().definition(),
|
Symbol::Variable(variable_symbol) => variable_symbol.source_definition(),
|
||||||
Symbol::Parameter(s) => s.definition(),
|
Symbol::ClassMember(class_member_symbol) => class_member_symbol.source_definition(),
|
||||||
Symbol::Variable(s) => s.definition(),
|
|
||||||
Symbol::ClassMember(s) => s.definition(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> {
|
|
||||||
match self {
|
|
||||||
Symbol::UseStatement(s) => s.clone(),
|
|
||||||
_ => panic!("unwrap_use_statement_symbol called on non-use statement symbol"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use-statement */
|
|
||||||
|
|
||||||
pub struct UseStatementSymbol {
|
|
||||||
pub fqn: String,
|
|
||||||
pub declared_name: String,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
referenced_symbol: Option<Box<Symbol>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UseStatementSymbol {
|
|
||||||
pub fn new(fqn: &str, declared_name: &str, identifier: Option<&Identifier>) -> Self {
|
|
||||||
UseStatementSymbol {
|
|
||||||
fqn: fqn.to_string(),
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
|
||||||
referenced_symbol: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_referenced_symbol(&mut self, referenced_symbol: Symbol) {
|
|
||||||
self.referenced_symbol = Some(Box::new(referenced_symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn referenced_symbol(&self) -> Option<Box<Symbol>> {
|
|
||||||
self.referenced_symbol.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for UseStatementSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
&self.declared_name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for UseStatementSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("UseStatementSymbol")
|
|
||||||
.field("fqn", &self.fqn)
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("referenced_symbol", &self.referenced_symbol)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Module */
|
|
||||||
|
|
||||||
pub struct ModuleSymbol {
|
|
||||||
fqn: String,
|
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ModuleSymbol {
|
|
||||||
pub fn new(
|
|
||||||
fqn: &str,
|
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
|
||||||
identifier: Option<&Identifier>,
|
|
||||||
) -> ModuleSymbol {
|
|
||||||
ModuleSymbol {
|
|
||||||
fqn: fqn.to_string(),
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for ModuleSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
self.declared_name.as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ModuleSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("ModuleSymbol")
|
|
||||||
.field("fqn", &self.fqn)
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("is_public", &self.is_public)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TypeSymbol */
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum TypeSymbol {
|
|
||||||
Concrete(ConcreteTypeSymbol),
|
|
||||||
Generic(GenericTypeSymbol),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeSymbol {
|
|
||||||
pub fn declared_name(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
TypeSymbol::Concrete(t) => t.declared_name(),
|
|
||||||
TypeSymbol::Generic(t) => t.declared_name(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ConcreteTypeSymbol {
|
|
||||||
fqn: String,
|
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConcreteTypeSymbol {
|
|
||||||
pub fn new(
|
|
||||||
fqn: &str,
|
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
|
||||||
identifier: Option<&Identifier>,
|
|
||||||
) -> Self {
|
|
||||||
ConcreteTypeSymbol {
|
|
||||||
fqn: fqn.to_string(),
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fqn(&self) -> &str {
|
|
||||||
&self.fqn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_public(&self) -> bool {
|
|
||||||
self.is_public
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for ConcreteTypeSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
&self.declared_name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ConcreteTypeSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("TypeSymbol")
|
|
||||||
.field("fqn", &self.fqn)
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("is_public", &self.is_public)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GenericTypeSymbol {
|
|
||||||
declared_name: String,
|
|
||||||
source_definition: SourceDefinition,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GenericTypeSymbol {
|
|
||||||
pub fn new(declared_name: &str, source_definition: SourceDefinition) -> Self {
|
|
||||||
GenericTypeSymbol {
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
source_definition,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for GenericTypeSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
self.declared_name.as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
Some(self.source_definition.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for GenericTypeSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("GenericTypeSymbol")
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function */
|
|
||||||
|
|
||||||
pub struct FunctionSymbol {
|
|
||||||
fqn: String,
|
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
|
||||||
is_platform: bool,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
parameters: Vec<Rc<ParameterSymbol>>,
|
|
||||||
return_type: Option<Rc<ConcreteTypeSymbol>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FunctionSymbol {
|
|
||||||
pub fn new(
|
|
||||||
fqn: &str,
|
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
|
||||||
is_platform: bool,
|
|
||||||
identifier: Option<&Identifier>,
|
|
||||||
) -> FunctionSymbol {
|
|
||||||
FunctionSymbol {
|
|
||||||
fqn: fqn.to_string(),
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
|
||||||
is_platform,
|
|
||||||
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: ConcreteTypeSymbol) -> 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 {
|
|
||||||
&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<ConcreteTypeSymbol>) {
|
|
||||||
self.return_type = Some(return_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for FunctionSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
self.declared_name.as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for FunctionSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("FunctionSymbol")
|
|
||||||
.field("fqn", &self.fqn)
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("is_public", &self.is_public)
|
|
||||||
.field("is_platform", &self.is_platform)
|
|
||||||
.field("parameters", &self.parameters)
|
|
||||||
.field("return_type", &self.return_type)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parameter */
|
|
||||||
|
|
||||||
pub struct ParameterSymbol {
|
|
||||||
declared_name: String,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ParameterSymbol {
|
|
||||||
pub fn new(declared_name: &str, identifier: Option<&Identifier>) -> Self {
|
|
||||||
ParameterSymbol {
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for ParameterSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
&self.declared_name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ParameterSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("ParameterSymbol")
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Variable */
|
|
||||||
|
|
||||||
pub struct VariableSymbol {
|
|
||||||
declared_name: String,
|
|
||||||
is_mutable: bool,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VariableSymbol {
|
|
||||||
pub fn new(declared_name: &str, is_mutable: bool, identifier: Option<&Identifier>) -> Self {
|
|
||||||
VariableSymbol {
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_mutable,
|
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for VariableSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
self.declared_name.as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for VariableSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("VariableSymbol")
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("is_mutable", &self.is_mutable)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Class Member */
|
|
||||||
|
|
||||||
pub struct ClassMemberSymbol {
|
|
||||||
declared_name: String,
|
|
||||||
is_field: bool,
|
|
||||||
definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClassMemberSymbol {
|
|
||||||
pub fn new(declared_name: &str, is_field: bool, definition: Option<SourceDefinition>) -> Self {
|
|
||||||
ClassMemberSymbol {
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_field,
|
|
||||||
definition,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SymbolInner for ClassMemberSymbol {
|
|
||||||
fn declared_name(&self) -> &str {
|
|
||||||
self.declared_name.as_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
self.definition.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ClassMemberSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("ClassMemberSymbol")
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
53
src/name_analysis/symbol/module_symbol.rs
Normal file
53
src/name_analysis/symbol/module_symbol.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ModuleSymbol {
|
||||||
|
fqn: String,
|
||||||
|
declared_name: String,
|
||||||
|
is_public: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleSymbol {
|
||||||
|
pub fn new(
|
||||||
|
fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
is_public: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
fqn: fqn.to_string(),
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_public,
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fqn(&self) -> &str {
|
||||||
|
&self.fqn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_public(&self) -> bool {
|
||||||
|
self.is_public
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ModuleSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ModuleSymbol")
|
||||||
|
.field("fqn", &self.fqn)
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("is_public", &self.is_public)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/name_analysis/symbol/parameter_symbol.rs
Normal file
34
src/name_analysis/symbol/parameter_symbol.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ParameterSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParameterSymbol {
|
||||||
|
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
|
ParameterSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ParameterSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ParameterSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
107
src/name_analysis/symbol/type_symbol.rs
Normal file
107
src/name_analysis/symbol/type_symbol.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum TypeSymbol {
|
||||||
|
Concrete(ConcreteTypeSymbol),
|
||||||
|
Generic(GenericTypeSymbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeSymbol {
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
TypeSymbol::Concrete(t) => t.declared_name(),
|
||||||
|
TypeSymbol::Generic(t) => t.declared_name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
match self {
|
||||||
|
TypeSymbol::Concrete(t) => t.source_definition(),
|
||||||
|
TypeSymbol::Generic(t) => t.source_definition(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ConcreteTypeSymbol {
|
||||||
|
fqn: String,
|
||||||
|
declared_name: String,
|
||||||
|
is_public: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConcreteTypeSymbol {
|
||||||
|
pub fn new(
|
||||||
|
fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
is_public: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
fqn: fqn.to_string(),
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_public,
|
||||||
|
source_definition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fqn(&self) -> &str {
|
||||||
|
&self.fqn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_public(&self) -> bool {
|
||||||
|
self.is_public
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ConcreteTypeSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("TypeSymbol")
|
||||||
|
.field("fqn", &self.fqn)
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("is_public", &self.is_public)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GenericTypeSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericTypeSymbol {
|
||||||
|
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
|
GenericTypeSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for GenericTypeSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("GenericTypeSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,56 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
pub enum UseStatementSymbol {
|
#[derive(Clone)]
|
||||||
Concrete,
|
pub struct ConcreteUseSymbol {
|
||||||
Star(StarUseStatementSymbol),
|
base_fqn: String,
|
||||||
|
declared_name: String,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StarUseStatementSymbol {
|
impl ConcreteUseSymbol {
|
||||||
|
pub fn new(
|
||||||
|
base_fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
base_fqn: base_fqn.to_string(),
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn base_fqn(&self) -> &str {
|
||||||
|
&self.base_fqn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ConcreteUseSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ConcreteUseStatementSymbol")
|
||||||
|
.field("base_fqn", &self.base_fqn)
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StarUseSymbol {
|
||||||
base_fqn: String,
|
base_fqn: String,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StarUseStatementSymbol {
|
impl StarUseSymbol {
|
||||||
pub fn new(base_fqn: &str, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(base_fqn: &str, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base_fqn: base_fqn.to_string(),
|
base_fqn: base_fqn.to_string(),
|
||||||
@ -26,3 +66,12 @@ impl StarUseStatementSymbol {
|
|||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for StarUseSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("StarUseStatementSymbol")
|
||||||
|
.field("base_fqn", &self.base_fqn)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
41
src/name_analysis/symbol/variable_symbol.rs
Normal file
41
src/name_analysis/symbol/variable_symbol.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct VariableSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
is_mutable: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VariableSymbol {
|
||||||
|
pub fn new(declared_name: &str, is_mutable: bool, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
|
VariableSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_mutable,
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_mutable(&self) -> bool {
|
||||||
|
self.is_mutable
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for VariableSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("VariableSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("is_mutable", &self.is_mutable)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,468 +0,0 @@
|
|||||||
use crate::name_analysis::symbol::*;
|
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
|
||||||
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
/* Scope */
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Scope {
|
|
||||||
parent: Option<usize>,
|
|
||||||
use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>,
|
|
||||||
module_symbols: HashMap<String, Rc<ModuleSymbol>>,
|
|
||||||
type_symbols: HashMap<String, Rc<TypeSymbol>>,
|
|
||||||
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
|
|
||||||
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
|
||||||
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
|
||||||
class_member_symbols: HashMap<String, Rc<ClassMemberSymbol>>,
|
|
||||||
debug_name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scope {
|
|
||||||
pub fn new(parent: Option<usize>, debug_name: String) -> Scope {
|
|
||||||
Scope {
|
|
||||||
parent,
|
|
||||||
use_statement_symbols: HashMap::new(),
|
|
||||||
module_symbols: HashMap::new(),
|
|
||||||
type_symbols: HashMap::new(),
|
|
||||||
function_symbols: HashMap::new(),
|
|
||||||
parameter_symbols: HashMap::new(),
|
|
||||||
variable_symbols: HashMap::new(),
|
|
||||||
class_member_symbols: HashMap::new(),
|
|
||||||
debug_name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
|
||||||
for module_symbol in self.module_symbols.values() {
|
|
||||||
if module_symbol.declared_name() == name {
|
|
||||||
return Some(module_symbol.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type_symbol_by_declared_name(&self, declared_name: &str) -> Option<Rc<TypeSymbol>> {
|
|
||||||
if let Some(type_symbol) = self.type_symbols.get(declared_name) {
|
|
||||||
Some(type_symbol.clone())
|
|
||||||
} else {
|
|
||||||
for use_statement_symbol in self.use_statement_symbols.values() {
|
|
||||||
let borrowed = use_statement_symbol.borrow();
|
|
||||||
if borrowed.declared_name() == declared_name {
|
|
||||||
if let Some(referenced_symbol) = borrowed.referenced_symbol() {
|
|
||||||
match *referenced_symbol {
|
|
||||||
Symbol::Type(type_symbol) => return Some(type_symbol.clone()),
|
|
||||||
_ => continue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
|
||||||
self.type_symbols
|
|
||||||
.values()
|
|
||||||
.find(|s| match s.deref().deref() {
|
|
||||||
TypeSymbol::Concrete(cts) => cts.fqn() == fqn,
|
|
||||||
_ => false,
|
|
||||||
})
|
|
||||||
.cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
|
||||||
for function_symbol in self.function_symbols.values() {
|
|
||||||
if function_symbol.borrow().fqn() == fqn {
|
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for type_symbol in self.type_symbols.values() {
|
|
||||||
match type_symbol.deref() {
|
|
||||||
TypeSymbol::Concrete(concrete_type_symbol) => {
|
|
||||||
if concrete_type_symbol.fqn() == fqn {
|
|
||||||
return Some(Symbol::Type(type_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => continue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
|
||||||
for function_symbol in self.function_symbols.values() {
|
|
||||||
if function_symbol.borrow().declared_name() == declared_name {
|
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for type_symbol in self.type_symbols.values() {
|
|
||||||
if type_symbol.declared_name() == declared_name {
|
|
||||||
return Some(Symbol::Type(type_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_value_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
|
||||||
for variable_symbol in self.variable_symbols.values() {
|
|
||||||
if variable_symbol.declared_name() == declared_name {
|
|
||||||
return Some(Symbol::Variable(variable_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for parameter_symbol in self.parameter_symbols.values() {
|
|
||||||
if parameter_symbol.declared_name() == declared_name {
|
|
||||||
return Some(Symbol::Parameter(parameter_symbol.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_expressible_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
|
||||||
self.variable_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|s| Symbol::Variable(s.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.parameter_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|p| Symbol::Parameter(p.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.class_member_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|cms| Symbol::ClassMember(cms.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.function_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|t| Symbol::Type(t.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.use_statement_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|us| Symbol::UseStatement(us.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_expressible_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
|
||||||
self.function_symbols
|
|
||||||
.values()
|
|
||||||
.find(|fs| fs.borrow().fqn() == fqn)
|
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.get_type_symbol_by_fqn(fqn)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Symbol table */
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum SymbolInsertError {
|
|
||||||
SymbolAlreadyDefined(Symbol),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum SymbolLookupError {
|
|
||||||
NoDefinition,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct SymbolTable {
|
|
||||||
scopes: Vec<Scope>,
|
|
||||||
current_scope_id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Contains a vec of scopes, like a flattened tree
|
|
||||||
impl SymbolTable {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut t = SymbolTable {
|
|
||||||
scopes: vec![Scope::new(None, String::from("GlobalScope"))],
|
|
||||||
current_scope_id: 0,
|
|
||||||
};
|
|
||||||
t
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn current_scope_id(&self) -> usize {
|
|
||||||
self.current_scope_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scopes(&self) -> &Vec<Scope> {
|
|
||||||
&self.scopes
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_scope(&mut self, debug_name: &str) {
|
|
||||||
let id = self.scopes.len();
|
|
||||||
self.scopes.push(Scope::new(
|
|
||||||
Some(self.current_scope_id),
|
|
||||||
debug_name.to_string(),
|
|
||||||
));
|
|
||||||
self.current_scope_id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pop_scope(&mut self) {
|
|
||||||
if let Some(parent_id) = self.scopes[self.current_scope_id].parent {
|
|
||||||
self.current_scope_id = parent_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_use_statement_symbol(
|
|
||||||
&mut self,
|
|
||||||
use_statement_symbol: UseStatementSymbol,
|
|
||||||
) -> Result<Rc<RefCell<UseStatementSymbol>>, SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} 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(declared_name, to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_module_symbol(
|
|
||||||
&mut self,
|
|
||||||
module_symbol: ModuleSymbol,
|
|
||||||
) -> Result<(), SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_module_symbol_by_declared_name(module_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(Symbol::Module(defined_symbol.clone())))
|
|
||||||
} else {
|
|
||||||
current_scope.module_symbols.insert(
|
|
||||||
module_symbol.declared_name().to_string(),
|
|
||||||
Rc::new(module_symbol),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_type_symbol(&mut self, type_symbol: TypeSymbol) -> Result<(), SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_usable_symbol_by_declared_name(type_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} else {
|
|
||||||
current_scope.type_symbols.insert(
|
|
||||||
type_symbol.declared_name().to_string(),
|
|
||||||
Rc::new(type_symbol),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_function_symbol(
|
|
||||||
&mut self,
|
|
||||||
function_symbol: FunctionSymbol,
|
|
||||||
) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} 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(declared_name, to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_parameter_symbol(
|
|
||||||
&mut self,
|
|
||||||
parameter_symbol: ParameterSymbol,
|
|
||||||
) -> Result<Rc<ParameterSymbol>, SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} else {
|
|
||||||
let to_insert = Rc::new(parameter_symbol);
|
|
||||||
let to_return = to_insert.clone();
|
|
||||||
current_scope
|
|
||||||
.parameter_symbols
|
|
||||||
.insert(to_insert.declared_name().to_string(), to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_variable_symbol(
|
|
||||||
&mut self,
|
|
||||||
variable_symbol: VariableSymbol,
|
|
||||||
) -> Result<Rc<VariableSymbol>, SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_value_symbol_by_declared_name(variable_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} else {
|
|
||||||
let declared_name = variable_symbol.declared_name().to_string();
|
|
||||||
let to_insert = Rc::new(variable_symbol);
|
|
||||||
let to_return = to_insert.clone();
|
|
||||||
current_scope
|
|
||||||
.variable_symbols
|
|
||||||
.insert(declared_name, to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_class_member_symbol(
|
|
||||||
&mut self,
|
|
||||||
class_member_symbol: ClassMemberSymbol,
|
|
||||||
) -> Result<(), SymbolInsertError> {
|
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} else {
|
|
||||||
current_scope.class_member_symbols.insert(
|
|
||||||
class_member_symbol.declared_name().to_string(),
|
|
||||||
Rc::new(class_member_symbol),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_type_by_declared_name(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Rc<TypeSymbol>, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_type_symbol_by_declared_name(declared_name) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_type_by_fqn(
|
|
||||||
&self,
|
|
||||||
fqn: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Rc<TypeSymbol>, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_type_symbol_by_fqn(fqn) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_usable_by_fqn(
|
|
||||||
&self,
|
|
||||||
fully_qualified_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
for scope in &self.scopes {
|
|
||||||
if let Some(symbol) = scope.get_usable_symbol_by_fqn(fully_qualified_name) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_expressible_by_declared_name(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_expressible_by_declared_name(declared_name) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_expressible_by_fqn(
|
|
||||||
&self,
|
|
||||||
fqn: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_expressible_by_fqn(fqn) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for SymbolTable {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?;
|
|
||||||
for (i, scope) in self.scopes.iter().enumerate() {
|
|
||||||
writeln!(f, "----Scope {} {}----", i, scope.debug_name)?;
|
|
||||||
for symbol in scope.use_statement_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol.borrow())?;
|
|
||||||
}
|
|
||||||
for symbol in scope.module_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
|
||||||
for symbol in scope.type_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
|
||||||
for symbol in scope.function_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol.borrow())?;
|
|
||||||
}
|
|
||||||
for symbol in scope.parameter_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
|
||||||
for symbol in scope.variable_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
|
||||||
for symbol in scope.class_member_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
333
src/name_analysis/symbol_table/mod.rs
Normal file
333
src/name_analysis/symbol_table/mod.rs
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
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::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
|
use crate::name_analysis::symbol::*;
|
||||||
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
|
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
||||||
|
use scope::Scope;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
mod scope;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SymbolInsertError {
|
||||||
|
SymbolAlreadyDefined(Symbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SymbolLookupError {
|
||||||
|
NoDefinition,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SymbolTable {
|
||||||
|
scopes: Vec<Scope>,
|
||||||
|
current_scope_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contains a vec of scopes, like a flattened tree
|
||||||
|
impl SymbolTable {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
scopes: vec![Scope::new(None, 0, String::from("GlobalScope"))],
|
||||||
|
current_scope_id: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_scope_id(&self) -> usize {
|
||||||
|
self.current_scope_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_scope(&mut self, debug_name: &str) {
|
||||||
|
let id = self.scopes.len();
|
||||||
|
self.scopes
|
||||||
|
.push(Scope::new(Some(self.current_scope_id), id, debug_name.to_string()));
|
||||||
|
self.current_scope_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop_scope(&mut self) {
|
||||||
|
if let Some(parent_id) = self.scopes[self.current_scope_id].parent() {
|
||||||
|
self.current_scope_id = parent_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_scope(&self) -> &Scope {
|
||||||
|
self.scopes.last().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_scope_mut(&mut self) -> &mut Scope {
|
||||||
|
self.scopes.last_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_concrete_use_symbol(
|
||||||
|
&self,
|
||||||
|
declared_name: &str,
|
||||||
|
) -> Option<&ConcreteUseSymbol> {
|
||||||
|
self.current_scope()
|
||||||
|
.concrete_use_symbols()
|
||||||
|
.get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_star_use_symbol(&self, base_fqn: &str) -> Option<&StarUseSymbol> {
|
||||||
|
self.current_scope().star_use_symbols().get(base_fqn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_type_symbol(&self, declared_name: &str) -> Option<&TypeSymbol> {
|
||||||
|
self.current_scope().type_symbols().get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_module_symbol(&self, declared_name: &str) -> Option<&ModuleSymbol> {
|
||||||
|
self.current_scope().module_symbols().get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_parameter_symbol(&self, declared_name: &str) -> Option<&ParameterSymbol> {
|
||||||
|
self.current_scope().parameter_symbols().get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_variable_symbol(&self, declared_name: &str) -> Option<&VariableSymbol> {
|
||||||
|
self.current_scope().variable_symbols().get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_class_member_symbol(
|
||||||
|
&self,
|
||||||
|
declared_name: &str,
|
||||||
|
) -> Option<&ClassMemberSymbol> {
|
||||||
|
self.current_scope()
|
||||||
|
.class_member_symbols()
|
||||||
|
.get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_variable_or_parameter_symbol(
|
||||||
|
&self,
|
||||||
|
declared_name: &str,
|
||||||
|
) -> Option<Symbol> {
|
||||||
|
self.find_current_scope_variable_symbol(declared_name)
|
||||||
|
.map(|variable_symbol| Symbol::Variable(variable_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.find_current_scope_parameter_symbol(declared_name)
|
||||||
|
.map(|parameter_symbol| Symbol::Parameter(parameter_symbol.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_current_scope_usable_symbol(&self, declared_name: &str) -> Option<Symbol> {
|
||||||
|
self.find_current_scope_concrete_use_symbol(declared_name)
|
||||||
|
.map(|concrete_use_symbol| Symbol::ConcreteUse(concrete_use_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.find_current_scope_type_symbol(declared_name)
|
||||||
|
.map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.find_current_scope_module_symbol(declared_name)
|
||||||
|
.map(|module_symbol| Symbol::Module(module_symbol.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_concrete_use_symbol(
|
||||||
|
&mut self,
|
||||||
|
concrete_use_symbol: ConcreteUseSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_usable_symbol(concrete_use_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut().concrete_use_symbols_mut().insert(
|
||||||
|
concrete_use_symbol.declared_name().to_string(),
|
||||||
|
concrete_use_symbol,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_star_use_symbol(
|
||||||
|
&mut self,
|
||||||
|
star_use_symbol: StarUseSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_star_use_symbol(star_use_symbol.base_fqn())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(Symbol::StarUse(
|
||||||
|
defined_symbol.clone(),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut()
|
||||||
|
.star_use_symbols_mut()
|
||||||
|
.insert(star_use_symbol.base_fqn().to_string(), star_use_symbol);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_module_symbol(
|
||||||
|
&mut self,
|
||||||
|
module_symbol: ModuleSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_usable_symbol(module_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut()
|
||||||
|
.module_symbols_mut()
|
||||||
|
.insert(module_symbol.declared_name().to_string(), module_symbol);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_type_symbol(&mut self, type_symbol: TypeSymbol) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_usable_symbol(type_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut()
|
||||||
|
.type_symbols_mut()
|
||||||
|
.insert(type_symbol.declared_name().to_string(), type_symbol);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_function_symbol(
|
||||||
|
&mut self,
|
||||||
|
function_symbol: FunctionSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_usable_symbol(function_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut()
|
||||||
|
.function_symbols_mut()
|
||||||
|
.insert(function_symbol.declared_name().to_string(), function_symbol);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_parameter_symbol(
|
||||||
|
&mut self,
|
||||||
|
parameter_symbol: ParameterSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_parameter_symbol(parameter_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(Symbol::Parameter(
|
||||||
|
defined_symbol.clone(),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut().parameter_symbols_mut().insert(
|
||||||
|
parameter_symbol.declared_name().to_string(),
|
||||||
|
parameter_symbol,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_variable_symbol(
|
||||||
|
&mut self,
|
||||||
|
variable_symbol: VariableSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_variable_or_parameter_symbol(variable_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut()
|
||||||
|
.variable_symbols_mut()
|
||||||
|
.insert(variable_symbol.declared_name().to_string(), variable_symbol);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_class_member_symbol(
|
||||||
|
&mut self,
|
||||||
|
class_member_symbol: ClassMemberSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) =
|
||||||
|
self.find_current_scope_class_member_symbol(class_member_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(Symbol::ClassMember(
|
||||||
|
defined_symbol.clone(),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
self.current_scope_mut().class_member_symbols_mut().insert(
|
||||||
|
class_member_symbol.declared_name().to_string(),
|
||||||
|
class_member_symbol,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lookup_type_in_scope_by_declared_name<'a>(
|
||||||
|
scope: &'a Scope,
|
||||||
|
declared_name: &str,
|
||||||
|
) -> Option<&'a TypeSymbol> {
|
||||||
|
scope.type_symbols().get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_type_by_declared_name(
|
||||||
|
&self,
|
||||||
|
declared_name: &str,
|
||||||
|
scope_id: usize,
|
||||||
|
) -> Result<&TypeSymbol, SymbolLookupError> {
|
||||||
|
let mut scope_opt = Some(&self.scopes[scope_id]);
|
||||||
|
while let Some(scope) = scope_opt {
|
||||||
|
if let Some(symbol) = Self::lookup_type_in_scope_by_declared_name(scope, declared_name)
|
||||||
|
{
|
||||||
|
return Ok(symbol);
|
||||||
|
}
|
||||||
|
scope_opt = if let Some(parent_id) = scope.parent() {
|
||||||
|
Some(&self.scopes[parent_id])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(NoDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lookup_type_in_scope_by_fqn<'a>(scope: &'a Scope, fqn: &str) -> Option<&'a TypeSymbol> {
|
||||||
|
for type_symbol in scope.type_symbols().values() {
|
||||||
|
match type_symbol {
|
||||||
|
TypeSymbol::Concrete(concrete_type_symbol) => {
|
||||||
|
if concrete_type_symbol.fqn() == fqn {
|
||||||
|
return Some(type_symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TypeSymbol::Generic(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_type_by_fqn(
|
||||||
|
&self,
|
||||||
|
fqn: &str,
|
||||||
|
scope_id: usize,
|
||||||
|
) -> Result<&TypeSymbol, SymbolLookupError> {
|
||||||
|
let mut scope_opt = Some(&self.scopes[scope_id]);
|
||||||
|
while let Some(scope) = scope_opt {
|
||||||
|
if let Some(type_symbol) = Self::lookup_type_in_scope_by_fqn(scope, fqn) {
|
||||||
|
return Ok(type_symbol);
|
||||||
|
}
|
||||||
|
scope_opt = if let Some(parent_id) = scope.parent() {
|
||||||
|
Some(&self.scopes[parent_id])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(NoDefinition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SymbolTable {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?;
|
||||||
|
for scope in &self.scopes {
|
||||||
|
writeln!(f, "{}", scope)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
141
src/name_analysis/symbol_table/scope.rs
Normal file
141
src/name_analysis/symbol_table/scope.rs
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
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::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Scope {
|
||||||
|
parent: Option<usize>,
|
||||||
|
id: usize,
|
||||||
|
concrete_use_symbols: HashMap<String, ConcreteUseSymbol>,
|
||||||
|
star_use_symbols: HashMap<String, StarUseSymbol>,
|
||||||
|
module_symbols: HashMap<String, ModuleSymbol>,
|
||||||
|
type_symbols: HashMap<String, TypeSymbol>,
|
||||||
|
function_symbols: HashMap<String, FunctionSymbol>,
|
||||||
|
parameter_symbols: HashMap<String, ParameterSymbol>,
|
||||||
|
variable_symbols: HashMap<String, VariableSymbol>,
|
||||||
|
class_member_symbols: HashMap<String, ClassMemberSymbol>,
|
||||||
|
debug_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scope {
|
||||||
|
pub fn new(parent: Option<usize>, id: usize, debug_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
parent,
|
||||||
|
id,
|
||||||
|
concrete_use_symbols: HashMap::new(),
|
||||||
|
star_use_symbols: HashMap::new(),
|
||||||
|
module_symbols: HashMap::new(),
|
||||||
|
type_symbols: HashMap::new(),
|
||||||
|
function_symbols: HashMap::new(),
|
||||||
|
parameter_symbols: HashMap::new(),
|
||||||
|
variable_symbols: HashMap::new(),
|
||||||
|
class_member_symbols: HashMap::new(),
|
||||||
|
debug_name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self) -> Option<usize> {
|
||||||
|
self.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> usize {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn concrete_use_symbols(&self) -> &HashMap<String, ConcreteUseSymbol> {
|
||||||
|
&self.concrete_use_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn concrete_use_symbols_mut(&mut self) -> &mut HashMap<String, ConcreteUseSymbol> {
|
||||||
|
&mut self.concrete_use_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn star_use_symbols(&self) -> &HashMap<String, StarUseSymbol> {
|
||||||
|
&self.star_use_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn star_use_symbols_mut(&mut self) -> &mut HashMap<String, StarUseSymbol> {
|
||||||
|
&mut self.star_use_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn module_symbols(&self) -> &HashMap<String, ModuleSymbol> {
|
||||||
|
&self.module_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn module_symbols_mut(&mut self) -> &mut HashMap<String, ModuleSymbol> {
|
||||||
|
&mut self.module_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_symbols(&self) -> &HashMap<String, TypeSymbol> {
|
||||||
|
&self.type_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_symbols_mut(&mut self) -> &mut HashMap<String, TypeSymbol> {
|
||||||
|
&mut self.type_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_symbols(&self) -> &HashMap<String, FunctionSymbol> {
|
||||||
|
&self.function_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_symbols_mut(&mut self) -> &mut HashMap<String, FunctionSymbol> {
|
||||||
|
&mut self.function_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameter_symbols(&self) -> &HashMap<String, ParameterSymbol> {
|
||||||
|
&self.parameter_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameter_symbols_mut(&mut self) -> &mut HashMap<String, ParameterSymbol> {
|
||||||
|
&mut self.parameter_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variable_symbols(&self) -> &HashMap<String, VariableSymbol> {
|
||||||
|
&self.variable_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variable_symbols_mut(&mut self) -> &mut HashMap<String, VariableSymbol> {
|
||||||
|
&mut self.variable_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_member_symbols(&self) -> &HashMap<String, ClassMemberSymbol> {
|
||||||
|
&self.class_member_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_member_symbols_mut(&mut self) -> &mut HashMap<String, ClassMemberSymbol> {
|
||||||
|
&mut self.class_member_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn debug_name(&self) -> &str {
|
||||||
|
&self.debug_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! write_symbols {
|
||||||
|
( $f:expr, $symbols:expr ) => {
|
||||||
|
for symbol in $symbols.values() {
|
||||||
|
writeln!($f, "{:#?}", symbol)?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Scope {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "----Scope {} {}----", self.id(), self.debug_name())?;
|
||||||
|
write_symbols!(f, self.concrete_use_symbols());
|
||||||
|
write_symbols!(f, self.star_use_symbols());
|
||||||
|
write_symbols!(f, self.module_symbols());
|
||||||
|
write_symbols!(f, self.type_symbols());
|
||||||
|
write_symbols!(f, self.function_symbols());
|
||||||
|
write_symbols!(f, self.parameter_symbols());
|
||||||
|
write_symbols!(f, self.variable_symbols());
|
||||||
|
write_symbols!(f, self.class_member_symbols());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,13 +1,26 @@
|
|||||||
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol};
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
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_function_symbol(
|
symbol_table.insert_function_symbol(
|
||||||
FunctionSymbol::new("std::core::println", "println", true, true, None)
|
FunctionSymbol::without_parameters_or_return_type(
|
||||||
|
"std::core::println",
|
||||||
|
"println",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||||
)?;
|
)?;
|
||||||
symbol_table.insert_function_symbol(
|
symbol_table.insert_function_symbol(
|
||||||
FunctionSymbol::new("std::core::print", "print", true, true, None)
|
FunctionSymbol::without_parameters_or_return_type(
|
||||||
|
"std::core::print",
|
||||||
|
"print",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user