855 lines
26 KiB
Rust
855 lines
26 KiB
Rust
use crate::ast::named::Named;
|
|
use crate::ast::*;
|
|
use crate::diagnostic::DmDiagnostic;
|
|
use crate::name_analysis::symbol::Symbol;
|
|
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
|
use std::ops::DerefMut;
|
|
use std::range::Range;
|
|
|
|
/* Type Use */
|
|
|
|
fn resolve_type_use(
|
|
type_use: &mut TypeUse,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
match type_use {
|
|
TypeUse::Primitive(primitive_type_use) => {
|
|
resolve_primitive_type_use(primitive_type_use, symbol_table, diagnostics)
|
|
}
|
|
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_primitive_type_use(
|
|
primitive_type_use: &mut PrimitiveTypeUse,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
match primitive_type_use {
|
|
PrimitiveTypeUse::Array(generic_arguments_opt) => {
|
|
if let Some(generic_arguments) = generic_arguments_opt {
|
|
resolve_generic_arguments(generic_arguments, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn resolve_interface_or_class_type_use(
|
|
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
// 1. handle main name
|
|
let fqn = interface_or_class_type_use.fqn_mut();
|
|
let lookup_result = if fqn.is_single_identifier() {
|
|
let identifier = fqn.last();
|
|
symbol_table.lookup_type_by_declared_name(
|
|
&identifier.name(),
|
|
identifier
|
|
.scope_id()
|
|
.expect("Identifier's scope id not set."),
|
|
)
|
|
} else {
|
|
todo!("Fully-qualified-name type uses sensitive to imports and so on")
|
|
};
|
|
match lookup_result {
|
|
Ok(type_symbol) => {
|
|
fqn.last_mut().set_saved_symbol(Symbol::Type(type_symbol));
|
|
}
|
|
Err(_) => {
|
|
diagnostics.push(
|
|
Diagnostic::error()
|
|
.with_message(&format!(
|
|
"No type symbol '{}' found in current scope.",
|
|
fqn.name()
|
|
))
|
|
.with_label(Label::primary(fqn.file_id(), fqn.range())),
|
|
);
|
|
}
|
|
}
|
|
|
|
// 2. generics
|
|
resolve_generic_arguments(
|
|
interface_or_class_type_use.generics_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
fn resolve_tuple_type_use(
|
|
tuple_type_use: &mut TupleTypeUse,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_tuple_arguments(tuple_type_use.arguments_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_function_type_use(
|
|
function_type_use: &mut FunctionTypeUse,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_parameters(
|
|
function_type_use.parameters_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_return_type(
|
|
function_type_use.return_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
/* Generic arguments */
|
|
|
|
fn resolve_generic_arguments(
|
|
generic_arguments: &mut GenericArguments,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for generic_argument in generic_arguments.arguments_mut() {
|
|
resolve_type_use(generic_argument, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Generic parameters: todo: no resolution needed? */
|
|
|
|
/* Tuple arguments */
|
|
|
|
fn resolve_tuple_arguments(
|
|
tuple_type_use: &mut TupleArguments,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for type_use in tuple_type_use.type_uses_mut() {
|
|
resolve_type_use(type_use, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Implements list */
|
|
|
|
fn resolve_implements_list(
|
|
implements_list: &mut ImplementsList,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for type_use in implements_list.type_uses_mut() {
|
|
resolve_type_use(type_use, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Function parameters */
|
|
|
|
fn resolve_parameters(
|
|
parameters: &mut Parameters,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for parameter in parameters.parameters_mut() {
|
|
resolve_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Return Type */
|
|
|
|
fn resolve_return_type(
|
|
return_type: &mut ReturnType,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_type_use(return_type.declared_type_mut(), symbol_table, diagnostics);
|
|
resolve_references(return_type.references_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
/* References */
|
|
|
|
fn resolve_references(
|
|
references: &mut References,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for reference in references.identifiers_mut() {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
/* Compilation Unit/Top-level construct */
|
|
|
|
pub(super) fn resolve_compilation_unit(
|
|
compilation_unit: &mut CompilationUnit,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for use_statement in compilation_unit.use_statements_mut() {
|
|
resolve_use_statement(use_statement, symbol_table, diagnostics);
|
|
}
|
|
for declaration in compilation_unit.declarations_mut() {
|
|
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Use Statement */
|
|
|
|
fn handle_use_statement_identifier(
|
|
identifier: &mut Identifier,
|
|
base_name: &str,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
file_id: usize,
|
|
error_range: Range<usize>,
|
|
) {
|
|
let declared_name = identifier.name().to_string();
|
|
let fqn = format!("{}::{}", base_name, &declared_name);
|
|
let lookup_result = symbol_table.lookup_usable_by_fqn(&fqn, identifier.scope_id().unwrap());
|
|
|
|
match lookup_result {
|
|
Ok(referenced_symbol) => {
|
|
let saved_symbol = identifier
|
|
.saved_symbol()
|
|
.expect("Identifier's saved_symbol is not set.");
|
|
let use_statement_symbol = saved_symbol.unwrap_use_statement_symbol();
|
|
use_statement_symbol
|
|
.borrow_mut()
|
|
.set_referenced_symbol(referenced_symbol);
|
|
}
|
|
Err(_) => {
|
|
diagnostics.push(
|
|
Diagnostic::error()
|
|
.with_message(&format!("Unable to find symbol '{}'.", fqn))
|
|
.with_label(Label::primary(file_id, error_range)),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_use_statement(
|
|
use_statement: &mut UseStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
let file_id = use_statement.file_id();
|
|
let use_statement_range = use_statement.range();
|
|
let base_name = use_statement.base_name().to_string();
|
|
|
|
match use_statement.last_mut() {
|
|
UseStatementLast::Identifier(identifier) => {
|
|
handle_use_statement_identifier(
|
|
identifier.deref_mut(),
|
|
&base_name,
|
|
symbol_table,
|
|
diagnostics,
|
|
file_id,
|
|
use_statement_range,
|
|
);
|
|
}
|
|
UseStatementLast::Identifiers(identifiers) => {
|
|
for identifier in identifiers {
|
|
let identifier_range = identifier.range();
|
|
handle_use_statement_identifier(
|
|
identifier.deref_mut(),
|
|
&base_name,
|
|
symbol_table,
|
|
diagnostics,
|
|
file_id,
|
|
identifier_range,
|
|
)
|
|
}
|
|
}
|
|
UseStatementLast::Star => todo!("star imports"),
|
|
}
|
|
}
|
|
|
|
/* Declarations allowed in each level */
|
|
|
|
fn resolve_module_level_declaration(
|
|
declaration: &mut ModuleLevelDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::ModuleLevelDeclaration::*;
|
|
match declaration {
|
|
Module(module_declaration) => {
|
|
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
|
}
|
|
Interface(interface_declaration) => {
|
|
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
|
}
|
|
Function(function_definition) => {
|
|
resolve_function_definition(function_definition, symbol_table, diagnostics)
|
|
}
|
|
Class(class_declaration) => {
|
|
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
|
}
|
|
PlatformFunction(platform_function_declaration) => resolve_platform_function_declaration(
|
|
platform_function_declaration,
|
|
symbol_table,
|
|
diagnostics,
|
|
),
|
|
}
|
|
}
|
|
|
|
fn resolve_interface_level_declaration(
|
|
declaration: &mut InterfaceLevelDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::InterfaceLevelDeclaration::*;
|
|
match declaration {
|
|
Module(module_declaration) => {
|
|
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
|
}
|
|
Interface(interface_declaration) => {
|
|
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
|
}
|
|
Class(class_declaration) => {
|
|
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
|
}
|
|
Function(interface_function_declaration) => {
|
|
resolve_interface_function_declaration(
|
|
interface_function_declaration,
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
OperatorFunction(interface_operator_function_declaration) => {
|
|
resolve_interface_operator_function_declaration(
|
|
interface_operator_function_declaration,
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_class_level_declaration(
|
|
declaration: &mut ClassLevelDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::ClassLevelDeclaration::*;
|
|
match declaration {
|
|
Module(module_declaration) => {
|
|
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
|
}
|
|
Interface(interface_declaration) => {
|
|
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
|
}
|
|
Class(class_declaration) => {
|
|
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
|
}
|
|
Function(function_definition) => {
|
|
resolve_function_definition(function_definition, symbol_table, diagnostics);
|
|
}
|
|
OperatorFunction(operator_function_definition) => {
|
|
resolve_operator_function_definition(
|
|
operator_function_definition,
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
PlatformFunction(platform_function_declaration) => {
|
|
resolve_platform_function_declaration(
|
|
platform_function_declaration,
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
Property(property_declaration) => {
|
|
resolve_property_declaration(property_declaration, symbol_table, diagnostics);
|
|
}
|
|
Field(field_declaration) => {
|
|
resolve_field_declaration(field_declaration, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Main Declarations */
|
|
|
|
fn resolve_module_declaration(
|
|
module_declaration: &mut ModuleDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for declaration in module_declaration.declarations_mut() {
|
|
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_interface_declaration(
|
|
interface_declaration: &mut InterfaceDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_implements_list(
|
|
interface_declaration.implements_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
for declaration in interface_declaration.declarations_mut() {
|
|
resolve_interface_level_declaration(declaration, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_class_declaration(
|
|
class_declaration: &mut ClassDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
|
|
resolve_class_constructor(class_constructor, symbol_table, diagnostics);
|
|
}
|
|
resolve_implements_list(class_declaration.implements_mut(), symbol_table, diagnostics);
|
|
for declaration in class_declaration.declarations_mut() {
|
|
resolve_class_level_declaration(declaration, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
/* Function declarations and components */
|
|
|
|
fn resolve_function_definition(
|
|
function_definition: &mut FunctionDefinition,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_parameters(
|
|
function_definition.parameters_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_return_type(
|
|
function_definition.return_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_function_body(function_definition.body_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_operator_function_definition(
|
|
operator_function_definition: &mut OperatorFunctionDefinition,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_platform_function_declaration(
|
|
platform_function_declaration: &mut PlatformFunctionDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_parameters(
|
|
platform_function_declaration.parameters_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_return_type(
|
|
platform_function_declaration.return_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
fn resolve_interface_function_declaration(
|
|
interface_function_declaration: &mut InterfaceFunctionDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_parameters(
|
|
interface_function_declaration.parameters_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_return_type(
|
|
interface_function_declaration.return_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
if let Some(body) = interface_function_declaration.body_mut() {
|
|
resolve_function_body(body, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_interface_operator_function_declaration(
|
|
interface_operator_function_declaration: &mut InterfaceOperatorFunctionDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_function_body(
|
|
function_body: &mut FunctionBody,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::FunctionBody::*;
|
|
match function_body {
|
|
Equals(expression) => resolve_expression(expression, symbol_table, diagnostics),
|
|
Block(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
|
Alias(identifier) => resolve_function_alias(identifier, symbol_table, diagnostics),
|
|
}
|
|
}
|
|
|
|
fn resolve_function_alias(
|
|
identifier: &mut Identifier,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
/* Class components */
|
|
|
|
fn resolve_class_constructor(
|
|
class_constructor: &mut ClassConstructor,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::ClassConstructorParameter::*;
|
|
for parameter in class_constructor.parameters_mut() {
|
|
match parameter {
|
|
Property(property) => resolve_property_declaration(property, symbol_table, diagnostics),
|
|
Field(field) => resolve_field_declaration(field, symbol_table, diagnostics),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_property_declaration(
|
|
property_declaration: &mut PropertyDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_type_use(
|
|
property_declaration.declared_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
fn resolve_field_declaration(
|
|
field_declaration: &mut FieldDeclaration,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_type_use(
|
|
field_declaration.declared_type_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
/* Statements */
|
|
|
|
fn resolve_block_statement(
|
|
block_statement: &mut BlockStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for statement in block_statement.statements_mut() {
|
|
resolve_statement(statement, symbol_table, diagnostics);
|
|
}
|
|
if let Some(expression) = block_statement.expression_mut() {
|
|
resolve_expression(expression, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_statement(
|
|
statement: &mut Statement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
use crate::ast::Statement::*;
|
|
match statement {
|
|
BlockStatement(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
|
VariableDeclarationStatement(variable_declaration) => {
|
|
resolve_variable_declaration(variable_declaration, symbol_table, diagnostics)
|
|
}
|
|
AssignStatement(assign_statement) => {
|
|
resolve_assign_statement(assign_statement, symbol_table, diagnostics)
|
|
}
|
|
CallStatement(call_statement) => {
|
|
resolve_call_statement(call_statement, symbol_table, diagnostics)
|
|
}
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
|
|
fn resolve_variable_declaration(
|
|
variable_declaration: &mut VariableDeclarationStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
if let Some(initializer) = variable_declaration.initializer_mut() {
|
|
resolve_expression(initializer, symbol_table, diagnostics)
|
|
}
|
|
}
|
|
|
|
fn resolve_assign_statement(
|
|
assign_statement: &mut AssignStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
|
|
resolve_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_call_statement(
|
|
call_statement: &mut CallStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(call_statement.expression_mut(), symbol_table, diagnostics)
|
|
}
|
|
|
|
fn resolve_return_statement(
|
|
return_statement: &mut ReturnStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
if let Some(expression) = return_statement.expression_mut() {
|
|
resolve_expression(expression, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_if_statement(
|
|
if_statement: &mut IfStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_while_statement(
|
|
while_statement: &mut WhileStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_for_statement(
|
|
for_statement: &mut ForStatement,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
/* Expressions */
|
|
|
|
fn resolve_expression(
|
|
expression: &mut Expression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
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) => {
|
|
if fqn.is_single_identifier() {
|
|
resolve_identifier_expression(fqn.last_mut(), symbol_table, diagnostics);
|
|
} else {
|
|
resolve_fqn_expression(fqn, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
Literal(literal) => {
|
|
resolve_literal(literal, symbol_table, diagnostics);
|
|
}
|
|
Closure(closure) => {
|
|
resolve_closure(closure, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn handle_named_lookup_result(
|
|
lookup_result: Result<Symbol, SymbolLookupError>,
|
|
named: &mut impl Named,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
match lookup_result {
|
|
Ok(referenced_symbol) => {
|
|
named.set_saved_symbol(referenced_symbol);
|
|
}
|
|
Err(_) => {
|
|
diagnostics.push(
|
|
DmDiagnostic::error()
|
|
.with_message(&format!(
|
|
"Unable to find expressible symbol {} in current scope.",
|
|
named.name()
|
|
))
|
|
.with_label(Label::primary(named.file_id(), named.range())),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_identifier_expression(
|
|
identifier: &mut Identifier,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
let lookup_result = symbol_table
|
|
.lookup_expressible_by_declared_name(&identifier.name(), identifier.scope_id().unwrap());
|
|
handle_named_lookup_result(lookup_result, identifier, diagnostics);
|
|
}
|
|
|
|
fn resolve_fqn_expression(
|
|
fqn: &mut FullyQualifiedName,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
let lookup_result =
|
|
symbol_table.lookup_expressible_by_fqn(&fqn.name(), fqn.last().scope_id().unwrap());
|
|
handle_named_lookup_result(lookup_result, fqn, diagnostics);
|
|
}
|
|
|
|
fn resolve_ternary_expression(
|
|
ternary_expression: &mut TernaryExpression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(ternary_expression.condition_mut(), symbol_table, diagnostics);
|
|
resolve_expression(
|
|
ternary_expression.true_expression_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
resolve_expression(
|
|
ternary_expression.false_expression_mut(),
|
|
symbol_table,
|
|
diagnostics,
|
|
);
|
|
}
|
|
|
|
fn resolve_binary_expression(
|
|
binary_expression: &mut BinaryExpression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(binary_expression.left_mut(), symbol_table, diagnostics);
|
|
resolve_expression(binary_expression.right_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_prefix_expression(
|
|
prefix_expression: &mut PrefixExpression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(prefix_expression.expression_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_suffix_expression(
|
|
suffix_expression: &mut SuffixExpression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(suffix_expression.expression_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_call_expression(
|
|
call_expression: &mut CallExpression,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(call_expression.callee_mut(), symbol_table, diagnostics);
|
|
if let Some(turbo_fish) = call_expression.turbo_fish_mut() {
|
|
resolve_turbo_fish(turbo_fish, symbol_table, diagnostics);
|
|
}
|
|
resolve_call_arguments(call_expression.arguments_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_turbo_fish(
|
|
turbo_fish: &mut TurboFish,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_generic_arguments(turbo_fish.generics_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_call_arguments(
|
|
call_arguments: &mut CallArguments,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
for argument in call_arguments.arguments_mut() {
|
|
resolve_call_argument(argument, symbol_table, diagnostics);
|
|
}
|
|
}
|
|
|
|
fn resolve_call_argument(
|
|
call_argument: &mut CallArgument,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
resolve_expression(call_argument.expression_mut(), symbol_table, diagnostics);
|
|
}
|
|
|
|
fn resolve_closure(
|
|
closure: &mut Closure,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_object_access(
|
|
object_access: &mut ObjectAccess,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|
|
|
|
fn resolve_literal(
|
|
literal: &mut Literal,
|
|
symbol_table: &mut SymbolTable,
|
|
diagnostics: &mut Vec<DmDiagnostic>,
|
|
) {
|
|
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 Vec<DmDiagnostic>,
|
|
) {
|
|
todo!()
|
|
}
|