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)]
|
#[derive(Debug)]
|
||||||
pub struct UseStatement {
|
pub struct UseStatement {
|
||||||
pub identifiers: Vec<Identifier>,
|
pub identifiers: Vec<Identifier>,
|
||||||
pub last: UseStatementLast
|
pub last: UseStatementLast,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -572,8 +572,8 @@ pub struct PrefixExpression {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SuffixExpression {
|
pub struct SuffixExpression {
|
||||||
expression: Box<Expression>,
|
pub expression: Box<Expression>,
|
||||||
operator: SuffixUnaryOperator,
|
pub operator: SuffixUnaryOperator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use crate::ast::named::Named;
|
use crate::ast::named::Named;
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::name_analysis::fqn_context::FqnContext;
|
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::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::name_analysis::DiagnosticsContainer;
|
use crate::name_analysis::DiagnosticsContainer;
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
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(
|
pub(super) fn gather_module_level_declaration(
|
||||||
declaration: &mut ModuleLevelDeclaration,
|
declaration: &mut ModuleLevelDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -52,9 +132,20 @@ pub(super) 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);
|
||||||
}
|
}
|
||||||
|
Class(class_declaration) => {
|
||||||
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
||||||
|
}
|
||||||
Function(function_definition) => {
|
Function(function_definition) => {
|
||||||
gather_function_definition(function_definition, symbol_table, fqn_context, diagnostics)
|
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!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,6 +194,38 @@ fn gather_module_declaration(
|
|||||||
symbol_table.pop_scope()
|
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(
|
fn gather_function_definition(
|
||||||
function: &mut FunctionDefinition,
|
function: &mut FunctionDefinition,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -118,6 +241,7 @@ fn gather_function_definition(
|
|||||||
&resolved_name,
|
&resolved_name,
|
||||||
&declared_name,
|
&declared_name,
|
||||||
function.is_public,
|
function.is_public,
|
||||||
|
false,
|
||||||
&function.identifier,
|
&function.identifier,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
@ -148,6 +272,53 @@ fn gather_function_definition(
|
|||||||
symbol_table.pop_scope();
|
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(
|
fn gather_parameters(
|
||||||
parameters: &mut Parameters,
|
parameters: &mut Parameters,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -190,6 +361,13 @@ fn gather_parameter(
|
|||||||
parameter
|
parameter
|
||||||
.identifier
|
.identifier
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
|
gather_type_use(
|
||||||
|
&mut parameter.type_use,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_function_body(
|
fn gather_function_body(
|
||||||
@ -247,6 +425,9 @@ fn gather_statement(
|
|||||||
AssignStatement(assign_statement) => {
|
AssignStatement(assign_statement) => {
|
||||||
gather_assign_statement(assign_statement, symbol_table, fqn_context, diagnostics)
|
gather_assign_statement(assign_statement, symbol_table, fqn_context, diagnostics)
|
||||||
}
|
}
|
||||||
|
CallStatement(call_statement) => {
|
||||||
|
gather_call_statement(call_statement, symbol_table, diagnostics)
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,6 +478,14 @@ fn gather_assign_statement(
|
|||||||
gather_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
|
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(
|
fn gather_expression(
|
||||||
expression: &mut Expression,
|
expression: &mut Expression,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -304,16 +493,135 @@ fn gather_expression(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::Expression::*;
|
use crate::ast::Expression::*;
|
||||||
match 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) => {
|
FullyQualifiedName(fully_qualified_name) => {
|
||||||
gather_fully_qualified_name(fully_qualified_name, symbol_table);
|
gather_fully_qualified_name(fully_qualified_name, symbol_table);
|
||||||
}
|
}
|
||||||
_ => {}
|
Closure(closure) => {
|
||||||
|
gather_closure(closure, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_fully_qualified_name(
|
fn gather_ternary_expression(
|
||||||
fully_qualified_name: &mut FullyQualifiedName,
|
ternary_expression: &mut TernaryExpression,
|
||||||
symbol_table: &mut SymbolTable,
|
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",
|
"main.dm",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
use std::core::println;
|
use std::core::{Array, String, println};
|
||||||
|
|
||||||
fn main(args: Array<String>) {
|
fn main(args: Array<String>) {
|
||||||
println(\"Hello, World!\");
|
println(\"Hello, World!\");
|
||||||
@ -144,11 +144,15 @@ mod tests {
|
|||||||
"},
|
"},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"print.dm",
|
"deps.dm",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
ns std::core;
|
ns std::core;
|
||||||
|
|
||||||
platform fn println(msg: String) -> Void;
|
pub class String {}
|
||||||
|
|
||||||
|
pub class Array {}
|
||||||
|
|
||||||
|
pub platform fn println(msg: String) -> Void;
|
||||||
"},
|
"},
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
@ -4,6 +4,170 @@ use crate::name_analysis::symbol_table::SymbolTable;
|
|||||||
use crate::name_analysis::DiagnosticsContainer;
|
use crate::name_analysis::DiagnosticsContainer;
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
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(
|
pub(super) fn resolve_module_level_declaration(
|
||||||
declaration: &mut ModuleLevelDeclaration,
|
declaration: &mut ModuleLevelDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -14,6 +178,16 @@ pub(super) fn resolve_module_level_declaration(
|
|||||||
Function(function_definition) => {
|
Function(function_definition) => {
|
||||||
resolve_function_definition(function_definition, symbol_table, diagnostics)
|
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!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,9 +197,20 @@ fn resolve_function_definition(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut DiagnosticsContainer,
|
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);
|
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(
|
fn resolve_function_body(
|
||||||
function_body: &mut FunctionBody,
|
function_body: &mut FunctionBody,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -106,38 +291,155 @@ fn resolve_expression(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::Expression::*;
|
use crate::ast::Expression::*;
|
||||||
match 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),
|
FullyQualifiedName(fqn) => resolve_fully_qualified_name(fqn, symbol_table, diagnostics),
|
||||||
Literal(_) => {}
|
Literal(literal) => {
|
||||||
_ => todo!(),
|
resolve_literal(literal, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Closure(closure) => {
|
||||||
|
resolve_closure(closure, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_fully_qualified_name(
|
fn resolve_ternary_expression(
|
||||||
fully_qualified_name: &mut FullyQualifiedName,
|
ternary_expression: &mut TernaryExpression,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut DiagnosticsContainer,
|
diagnostics: &mut DiagnosticsContainer
|
||||||
) {
|
) {
|
||||||
let lookup_result = symbol_table.lookup(
|
resolve_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
|
||||||
fully_qualified_name.name().as_ref(),
|
resolve_expression(&mut ternary_expression.true_expression, symbol_table, diagnostics);
|
||||||
fully_qualified_name.scope_id().expect(&format!(
|
resolve_expression(&mut ternary_expression.false_expression, symbol_table, diagnostics);
|
||||||
"FullyQualifiedName has no scope_id set: {:?}",
|
}
|
||||||
fully_qualified_name
|
|
||||||
)),
|
fn resolve_binary_expression(
|
||||||
);
|
binary_expression: &mut BinaryExpression,
|
||||||
match lookup_result {
|
symbol_table: &mut SymbolTable,
|
||||||
Ok(symbol) => {
|
diagnostics: &mut DiagnosticsContainer
|
||||||
fully_qualified_name.set_symbol(symbol.clone());
|
) {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
Err(e) => diagnostics.add(
|
resolve_call_arguments(&mut call_expression.arguments, symbol_table, diagnostics);
|
||||||
Diagnostic::error()
|
}
|
||||||
.with_message(format!(
|
|
||||||
"No symbol with name '{}' found in current scope.",
|
fn resolve_turbo_fish(
|
||||||
fully_qualified_name.name()
|
turbo_fish: &mut TurboFish,
|
||||||
))
|
symbol_table: &mut SymbolTable,
|
||||||
.with_label(Label::primary(
|
diagnostics: &mut DiagnosticsContainer
|
||||||
fully_qualified_name.file_id,
|
) {
|
||||||
fully_qualified_name.range,
|
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),
|
Function(FunctionSymbol),
|
||||||
Variable(VariableSymbol),
|
Variable(VariableSymbol),
|
||||||
Module(ModuleSymbol),
|
Module(ModuleSymbol),
|
||||||
|
Class(ClassSymbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Symbol {
|
impl Symbol {
|
||||||
@ -38,6 +39,7 @@ impl Symbol {
|
|||||||
Symbol::Function(s) => s.declared_name.as_str(),
|
Symbol::Function(s) => s.declared_name.as_str(),
|
||||||
Symbol::Variable(s) => s.name.as_str(),
|
Symbol::Variable(s) => s.name.as_str(),
|
||||||
Symbol::Module(s) => s.declared_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::Function(s) => s.definition(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::Module(s) => s.definition(),
|
||||||
Symbol::Variable(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),
|
Function(function_symbol) => write!(f, "{}", function_symbol),
|
||||||
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
|
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
|
||||||
Module(module_symbol) => write!(f, "{}", module_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 fqn: String,
|
||||||
pub declared_name: String,
|
pub declared_name: String,
|
||||||
pub is_public: bool,
|
pub is_public: bool,
|
||||||
|
pub is_platform: bool,
|
||||||
definition: SourceDefinition,
|
definition: SourceDefinition,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,12 +79,14 @@ impl FunctionSymbol {
|
|||||||
fqn: &str,
|
fqn: &str,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
|
is_platform: bool,
|
||||||
identifier: &Identifier,
|
identifier: &Identifier,
|
||||||
) -> FunctionSymbol {
|
) -> FunctionSymbol {
|
||||||
FunctionSymbol {
|
FunctionSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
is_public,
|
is_public,
|
||||||
|
is_platform,
|
||||||
definition: SourceDefinition::from_identifier(identifier),
|
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(_) => {
|
Symbol::Function(_) | Symbol::Variable(_) => {
|
||||||
self.insert_function_or_variable(name, symbol)
|
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)?;
|
writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?;
|
||||||
for (i, scope) in self.scopes.iter().enumerate() {
|
for (i, scope) in self.scopes.iter().enumerate() {
|
||||||
writeln!(f, "Scope {} {}", i, scope.debug_name)?;
|
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 {
|
for (name, symbol) in &scope.function_and_variable_symbols {
|
||||||
writeln!(f, " {}({})", name, symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user