Compare commits

...

4 Commits

Author SHA1 Message Date
Jesse Brault
c8ff1d0fa2 Add todos. 2025-05-22 15:02:29 -05:00
Jesse Brault
f5f247e636 Add class-member symbols to symbol table display. 2025-05-21 22:31:51 -05:00
Jesse Brault
41ab922f2c Add interface/class test case. 2025-05-21 12:25:23 -05:00
Jesse Brault
d8fe97b401 Miscellaneous gather work and related. 2025-05-21 08:54:21 -05:00
9 changed files with 703 additions and 149 deletions

13
TODO.md
View File

@ -1,6 +1,12 @@
# 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
- Transform a single file into a `CompilationUnit` AST node.
- Gather all `CompilationUnit`s and determine which modules need to be built.
- A module corresponds to one syntactical namespace `ns`, but not its children!
@ -45,11 +51,13 @@
## More Namespace Rules
Top-level namespace declaration:
```
decl pub ns std
```
Nested namespace declaration and members:
```
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
std/std.dm
```
decl pub ns std {
decl pub ns core, http, json
@ -72,6 +81,7 @@ decl pub ns std {
```
std/core/core.dm
```
ns std
@ -82,6 +92,7 @@ decl pub ns core {
```
std/core/array.dm
```
ns std::core
@ -119,6 +130,7 @@ pub ns array {
```
std/core/hkt/monad.dm
```
ns std::core::hkt
@ -132,6 +144,7 @@ pub hkt Monad<T = Self>[a] {
```
std/core/string.dm
```
ns std::core

13
sketching/may_2025/int.dm Normal file
View 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!");
}

View File

@ -494,7 +494,7 @@ fn build_interface_declaration(file_id: usize, interface_pair: Pair<Rule>) -> In
Rule::Pub => {
is_public = true;
}
Rule::Int => {}
Rule::IntKw => {}
Rule::Identifier => {
identifier = Some(build_identifier(file_id, inner_pair));
}
@ -671,7 +671,46 @@ fn build_interface_function_declaration(
file_id: usize,
interface_function_pair: Pair<Rule>,
) -> 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(

View File

@ -7,8 +7,8 @@ impl FqnContext {
FqnContext { stack: Vec::new() }
}
pub fn push(&mut self, name: String) {
self.stack.push(name);
pub fn push(&mut self, name: &str) {
self.stack.push(name.to_string());
}
pub fn pop(&mut self) {

View File

@ -132,12 +132,8 @@ fn gather_function_type_use(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
gather_generic_parameters(
&mut function_type_use.generics,
symbol_table,
fqn_context,
diagnostics,
);
symbol_table.push_scope("FunctionTypeUseScope");
gather_generic_parameters(&mut function_type_use.generics, symbol_table, diagnostics);
gather_parameters(
&mut function_type_use.parameters,
symbol_table,
@ -150,6 +146,7 @@ fn gather_function_type_use(
fqn_context,
diagnostics,
);
symbol_table.pop_scope();
}
/* Generic Arguments */
@ -170,10 +167,28 @@ fn gather_generic_arguments(
fn gather_generic_parameters(
generic_parameters: &mut GenericParameters,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
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 */
@ -259,22 +274,12 @@ fn gather_return_type(
fqn_context,
diagnostics,
);
gather_references(
&mut return_type.references,
symbol_table,
fqn_context,
diagnostics,
);
gather_references(&mut return_type.references, symbol_table);
}
/* References */
fn gather_references(
references: &mut References,
symbol_table: &mut SymbolTable,
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
fn gather_references(references: &mut References, symbol_table: &mut SymbolTable) {
for identifier in &mut references.0 {
gather_identifier(identifier, symbol_table);
}
@ -289,7 +294,7 @@ pub(super) fn gather_compilation_unit(
) {
let mut fqn_context = FqnContext::new();
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));
@ -384,6 +389,14 @@ fn gather_module_level_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)
}
@ -398,7 +411,6 @@ fn gather_module_level_declaration(
diagnostics,
);
}
_ => todo!(),
}
}
@ -408,7 +420,39 @@ fn gather_interface_level_declaration(
fqn_context: &mut FqnContext,
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(
@ -417,7 +461,53 @@ fn gather_class_level_declaration(
fqn_context: &mut FqnContext,
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 */
@ -429,10 +519,11 @@ fn gather_module_declaration(
diagnostics: &mut Vec<DmDiagnostic>,
) {
// 1. Add mod identifier symbol
// 2. Update fqn context
// 2. Push identifier on fqn_context
// 3. Push scope
// 4. Process declarations
// 5. Pop scope
// 6. Pop fqn_context
let module_name = declaration.identifier.name();
@ -443,24 +534,78 @@ fn gather_module_declaration(
Some(&declaration.identifier),
));
if let Err(err) = insert_result {
handle_insert_error(
err,
match insert_result {
Ok(_) => {
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,
declaration.identifier.file_id(),
declaration.identifier.range(),
"module/type",
"Module",
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();
let insert_result =
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
&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));
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);
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(
@ -469,27 +614,58 @@ fn gather_class_declaration(
fqn_context: &mut FqnContext,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let declared_name = class_declaration.identifier.name();
let resolved_name = fqn_context.resolve(&declared_name);
let class_name = class_declaration.identifier.name();
let insert_result = symbol_table.insert_type_symbol(TypeSymbol::new(
&resolved_name,
&declared_name,
let insert_result =
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
&fqn_context.resolve(&class_name),
&class_name,
class_declaration.is_public,
Some(&class_declaration.identifier),
));
if let Err(err) = insert_result {
)));
match insert_result {
Ok(_) => {
// Do this first so we can't implement generic parameters!
gather_implements_list(
&mut class_declaration.implements,
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(
err,
&declared_name,
insert_error,
&class_name,
class_declaration.identifier.file_id(),
class_declaration.identifier.range(),
"interface/class",
diagnostics,
);
}
// todo: scopes, generics, etc.
}
}
/* Function declarations and components */
@ -646,7 +822,57 @@ fn gather_interface_function_declaration(
fqn_context: &mut FqnContext,
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(
@ -666,6 +892,7 @@ fn gather_function_body(
) {
use crate::ast::FunctionBody::*;
match function_body {
Equals(expression) => gather_expression(expression, symbol_table, diagnostics),
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
_ => todo!(),
}
@ -679,7 +906,16 @@ fn gather_class_constructor(
fqn_context: &mut FqnContext,
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(
@ -688,7 +924,23 @@ fn gather_property_declaration(
fqn_context: &mut FqnContext,
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(
@ -697,7 +949,23 @@ fn gather_field_declaration(
fqn_context: &mut FqnContext,
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 */
@ -819,7 +1087,13 @@ fn gather_if_statement(
fqn_context: &mut FqnContext,
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(
@ -828,7 +1102,18 @@ fn gather_if_else_statement(
fqn_context: &mut FqnContext,
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(
@ -837,7 +1122,13 @@ fn gather_while_statement(
fqn_context: &mut FqnContext,
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(
@ -846,7 +1137,37 @@ fn gather_for_statement(
fqn_context: &mut FqnContext,
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 */

View File

@ -146,7 +146,9 @@ fn resolve_implements_list(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
for type_use in &mut implements_list.0 {
resolve_type_use(type_use, symbol_table, diagnostics);
}
}
/* Function parameters */
@ -278,18 +280,23 @@ fn resolve_module_level_declaration(
) {
use crate::ast::ModuleLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
}
Interface(interface_declaration) => {
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
}
Function(function_definition) => {
resolve_function_definition(function_definition, symbol_table, diagnostics)
}
Class(class_declaration) => {
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
}
PlatformFunction(platform_function_declaration) => resolve_platform_function_declaration(
platform_function_declaration,
symbol_table,
diagnostics,
),
Class(class_declaration) => {
// todo
}
_ => todo!(),
}
}
@ -298,7 +305,32 @@ fn resolve_interface_level_declaration(
symbol_table: &mut SymbolTable,
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(
@ -306,7 +338,41 @@ fn resolve_class_level_declaration(
symbol_table: &mut SymbolTable,
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 */
@ -400,7 +466,19 @@ fn resolve_interface_function_declaration(
symbol_table: &mut SymbolTable,
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(
@ -439,7 +517,13 @@ fn resolve_class_constructor(
symbol_table: &mut SymbolTable,
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(
@ -447,7 +531,11 @@ fn resolve_property_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
resolve_type_use(
&mut property_declaration.declared_type,
symbol_table,
diagnostics,
);
}
fn resolve_field_declaration(
@ -455,7 +543,11 @@ fn resolve_field_declaration(
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
resolve_type_use(
&mut field_declaration.declared_type,
symbol_table,
diagnostics,
);
}
/* Statements */

View File

@ -1,9 +1,10 @@
use crate::ast::named::Named;
use crate::ast::{Identifier, UseStatement};
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref;
use std::range::Range;
use std::rc::Rc;
use crate::ast::named::Named;
#[derive(Clone, Debug)]
pub struct SourceDefinition {
@ -59,6 +60,7 @@ pub enum Symbol {
Function(Rc<RefCell<FunctionSymbol>>),
Parameter(Rc<ParameterSymbol>),
Variable(Rc<VariableSymbol>),
ClassMember(Rc<ClassMemberSymbol>),
}
impl Symbol {
@ -66,10 +68,14 @@ impl Symbol {
match self {
Symbol::UseStatement(s) => s.borrow().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::Parameter(s) => s.definition(),
Symbol::Variable(s) => s.definition(),
Symbol::ClassMember(s) => s.definition(),
}
}
@ -180,21 +186,36 @@ impl Debug for ModuleSymbol {
/* 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,
declared_name: String,
is_public: bool,
definition: Option<SourceDefinition>,
}
impl TypeSymbol {
impl ConcreteTypeSymbol {
pub fn new(
fqn: &str,
declared_name: &str,
is_public: bool,
identifier: Option<&Identifier>,
) -> Self {
TypeSymbol {
ConcreteTypeSymbol {
fqn: fqn.to_string(),
declared_name: declared_name.to_string(),
is_public,
@ -211,7 +232,7 @@ impl TypeSymbol {
}
}
impl SymbolInner for TypeSymbol {
impl SymbolInner for ConcreteTypeSymbol {
fn declared_name(&self) -> &str {
&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 {
f.debug_struct("TypeSymbol")
.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 */
pub struct FunctionSymbol {
@ -240,7 +293,7 @@ pub struct FunctionSymbol {
is_platform: bool,
definition: Option<SourceDefinition>,
parameters: Vec<Rc<ParameterSymbol>>,
return_type: Option<Rc<TypeSymbol>>,
return_type: Option<Rc<ConcreteTypeSymbol>>,
}
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 {
fqn: self.fqn,
declared_name: self.declared_name,
@ -297,7 +350,7 @@ impl FunctionSymbol {
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);
}
}
@ -395,3 +448,39 @@ impl Debug for VariableSymbol {
.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()
}
}

View File

@ -1,13 +1,12 @@
use crate::name_analysis::symbol::{
FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol,
UseStatementSymbol, VariableSymbol,
};
use crate::name_analysis::symbol::*;
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt::Display;
use std::ops::Deref;
use std::rc::Rc;
/* Scope */
#[derive(Debug)]
@ -19,6 +18,7 @@ struct Scope {
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
class_member_symbols: HashMap<String, Rc<ClassMemberSymbol>>,
debug_name: String,
}
@ -32,41 +32,11 @@ impl Scope {
function_symbols: HashMap::new(),
parameter_symbols: HashMap::new(),
variable_symbols: HashMap::new(),
class_member_symbols: HashMap::new(),
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>> {
for module_symbol in self.module_symbols.values() {
if module_symbol.declared_name() == name {
@ -96,7 +66,13 @@ impl Scope {
}
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> {
@ -106,10 +82,15 @@ impl Scope {
}
}
for type_symbol in self.type_symbols.values() {
if type_symbol.fqn() == fqn {
match type_symbol.deref() {
TypeSymbol::Concrete(concrete_type_symbol) => {
if concrete_type_symbol.fqn() == fqn {
return Some(Symbol::Type(type_symbol.clone()));
}
}
_ => continue,
}
}
None
}
@ -150,6 +131,11 @@ impl Scope {
.get(declared_name)
.map(|p| Symbol::Parameter(p.clone()))
})
.or_else(|| {
self.class_member_symbols
.get(declared_name)
.map(|cms| Symbol::ClassMember(cms.clone()))
})
.or_else(|| {
self.function_symbols
.get(declared_name)
@ -173,9 +159,7 @@ impl Scope {
.find(|fs| fs.borrow().fqn() == fqn)
.map(|f| Symbol::Function(f.clone()))
.or_else(|| {
self.type_symbols
.values()
.find(|ts| ts.fqn() == fqn)
self.get_type_symbol_by_fqn(fqn)
.map(|ts| Symbol::Type(ts.clone()))
})
}
@ -342,20 +326,20 @@ impl SymbolTable {
}
}
#[deprecated(note = "Use more specific lookup methods.")]
pub fn lookup(&self, name: &str, scope_id: usize) -> Result<Symbol, SymbolLookupError> {
let mut scope_opt = Some(&self.scopes[scope_id]);
while let Some(scope) = scope_opt {
if let Some(symbol) = scope.get_any_symbol(name) {
return Ok(symbol);
}
scope_opt = if let Some(parent_id) = scope.parent {
Some(&self.scopes[parent_id])
pub fn insert_class_member_symbol(
&mut self,
class_member_symbol: ClassMemberSymbol,
) -> Result<(), SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name()) {
Err(SymbolAlreadyDefined(defined_symbol))
} else {
None
};
current_scope.class_member_symbols.insert(
class_member_symbol.declared_name().to_string(),
Rc::new(class_member_symbol),
);
Ok(())
}
Err(NoDefinition)
}
pub fn lookup_type_by_declared_name(
@ -471,6 +455,9 @@ impl Display for SymbolTable {
for symbol in scope.variable_symbols.values() {
writeln!(f, "{:#?}", symbol)?;
}
for symbol in scope.class_member_symbols.values() {
writeln!(f, "{:#?}", symbol)?;
}
}
Ok(())
}

View File

@ -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};
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {