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