This commit is contained in:
Folkert 2022-04-29 21:21:32 +02:00
parent c725c27c1b
commit 76a9d25f55
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -84,7 +84,7 @@ impl Scope {
Scope { Scope {
home, home,
exposed_ident_count: initial_ident_ids.len(), exposed_ident_count: initial_ident_ids.len(),
locals: ScopedIdentIds::from_ident_ids(initial_ident_ids.clone()), locals: ScopedIdentIds::from_ident_ids(home, initial_ident_ids.clone()),
ident_ids: initial_ident_ids, ident_ids: initial_ident_ids,
idents: IdentStore::new(), idents: IdentStore::new(),
aliases: VecMap::default(), aliases: VecMap::default(),
@ -107,7 +107,7 @@ impl Scope {
Scope { Scope {
home, home,
exposed_ident_count: initial_ident_ids.len(), exposed_ident_count: initial_ident_ids.len(),
locals: ScopedIdentIds::from_ident_ids(initial_ident_ids.clone()), locals: ScopedIdentIds::from_ident_ids(home, initial_ident_ids.clone()),
ident_ids: initial_ident_ids, ident_ids: initial_ident_ids,
idents: IdentStore::new(), idents: IdentStore::new(),
aliases: add_aliases(var_store), aliases: add_aliases(var_store),
@ -118,7 +118,16 @@ impl Scope {
} }
pub fn lookup(&self, ident: &Ident, region: Region) -> Result<Symbol, RuntimeError> { pub fn lookup(&self, ident: &Ident, region: Region) -> Result<Symbol, RuntimeError> {
match self.idents.get_symbol(ident) { // match self.idents.get_symbol(ident) {
let a = self.idents.get_symbol(ident);
let b = self.locals.get_symbol(ident);
// dbg!(ident);
// assert_eq!(a, b, "{:?} != {:?} | {:?}", a, b, ident);
match a {
Some(symbol) => Ok(symbol), Some(symbol) => Ok(symbol),
None => { None => {
for (import, symbol, _) in self.imports.iter() { for (import, symbol, _) in self.imports.iter() {
@ -311,6 +320,8 @@ impl Scope {
let dummy = Ident::default(); let dummy = Ident::default();
self.idents.insert_unchecked(&dummy, shadow_symbol, region); self.idents.insert_unchecked(&dummy, shadow_symbol, region);
let _ = self.locals.scopeless(&ident, region);
Ok((shadow_symbol, Some(original_symbol))) Ok((shadow_symbol, Some(original_symbol)))
} else { } else {
// This is an illegal shadow. // This is an illegal shadow.
@ -331,10 +342,19 @@ impl Scope {
fn commit_introduction(&mut self, ident: &Ident, region: Region) -> Symbol { fn commit_introduction(&mut self, ident: &Ident, region: Region) -> Symbol {
// if the identifier is exposed, use the IdentId we already have for it // if the identifier is exposed, use the IdentId we already have for it
let ident_id = match self.ident_ids.get_id(ident) { match self.ident_ids.get_id(ident) {
Some(ident_id) if ident_id.index() < self.exposed_ident_count => ident_id, Some(ident_id) if ident_id.index() < self.exposed_ident_count => {
_ => self.ident_ids.add_ident(ident), let symbol = Symbol::new(self.home, ident_id);
};
self.idents.insert_unchecked(ident, symbol, region);
self.locals.in_scope.set(ident_id.index(), true);
self.locals.regions[ident_id.index()] = region;
symbol
}
_ => {
let ident_id = self.ident_ids.add_ident(ident);
let symbol = Symbol::new(self.home, ident_id); let symbol = Symbol::new(self.home, ident_id);
@ -344,12 +364,15 @@ impl Scope {
symbol symbol
} }
}
}
/// Ignore an identifier. /// Ignore an identifier.
/// ///
/// Used for record guards like { x: Just _ } /// Used for record guards like { x: Just _ }
pub fn ignore(&mut self, ident: &Ident) -> Symbol { pub fn ignore(&mut self, ident: &Ident) -> Symbol {
let ident_id = self.ident_ids.add_ident(ident); let ident_id = self.ident_ids.add_ident(ident);
let _ = self.locals.scopeless(ident, Region::zero());
Symbol::new(self.home, ident_id) Symbol::new(self.home, ident_id)
} }
@ -546,16 +569,18 @@ struct ScopedIdentIds {
ident_ids: IdentIds, ident_ids: IdentIds,
in_scope: BitVec, in_scope: BitVec,
regions: Vec<Region>, regions: Vec<Region>,
home: ModuleId,
} }
impl ScopedIdentIds { impl ScopedIdentIds {
fn from_ident_ids(ident_ids: IdentIds) -> Self { fn from_ident_ids(home: ModuleId, ident_ids: IdentIds) -> Self {
let capacity = ident_ids.len(); let capacity = ident_ids.len();
Self { Self {
in_scope: BitVec::repeat(false, capacity), in_scope: BitVec::repeat(false, capacity),
ident_ids, ident_ids,
regions: std::iter::repeat(Region::zero()).take(capacity).collect(), regions: std::iter::repeat(Region::zero()).take(capacity).collect(),
home,
} }
} }
@ -579,6 +604,19 @@ impl ScopedIdentIds {
} }
} }
fn get_symbol(&self, ident: &Ident) -> Option<Symbol> {
self.ident_ids
.ident_strs()
.zip(self.in_scope.iter())
.find_map(|((ident_id, string), keep)| {
if *keep && string == ident.as_str() {
Some(Symbol::new(self.home, ident_id))
} else {
None
}
})
}
fn has_in_scope(&self, ident: &Ident) -> Option<(IdentId, Region)> { fn has_in_scope(&self, ident: &Ident) -> Option<(IdentId, Region)> {
self.ident_ids self.ident_ids
.ident_strs() .ident_strs()