Add gathering and resolving for various constructs; two-file test still failing but fails correctly.

This commit is contained in:
Jesse Brault 2025-05-18 10:26:38 -05:00
parent c54e005b62
commit 8cd5e588a0
6 changed files with 698 additions and 41 deletions

View File

@ -454,7 +454,7 @@ pub struct FieldDeclaration {
#[derive(Debug)]
pub struct UseStatement {
pub identifiers: Vec<Identifier>,
pub last: UseStatementLast
pub last: UseStatementLast,
}
#[derive(Debug)]
@ -572,8 +572,8 @@ pub struct PrefixExpression {
#[derive(Debug)]
pub struct SuffixExpression {
expression: Box<Expression>,
operator: SuffixUnaryOperator,
pub expression: Box<Expression>,
pub operator: SuffixUnaryOperator,
}
#[derive(Debug)]

View File

@ -1,7 +1,9 @@
use crate::ast::named::Named;
use crate::ast::*;
use crate::name_analysis::fqn_context::FqnContext;
use crate::name_analysis::symbol::{FunctionSymbol, ModuleSymbol, SourceDefinition, Symbol, VariableSymbol};
use crate::name_analysis::symbol::{
ClassSymbol, FunctionSymbol, ModuleSymbol, SourceDefinition, Symbol, VariableSymbol,
};
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
use crate::name_analysis::DiagnosticsContainer;
use codespan_reporting::diagnostic::{Diagnostic, Label};
@ -41,6 +43,84 @@ fn handle_insert_error(
}
}
fn gather_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName,
symbol_table: &mut SymbolTable,
) {
fully_qualified_name.set_scope_id(symbol_table.current_scope_id());
}
fn gather_type_use(
type_use: &mut TypeUse,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
match type_use {
TypeUse::Void => {}
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
gather_interface_or_class_type_use(
interface_or_class_type_use,
symbol_table,
fqn_context,
diagnostics,
);
}
TypeUse::Tuple(tuple_type_use) => {
gather_tuple_type_use(tuple_type_use, symbol_table, fqn_context, diagnostics);
}
TypeUse::Function(function_type_use) => {
gather_function_type_use(function_type_use, symbol_table, fqn_context, diagnostics);
}
}
}
fn gather_interface_or_class_type_use(
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
gather_fully_qualified_name(&mut interface_or_class_type_use.fqn, symbol_table);
gather_generic_arguments(
&mut interface_or_class_type_use.generics,
symbol_table,
fqn_context,
diagnostics,
);
}
fn gather_tuple_type_use(
tuple_type_use: &mut TupleTypeUse,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
for generic_argument in &mut tuple_type_use.arguments.0 {
gather_type_use(generic_argument, symbol_table, fqn_context, diagnostics);
}
}
fn gather_function_type_use(
function_type_use: &mut FunctionTypeUse,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
todo!()
}
fn gather_generic_arguments(
generic_arguments: &mut GenericArguments,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
for argument in &mut generic_arguments.0 {
gather_type_use(argument, symbol_table, fqn_context, diagnostics);
}
}
pub(super) fn gather_module_level_declaration(
declaration: &mut ModuleLevelDeclaration,
symbol_table: &mut SymbolTable,
@ -52,9 +132,20 @@ pub(super) fn gather_module_level_declaration(
Module(module_declaration) => {
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
}
Class(class_declaration) => {
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
}
Function(function_definition) => {
gather_function_definition(function_definition, symbol_table, fqn_context, diagnostics)
}
PlatformFunction(platform_function_definition) => {
gather_platform_function_definition(
platform_function_definition,
symbol_table,
fqn_context,
diagnostics,
);
}
_ => todo!(),
}
}
@ -103,6 +194,38 @@ fn gather_module_declaration(
symbol_table.pop_scope()
}
fn gather_class_declaration(
class_declaration: &mut ClassDeclaration,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
let declared_name = class_declaration.identifier.name();
let resolved_name = fqn_context.resolve(&declared_name);
let insert_result = symbol_table.insert(
&declared_name,
Symbol::Class(ClassSymbol::new(
&resolved_name,
&declared_name,
class_declaration.is_public,
&class_declaration.identifier,
)),
);
if let Err(err) = insert_result {
handle_insert_error(
err,
&declared_name,
class_declaration.identifier.file_id,
class_declaration.identifier.range,
"interface/class",
diagnostics,
);
}
// todo: scopes, generics, etc.
}
fn gather_function_definition(
function: &mut FunctionDefinition,
symbol_table: &mut SymbolTable,
@ -118,6 +241,7 @@ fn gather_function_definition(
&resolved_name,
&declared_name,
function.is_public,
false,
&function.identifier,
)),
);
@ -148,6 +272,53 @@ fn gather_function_definition(
symbol_table.pop_scope();
}
fn gather_platform_function_definition(
platform_function_declaration: &mut PlatformFunctionDeclaration,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut DiagnosticsContainer,
) {
let declared_name = platform_function_declaration.identifier.name();
let fully_qualified_name = fqn_context.resolve(&declared_name);
let insert_result = symbol_table.insert(
&declared_name,
Symbol::Function(FunctionSymbol::new(
&fully_qualified_name,
&declared_name,
platform_function_declaration.is_public,
true,
&platform_function_declaration.identifier,
)),
);
if let Err(err) = insert_result {
handle_insert_error(
err,
&declared_name,
platform_function_declaration.identifier.file_id,
platform_function_declaration.identifier.range,
"(Platform-) Function",
diagnostics,
);
}
let declared_name_as_string = platform_function_declaration.identifier.name().to_string();
platform_function_declaration
.identifier
.set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!("FunctionScope({})", declared_name_as_string));
gather_parameters(
&mut platform_function_declaration.parameters,
symbol_table,
fqn_context,
diagnostics,
);
symbol_table.pop_scope();
}
fn gather_parameters(
parameters: &mut Parameters,
symbol_table: &mut SymbolTable,
@ -190,6 +361,13 @@ fn gather_parameter(
parameter
.identifier
.set_scope_id(symbol_table.current_scope_id());
gather_type_use(
&mut parameter.type_use,
symbol_table,
fqn_context,
diagnostics,
)
}
fn gather_function_body(
@ -247,6 +425,9 @@ fn gather_statement(
AssignStatement(assign_statement) => {
gather_assign_statement(assign_statement, symbol_table, fqn_context, diagnostics)
}
CallStatement(call_statement) => {
gather_call_statement(call_statement, symbol_table, diagnostics)
}
_ => todo!(),
}
}
@ -260,7 +441,7 @@ fn gather_variable_declaration(
let insert_result = symbol_table.insert(
&variable_name,
Symbol::Variable(VariableSymbol::new(
Symbol::Variable(VariableSymbol::new(
&variable_name,
variable_declaration.is_mutable,
SourceDefinition::from_identifier(&variable_declaration.identifier),
@ -297,6 +478,14 @@ fn gather_assign_statement(
gather_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
}
fn gather_call_statement(
call_statement: &mut CallStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut call_statement.0, symbol_table, diagnostics);
}
fn gather_expression(
expression: &mut Expression,
symbol_table: &mut SymbolTable,
@ -304,16 +493,135 @@ fn gather_expression(
) {
use crate::ast::Expression::*;
match expression {
Ternary(ternary_expression) => {
gather_ternary_expression(ternary_expression, symbol_table, diagnostics);
}
Binary(binary_expression) => {
gather_binary_expression(binary_expression, symbol_table, diagnostics);
}
UnaryPrefix(prefix_expression) => {
gather_prefix_expression(prefix_expression, symbol_table, diagnostics);
}
UnarySuffix(suffix_expression) => {
gather_suffix_expression(suffix_expression, symbol_table, diagnostics);
}
Call(call_expression) => {
gather_call_expression(call_expression, symbol_table, diagnostics);
}
ObjectAccess(object_access) => {
gather_object_access(object_access, symbol_table, diagnostics);
}
Literal(literal) => {
gather_literal(literal, symbol_table, diagnostics);
}
FullyQualifiedName(fully_qualified_name) => {
gather_fully_qualified_name(fully_qualified_name, symbol_table);
}
_ => {}
Closure(closure) => {
gather_closure(closure, symbol_table, diagnostics);
}
}
}
fn gather_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName,
fn gather_ternary_expression(
ternary_expression: &mut TernaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
fully_qualified_name.set_scope_id(symbol_table.current_scope_id());
gather_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
gather_expression(
&mut ternary_expression.true_expression,
symbol_table,
diagnostics,
);
gather_expression(
&mut ternary_expression.false_expression,
symbol_table,
diagnostics,
);
}
fn gather_binary_expression(
binary_expression: &mut BinaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut binary_expression.left, symbol_table, diagnostics);
gather_expression(&mut binary_expression.right, symbol_table, diagnostics);
}
fn gather_prefix_expression(
prefix_expression: &mut PrefixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
}
fn gather_suffix_expression(
suffix_expression: &mut SuffixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
}
fn gather_call_expression(
call_expression: &mut CallExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut call_expression.callee, symbol_table, diagnostics);
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
gather_turbo_fish(turbo_fish, symbol_table, diagnostics);
}
for call_argument in &mut call_expression.arguments.0 {
gather_expression(&mut call_argument.0, symbol_table, diagnostics);
}
}
fn gather_turbo_fish(
turbo_fish: &mut TurboFish,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
todo!()
}
fn gather_closure(
closure: &mut Closure,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
todo!()
}
fn gather_object_access(
object_access: &mut ObjectAccess,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
gather_expression(&mut object_access.receiver, symbol_table, diagnostics);
for object_navigation in &mut object_access.navigations.0 {
match object_navigation {
ObjectNavigation::Index(index_expression) => {
gather_expression(index_expression, symbol_table, diagnostics);
}
ObjectNavigation::Identifier(identifier) => {
identifier.set_scope_id(symbol_table.current_scope_id());
}
}
}
}
fn gather_literal(
literal: &mut Literal,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
match literal {
Literal::DString(d_string) => todo!(),
Literal::BacktickString(backtick_string) => todo!(),
_ => {}
}
}

View File

@ -136,7 +136,7 @@ mod tests {
(
"main.dm",
indoc! {"
use std::core::println;
use std::core::{Array, String, println};
fn main(args: Array<String>) {
println(\"Hello, World!\");
@ -144,15 +144,19 @@ mod tests {
"},
),
(
"print.dm",
"deps.dm",
indoc! {"
ns std::core;
platform fn println(msg: String) -> Void;
pub class String {}
pub class Array {}
pub platform fn println(msg: String) -> Void;
"},
),
]);
assert_no_diagnostics(sources);
}
}

View File

@ -4,6 +4,170 @@ use crate::name_analysis::symbol_table::SymbolTable;
use crate::name_analysis::DiagnosticsContainer;
use codespan_reporting::diagnostic::{Diagnostic, Label};
fn resolve_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
let lookup_result = symbol_table.lookup(
fully_qualified_name.name().as_ref(),
fully_qualified_name.scope_id().expect(&format!(
"FullyQualifiedName has no scope_id set: {:?}",
fully_qualified_name
)),
);
match lookup_result {
Ok(symbol) => {
fully_qualified_name.set_symbol(symbol.clone());
}
Err(e) => diagnostics.add(
Diagnostic::error()
.with_message(format!(
"No symbol with name '{}' found in current scope.",
fully_qualified_name.name()
))
.with_label(Label::primary(
fully_qualified_name.file_id,
fully_qualified_name.range,
)),
),
}
}
fn resolve_type_use(
type_use: &mut TypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
match type_use {
TypeUse::Void => {},
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
resolve_interface_or_class_type_use(
interface_or_class_type_use,
symbol_table,
diagnostics
);
}
TypeUse::Tuple(tuple_type_use) => {
resolve_tuple_type_use(tuple_type_use, symbol_table, diagnostics);
}
TypeUse::Function(function_type_use) => {
resolve_function_type_use(function_type_use, symbol_table, diagnostics);
}
}
}
fn resolve_interface_or_class_type_use(
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_fully_qualified_name(
&mut interface_or_class_type_use.fqn,
symbol_table,
diagnostics
);
resolve_generic_arguments(
&mut interface_or_class_type_use.generics,
symbol_table,
diagnostics
);
}
fn resolve_tuple_type_use(
tuple_type_use: &mut TupleTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_tuple_arguments(
&mut tuple_type_use.arguments,
symbol_table,
diagnostics
);
}
fn resolve_function_type_use(
function_type_use: &mut FunctionTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_parameters(&mut function_type_use.parameters, symbol_table, diagnostics);
resolve_return_type(&mut function_type_use.return_type, symbol_table, diagnostics);
}
fn resolve_generic_arguments(
generic_arguments: &mut GenericArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
for generic_argument in &mut generic_arguments.0 {
resolve_type_use(
generic_argument,
symbol_table,
diagnostics
);
}
}
fn resolve_tuple_arguments(
tuple_type_use: &mut TupleArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
for type_use in &mut tuple_type_use.0 {
resolve_type_use(
type_use,
symbol_table,
diagnostics
);
}
}
fn resolve_implements_list(
implements_list: &mut ImplementsList,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
todo!()
}
fn resolve_parameters(
parameters: &mut Parameters,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
for parameter in &mut parameters.0 {
resolve_type_use(&mut parameter.type_use, symbol_table, diagnostics);
}
}
fn resolve_return_type(
return_type: &mut ReturnType,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_type_use(
&mut return_type.declared_type,
symbol_table,
diagnostics
);
resolve_references(
&mut return_type.references,
symbol_table,
diagnostics
);
}
fn resolve_references(
references: &mut References,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
for reference in &mut references.0 {
todo!()
}
}
pub(super) fn resolve_module_level_declaration(
declaration: &mut ModuleLevelDeclaration,
symbol_table: &mut SymbolTable,
@ -14,6 +178,16 @@ pub(super) fn resolve_module_level_declaration(
Function(function_definition) => {
resolve_function_definition(function_definition, symbol_table, diagnostics)
}
PlatformFunction(platform_function_declaration) => {
resolve_platform_function_declaration(
platform_function_declaration,
symbol_table,
diagnostics,
)
}
Class(class_declaration) => {
// todo
}
_ => todo!(),
}
}
@ -23,9 +197,20 @@ fn resolve_function_definition(
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
) {
resolve_parameters(&mut function_definition.parameters, symbol_table, diagnostics);
resolve_return_type(&mut function_definition.return_type, symbol_table, diagnostics);
resolve_function_body(&mut function_definition.body, symbol_table, diagnostics);
}
fn resolve_platform_function_declaration(
platform_function_declaration: &mut PlatformFunctionDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_parameters(&mut platform_function_declaration.parameters, symbol_table, diagnostics);
resolve_return_type(&mut platform_function_declaration.return_type, symbol_table, diagnostics);
}
fn resolve_function_body(
function_body: &mut FunctionBody,
symbol_table: &mut SymbolTable,
@ -106,38 +291,155 @@ fn resolve_expression(
) {
use crate::ast::Expression::*;
match expression {
Ternary(ternary_expression) => {
resolve_ternary_expression(ternary_expression, symbol_table, diagnostics);
}
Binary(binary_expression) => {
resolve_binary_expression(binary_expression, symbol_table, diagnostics);
}
UnaryPrefix(prefix_expression) => {
resolve_prefix_expression(
prefix_expression,
symbol_table,
diagnostics,
);
}
UnarySuffix(suffix_expression) => {
resolve_suffix_expression(
suffix_expression,
symbol_table,
diagnostics,
);
}
Call(call_expression) => {
resolve_call_expression(
call_expression,
symbol_table,
diagnostics,
)
}
ObjectAccess(object_access) => {
resolve_object_access(
object_access,
symbol_table,
diagnostics,
);
}
FullyQualifiedName(fqn) => resolve_fully_qualified_name(fqn, symbol_table, diagnostics),
Literal(_) => {}
_ => todo!(),
Literal(literal) => {
resolve_literal(literal, symbol_table, diagnostics);
}
Closure(closure) => {
resolve_closure(closure, symbol_table, diagnostics);
}
}
}
fn resolve_fully_qualified_name(
fully_qualified_name: &mut FullyQualifiedName,
fn resolve_ternary_expression(
ternary_expression: &mut TernaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer,
diagnostics: &mut DiagnosticsContainer
) {
let lookup_result = symbol_table.lookup(
fully_qualified_name.name().as_ref(),
fully_qualified_name.scope_id().expect(&format!(
"FullyQualifiedName has no scope_id set: {:?}",
fully_qualified_name
)),
);
match lookup_result {
Ok(symbol) => {
fully_qualified_name.set_symbol(symbol.clone());
}
Err(e) => diagnostics.add(
Diagnostic::error()
.with_message(format!(
"No symbol with name '{}' found in current scope.",
fully_qualified_name.name()
))
.with_label(Label::primary(
fully_qualified_name.file_id,
fully_qualified_name.range,
)),
),
resolve_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
resolve_expression(&mut ternary_expression.true_expression, symbol_table, diagnostics);
resolve_expression(&mut ternary_expression.false_expression, symbol_table, diagnostics);
}
fn resolve_binary_expression(
binary_expression: &mut BinaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_expression(&mut binary_expression.left, symbol_table, diagnostics);
resolve_expression(&mut binary_expression.right, symbol_table, diagnostics);
}
fn resolve_prefix_expression(
prefix_expression: &mut PrefixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
}
fn resolve_suffix_expression(
suffix_expression: &mut SuffixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
}
fn resolve_call_expression(
call_expression: &mut CallExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_expression(&mut call_expression.callee, symbol_table, diagnostics);
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
resolve_turbo_fish(turbo_fish, symbol_table, diagnostics);
}
resolve_call_arguments(&mut call_expression.arguments, symbol_table, diagnostics);
}
fn resolve_turbo_fish(
turbo_fish: &mut TurboFish,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
todo!()
}
fn resolve_call_arguments(
call_arguments: &mut CallArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
for argument in &mut call_arguments.0 {
resolve_call_argument(argument, symbol_table, diagnostics);
}
}
fn resolve_call_argument(
call_argument: &mut CallArgument,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
resolve_expression(&mut call_argument.0, symbol_table, diagnostics);
}
fn resolve_closure(
closure: &mut Closure,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
todo!()
}
fn resolve_object_access(
object_access: &mut ObjectAccess,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
todo!()
}
fn resolve_literal(
literal: &mut Literal,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
match literal {
Literal::DString(d_string) => resolve_d_string(d_string, symbol_table, diagnostics),
Literal::BacktickString(d_string) => resolve_d_string(d_string, symbol_table, diagnostics),
_ => {}
}
}
fn resolve_d_string(
d_string: &mut DString,
symbol_table: &mut SymbolTable,
diagnostics: &mut DiagnosticsContainer
) {
todo!()
}

View File

@ -30,6 +30,7 @@ pub enum Symbol {
Function(FunctionSymbol),
Variable(VariableSymbol),
Module(ModuleSymbol),
Class(ClassSymbol),
}
impl Symbol {
@ -38,6 +39,7 @@ impl Symbol {
Symbol::Function(s) => s.declared_name.as_str(),
Symbol::Variable(s) => s.name.as_str(),
Symbol::Module(s) => s.declared_name.as_str(),
Symbol::Class(s) => s.declared_name.as_str(),
}
}
@ -46,6 +48,7 @@ impl Symbol {
Symbol::Function(s) => s.definition(),
Symbol::Module(s) => s.definition(),
Symbol::Variable(s) => s.definition(),
Symbol::Class(s) => s.definition(),
}
}
}
@ -57,6 +60,7 @@ impl Display for Symbol {
Function(function_symbol) => write!(f, "{}", function_symbol),
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
Module(module_symbol) => write!(f, "{}", module_symbol),
Class(class_symbol) => write!(f, "{}", class_symbol),
}
}
}
@ -66,6 +70,7 @@ pub struct FunctionSymbol {
pub fqn: String,
pub declared_name: String,
pub is_public: bool,
pub is_platform: bool,
definition: SourceDefinition,
}
@ -74,12 +79,14 @@ impl FunctionSymbol {
fqn: &str,
declared_name: &str,
is_public: bool,
is_platform: bool,
identifier: &Identifier,
) -> FunctionSymbol {
FunctionSymbol {
fqn: fqn.to_string(),
declared_name: declared_name.to_string(),
is_public,
is_platform,
definition: SourceDefinition::from_identifier(identifier),
}
}
@ -167,3 +174,36 @@ impl Display for ModuleSymbol {
)
}
}
#[derive(Debug, Clone)]
pub struct ClassSymbol {
pub fqn: String,
pub declared_name: String,
pub is_public: bool,
definition: SourceDefinition,
}
impl ClassSymbol {
pub fn new(fqn: &str, declared_name: &str, is_public: bool, identifier: &Identifier) -> Self {
ClassSymbol {
fqn: fqn.to_string(),
declared_name: declared_name.to_string(),
is_public,
definition: SourceDefinition::from_identifier(identifier),
}
}
pub fn definition(&self) -> &SourceDefinition {
&self.definition
}
}
impl Display for ClassSymbol {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"ClassSymbol(fqn = {}, declared_name = {})",
self.fqn, self.declared_name
)
}
}

View File

@ -67,7 +67,7 @@ impl SymbolTable {
Symbol::Function(_) | Symbol::Variable(_) => {
self.insert_function_or_variable(name, symbol)
}
Symbol::Module(_) => self.insert_module_or_type(name, symbol),
Symbol::Module(_) | Symbol::Class(_) => self.insert_module_or_type(name, symbol),
}
}
@ -120,6 +120,9 @@ impl Display for SymbolTable {
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 (name, symbol) in &scope.type_and_module_symbols {
writeln!(f, " {}({})", name, symbol)?;
}
for (name, symbol) in &scope.function_and_variable_symbols {
writeln!(f, " {}({})", name, symbol)?;
}