Compare commits
4 Commits
f614d00575
...
c8ff1d0fa2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c8ff1d0fa2 | ||
![]() |
f5f247e636 | ||
![]() |
41ab922f2c | ||
![]() |
d8fe97b401 |
25
TODO.md
25
TODO.md
@ -1,6 +1,12 @@
|
|||||||
# TODO/Plans
|
# TODO/Plans
|
||||||
|
|
||||||
|
## May 2025
|
||||||
|
|
||||||
|
- Refactor name-analysis to add custom errors for name-analysis only, which can then be tested.
|
||||||
|
- Refactor `pub` fields of AST structs into private fields accessed by methods.
|
||||||
|
|
||||||
## General Pipeline
|
## General Pipeline
|
||||||
|
|
||||||
- Transform a single file into a `CompilationUnit` AST node.
|
- Transform a single file into a `CompilationUnit` AST node.
|
||||||
- Gather all `CompilationUnit`s and determine which modules need to be built.
|
- Gather all `CompilationUnit`s and determine which modules need to be built.
|
||||||
- A module corresponds to one syntactical namespace `ns`, but not its children!
|
- A module corresponds to one syntactical namespace `ns`, but not its children!
|
||||||
@ -35,21 +41,23 @@
|
|||||||
appropriate objects, such as `DmInterface`, `DmImplementation`, `DmFunction`, or `DmConstant`.
|
appropriate objects, such as `DmInterface`, `DmImplementation`, `DmFunction`, or `DmConstant`.
|
||||||
- Thus, a `DmModule` is a single-file containing all the code for one namespace, but not its child namespaces. Using
|
- Thus, a `DmModule` is a single-file containing all the code for one namespace, but not its child namespaces. Using
|
||||||
the above examples, the following DmModules would be created, with their appropriate contents:
|
the above examples, the following DmModules would be created, with their appropriate contents:
|
||||||
- `pub ns std`: *no contents, only metadata.*
|
- `pub ns std`: *no contents, only metadata.*
|
||||||
- `pub ns std::core`:
|
- `pub ns std::core`:
|
||||||
- `pub fn std::core::foo`
|
- `pub fn std::core::foo`
|
||||||
- `ns std::core::bar`
|
- `ns std::core::bar`
|
||||||
- `fn std::core::bar::baz`
|
- `fn std::core::bar::baz`
|
||||||
- `prv fn std::core::bar::hello`: only accessible inside `std::core::bar`.
|
- `prv fn std::core::bar::hello`: only accessible inside `std::core::bar`.
|
||||||
|
|
||||||
## More Namespace Rules
|
## More Namespace Rules
|
||||||
|
|
||||||
Top-level namespace declaration:
|
Top-level namespace declaration:
|
||||||
|
|
||||||
```
|
```
|
||||||
decl pub ns std
|
decl pub ns std
|
||||||
```
|
```
|
||||||
|
|
||||||
Nested namespace declaration and members:
|
Nested namespace declaration and members:
|
||||||
|
|
||||||
```
|
```
|
||||||
ns std::core // indicates that all members of this file are in the std::core namespace
|
ns std::core // indicates that all members of this file are in the std::core namespace
|
||||||
|
|
||||||
@ -64,6 +72,7 @@ pub ns array {
|
|||||||
## Example of std lib would be coded
|
## Example of std lib would be coded
|
||||||
|
|
||||||
std/std.dm
|
std/std.dm
|
||||||
|
|
||||||
```
|
```
|
||||||
decl pub ns std {
|
decl pub ns std {
|
||||||
decl pub ns core, http, json
|
decl pub ns core, http, json
|
||||||
@ -72,6 +81,7 @@ decl pub ns std {
|
|||||||
```
|
```
|
||||||
|
|
||||||
std/core/core.dm
|
std/core/core.dm
|
||||||
|
|
||||||
```
|
```
|
||||||
ns std
|
ns std
|
||||||
|
|
||||||
@ -82,6 +92,7 @@ decl pub ns core {
|
|||||||
```
|
```
|
||||||
|
|
||||||
std/core/array.dm
|
std/core/array.dm
|
||||||
|
|
||||||
```
|
```
|
||||||
ns std::core
|
ns std::core
|
||||||
|
|
||||||
@ -119,6 +130,7 @@ pub ns array {
|
|||||||
```
|
```
|
||||||
|
|
||||||
std/core/hkt/monad.dm
|
std/core/hkt/monad.dm
|
||||||
|
|
||||||
```
|
```
|
||||||
ns std::core::hkt
|
ns std::core::hkt
|
||||||
|
|
||||||
@ -132,6 +144,7 @@ pub hkt Monad<T = Self>[a] {
|
|||||||
```
|
```
|
||||||
|
|
||||||
std/core/string.dm
|
std/core/string.dm
|
||||||
|
|
||||||
```
|
```
|
||||||
ns std::core
|
ns std::core
|
||||||
|
|
||||||
|
13
sketching/may_2025/int.dm
Normal file
13
sketching/may_2025/int.dm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
int Greeter {
|
||||||
|
fn greet() -> Void
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyGreeter(fld greeting: String) : Greeter {
|
||||||
|
fn greet() {
|
||||||
|
println(greeting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let greeter: Greeter = MyGreeter("Hello, World!");
|
||||||
|
}
|
@ -494,7 +494,7 @@ fn build_interface_declaration(file_id: usize, interface_pair: Pair<Rule>) -> In
|
|||||||
Rule::Pub => {
|
Rule::Pub => {
|
||||||
is_public = true;
|
is_public = true;
|
||||||
}
|
}
|
||||||
Rule::Int => {}
|
Rule::IntKw => {}
|
||||||
Rule::Identifier => {
|
Rule::Identifier => {
|
||||||
identifier = Some(build_identifier(file_id, inner_pair));
|
identifier = Some(build_identifier(file_id, inner_pair));
|
||||||
}
|
}
|
||||||
@ -671,7 +671,46 @@ fn build_interface_function_declaration(
|
|||||||
file_id: usize,
|
file_id: usize,
|
||||||
interface_function_pair: Pair<Rule>,
|
interface_function_pair: Pair<Rule>,
|
||||||
) -> InterfaceFunctionDeclaration {
|
) -> InterfaceFunctionDeclaration {
|
||||||
todo!()
|
let mut modifier = None;
|
||||||
|
let mut generics = GenericParameters::default();
|
||||||
|
let mut identifier = None;
|
||||||
|
let mut parameters = Parameters::default();
|
||||||
|
let mut return_type = None;
|
||||||
|
let mut body = None;
|
||||||
|
|
||||||
|
for inner_pair in interface_function_pair.into_inner() {
|
||||||
|
match inner_pair.as_rule() {
|
||||||
|
Rule::Def | Rule::Fn => {},
|
||||||
|
Rule::FunctionModifier => {
|
||||||
|
modifier = Some(build_function_modifier(file_id, inner_pair));
|
||||||
|
},
|
||||||
|
Rule::GenericParameters => {
|
||||||
|
generics = build_generic_parameters(file_id, inner_pair);
|
||||||
|
}
|
||||||
|
Rule::Identifier => {
|
||||||
|
identifier = Some(build_identifier(file_id, inner_pair));
|
||||||
|
}
|
||||||
|
Rule::Parameters => {
|
||||||
|
parameters = build_parameters(file_id, inner_pair);
|
||||||
|
}
|
||||||
|
Rule::ReturnType => {
|
||||||
|
return_type = Some(build_return_type(file_id, inner_pair));
|
||||||
|
}
|
||||||
|
Rule::FunctionBody => {
|
||||||
|
body = Some(build_function_body(file_id, inner_pair));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceFunctionDeclaration {
|
||||||
|
modifier,
|
||||||
|
generics,
|
||||||
|
identifier: identifier.unwrap(),
|
||||||
|
parameters,
|
||||||
|
return_type: return_type.unwrap(),
|
||||||
|
body
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_interface_operator_function_declaration(
|
fn build_interface_operator_function_declaration(
|
||||||
|
@ -7,8 +7,8 @@ impl FqnContext {
|
|||||||
FqnContext { stack: Vec::new() }
|
FqnContext { stack: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, name: String) {
|
pub fn push(&mut self, name: &str) {
|
||||||
self.stack.push(name);
|
self.stack.push(name.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) {
|
pub fn pop(&mut self) {
|
||||||
|
@ -132,12 +132,8 @@ fn gather_function_type_use(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
gather_generic_parameters(
|
symbol_table.push_scope("FunctionTypeUseScope");
|
||||||
&mut function_type_use.generics,
|
gather_generic_parameters(&mut function_type_use.generics, symbol_table, diagnostics);
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_parameters(
|
gather_parameters(
|
||||||
&mut function_type_use.parameters,
|
&mut function_type_use.parameters,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
@ -150,6 +146,7 @@ fn gather_function_type_use(
|
|||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic Arguments */
|
/* Generic Arguments */
|
||||||
@ -170,10 +167,28 @@ fn gather_generic_arguments(
|
|||||||
fn gather_generic_parameters(
|
fn gather_generic_parameters(
|
||||||
generic_parameters: &mut GenericParameters,
|
generic_parameters: &mut GenericParameters,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!("Add each Identifier as a type to the current scope; make sure caller's push/pop before/after")
|
for identifier in &mut generic_parameters.0 {
|
||||||
|
let insert_result =
|
||||||
|
symbol_table.insert_type_symbol(TypeSymbol::Generic(GenericTypeSymbol::new(
|
||||||
|
&identifier.name(),
|
||||||
|
SourceDefinition::from_identifier(identifier),
|
||||||
|
)));
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&identifier.name(),
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
"Type",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implements List */
|
/* Implements List */
|
||||||
@ -259,22 +274,12 @@ fn gather_return_type(
|
|||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
gather_references(
|
gather_references(&mut return_type.references, symbol_table);
|
||||||
&mut return_type.references,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* References */
|
/* References */
|
||||||
|
|
||||||
fn gather_references(
|
fn gather_references(references: &mut References, symbol_table: &mut SymbolTable) {
|
||||||
references: &mut References,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
for identifier in &mut references.0 {
|
for identifier in &mut references.0 {
|
||||||
gather_identifier(identifier, symbol_table);
|
gather_identifier(identifier, symbol_table);
|
||||||
}
|
}
|
||||||
@ -289,7 +294,7 @@ pub(super) fn gather_compilation_unit(
|
|||||||
) {
|
) {
|
||||||
let mut fqn_context = FqnContext::new();
|
let mut fqn_context = FqnContext::new();
|
||||||
if let Some(namespace) = &compilation_unit.namespace {
|
if let Some(namespace) = &compilation_unit.namespace {
|
||||||
fqn_context.push(namespace.name().to_string());
|
fqn_context.push(&namespace.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
|
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
|
||||||
@ -384,6 +389,14 @@ fn gather_module_level_declaration(
|
|||||||
Module(module_declaration) => {
|
Module(module_declaration) => {
|
||||||
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
Class(class_declaration) => {
|
Class(class_declaration) => {
|
||||||
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
||||||
}
|
}
|
||||||
@ -398,7 +411,6 @@ fn gather_module_level_declaration(
|
|||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +420,39 @@ fn gather_interface_level_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
use InterfaceLevelDeclaration::*;
|
||||||
|
match declaration {
|
||||||
|
Module(module_declaration) => {
|
||||||
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Class(class_declaration) => {
|
||||||
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics)
|
||||||
|
}
|
||||||
|
Function(interface_function_declaration) => {
|
||||||
|
gather_interface_function_declaration(
|
||||||
|
interface_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OperatorFunction(interface_operator_function_declaration) => {
|
||||||
|
gather_interface_operator_function_declaration(
|
||||||
|
interface_operator_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_class_level_declaration(
|
fn gather_class_level_declaration(
|
||||||
@ -417,7 +461,53 @@ fn gather_class_level_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
use ClassLevelDeclaration::*;
|
||||||
|
match declaration {
|
||||||
|
Module(module_declaration) => {
|
||||||
|
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
Interface(interface_declaration) => {
|
||||||
|
gather_interface_declaration(
|
||||||
|
interface_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Class(class_declaration) => {
|
||||||
|
gather_class_declaration(class_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
Function(function_definition) => {
|
||||||
|
gather_function_definition(function_definition, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
OperatorFunction(operator_function_definition) => {
|
||||||
|
gather_operator_function_definition(
|
||||||
|
operator_function_definition,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PlatformFunction(platform_function_declaration) => {
|
||||||
|
gather_platform_function_definition(
|
||||||
|
platform_function_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Property(property_declaration) => {
|
||||||
|
gather_property_declaration(
|
||||||
|
property_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Field(field_declaration) => {
|
||||||
|
gather_field_declaration(field_declaration, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main Declarations */
|
/* Main Declarations */
|
||||||
@ -429,10 +519,11 @@ fn gather_module_declaration(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
// 1. Add mod identifier symbol
|
// 1. Add mod identifier symbol
|
||||||
// 2. Update fqn context
|
// 2. Push identifier on fqn_context
|
||||||
// 3. Push scope
|
// 3. Push scope
|
||||||
// 4. Process declarations
|
// 4. Process declarations
|
||||||
// 5. Pop scope
|
// 5. Pop scope
|
||||||
|
// 6. Pop fqn_context
|
||||||
|
|
||||||
let module_name = declaration.identifier.name();
|
let module_name = declaration.identifier.name();
|
||||||
|
|
||||||
@ -443,24 +534,78 @@ fn gather_module_declaration(
|
|||||||
Some(&declaration.identifier),
|
Some(&declaration.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Err(err) = insert_result {
|
match insert_result {
|
||||||
handle_insert_error(
|
Ok(_) => {
|
||||||
err,
|
fqn_context.push(&module_name);
|
||||||
|
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
|
||||||
|
|
||||||
|
for inner_declaration in &mut declaration.declarations {
|
||||||
|
gather_module_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => handle_insert_error(
|
||||||
|
insert_error,
|
||||||
&module_name,
|
&module_name,
|
||||||
declaration.identifier.file_id(),
|
declaration.identifier.file_id(),
|
||||||
declaration.identifier.range(),
|
declaration.identifier.range(),
|
||||||
"module/type",
|
"Module",
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fqn_context.push(module_name.to_string());
|
fn gather_interface_declaration(
|
||||||
|
declaration: &mut InterfaceDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let interface_name = declaration.identifier.name();
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
|
let insert_result =
|
||||||
for inner_declaration in &mut declaration.declarations {
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||||
gather_module_level_declaration(inner_declaration, symbol_table, fqn_context, diagnostics);
|
&fqn_context.resolve(&interface_name),
|
||||||
|
&interface_name,
|
||||||
|
declaration.is_public,
|
||||||
|
Some(&declaration.identifier),
|
||||||
|
)));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {
|
||||||
|
fqn_context.push(&interface_name);
|
||||||
|
symbol_table.push_scope(&format!("InterfaceScope({})", interface_name));
|
||||||
|
|
||||||
|
for inner_declaration in &mut declaration.declarations {
|
||||||
|
gather_interface_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&interface_name,
|
||||||
|
declaration.identifier.file_id(),
|
||||||
|
declaration.identifier.range(),
|
||||||
|
"Interface",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
symbol_table.pop_scope()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_class_declaration(
|
fn gather_class_declaration(
|
||||||
@ -469,27 +614,58 @@ fn gather_class_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let declared_name = class_declaration.identifier.name();
|
let class_name = class_declaration.identifier.name();
|
||||||
let resolved_name = fqn_context.resolve(&declared_name);
|
|
||||||
|
|
||||||
let insert_result = symbol_table.insert_type_symbol(TypeSymbol::new(
|
let insert_result =
|
||||||
&resolved_name,
|
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||||
&declared_name,
|
&fqn_context.resolve(&class_name),
|
||||||
class_declaration.is_public,
|
&class_name,
|
||||||
Some(&class_declaration.identifier),
|
class_declaration.is_public,
|
||||||
));
|
Some(&class_declaration.identifier),
|
||||||
if let Err(err) = insert_result {
|
)));
|
||||||
handle_insert_error(
|
|
||||||
err,
|
match insert_result {
|
||||||
&declared_name,
|
Ok(_) => {
|
||||||
class_declaration.identifier.file_id(),
|
// Do this first so we can't implement generic parameters!
|
||||||
class_declaration.identifier.range(),
|
gather_implements_list(
|
||||||
"interface/class",
|
&mut class_declaration.implements,
|
||||||
diagnostics,
|
symbol_table,
|
||||||
);
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
fqn_context.push(&class_name);
|
||||||
|
symbol_table.push_scope(&format!("ClassScope({})", class_name));
|
||||||
|
|
||||||
|
gather_generic_parameters(&mut class_declaration.generics, symbol_table, diagnostics);
|
||||||
|
|
||||||
|
if let Some(class_constructor) = &mut class_declaration.class_constructor {
|
||||||
|
gather_class_constructor(class_constructor, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
for inner_declaration in &mut class_declaration.declarations {
|
||||||
|
gather_class_level_declaration(
|
||||||
|
inner_declaration,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
fqn_context.pop();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&class_name,
|
||||||
|
class_declaration.identifier.file_id(),
|
||||||
|
class_declaration.identifier.range(),
|
||||||
|
"interface/class",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: scopes, generics, etc.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function declarations and components */
|
/* Function declarations and components */
|
||||||
@ -646,7 +822,57 @@ fn gather_interface_function_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
let name = declaration.identifier.name();
|
||||||
|
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
|
||||||
|
&fqn_context.resolve(&name),
|
||||||
|
&name,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
Some(&declaration.identifier),
|
||||||
|
));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(function_symbol) => {
|
||||||
|
symbol_table.push_scope(&format!("FunctionParameterScope({})", &name));
|
||||||
|
|
||||||
|
gather_generic_parameters(&mut declaration.generics, symbol_table, diagnostics);
|
||||||
|
|
||||||
|
let parameters = gather_parameters(
|
||||||
|
&mut declaration.parameters,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
if let Some(parameter_symbols) = parameters {
|
||||||
|
function_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parameters(parameter_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
gather_return_type(
|
||||||
|
&mut declaration.return_type,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(body) = &mut declaration.body {
|
||||||
|
gather_function_body(body, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&name,
|
||||||
|
declaration.identifier.file_id(),
|
||||||
|
declaration.identifier.range(),
|
||||||
|
"Interface Function",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_interface_operator_function_declaration(
|
fn gather_interface_operator_function_declaration(
|
||||||
@ -666,6 +892,7 @@ fn gather_function_body(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::FunctionBody::*;
|
use crate::ast::FunctionBody::*;
|
||||||
match function_body {
|
match function_body {
|
||||||
|
Equals(expression) => gather_expression(expression, symbol_table, diagnostics),
|
||||||
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
@ -679,7 +906,16 @@ fn gather_class_constructor(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
for parameter in &mut class_constructor.0 {
|
||||||
|
match parameter {
|
||||||
|
ClassConstructorParameter::Property(property) => {
|
||||||
|
gather_property_declaration(property, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
ClassConstructorParameter::Field(field) => {
|
||||||
|
gather_field_declaration(field, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_property_declaration(
|
fn gather_property_declaration(
|
||||||
@ -688,7 +924,23 @@ fn gather_property_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
let insert_result = symbol_table.insert_class_member_symbol(
|
||||||
|
ClassMemberSymbol::new(
|
||||||
|
&property_declaration.identifier.name(),
|
||||||
|
false,
|
||||||
|
Some(SourceDefinition::from_identifier(&property_declaration.identifier))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = insert_result {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&property_declaration.identifier.name(),
|
||||||
|
property_declaration.identifier.file_id(),
|
||||||
|
property_declaration.identifier.range(),
|
||||||
|
"Data Member",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_field_declaration(
|
fn gather_field_declaration(
|
||||||
@ -697,7 +949,23 @@ fn gather_field_declaration(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
let insert_result = symbol_table.insert_class_member_symbol(
|
||||||
|
ClassMemberSymbol::new(
|
||||||
|
&field_declaration.identifier.name(),
|
||||||
|
true,
|
||||||
|
Some(SourceDefinition::from_identifier(&field_declaration.identifier))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if let Err(insert_error) = insert_result {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&field_declaration.identifier.name(),
|
||||||
|
field_declaration.identifier.file_id(),
|
||||||
|
field_declaration.identifier.range(),
|
||||||
|
"Data Member",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Statements */
|
/* Statements */
|
||||||
@ -819,7 +1087,13 @@ fn gather_if_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut if_statement.condition, symbol_table, diagnostics);
|
||||||
|
gather_block_statement(
|
||||||
|
&mut if_statement.then_block,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_if_else_statement(
|
fn gather_if_else_statement(
|
||||||
@ -828,7 +1102,18 @@ fn gather_if_else_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_if_statement(
|
||||||
|
&mut if_else_statement.if_statement,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
for if_statement in &mut if_else_statement.else_ifs.0 {
|
||||||
|
gather_if_statement(if_statement, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
if let Some(else_block) = &mut if_else_statement.else_block {
|
||||||
|
gather_block_statement(&mut else_block.0, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_while_statement(
|
fn gather_while_statement(
|
||||||
@ -837,7 +1122,13 @@ fn gather_while_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut while_statement.condition, symbol_table, diagnostics);
|
||||||
|
gather_block_statement(
|
||||||
|
&mut while_statement.body,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_for_statement(
|
fn gather_for_statement(
|
||||||
@ -846,7 +1137,37 @@ fn gather_for_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
gather_expression(&mut for_statement.iterator, symbol_table, diagnostics);
|
||||||
|
symbol_table.push_scope("ForStatementScope");
|
||||||
|
let variable_identifier = &mut for_statement.variable;
|
||||||
|
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
|
||||||
|
&variable_identifier.name(),
|
||||||
|
false,
|
||||||
|
Some(variable_identifier),
|
||||||
|
));
|
||||||
|
|
||||||
|
match insert_result {
|
||||||
|
Ok(_) => {
|
||||||
|
gather_block_statement_inner(
|
||||||
|
&mut for_statement.body,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
&variable_identifier.name(),
|
||||||
|
variable_identifier.file_id(),
|
||||||
|
variable_identifier.range(),
|
||||||
|
"variable",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expressions */
|
/* Expressions */
|
||||||
|
@ -146,7 +146,9 @@ fn resolve_implements_list(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
for type_use in &mut implements_list.0 {
|
||||||
|
resolve_type_use(type_use, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function parameters */
|
/* Function parameters */
|
||||||
@ -278,18 +280,23 @@ fn resolve_module_level_declaration(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::ModuleLevelDeclaration::*;
|
use crate::ast::ModuleLevelDeclaration::*;
|
||||||
match declaration {
|
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) => {
|
Function(function_definition) => {
|
||||||
resolve_function_definition(function_definition, symbol_table, diagnostics)
|
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(
|
PlatformFunction(platform_function_declaration) => resolve_platform_function_declaration(
|
||||||
platform_function_declaration,
|
platform_function_declaration,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
),
|
),
|
||||||
Class(class_declaration) => {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +305,32 @@ fn resolve_interface_level_declaration(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
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(
|
fn resolve_class_level_declaration(
|
||||||
@ -306,7 +338,41 @@ fn resolve_class_level_declaration(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
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 */
|
/* Main Declarations */
|
||||||
@ -400,7 +466,19 @@ fn resolve_interface_function_declaration(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
resolve_parameters(
|
||||||
|
&mut interface_function_declaration.parameters,
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
resolve_return_type(
|
||||||
|
&mut interface_function_declaration.return_type,
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
if let Some(body) = &mut interface_function_declaration.body {
|
||||||
|
resolve_function_body(body, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_interface_operator_function_declaration(
|
fn resolve_interface_operator_function_declaration(
|
||||||
@ -439,7 +517,13 @@ fn resolve_class_constructor(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
use crate::ast::ClassConstructorParameter::*;
|
||||||
|
for parameter in &mut class_constructor.0 {
|
||||||
|
match parameter {
|
||||||
|
Property(property) => resolve_property_declaration(property, symbol_table, diagnostics),
|
||||||
|
Field(field) => resolve_field_declaration(field, symbol_table, diagnostics),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_property_declaration(
|
fn resolve_property_declaration(
|
||||||
@ -447,7 +531,11 @@ fn resolve_property_declaration(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
resolve_type_use(
|
||||||
|
&mut property_declaration.declared_type,
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_field_declaration(
|
fn resolve_field_declaration(
|
||||||
@ -455,7 +543,11 @@ fn resolve_field_declaration(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
resolve_type_use(
|
||||||
|
&mut field_declaration.declared_type,
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Statements */
|
/* Statements */
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
use crate::ast::named::Named;
|
||||||
use crate::ast::{Identifier, UseStatement};
|
use crate::ast::{Identifier, UseStatement};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use std::ops::Deref;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::ast::named::Named;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SourceDefinition {
|
pub struct SourceDefinition {
|
||||||
@ -59,6 +60,7 @@ pub enum Symbol {
|
|||||||
Function(Rc<RefCell<FunctionSymbol>>),
|
Function(Rc<RefCell<FunctionSymbol>>),
|
||||||
Parameter(Rc<ParameterSymbol>),
|
Parameter(Rc<ParameterSymbol>),
|
||||||
Variable(Rc<VariableSymbol>),
|
Variable(Rc<VariableSymbol>),
|
||||||
|
ClassMember(Rc<ClassMemberSymbol>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Symbol {
|
impl Symbol {
|
||||||
@ -66,10 +68,14 @@ impl Symbol {
|
|||||||
match self {
|
match self {
|
||||||
Symbol::UseStatement(s) => s.borrow().definition(),
|
Symbol::UseStatement(s) => s.borrow().definition(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::Module(s) => s.definition(),
|
||||||
Symbol::Type(s) => s.definition(),
|
Symbol::Type(s) => match s.deref() {
|
||||||
|
TypeSymbol::Concrete(cts) => cts.definition(),
|
||||||
|
TypeSymbol::Generic(gts) => gts.definition(),
|
||||||
|
},
|
||||||
Symbol::Function(s) => s.borrow().definition(),
|
Symbol::Function(s) => s.borrow().definition(),
|
||||||
Symbol::Parameter(s) => s.definition(),
|
Symbol::Parameter(s) => s.definition(),
|
||||||
Symbol::Variable(s) => s.definition(),
|
Symbol::Variable(s) => s.definition(),
|
||||||
|
Symbol::ClassMember(s) => s.definition(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,21 +186,36 @@ impl Debug for ModuleSymbol {
|
|||||||
|
|
||||||
/* TypeSymbol */
|
/* TypeSymbol */
|
||||||
|
|
||||||
pub struct TypeSymbol {
|
#[derive(Debug)]
|
||||||
|
pub enum TypeSymbol {
|
||||||
|
Concrete(ConcreteTypeSymbol),
|
||||||
|
Generic(GenericTypeSymbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeSymbol {
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
TypeSymbol::Concrete(t) => t.declared_name(),
|
||||||
|
TypeSymbol::Generic(t) => t.declared_name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ConcreteTypeSymbol {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeSymbol {
|
impl ConcreteTypeSymbol {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
fqn: &str,
|
fqn: &str,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
identifier: Option<&Identifier>,
|
identifier: Option<&Identifier>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
TypeSymbol {
|
ConcreteTypeSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
is_public,
|
is_public,
|
||||||
@ -211,7 +232,7 @@ impl TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolInner for TypeSymbol {
|
impl SymbolInner for ConcreteTypeSymbol {
|
||||||
fn declared_name(&self) -> &str {
|
fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
@ -221,7 +242,7 @@ impl SymbolInner for TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for TypeSymbol {
|
impl Debug for ConcreteTypeSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("TypeSymbol")
|
f.debug_struct("TypeSymbol")
|
||||||
.field("fqn", &self.fqn)
|
.field("fqn", &self.fqn)
|
||||||
@ -231,6 +252,38 @@ impl Debug for TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GenericTypeSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
source_definition: SourceDefinition,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericTypeSymbol {
|
||||||
|
pub fn new(declared_name: &str, source_definition: SourceDefinition) -> Self {
|
||||||
|
GenericTypeSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolInner for GenericTypeSymbol {
|
||||||
|
fn declared_name(&self) -> &str {
|
||||||
|
self.declared_name.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn definition(&self) -> Option<SourceDefinition> {
|
||||||
|
Some(self.source_definition.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for GenericTypeSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("GenericTypeSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Function */
|
/* Function */
|
||||||
|
|
||||||
pub struct FunctionSymbol {
|
pub struct FunctionSymbol {
|
||||||
@ -240,7 +293,7 @@ pub struct FunctionSymbol {
|
|||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
parameters: Vec<Rc<ParameterSymbol>>,
|
parameters: Vec<Rc<ParameterSymbol>>,
|
||||||
return_type: Option<Rc<TypeSymbol>>,
|
return_type: Option<Rc<ConcreteTypeSymbol>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionSymbol {
|
impl FunctionSymbol {
|
||||||
@ -277,7 +330,7 @@ impl FunctionSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_return_type(self, return_type: TypeSymbol) -> Self {
|
pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn: self.fqn,
|
fqn: self.fqn,
|
||||||
declared_name: self.declared_name,
|
declared_name: self.declared_name,
|
||||||
@ -297,7 +350,7 @@ impl FunctionSymbol {
|
|||||||
self.parameters = parameters;
|
self.parameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_return_type(&mut self, return_type: Rc<TypeSymbol>) {
|
pub fn set_return_type(&mut self, return_type: Rc<ConcreteTypeSymbol>) {
|
||||||
self.return_type = Some(return_type);
|
self.return_type = Some(return_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,3 +448,39 @@ impl Debug for VariableSymbol {
|
|||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Class Member */
|
||||||
|
|
||||||
|
pub struct ClassMemberSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
is_field: bool,
|
||||||
|
definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassMemberSymbol {
|
||||||
|
pub fn new(declared_name: &str, is_field: bool, definition: Option<SourceDefinition>) -> Self {
|
||||||
|
ClassMemberSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
is_field,
|
||||||
|
definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolInner for ClassMemberSymbol {
|
||||||
|
fn declared_name(&self) -> &str {
|
||||||
|
self.declared_name.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn definition(&self) -> Option<SourceDefinition> {
|
||||||
|
self.definition.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ClassMemberSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ClassMemberSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
use crate::name_analysis::symbol::{
|
use crate::name_analysis::symbol::*;
|
||||||
FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol,
|
|
||||||
UseStatementSymbol, VariableSymbol,
|
|
||||||
};
|
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
/* Scope */
|
/* Scope */
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -19,6 +18,7 @@ struct Scope {
|
|||||||
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
|
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
||||||
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
||||||
|
class_member_symbols: HashMap<String, Rc<ClassMemberSymbol>>,
|
||||||
debug_name: String,
|
debug_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,41 +32,11 @@ impl Scope {
|
|||||||
function_symbols: HashMap::new(),
|
function_symbols: HashMap::new(),
|
||||||
parameter_symbols: HashMap::new(),
|
parameter_symbols: HashMap::new(),
|
||||||
variable_symbols: HashMap::new(),
|
variable_symbols: HashMap::new(),
|
||||||
|
class_member_symbols: HashMap::new(),
|
||||||
debug_name,
|
debug_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_any_symbol(&self, name: &str) -> Option<Symbol> {
|
|
||||||
self.variable_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Variable(s.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.parameter_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Parameter(s.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.function_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Function(s.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.module_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ms| Symbol::Module(ms.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.use_statement_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|us| Symbol::UseStatement(us.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
||||||
for module_symbol in self.module_symbols.values() {
|
for module_symbol in self.module_symbols.values() {
|
||||||
if module_symbol.declared_name() == name {
|
if module_symbol.declared_name() == name {
|
||||||
@ -96,7 +66,13 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
||||||
self.type_symbols.values().find(|s| s.fqn() == fqn).cloned()
|
self.type_symbols
|
||||||
|
.values()
|
||||||
|
.find(|s| match s.deref().deref() {
|
||||||
|
TypeSymbol::Concrete(cts) => cts.fqn() == fqn,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
||||||
@ -106,8 +82,13 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for type_symbol in self.type_symbols.values() {
|
for type_symbol in self.type_symbols.values() {
|
||||||
if type_symbol.fqn() == fqn {
|
match type_symbol.deref() {
|
||||||
return Some(Symbol::Type(type_symbol.clone()));
|
TypeSymbol::Concrete(concrete_type_symbol) => {
|
||||||
|
if concrete_type_symbol.fqn() == fqn {
|
||||||
|
return Some(Symbol::Type(type_symbol.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -150,6 +131,11 @@ impl Scope {
|
|||||||
.get(declared_name)
|
.get(declared_name)
|
||||||
.map(|p| Symbol::Parameter(p.clone()))
|
.map(|p| Symbol::Parameter(p.clone()))
|
||||||
})
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.class_member_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|cms| Symbol::ClassMember(cms.clone()))
|
||||||
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.function_symbols
|
self.function_symbols
|
||||||
.get(declared_name)
|
.get(declared_name)
|
||||||
@ -173,9 +159,7 @@ impl Scope {
|
|||||||
.find(|fs| fs.borrow().fqn() == fqn)
|
.find(|fs| fs.borrow().fqn() == fqn)
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
.map(|f| Symbol::Function(f.clone()))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.type_symbols
|
self.get_type_symbol_by_fqn(fqn)
|
||||||
.values()
|
|
||||||
.find(|ts| ts.fqn() == fqn)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
.map(|ts| Symbol::Type(ts.clone()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -341,21 +325,21 @@ impl SymbolTable {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "Use more specific lookup methods.")]
|
pub fn insert_class_member_symbol(
|
||||||
pub fn lookup(&self, name: &str, scope_id: usize) -> Result<Symbol, SymbolLookupError> {
|
&mut self,
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
class_member_symbol: ClassMemberSymbol,
|
||||||
while let Some(scope) = scope_opt {
|
) -> Result<(), SymbolInsertError> {
|
||||||
if let Some(symbol) = scope.get_any_symbol(name) {
|
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
||||||
return Ok(symbol);
|
if let Some(defined_symbol) = current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name()) {
|
||||||
}
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
} else {
|
||||||
Some(&self.scopes[parent_id])
|
current_scope.class_member_symbols.insert(
|
||||||
} else {
|
class_member_symbol.declared_name().to_string(),
|
||||||
None
|
Rc::new(class_member_symbol),
|
||||||
};
|
);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_type_by_declared_name(
|
pub fn lookup_type_by_declared_name(
|
||||||
@ -471,6 +455,9 @@ impl Display for SymbolTable {
|
|||||||
for symbol in scope.variable_symbols.values() {
|
for symbol in scope.variable_symbols.values() {
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
writeln!(f, "{:#?}", symbol)?;
|
||||||
}
|
}
|
||||||
|
for symbol in scope.class_member_symbols.values() {
|
||||||
|
writeln!(f, "{:#?}", symbol)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol, TypeSymbol};
|
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol};
|
||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
|
|
||||||
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||||
|
Loading…
Reference in New Issue
Block a user