From d4b00b008b95fb0dd8872579f2e50c7de6fa56ce Mon Sep 17 00:00:00 2001
From: Greg Shuflin <greg.shuflin@protonmail.com>
Date: Mon, 1 Nov 2021 23:58:27 -0700
Subject: [PATCH] Get rid of id_to_symbol table

Now, an ItemId maps to a DefId, and a DefId maps to
a Symbol in a different table.
---
 schala-lang/language/src/symbol_table/mod.rs  | 17 +++---
 .../language/src/symbol_table/resolver.rs     | 54 ++++++-------------
 2 files changed, 28 insertions(+), 43 deletions(-)

diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs
index 10c40e6..79b65f9 100644
--- a/schala-lang/language/src/symbol_table/mod.rs
+++ b/schala-lang/language/src/symbol_table/mod.rs
@@ -141,7 +141,7 @@ pub struct SymbolTable {
     fq_names: NameTable<NameKind>, //Note that presence of two tables implies that a type and other binding with the same name can co-exist
     types: NameTable<TypeKind>,
 
-    id_to_symbol: HashMap<ItemId, Rc<Symbol>>,
+    id_to_def: HashMap<ItemId, DefId>,
     def_to_symbol: HashMap<DefId, Rc<Symbol>>,
 }
 
@@ -153,7 +153,7 @@ impl SymbolTable {
             fq_names: NameTable::new(),
             types: NameTable::new(),
 
-            id_to_symbol: HashMap::new(),
+            id_to_def: HashMap::new(),
             def_to_symbol: HashMap::new(),
         };
 
@@ -180,7 +180,8 @@ impl SymbolTable {
     }
 
     pub fn lookup_symbol(&self, id: &ItemId) -> Option<&Symbol> {
-        self.id_to_symbol.get(id).map(|s| s.as_ref())
+        let def = self.id_to_def.get(id)?;
+        self.def_to_symbol.get(def).map(|s| s.as_ref())
     }
 
     pub fn lookup_symbol_by_def(&self, def: &DefId) -> Option<&Symbol> {
@@ -191,8 +192,12 @@ impl SymbolTable {
     pub fn debug(&self) {
         println!("Symbol table:");
         println!("----------------");
-        for (id, sym) in self.id_to_symbol.iter() {
-            println!("{} => {}", id, sym);
+        for (id, def) in self.id_to_def.iter() {
+            if let Some(symbol) = self.def_to_symbol.get(def) {
+                println!("{} => {}: {}", id, def, symbol);
+            } else {
+                println!("{} => {} <NO SYMBOL FOUND>", id, def);
+            }
         }
     }
 
@@ -202,7 +207,7 @@ impl SymbolTable {
         let def_id = self.def_id_store.fresh();
         let symbol = Rc::new(Symbol { fully_qualified_name: fqsn.clone(), spec, def_id });
         self.symbol_trie.insert(&fqsn, def_id);
-        self.id_to_symbol.insert(*id, symbol.clone());
+        self.id_to_def.insert(*id, def_id);
         self.def_to_symbol.insert(def_id, symbol);
     }
 
diff --git a/schala-lang/language/src/symbol_table/resolver.rs b/schala-lang/language/src/symbol_table/resolver.rs
index 29e30a8..6556e59 100644
--- a/schala-lang/language/src/symbol_table/resolver.rs
+++ b/schala-lang/language/src/symbol_table/resolver.rs
@@ -39,7 +39,7 @@ impl<'a> ScopeResolver<'a> {
         walk_ast(self, ast);
     }
 
-    /// This method correctly modifies the id_to_symbol table (ItemId) to have the appropriate
+    /// This method correctly modifies the id_to_def table (ItemId) to have the appropriate
     /// mappings.
     fn lookup_name_in_scope(&mut self, name: &QualifiedName) {
         let QualifiedName { id, components } = name;
@@ -47,32 +47,17 @@ impl<'a> ScopeResolver<'a> {
         let local_name = components.first().unwrap().clone();
         let name_type = self.lexical_scopes.lookup(&local_name);
         let fqsn = Fqsn { scopes: components.iter().map(|name| Scope::Name(name.clone())).collect() };
-        let symbol = self
-            .symbol_table
-            .symbol_trie
-            .lookup(&fqsn)
-            .as_ref()
-            .and_then(|def_id| self.symbol_table.lookup_symbol_by_def(def_id))
-            .cloned();
-        //println!("\tFound lexical_scope entry: {:?} and {} symbol: {:?}", name_type, fqsn, symbol);
+        let def_id = self.symbol_table.symbol_trie.lookup(&fqsn);
 
         //TODO handle a "partial" qualified name, and also handle it down in the pattern-matching
         //section
-        //TODO some of these if lets that look into the fqsn_to_symbol table should probaby fail
-        //with an error
         if components.len() == 1 {
             match name_type {
                 Some(NameType::Import(fqsn)) => {
-                    let symbol = self
-                        .symbol_table
-                        .symbol_trie
-                        .lookup(&fqsn)
-                        .as_ref()
-                        .and_then(|def_id| self.symbol_table.lookup_symbol_by_def(def_id))
-                        .cloned();
+                    let def_id = self.symbol_table.symbol_trie.lookup(&fqsn);
 
-                    if let Some(symbol) = symbol {
-                        self.symbol_table.id_to_symbol.insert(*id, Rc::new(symbol));
+                    if let Some(def_id) = def_id {
+                        self.symbol_table.id_to_def.insert(*id, def_id);
                     }
                 }
                 Some(NameType::Param(n)) => {
@@ -83,19 +68,20 @@ impl<'a> ScopeResolver<'a> {
                     self.symbol_table.add_symbol(id, fqsn, spec);
                 }
                 Some(NameType::LocalVariable(item_id)) => {
-                    let symbol = self.symbol_table.id_to_symbol.get(item_id).cloned();
-                    if let Some(symbol) = symbol {
-                        self.symbol_table.id_to_symbol.insert(*id, symbol);
+                    let def_id = self.symbol_table.id_to_def.get(item_id);
+                    if let Some(def_id) = def_id {
+                        let def_id = def_id.clone();
+                        self.symbol_table.id_to_def.insert(*id, def_id);
                     }
                 }
                 None =>
-                    if let Some(symbol) = symbol {
-                        self.symbol_table.id_to_symbol.insert(*id, Rc::new(symbol));
+                    if let Some(def_id) = def_id {
+                        self.symbol_table.id_to_def.insert(*id, def_id);
                     },
             }
         } else {
-            if let Some(symbol) = symbol {
-                self.symbol_table.id_to_symbol.insert(*id, Rc::new(symbol));
+            if let Some(def_id) = def_id {
+                self.symbol_table.id_to_def.insert(*id, def_id);
             }
         }
     }
@@ -261,21 +247,15 @@ impl<'a> ASTVisitor for ScopeResolver<'a> {
                     let local_name: Rc<String> = components[0].clone();
                     let lscope = Scope::Name(Rc::new("<local-case-match>".to_string()));
                     let fqsn = Fqsn { scopes: vec![lscope, Scope::Name(local_name.clone())] };
-                    //let local_name = fqsn.local_name();
                     self.symbol_table.add_symbol(id, fqsn, SymbolSpec::LocalVariable);
                     self.lexical_scopes.insert(local_name, NameType::LocalVariable(*id));
                 } else {
                     let fqsn =
                         Fqsn { scopes: components.iter().map(|name| Scope::Name(name.clone())).collect() };
-                    let symbol = self
-                        .symbol_table
-                        .symbol_trie
-                        .lookup(&fqsn)
-                        .as_ref()
-                        .and_then(|def_id| self.symbol_table.lookup_symbol_by_def(def_id))
-                        .cloned();
-                    if let Some(symbol) = symbol {
-                        self.symbol_table.id_to_symbol.insert(*id, Rc::new(symbol));
+                    let def_id = self.symbol_table.symbol_trie.lookup(&fqsn);
+
+                    if let Some(def_id) = def_id {
+                        self.symbol_table.id_to_def.insert(*id, def_id);
                     }
                 }
             }