WIP file interns

This commit is contained in:
2026-05-08 14:44:58 -06:00
parent 1672ab5d0a
commit 13dbda7f65

View File

@@ -26,7 +26,7 @@ use kerolox_ir::EnumRepr;
use salsa::Update;
use strum::EnumIter;
use crate::prelude::*;
use crate::{prelude::*, workspace::File};
/// A complete definition for a Kerolox scope which can be accessed by paths.
#[salsa::tracked]
@@ -225,6 +225,80 @@ pub fn expr<'db>(
/// Resolve a reference to a relation by name.
pub fn relation_name<'db>(db: &'db dyn Database, name: ast::Name) -> RelationLabel<'db> {
// get table of interns for the name's file
let interns = file_interns(db, name.ast.file(db));
assert!(name.path.len() == 1, "relation name paths are unsupported");
// look up the relation by its last path segment
let tail = name.path.last().unwrap();
match interns.get(&tail.inner) {
None => RelationLabel::Unknown(name.clone()),
Some(NamespaceItem::Relation(rel)) => RelationLabel::Relation(*rel),
Some(_) => todo!("handle non-relation lookups gracefully"),
}
}
/// Resolves a file's internal name table.
#[salsa::tracked]
pub fn file_interns<'db>(
db: &'db dyn Database,
file: File,
) -> BTreeMap<String, NamespaceItem<'db>> {
// add top-level entries to a complete list of names
let mut names = Vec::new();
for item in ast::items(db, file) {
// get name info based on kind of item
use ast::ItemKind::*;
let entry = match item.kind(db) {
// some items do not define names
Rule | Assumption => continue,
// add relations
Relation => {
let relation = ast::relation(db, item.ast(db));
(relation.name(db), NamespaceItem::Relation(relation))
}
// add type aliases
TypeAlias => {
let type_alias = ast::type_alias(db, item.ast(db));
(type_alias.name(db), NamespaceItem::TypeAlias(type_alias))
}
// add imports separately
Import => {
let import = ast::import(db, item.ast(db));
names.extend(import_items(db, import));
continue;
}
};
// add entry to list of names
names.push(entry);
}
// build table with only one entry per name
let mut table = BTreeMap::new();
for (name, item) in names {
use std::collections::btree_map::Entry;
match table.entry(name.clone().inner) {
Entry::Vacant(entry) => {
entry.insert(item);
}
Entry::Occupied(_) => {
todo!("handle duplicate definitions");
}
}
}
// return the completed table
table
}
/// Resolves an import item to a table of namespace items.
#[salsa::tracked]
pub fn import_items<'db>(
db: &'db dyn Database,
import: ast::Import<'db>,
) -> Vec<(WithAst<String>, NamespaceItem<'db>)> {
todo!()
}