Miscellaneous gather work and related.
This commit is contained in:
parent
f614d00575
commit
d8fe97b401
@ -7,8 +7,8 @@ impl FqnContext {
|
|||||||
FqnContext { stack: Vec::new() }
|
FqnContext { stack: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, name: String) {
|
pub fn push(&mut self, name: &str) {
|
||||||
self.stack.push(name);
|
self.stack.push(name.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) {
|
pub fn pop(&mut self) {
|
||||||
|
@ -132,12 +132,8 @@ fn gather_function_type_use(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
gather_generic_parameters(
|
symbol_table.push_scope("FunctionTypeUseScope");
|
||||||
&mut function_type_use.generics,
|
gather_generic_parameters(&mut function_type_use.generics, symbol_table, diagnostics);
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_parameters(
|
gather_parameters(
|
||||||
&mut function_type_use.parameters,
|
&mut function_type_use.parameters,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
@ -150,6 +146,7 @@ fn gather_function_type_use(
|
|||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic Arguments */
|
/* Generic Arguments */
|
||||||
@ -170,10 +167,28 @@ fn gather_generic_arguments(
|
|||||||
fn gather_generic_parameters(
|
fn gather_generic_parameters(
|
||||||
generic_parameters: &mut GenericParameters,
|
generic_parameters: &mut GenericParameters,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!("Add each Identifier as a type to the current scope; make sure caller's push/pop before/after")
|
for identifier in &mut generic_parameters.0 {
|
||||||
|
let insert_result =
|
||||||
|
symbol_table.insert_type_symbol(TypeSymbol::Generic(GenericTypeSymbol::new(
|
||||||
|
&identifier.name(),
|
||||||
|
SourceDefinition::from_identifier(identifier),
|
||||||
|
)));
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&identifier.name(),
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
"Type",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implements List */
|
/* Implements List */
|
||||||
@ -259,22 +274,12 @@ fn gather_return_type(
|
|||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
gather_references(
|
gather_references(&mut return_type.references, symbol_table);
|
||||||
&mut return_type.references,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* References */
|
/* References */
|
||||||
|
|
||||||
fn gather_references(
|
fn gather_references(references: &mut References, symbol_table: &mut SymbolTable) {
|
||||||
references: &mut References,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
for identifier in &mut references.0 {
|
for identifier in &mut references.0 {
|
||||||
gather_identifier(identifier, symbol_table);
|
gather_identifier(identifier, symbol_table);
|
||||||
}
|
}
|
||||||
@ -289,7 +294,7 @@ pub(super) fn gather_compilation_unit(
|
|||||||
) {
|
) {
|
||||||
let mut fqn_context = FqnContext::new();
|
let mut fqn_context = FqnContext::new();
|
||||||
if let Some(namespace) = &compilation_unit.namespace {
|
if let Some(namespace) = &compilation_unit.namespace {
|
||||||
fqn_context.push(namespace.name().to_string());
|
fqn_context.push(&namespace.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
|
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
|
||||||
@ -384,6 +389,14 @@ fn gather_module_level_declaration(
|
|||||||
Module(module_declaration) => {
|
Module(module_declaration) => {
|
||||||
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
Class(class_declaration) => {
|
Class(class_declaration) => {
|
||||||
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
||||||
}
|
}
|
||||||
@ -398,7 +411,6 @@ fn gather_module_level_declaration(
|
|||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +420,39 @@ fn gather_interface_level_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
use InterfaceLevelDeclaration::*;
|
||||||
|
match declaration {
|
||||||
|
Module(module_declaration) => {
|
||||||
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Class(class_declaration) => {
|
||||||
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
||||||
|
}
|
||||||
|
Function(interface_function_declaration) => {
|
||||||
|
gather_interface_function_declaration(
|
||||||
|
interface_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OperatorFunction(interface_operator_function_declaration) => {
|
||||||
|
gather_interface_operator_function_declaration(
|
||||||
|
interface_operator_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_class_level_declaration(
|
fn gather_class_level_declaration(
|
||||||
@ -417,7 +461,53 @@ fn gather_class_level_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
use ClassLevelDeclaration::*;
|
||||||
|
match declaration {
|
||||||
|
Module(module_declaration) => {
|
||||||
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_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);
|
||||||
|
}
|
||||||
|
OperatorFunction(operator_function_definition) => {
|
||||||
|
gather_operator_function_definition(
|
||||||
|
operator_function_definition,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PlatformFunction(platform_function_declaration) => {
|
||||||
|
gather_platform_function_definition(
|
||||||
|
platform_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Property(property_declaration) => {
|
||||||
|
gather_property_declaration(
|
||||||
|
property_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Field(field_declaration) => {
|
||||||
|
gather_field_declaration(field_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main Declarations */
|
/* Main Declarations */
|
||||||
@ -429,10 +519,11 @@ fn gather_module_declaration(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
// 1. Add mod identifier symbol
|
// 1. Add mod identifier symbol
|
||||||
// 2. Update fqn context
|
// 2. Push identifier on fqn_context
|
||||||
// 3. Push scope
|
// 3. Push scope
|
||||||
// 4. Process declarations
|
// 4. Process declarations
|
||||||
// 5. Pop scope
|
// 5. Pop scope
|
||||||
|
// 6. Pop fqn_context
|
||||||
|
|
||||||
let module_name = declaration.identifier.name();
|
let module_name = declaration.identifier.name();
|
||||||
|
|
||||||
@ -443,24 +534,78 @@ fn gather_module_declaration(
|
|||||||
Some(&declaration.identifier),
|
Some(&declaration.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Err(err) = insert_result {
|
match insert_result {
|
||||||
handle_insert_error(
|
Ok(_) => {
|
||||||
err,
|
fqn_context.push(&module_name);
|
||||||
|
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
|
||||||
|
|
||||||
|
for inner_declaration in &mut declaration.declarations {
|
||||||
|
gather_module_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => handle_insert_error(
|
||||||
|
insert_error,
|
||||||
&module_name,
|
&module_name,
|
||||||
declaration.identifier.file_id(),
|
declaration.identifier.file_id(),
|
||||||
declaration.identifier.range(),
|
declaration.identifier.range(),
|
||||||
"module/type",
|
"Module",
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fqn_context.push(module_name.to_string());
|
fn gather_interface_declaration(
|
||||||
|
declaration: &mut InterfaceDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let interface_name = declaration.identifier.name();
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
|
let insert_result =
|
||||||
for inner_declaration in &mut declaration.declarations {
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||||
gather_module_level_declaration(inner_declaration, symbol_table, fqn_context, diagnostics);
|
&fqn_context.resolve(&interface_name),
|
||||||
|
&interface_name,
|
||||||
|
declaration.is_public,
|
||||||
|
Some(&declaration.identifier),
|
||||||
|
)));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {
|
||||||
|
fqn_context.push(&interface_name);
|
||||||
|
symbol_table.push_scope(&format!("InterfaceScope({})", interface_name));
|
||||||
|
|
||||||
|
for inner_declaration in &mut declaration.declarations {
|
||||||
|
gather_interface_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&interface_name,
|
||||||
|
declaration.identifier.file_id(),
|
||||||
|
declaration.identifier.range(),
|
||||||
|
"Interface",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
symbol_table.pop_scope()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_class_declaration(
|
fn gather_class_declaration(
|
||||||
@ -469,27 +614,58 @@ fn gather_class_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let declared_name = class_declaration.identifier.name();
|
let class_name = class_declaration.identifier.name();
|
||||||
let resolved_name = fqn_context.resolve(&declared_name);
|
|
||||||
|
|
||||||
let insert_result = symbol_table.insert_type_symbol(TypeSymbol::new(
|
let insert_result =
|
||||||
&resolved_name,
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||||
&declared_name,
|
&fqn_context.resolve(&class_name),
|
||||||
class_declaration.is_public,
|
&class_name,
|
||||||
Some(&class_declaration.identifier),
|
class_declaration.is_public,
|
||||||
));
|
Some(&class_declaration.identifier),
|
||||||
if let Err(err) = insert_result {
|
)));
|
||||||
handle_insert_error(
|
|
||||||
err,
|
match insert_result {
|
||||||
&declared_name,
|
Ok(_) => {
|
||||||
class_declaration.identifier.file_id(),
|
// Do this first so we can't implement generic parameters!
|
||||||
class_declaration.identifier.range(),
|
gather_implements_list(
|
||||||
"interface/class",
|
&mut class_declaration.implements,
|
||||||
diagnostics,
|
symbol_table,
|
||||||
);
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
fqn_context.push(&class_name);
|
||||||
|
symbol_table.push_scope(&format!("ClassScope({})", class_name));
|
||||||
|
|
||||||
|
gather_generic_parameters(&mut class_declaration.generics, symbol_table, diagnostics);
|
||||||
|
|
||||||
|
if let Some(class_constructor) = &mut class_declaration.class_constructor {
|
||||||
|
gather_class_constructor(class_constructor, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
for inner_declaration in &mut class_declaration.declarations {
|
||||||
|
gather_class_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&class_name,
|
||||||
|
class_declaration.identifier.file_id(),
|
||||||
|
class_declaration.identifier.range(),
|
||||||
|
"interface/class",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: scopes, generics, etc.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function declarations and components */
|
/* Function declarations and components */
|
||||||
@ -646,7 +822,57 @@ fn gather_interface_function_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
let name = declaration.identifier.name();
|
||||||
|
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
|
||||||
|
&fqn_context.resolve(&name),
|
||||||
|
&name,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
Some(&declaration.identifier),
|
||||||
|
));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(function_symbol) => {
|
||||||
|
symbol_table.push_scope(&format!("FunctionParameterScope({})", &name));
|
||||||
|
|
||||||
|
gather_generic_parameters(&mut declaration.generics, symbol_table, diagnostics);
|
||||||
|
|
||||||
|
let parameters = gather_parameters(
|
||||||
|
&mut declaration.parameters,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
if let Some(parameter_symbols) = parameters {
|
||||||
|
function_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parameters(parameter_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
gather_return_type(
|
||||||
|
&mut declaration.return_type,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(body) = &mut declaration.body {
|
||||||
|
gather_function_body(body, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&name,
|
||||||
|
declaration.identifier.file_id(),
|
||||||
|
declaration.identifier.range(),
|
||||||
|
"Interface Function",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_interface_operator_function_declaration(
|
fn gather_interface_operator_function_declaration(
|
||||||
@ -666,6 +892,7 @@ fn gather_function_body(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::FunctionBody::*;
|
use crate::ast::FunctionBody::*;
|
||||||
match function_body {
|
match function_body {
|
||||||
|
Equals(expression) => gather_expression(expression, symbol_table, diagnostics),
|
||||||
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
@ -819,7 +1046,13 @@ fn gather_if_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut if_statement.condition, symbol_table, diagnostics);
|
||||||
|
gather_block_statement(
|
||||||
|
&mut if_statement.then_block,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_if_else_statement(
|
fn gather_if_else_statement(
|
||||||
@ -828,7 +1061,18 @@ fn gather_if_else_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_if_statement(
|
||||||
|
&mut if_else_statement.if_statement,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
for if_statement in &mut if_else_statement.else_ifs.0 {
|
||||||
|
gather_if_statement(if_statement, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
if let Some(else_block) = &mut if_else_statement.else_block {
|
||||||
|
gather_block_statement(&mut else_block.0, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_while_statement(
|
fn gather_while_statement(
|
||||||
@ -837,7 +1081,13 @@ fn gather_while_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut while_statement.condition, symbol_table, diagnostics);
|
||||||
|
gather_block_statement(
|
||||||
|
&mut while_statement.body,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_for_statement(
|
fn gather_for_statement(
|
||||||
@ -846,7 +1096,37 @@ fn gather_for_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut for_statement.iterator, symbol_table, diagnostics);
|
||||||
|
symbol_table.push_scope("ForStatementScope");
|
||||||
|
let variable_identifier = &mut for_statement.variable;
|
||||||
|
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
|
||||||
|
&variable_identifier.name(),
|
||||||
|
false,
|
||||||
|
Some(variable_identifier),
|
||||||
|
));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {
|
||||||
|
gather_block_statement_inner(
|
||||||
|
&mut for_statement.body,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&variable_identifier.name(),
|
||||||
|
variable_identifier.file_id(),
|
||||||
|
variable_identifier.range(),
|
||||||
|
"variable",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expressions */
|
/* Expressions */
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
use crate::ast::named::Named;
|
||||||
use crate::ast::{Identifier, UseStatement};
|
use crate::ast::{Identifier, UseStatement};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use std::ops::Deref;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::ast::named::Named;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SourceDefinition {
|
pub struct SourceDefinition {
|
||||||
@ -66,7 +67,10 @@ impl Symbol {
|
|||||||
match self {
|
match self {
|
||||||
Symbol::UseStatement(s) => s.borrow().definition(),
|
Symbol::UseStatement(s) => s.borrow().definition(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::Module(s) => s.definition(),
|
||||||
Symbol::Type(s) => s.definition(),
|
Symbol::Type(s) => match s.deref() {
|
||||||
|
TypeSymbol::Concrete(cts) => cts.definition(),
|
||||||
|
TypeSymbol::Generic(gts) => gts.definition(),
|
||||||
|
},
|
||||||
Symbol::Function(s) => s.borrow().definition(),
|
Symbol::Function(s) => s.borrow().definition(),
|
||||||
Symbol::Parameter(s) => s.definition(),
|
Symbol::Parameter(s) => s.definition(),
|
||||||
Symbol::Variable(s) => s.definition(),
|
Symbol::Variable(s) => s.definition(),
|
||||||
@ -180,21 +184,36 @@ impl Debug for ModuleSymbol {
|
|||||||
|
|
||||||
/* TypeSymbol */
|
/* TypeSymbol */
|
||||||
|
|
||||||
pub struct 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,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeSymbol {
|
impl ConcreteTypeSymbol {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
fqn: &str,
|
fqn: &str,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
identifier: Option<&Identifier>,
|
identifier: Option<&Identifier>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
TypeSymbol {
|
ConcreteTypeSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
is_public,
|
is_public,
|
||||||
@ -211,7 +230,7 @@ impl TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolInner for TypeSymbol {
|
impl SymbolInner for ConcreteTypeSymbol {
|
||||||
fn declared_name(&self) -> &str {
|
fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
@ -221,7 +240,7 @@ impl SymbolInner for TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for TypeSymbol {
|
impl Debug for ConcreteTypeSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("TypeSymbol")
|
f.debug_struct("TypeSymbol")
|
||||||
.field("fqn", &self.fqn)
|
.field("fqn", &self.fqn)
|
||||||
@ -231,6 +250,38 @@ impl Debug for TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Function */
|
||||||
|
|
||||||
pub struct FunctionSymbol {
|
pub struct FunctionSymbol {
|
||||||
@ -240,7 +291,7 @@ pub struct FunctionSymbol {
|
|||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
parameters: Vec<Rc<ParameterSymbol>>,
|
parameters: Vec<Rc<ParameterSymbol>>,
|
||||||
return_type: Option<Rc<TypeSymbol>>,
|
return_type: Option<Rc<ConcreteTypeSymbol>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionSymbol {
|
impl FunctionSymbol {
|
||||||
@ -277,7 +328,7 @@ impl FunctionSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_return_type(self, return_type: TypeSymbol) -> Self {
|
pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn: self.fqn,
|
fqn: self.fqn,
|
||||||
declared_name: self.declared_name,
|
declared_name: self.declared_name,
|
||||||
@ -297,7 +348,7 @@ impl FunctionSymbol {
|
|||||||
self.parameters = parameters;
|
self.parameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_return_type(&mut self, return_type: Rc<TypeSymbol>) {
|
pub fn set_return_type(&mut self, return_type: Rc<ConcreteTypeSymbol>) {
|
||||||
self.return_type = Some(return_type);
|
self.return_type = Some(return_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
use crate::name_analysis::symbol::{
|
use crate::name_analysis::symbol::*;
|
||||||
FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol,
|
|
||||||
UseStatementSymbol, VariableSymbol,
|
|
||||||
};
|
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
/* Scope */
|
/* Scope */
|
||||||
|
|
||||||
@ -36,37 +34,6 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_any_symbol(&self, name: &str) -> Option<Symbol> {
|
|
||||||
self.variable_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Variable(s.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.parameter_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Parameter(s.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.function_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Function(s.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.module_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ms| Symbol::Module(ms.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.use_statement_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|us| Symbol::UseStatement(us.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
||||||
for module_symbol in self.module_symbols.values() {
|
for module_symbol in self.module_symbols.values() {
|
||||||
if module_symbol.declared_name() == name {
|
if module_symbol.declared_name() == name {
|
||||||
@ -96,7 +63,13 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
||||||
self.type_symbols.values().find(|s| s.fqn() == fqn).cloned()
|
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> {
|
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
||||||
@ -106,8 +79,13 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for type_symbol in self.type_symbols.values() {
|
for type_symbol in self.type_symbols.values() {
|
||||||
if type_symbol.fqn() == fqn {
|
match type_symbol.deref() {
|
||||||
return Some(Symbol::Type(type_symbol.clone()));
|
TypeSymbol::Concrete(concrete_type_symbol) => {
|
||||||
|
if concrete_type_symbol.fqn() == fqn {
|
||||||
|
return Some(Symbol::Type(type_symbol.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -173,9 +151,7 @@ impl Scope {
|
|||||||
.find(|fs| fs.borrow().fqn() == fqn)
|
.find(|fs| fs.borrow().fqn() == fqn)
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
.map(|f| Symbol::Function(f.clone()))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.type_symbols
|
self.get_type_symbol_by_fqn(fqn)
|
||||||
.values()
|
|
||||||
.find(|ts| ts.fqn() == fqn)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
.map(|ts| Symbol::Type(ts.clone()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -342,22 +318,6 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "Use more specific lookup methods.")]
|
|
||||||
pub fn lookup(&self, 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_any_symbol(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_declared_name(
|
pub fn lookup_type_by_declared_name(
|
||||||
&self,
|
&self,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol, TypeSymbol};
|
use crate::name_analysis::symbol::{FunctionSymbol, 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> {
|
||||||
|
Loading…
Reference in New Issue
Block a user