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 | ||||
| 
 | ||||
| ## 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! | ||||
| @ -35,21 +41,23 @@ | ||||
|   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 | ||||
|   the above examples, the following DmModules would be created, with their appropriate contents: | ||||
|     - `pub ns std`: *no contents, only metadata.* | ||||
|     - `pub ns std::core`: | ||||
|       - `pub fn std::core::foo` | ||||
|     - `ns std::core::bar` | ||||
|       - `fn std::core::bar::baz` | ||||
|       - `prv fn std::core::bar::hello`: only accessible inside `std::core::bar`. | ||||
|   - `pub ns std`: *no contents, only metadata.* | ||||
|   - `pub ns std::core`: | ||||
|     - `pub fn std::core::foo` | ||||
|   - `ns std::core::bar` | ||||
|     - `fn std::core::bar::baz` | ||||
|     - `prv fn std::core::bar::hello`: only accessible inside `std::core::bar`. | ||||
| 
 | ||||
| ## 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
									
								
							
							
						
						
									
										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 => { | ||||
|                 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( | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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(); | ||||
| 
 | ||||
|     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); | ||||
|     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)); | ||||
| 
 | ||||
|             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( | ||||
| @ -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, | ||||
|         class_declaration.is_public, | ||||
|         Some(&class_declaration.identifier), | ||||
|     )); | ||||
|     if let Err(err) = insert_result { | ||||
|         handle_insert_error( | ||||
|             err, | ||||
|             &declared_name, | ||||
|             class_declaration.identifier.file_id(), | ||||
|             class_declaration.identifier.range(), | ||||
|             "interface/class", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     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), | ||||
|         ))); | ||||
| 
 | ||||
|     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( | ||||
|                 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 */ | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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() | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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,8 +82,13 @@ impl Scope { | ||||
|             } | ||||
|         } | ||||
|         for type_symbol in self.type_symbols.values() { | ||||
|             if type_symbol.fqn() == fqn { | ||||
|                 return Some(Symbol::Type(type_symbol.clone())); | ||||
|             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]) | ||||
|             } else { | ||||
|                 None | ||||
|             }; | ||||
|     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 { | ||||
|             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(()) | ||||
|     } | ||||
|  | ||||
| @ -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> { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user