[fine] Loader takes Option<base>, global module map
Just some hacking on modules
This commit is contained in:
parent
a3d4c24f11
commit
52e1879ef4
4 changed files with 121 additions and 65 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue