Add gathering and resolving for various constructs; two-file test still failing but fails correctly.
This commit is contained in:
parent
c54e005b62
commit
8cd5e588a0
@ -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)]
|
||||
|
@ -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!(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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!()
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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)?;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user