[fine] Loader takes Option<base>, global module map

Just some hacking on modules
This commit is contained in:
John Doty 2024-04-06 10:00:22 -07:00
parent a3d4c24f11
commit 52e1879ef4
4 changed files with 121 additions and 65 deletions

View file

@ -122,11 +122,28 @@ impl fmt::Display for ModuleId {
}
}
#[derive(Clone, Debug)]
pub struct ImportRecord {
pub name: String,
pub module_id: ModuleId,
pub semantics: Weak<Semantics>,
pub struct ModuleTable {
modules: HashMap<ModuleId, Weak<Semantics>>,
}
impl ModuleTable {
pub fn new() -> ModuleTable {
ModuleTable {
modules: HashMap::new(),
}
}
pub fn set_module(&mut self, id: ModuleId, semantics: Weak<Semantics>) {
self.modules.insert(id, semantics);
}
pub fn get_module(&self, id: &ModuleId) -> Option<Rc<Semantics>> {
self.modules.get(id).map(|s| s.upgrade()).flatten()
}
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, ModuleId, Weak<Semantics>> {
self.modules.iter()
}
}
#[derive(Clone)]
@ -181,7 +198,7 @@ pub enum Type {
Alternate(Box<[Type]>),
// A module of some kind. What module?
Module(Rc<str>, ImportRecord),
Module(Rc<str>, ModuleId),
}
impl Type {
@ -670,12 +687,6 @@ enum Incremental<T> {
Complete(T),
}
#[derive(Debug)]
struct ImportMap {
by_name: HashMap<String, ImportRecord>,
by_id: HashMap<ModuleId, ImportRecord>,
}
pub struct Semantics {
mid: ModuleId,
file: Rc<str>,
@ -683,7 +694,8 @@ pub struct Semantics {
syntax_tree: Rc<SyntaxTree>,
lines: Rc<Lines>,
import_map: OnceCell<ImportMap>,
module_table: RefCell<Rc<ModuleTable>>,
import_map: OnceCell<HashMap<String, ModuleId>>,
// Instead of physical parents, this is the set of *logical* parents.
// This is what is used for binding.
@ -734,6 +746,7 @@ impl Semantics {
source,
syntax_tree: tree.clone(),
lines,
module_table: RefCell::new(Rc::new(ModuleTable::new())),
import_map: OnceCell::new(),
logical_parents,
function_count,
@ -755,31 +768,21 @@ impl Semantics {
semantics
}
pub fn set_imports(&self, imports: HashMap<String, ImportRecord>) {
let mut by_id = HashMap::new();
for (_, v) in imports.iter() {
by_id.insert(v.module_id, v.clone());
}
let imports = ImportMap {
by_name: imports,
by_id,
};
pub fn set_imports(&self, imports: HashMap<String, ModuleId>) {
self.import_map.set(imports).expect("imports already set");
}
pub fn set_module_table(&self, table: Rc<ModuleTable>) {
self.module_table.replace(table);
}
pub fn import_ids(&self) -> Vec<ModuleId> {
// TODO: Pull from by_name when we go global
let import_map = self.import_map.get().unwrap();
import_map.by_id.keys().map(|id| *id).collect()
import_map.values().map(|id| *id).collect()
}
pub fn import_by_id(&self, mid: ModuleId) -> Option<Rc<Semantics>> {
// TODO: ACTUALLY THIS IS WRONG, WE NEED THE GLOBAL MAP HERE, NOT THE LOCAL ONE.
let import_map = self.import_map.get()?;
let record = import_map.by_id.get(&mid)?;
record.semantics.upgrade()
self.module_table.borrow().get_module(&mid)
}
pub fn source(&self) -> Rc<str> {
@ -2192,7 +2195,7 @@ impl Semantics {
}
Type::Module(_, import) => {
// TODO: Cache this somehow, man.
let Some(other) = import.semantics.upgrade() else {
let Some(other) = self.import_by_id(*import) else {
self.internal_compiler_error(Some(t), "Unable to bind module");
};
@ -2601,8 +2604,8 @@ impl Semantics {
self.internal_compiler_error(None, "import map not initialized");
};
match import_map.by_name.get(&name) {
Some(import) => Some(Type::Module(name.into(), import.clone())),
match import_map.get(&name) {
Some(import) => Some(Type::Module(name.into(), *import)),
None => {
let error =
self.report_error_tree(tree, format!("unable to resolve module import {name}"));
@ -2766,8 +2769,8 @@ impl Semantics {
match self.import_map.get() {
Some(m) => {
eprintln!("Import map:");
for (k, b) in m.by_name.iter() {
eprintln!(" {k} => {} ({:?})", b.name, b.module_id);
for (k, b) in m.iter() {
eprintln!(" {k} => {:?}", b);
}
eprintln!();
}
@ -2775,6 +2778,12 @@ impl Semantics {
eprintln!("The import map is not set.\n")
}
}
eprintln!("Module Table:");
for (id, _sem) in self.module_table.borrow().iter() {
eprintln!(" {:?} => ??", id);
}
eprintln!();
}
if let Some(tr) = tr {