From 4b160fe412aef4f68e0e382e322f2cd450e42339 Mon Sep 17 00:00:00 2001 From: oxalica Date: Tue, 9 Aug 2022 03:29:36 +0800 Subject: [PATCH] Flatten Bindings into Arena in Module --- src/def/lower.rs | 155 ++++++++++++++++++++++++++++++++++++----------- src/def/mod.rs | 49 ++++++++++----- src/def/scope.rs | 16 ++--- 3 files changed, 162 insertions(+), 58 deletions(-) diff --git a/src/def/lower.rs b/src/def/lower.rs index 4dc5570..c27632f 100644 --- a/src/def/lower.rs +++ b/src/def/lower.rs @@ -1,6 +1,6 @@ use super::{ - AstPtr, Attrpath, BindingKey, BindingValue, Bindings, Expr, ExprId, Literal, Module, - ModuleSourceMap, NameDef, NameDefId, NameDefKind, Pat, Path, PathAnchor, + AstPtr, Attrpath, Binding, BindingId, BindingKey, BindingValue, Bindings, Expr, ExprId, + Literal, Module, ModuleSourceMap, NameDef, NameDefId, NameDefKind, Pat, Path, PathAnchor, }; use crate::{Diagnostic, DiagnosticKind, FileId}; use indexmap::IndexMap; @@ -17,6 +17,7 @@ pub(super) fn lower(file_id: FileId, parse: Parse) -> (Module, ModuleSourceMap) module: Module { exprs: Arena::new(), name_defs: Arena::new(), + bindings: Arena::new(), // Placeholder. entry_expr: ExprId::from_raw(0.into()), diagnostics: Vec::new(), @@ -51,6 +52,10 @@ impl LowerCtx { id } + fn alloc_binding(&mut self, key: BindingKey, value: BindingValue) -> BindingId { + self.module.bindings.alloc(Binding { key, value }) + } + fn diagnostic(&mut self, range: TextRange, kind: DiagnosticKind) { self.module.diagnostics.push(Diagnostic { range, kind }); } @@ -521,7 +526,10 @@ impl MergingSet { entries: self .entries .into_iter() - .map(|(k, v)| (k, v.finish(ctx))) + .map(|(k, v)| { + let v = v.finish(ctx); + ctx.alloc_binding(k, v) + }) .collect(), inherit_froms: self.inherit_froms.into(), } @@ -647,6 +655,12 @@ mod tests { for (i, e) in module.exprs.iter() { writeln!(got, "{}: {:?}", i.into_raw(), e).unwrap(); } + if !module.bindings.is_empty() { + writeln!(got).unwrap(); + } + for (i, b) in module.bindings.iter() { + writeln!(got, "{}: {:?}", i.into_raw(), b).unwrap(); + } if !module.name_defs.is_empty() { writeln!(got).unwrap(); } @@ -921,7 +935,12 @@ mod tests { 2: Literal(Int(2)) 3: Literal(Int(3)) 4: Literal(Int(4)) - 5: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(0))), (Dynamic(Idx::(1)), Expr(Idx::(2))), (Name("c"), Expr(Idx::(3))), (Name("\n"), Expr(Idx::(4)))], inherit_froms: [] }) + 5: Attrset(Bindings { entries: [Idx::(0), Idx::(1), Idx::(2), Idx::(3)], inherit_froms: [] }) + + 0: Binding { key: Name("a"), value: Expr(Idx::(0)) } + 1: Binding { key: Dynamic(Idx::(1)), value: Expr(Idx::(2)) } + 2: Binding { key: Name("c"), value: Expr(Idx::(3)) } + 3: Binding { key: Name("\n"), value: Expr(Idx::(4)) } "#]], ); } @@ -939,7 +958,13 @@ mod tests { 2: Reference("c") 3: Reference("d") 4: Reference("e") - 5: Attrset(Bindings { entries: [(Name("a"), Inherit(Idx::(0))), (Name("b"), Inherit(Idx::(1))), (Name("c"), Inherit(Idx::(2))), (Name("f"), InheritFrom(1)), (Name("g"), InheritFrom(1))], inherit_froms: [Idx::(3), Idx::(4)] }) + 5: Attrset(Bindings { entries: [Idx::(0), Idx::(1), Idx::(2), Idx::(3), Idx::(4)], inherit_froms: [Idx::(3), Idx::(4)] }) + + 0: Binding { key: Name("a"), value: Inherit(Idx::(0)) } + 1: Binding { key: Name("b"), value: Inherit(Idx::(1)) } + 2: Binding { key: Name("c"), value: Inherit(Idx::(2)) } + 3: Binding { key: Name("f"), value: InheritFrom(1) } + 4: Binding { key: Name("g"), value: InheritFrom(1) } "#]], ); } @@ -952,8 +977,12 @@ mod tests { expect![[r#" 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); // Path and attrset. @@ -962,8 +991,12 @@ mod tests { expect![[r#" 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); // Attrset and path. @@ -972,8 +1005,12 @@ mod tests { expect![[r#" 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); // Attrset and attrset. @@ -982,8 +1019,12 @@ mod tests { expect![[r#" 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); } @@ -998,8 +1039,12 @@ mod tests { 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: RecAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(0))), (NameDef(Idx::(1)), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: RecAttrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(0)) } + 1: Binding { key: NameDef(Idx::(1)), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } 0: NameDef { name: "b", kind: RecAttrset } 1: NameDef { name: "c", kind: RecAttrset } @@ -1014,8 +1059,12 @@ mod tests { 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: RecAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(0))), (NameDef(Idx::(1)), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: RecAttrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(0)) } + 1: Binding { key: NameDef(Idx::(1)), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } 0: NameDef { name: "b", kind: RecAttrset } 1: NameDef { name: "c", kind: RecAttrset } @@ -1030,8 +1079,12 @@ mod tests { 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); @@ -1043,8 +1096,12 @@ mod tests { 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0))), (Name("c"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: Name("c"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } "#]], ); @@ -1056,8 +1113,12 @@ mod tests { 0: Literal(Int(1)) 1: Literal(Int(2)) - 2: RecAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(0))), (NameDef(Idx::(1)), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 2: RecAttrset(Bindings { entries: [Idx::(0), Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(0)) } + 1: Binding { key: NameDef(Idx::(1)), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } 0: NameDef { name: "b", kind: RecAttrset } 1: NameDef { name: "c", kind: RecAttrset } @@ -1071,8 +1132,11 @@ mod tests { "rec { a.b = 1; }", expect![[r#" 0: Literal(Int(1)) - 1: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(0)))], inherit_froms: [] }) - 2: RecAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(1)))], inherit_froms: [] }) + 1: Attrset(Bindings { entries: [Idx::(0)], inherit_froms: [] }) + 2: RecAttrset(Bindings { entries: [Idx::(1)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(0)) } + 1: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(1)) } 0: NameDef { name: "a", kind: RecAttrset } "#]], @@ -1086,9 +1150,13 @@ mod tests { "{ a.b = rec { c = 1; }; }", expect![[r#" 0: Literal(Int(1)) - 1: RecAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(0)))], inherit_froms: [] }) - 2: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(2)))], inherit_froms: [] }) + 1: RecAttrset(Bindings { entries: [Idx::(0)], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + + 0: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(0)) } + 1: Binding { key: Name("b"), value: Expr(Idx::(1)) } + 2: Binding { key: Name("a"), value: Expr(Idx::(2)) } 0: NameDef { name: "c", kind: RecAttrset } "#]], @@ -1103,10 +1171,15 @@ mod tests { Diagnostic { range: 8..24, kind: LetAttrset } 0: Literal(Int(1)) - 1: Attrset(Bindings { entries: [(Name("d"), Expr(Idx::(0)))], inherit_froms: [] }) - 2: LetAttrset(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(1)))], inherit_froms: [] }) - 3: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(2)))], inherit_froms: [] }) - 4: Attrset(Bindings { entries: [(Name("a"), Expr(Idx::(3)))], inherit_froms: [] }) + 1: Attrset(Bindings { entries: [Idx::(0)], inherit_froms: [] }) + 2: LetAttrset(Bindings { entries: [Idx::(1)], inherit_froms: [] }) + 3: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + 4: Attrset(Bindings { entries: [Idx::(3)], inherit_froms: [] }) + + 0: Binding { key: Name("d"), value: Expr(Idx::(0)) } + 1: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(1)) } + 2: Binding { key: Name("b"), value: Expr(Idx::(2)) } + 3: Binding { key: Name("a"), value: Expr(Idx::(3)) } 0: NameDef { name: "c", kind: RecAttrset } "#]], @@ -1122,9 +1195,14 @@ mod tests { 1: Literal(Int(1)) 2: Reference("a") 3: Literal(Int(2)) - 4: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(1)))], inherit_froms: [] }) - 5: Attrset(Bindings { entries: [(Name("b"), Expr(Idx::(3)))], inherit_froms: [] }) - 6: Attrset(Bindings { entries: [(Dynamic(Idx::(0)), Expr(Idx::(4))), (Dynamic(Idx::(2)), Expr(Idx::(5)))], inherit_froms: [] }) + 4: Attrset(Bindings { entries: [Idx::(0)], inherit_froms: [] }) + 5: Attrset(Bindings { entries: [Idx::(2)], inherit_froms: [] }) + 6: Attrset(Bindings { entries: [Idx::(1), Idx::(3)], inherit_froms: [] }) + + 0: Binding { key: Name("b"), value: Expr(Idx::(1)) } + 1: Binding { key: Dynamic(Idx::(0)), value: Expr(Idx::(4)) } + 2: Binding { key: Name("b"), value: Expr(Idx::(3)) } + 3: Binding { key: Dynamic(Idx::(2)), value: Expr(Idx::(5)) } "#]], ); } @@ -1149,9 +1227,12 @@ mod tests { expect![[r#" 0: Reference("a") 1: Literal(Int(1)) - 2: Attrset(Bindings { entries: [(Dynamic(Idx::(0)), Expr(Idx::(1)))], inherit_froms: [] }) + 2: Attrset(Bindings { entries: [Idx::(0)], inherit_froms: [] }) 3: Literal(Int(1)) - 4: LetIn(Bindings { entries: [(NameDef(Idx::(0)), Expr(Idx::(2)))], inherit_froms: [] }, Idx::(3)) + 4: LetIn(Bindings { entries: [Idx::(1)], inherit_froms: [] }, Idx::(3)) + + 0: Binding { key: Dynamic(Idx::(0)), value: Expr(Idx::(1)) } + 1: Binding { key: NameDef(Idx::(0)), value: Expr(Idx::(2)) } 0: NameDef { name: "a", kind: LetIn } "#]], diff --git a/src/def/mod.rs b/src/def/mod.rs index bbba8ef..7348e3a 100644 --- a/src/def/mod.rs +++ b/src/def/mod.rs @@ -55,12 +55,14 @@ fn source_map(db: &dyn DefDatabase, file_id: FileId) -> Arc { pub struct Module { exprs: Arena, name_defs: Arena, + bindings: Arena, entry_expr: ExprId, diagnostics: Vec, } pub type ExprId = Idx; pub type NameDefId = Idx; +pub type BindingId = Idx; impl ops::Index for Module { type Output = Expr; @@ -76,6 +78,13 @@ impl ops::Index for Module { } } +impl ops::Index for Module { + type Output = Binding; + fn index(&self, index: BindingId) -> &Self::Output { + &self.bindings[index] + } +} + impl Module { pub fn diagnostics(&self) -> &[Diagnostic] { &self.diagnostics @@ -138,7 +147,7 @@ pub enum Expr { } impl Expr { - pub(crate) fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { + pub(crate) fn walk_child_exprs(&self, module: &Module, mut f: impl FnMut(ExprId)) { match self { Self::Missing | Self::Reference(_) | Self::Literal(_) => {} Self::Lambda(_, pat, body) => { @@ -175,11 +184,11 @@ impl Expr { xs.iter().copied().for_each(f) } Self::LetIn(bindings, body) => { - bindings.walk_child_exprs(&mut f); + bindings.walk_child_exprs(module, &mut f); f(*body); } Self::Attrset(bindings) | Self::RecAttrset(bindings) | Self::LetAttrset(bindings) => { - bindings.walk_child_exprs(f); + bindings.walk_child_exprs(module, f); } } } @@ -239,10 +248,16 @@ pub type Attrpath = Box<[ExprId]>; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Bindings { - pub entries: Box<[(BindingKey, BindingValue)]>, + pub entries: Box<[BindingId]>, pub inherit_froms: Box<[ExprId]>, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Binding { + pub key: BindingKey, + pub value: BindingValue, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum BindingKey { NameDef(NameDefId), @@ -258,19 +273,25 @@ pub enum BindingValue { } impl Bindings { - pub(crate) fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { - for (key, kind) in self.entries.iter() { - match key { - BindingKey::NameDef(_) | BindingKey::Name(_) => {} - &BindingKey::Dynamic(expr) => f(expr), - } - match *kind { - BindingValue::Inherit(e) | BindingValue::Expr(e) => f(e), - BindingValue::InheritFrom(_) => {} - } + pub(crate) fn walk_child_exprs(&self, module: &Module, mut f: impl FnMut(ExprId)) { + for &binding in self.entries.iter() { + module[binding].walk_child_exprs(&mut f); } for &e in self.inherit_froms.iter() { f(e); } } } + +impl Binding { + pub(crate) fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { + match self.key { + BindingKey::NameDef(_) | BindingKey::Name(_) => {} + BindingKey::Dynamic(expr) => f(expr), + } + match self.value { + BindingValue::Inherit(e) | BindingValue::Expr(e) => f(e), + BindingValue::InheritFrom(_) => {} + } + } +} diff --git a/src/def/scope.rs b/src/def/scope.rs index ab9c2fd..c3d664f 100644 --- a/src/def/scope.rs +++ b/src/def/scope.rs @@ -124,7 +124,7 @@ impl ModuleScopes { let scope = self.traverse_bindings(module, bindings, scope); self.traverse_expr(module, *body, scope); } - e => e.walk_child_exprs(|e| self.traverse_expr(module, e, scope)), + e => e.walk_child_exprs(module, |e| self.traverse_expr(module, e, scope)), } } @@ -136,13 +136,14 @@ impl ModuleScopes { ) -> ScopeId { let mut defs = HashMap::default(); - for (k, v) in bindings.entries.iter() { - if let &BindingKey::NameDef(def) = k { + for &binding in bindings.entries.iter() { + let binding = &module[binding]; + if let &BindingKey::NameDef(def) = &binding.key { defs.insert(module[def].name.clone(), def); } // Inherited attrs are resolved in the outer scope. - if let &BindingValue::Inherit(expr) = v { + if let BindingValue::Inherit(expr) = binding.value { assert!(matches!(&module[expr], Expr::Reference(_))); self.traverse_expr(module, expr, scope); } @@ -157,11 +158,12 @@ impl ModuleScopes { }) }; - for (k, v) in bindings.entries.iter() { - if let &BindingKey::Dynamic(expr) = k { + for &binding in bindings.entries.iter() { + let binding = &module[binding]; + if let BindingKey::Dynamic(expr) = binding.key { self.traverse_expr(module, expr, scope); } - if let &BindingValue::Expr(expr) = v { + if let BindingValue::Expr(expr) = binding.value { self.traverse_expr(module, expr, scope); } }