From 765a0bec58082b5e6c239fed91a44a10cfff430a Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Wed, 27 Oct 2021 15:39:09 -0700 Subject: [PATCH] Make use of TypeContext in SymbolTable --- schala-lang/language/src/reduced_ir/test.rs | 17 +++-- schala-lang/language/src/schala.rs | 4 +- schala-lang/language/src/symbol_table/mod.rs | 74 +++++++++++-------- schala-lang/language/src/symbol_table/test.rs | 3 +- .../language/src/tree_walk_eval/test.rs | 4 +- .../language/src/type_inference/mod.rs | 10 +-- 6 files changed, 64 insertions(+), 48 deletions(-) diff --git a/schala-lang/language/src/reduced_ir/test.rs b/schala-lang/language/src/reduced_ir/test.rs index 3cd7197..a2b603f 100644 --- a/schala-lang/language/src/reduced_ir/test.rs +++ b/schala-lang/language/src/reduced_ir/test.rs @@ -1,20 +1,21 @@ #![cfg(test)] -use crate::symbol_table::SymbolTable; use super::*; +use crate::{symbol_table::SymbolTable, type_inference::TypeContext}; fn build_ir(input: &str) -> ReducedIR { - let ast = crate::util::quick_ast(input); + let ast = crate::util::quick_ast(input); - let mut symbol_table = SymbolTable::new(); - symbol_table.process_ast(&ast).unwrap(); + let mut symbol_table = SymbolTable::new(); + let mut type_context = TypeContext::new(); - let reduced = reduce(&ast, &symbol_table); - reduced.debug(&symbol_table); - reduced + symbol_table.process_ast(&ast, &mut type_context).unwrap(); + + let reduced = reduce(&ast, &symbol_table); + reduced.debug(&symbol_table); + reduced } - #[test] fn test_ir() { let src = r#" diff --git a/schala-lang/language/src/schala.rs b/schala-lang/language/src/schala.rs index 6e8ed37..c104f32 100644 --- a/schala-lang/language/src/schala.rs +++ b/schala-lang/language/src/schala.rs @@ -83,7 +83,9 @@ impl<'a> Schala<'a> { .map_err(|err| SchalaError::from_parse_error(err, &self.source_reference))?; //Perform all symbol table work - self.symbol_table.process_ast(&ast).map_err(SchalaError::from_symbol_table)?; + self.symbol_table + .process_ast(&ast, &mut self.type_context) + .map_err(SchalaError::from_symbol_table)?; // Typechecking // TODO typechecking not working diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index ce6d04f..29aa210 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -8,7 +8,7 @@ use crate::ast::{ Variant, VariantKind, }; use crate::tokenizing::Location; -use crate::type_inference::TypeId; +use crate::type_inference::{TypeContext, TypeId}; mod resolver; mod symbol_trie; @@ -171,12 +171,15 @@ impl SymbolTable { /// The main entry point into the symbol table. This will traverse the AST in several /// different ways and populate subtables with information that will be used further in the /// compilation process. - pub fn process_ast(&mut self, ast: &ast::AST) -> Result<(), Vec> { - let errs = self.populate_name_tables(ast); + pub fn process_ast(&mut self, ast: &ast::AST, type_context: &mut TypeContext) -> Result<(), Vec> { + + let mut runner = SymbolTableRunner { type_context, table: self }; + + let errs = runner.populate_name_tables(ast); if !errs.is_empty() { return Err(errs); } - self.resolve_scopes(ast); + runner.resolve_scopes(ast); Ok(()) } @@ -198,6 +201,26 @@ impl SymbolTable { println!("{} => {}", id, sym); } } + + /// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`) + /// to a Symbol, a descriptor of what that name refers to. + fn add_symbol(&mut self, id: &ItemId, fqsn: Fqsn, spec: SymbolSpec) { + let def_id = self.def_id_store.fresh(); + let symbol = Rc::new(Symbol { + fully_qualified_name: fqsn.clone(), + spec, + def_id, + }); + println!("In add_symbol(), adding: {:?}", symbol); + self.symbol_trie.insert(&fqsn); + self.fqsn_to_symbol.insert(fqsn, symbol.clone()); + self.id_to_symbol.insert(*id, symbol); + } +} + +struct SymbolTableRunner<'a> { + type_context: &'a mut TypeContext, + table: &'a mut SymbolTable } #[allow(dead_code)] @@ -286,29 +309,18 @@ impl fmt::Display for SymbolSpec { } } -impl SymbolTable { +impl<'a> SymbolTableRunner<'a> { /* note: this adds names for *forward reference* but doesn't actually create any types. solve that problem * later */ - /// Register a new mapping of a fully-qualified symbol name (e.g. `Option::Some`) - /// to a Symbol, a descriptor of what that name refers to. fn add_symbol(&mut self, id: &ItemId, fqsn: Fqsn, spec: SymbolSpec) { - let def_id = self.def_id_store.fresh(); - let symbol = Rc::new(Symbol { - fully_qualified_name: fqsn.clone(), - spec, - def_id, - }); - println!("In add_symbol(), adding: {:?}", symbol); - self.symbol_trie.insert(&fqsn); - self.fqsn_to_symbol.insert(fqsn, symbol.clone()); - self.id_to_symbol.insert(*id, symbol); + self.table.add_symbol(id, fqsn, spec) } /// Walks the AST, matching the ID of an identifier used in some expression to /// the corresponding Symbol. fn resolve_scopes(&mut self, ast: &ast::AST) { - let mut resolver = resolver::ScopeResolver::new(self); + let mut resolver = resolver::ScopeResolver::new(self.table); resolver.resolve(ast); } @@ -321,8 +333,8 @@ impl SymbolTable { self.add_from_scope(ast.statements.as_ref(), &mut scope_stack, false) } - fn add_from_scope<'a>( - &'a mut self, + fn add_from_scope( + &mut self, statements: &[Statement], scope_stack: &mut Vec, function_scope: bool, @@ -380,14 +392,14 @@ impl SymbolTable { match kind { StatementKind::Declaration(Declaration::FuncSig(signature)) => { let fq_function = Fqsn::from_scope_stack(scope_stack, signature.name.clone()); - self.fq_names.register( + self.table.fq_names.register( fq_function.clone(), NameSpec { location, kind: NameKind::Function, }, )?; - self.types.register( + self.table.types.register( fq_function.clone(), NameSpec { location, @@ -404,14 +416,14 @@ impl SymbolTable { StatementKind::Declaration(Declaration::FuncDecl(signature, ..)) => { let fn_name = &signature.name; let fq_function = Fqsn::from_scope_stack(scope_stack, fn_name.clone()); - self.fq_names.register( + self.table.fq_names.register( fq_function.clone(), NameSpec { location, kind: NameKind::Function, }, )?; - self.types.register( + self.table.types.register( fq_function.clone(), NameSpec { location, @@ -427,7 +439,7 @@ impl SymbolTable { } StatementKind::Declaration(Declaration::TypeDecl { name, .. }) => { let fq_type = Fqsn::from_scope_stack(scope_stack, name.name.clone()); - self.types.register( + self.table.types.register( fq_type, NameSpec { location, @@ -437,7 +449,7 @@ impl SymbolTable { } StatementKind::Declaration(Declaration::Binding { name, .. }) => { let fq_binding = Fqsn::from_scope_stack(scope_stack, name.clone()); - self.fq_names.register( + self.table.fq_names.register( fq_binding.clone(), NameSpec { location, @@ -454,7 +466,7 @@ impl SymbolTable { } StatementKind::Module(ModuleSpecifier { name, .. }) => { let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone()); - self.fq_names.register( + self.table.fq_names.register( fq_module, NameSpec { location, @@ -483,10 +495,10 @@ impl SymbolTable { location, kind: TypeKind, }; - if let Err(err) = self.types.register(fqsn.clone(), name_spec) { + if let Err(err) = self.table.types.register(fqsn.clone(), name_spec) { errors.push(err); } else { - self.add_symbol(id, fqsn, spec); + self.table.add_symbol(id, fqsn, spec); }; }; @@ -497,7 +509,7 @@ impl SymbolTable { for (index, variant) in variants.iter().enumerate() { let tag = index as u32; let Variant { name, kind, id } = variant; - let type_id = TypeId::lookup_name(name.as_ref()); + let type_id = self.type_context.id_from_name(name.as_ref()); match kind { VariantKind::UnitStruct => { @@ -547,7 +559,7 @@ impl SymbolTable { .map(|(member_name, _type_identifier)| { ( member_name.clone(), - TypeId::lookup_name("DUMMY_TYPE_ID"), + self.type_context.id_from_name("DUMMY_TYPE_ID") ) }) .collect(), diff --git a/schala-lang/language/src/symbol_table/test.rs b/schala-lang/language/src/symbol_table/test.rs index 5a2c66f..4489628 100644 --- a/schala-lang/language/src/symbol_table/test.rs +++ b/schala-lang/language/src/symbol_table/test.rs @@ -6,7 +6,8 @@ use assert_matches::assert_matches; fn add_symbols(src: &str) -> (SymbolTable, Result<(), Vec>) { let ast = quick_ast(src); let mut symbol_table = SymbolTable::new(); - let result = symbol_table.process_ast(&ast); + let mut type_context = crate::type_inference::TypeContext::new(); + let result = symbol_table.process_ast(&ast, &mut type_context); (symbol_table, result) } diff --git a/schala-lang/language/src/tree_walk_eval/test.rs b/schala-lang/language/src/tree_walk_eval/test.rs index 3671332..e49d1e6 100644 --- a/schala-lang/language/src/tree_walk_eval/test.rs +++ b/schala-lang/language/src/tree_walk_eval/test.rs @@ -10,9 +10,9 @@ use crate::{ fn evaluate_input(input: &str) -> Result { let ast = crate::util::quick_ast(input); let mut symbol_table = SymbolTable::new(); - symbol_table.process_ast(&ast).unwrap(); + let mut type_context = TypeContext::new(); - let type_context = TypeContext::new(); + symbol_table.process_ast(&ast, &mut type_context).unwrap(); let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table); reduced_ir.debug(&symbol_table); diff --git a/schala-lang/language/src/type_inference/mod.rs b/schala-lang/language/src/type_inference/mod.rs index 4bfdf82..062e113 100644 --- a/schala-lang/language/src/type_inference/mod.rs +++ b/schala-lang/language/src/type_inference/mod.rs @@ -13,11 +13,6 @@ impl fmt::Display for TypeId { } impl TypeId { - //TODO this is definitely incomplete - pub fn lookup_name(name: &str) -> TypeId { - TypeId { local_name: Rc::new(name.to_string()) } - } - pub fn local_name(&self) -> &str { self.local_name.as_ref() } @@ -29,6 +24,11 @@ impl TypeContext { pub fn new() -> Self { Self } + + //TODO flesh this out... + pub fn id_from_name(&self, name: &str) -> TypeId { + TypeId { local_name: Rc::new(name.to_string()) } + } } #[derive(Debug, Clone)]