about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-09-28T10·11+0300
committertazjin <tazjin@tvl.su>2022-09-29T11·47+0000
commit82df0b432ae85b04d48c4c4352c2173de251e6e5 (patch)
tree925f7252c716d1211c14f4501342982e8b2e1ec3 /tvix
parente96f94ac88638c0fb2b9575a5b631eebdc70c1d8 (diff)
refactor(tvix/eval): introduce `TrackedBindings` struct r/4993
This struct will be the key to correctly compiling nested bindings, by
having insertions flow through some logic that will attempt to bind
attribute-set-like things when encountering them.

Change-Id: I8b5b20798de60688f3b6dc4526a460ebb2079f6e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6795
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix')
-rw-r--r--tvix/eval/src/compiler/bindings.rs45
1 files changed, 34 insertions, 11 deletions
diff --git a/tvix/eval/src/compiler/bindings.rs b/tvix/eval/src/compiler/bindings.rs
index e5f558edeec5..95ae85569aaa 100644
--- a/tvix/eval/src/compiler/bindings.rs
+++ b/tvix/eval/src/compiler/bindings.rs
@@ -38,6 +38,29 @@ struct TrackedBinding {
     binding: Binding,
 }
 
+struct TrackedBindings {
+    kind: BindingsKind,
+    bindings: Vec<TrackedBinding>,
+}
+
+impl TrackedBindings {
+    fn new(kind: BindingsKind) -> Self {
+        TrackedBindings {
+            kind,
+            bindings: vec![],
+        }
+    }
+
+    /// Add a completely new binding to the tracked bindings.
+    fn track_new(&mut self, key_slot: KeySlot, value_slot: LocalIdx, binding: Binding) {
+        self.bindings.push(TrackedBinding {
+            key_slot,
+            value_slot,
+            binding,
+        });
+    }
+}
+
 /// What kind of bindings scope is being compiled?
 #[derive(Clone, Copy, PartialEq)]
 enum BindingsKind {
@@ -168,7 +191,7 @@ impl Compiler<'_> {
         &mut self,
         kind: BindingsKind,
         inherit_froms: Vec<(ast::Expr, SmolStr, Span)>,
-        bindings: &mut Vec<TrackedBinding>,
+        bindings: &mut TrackedBindings,
     ) {
         for (from, name, span) in inherit_froms {
             let key_slot = if kind.is_attrs() {
@@ -195,15 +218,15 @@ impl Compiler<'_> {
                 BindingsKind::Attrs => self.scope_mut().declare_phantom(span, false),
             };
 
-            bindings.push(TrackedBinding {
+            bindings.track_new(
                 key_slot,
                 value_slot,
-                binding: Binding::InheritFrom {
+                Binding::InheritFrom {
                     namespace: from,
                     name,
                     span,
                 },
-            });
+            );
         }
     }
 
@@ -213,7 +236,7 @@ impl Compiler<'_> {
         &mut self,
         kind: BindingsKind,
         count: &mut usize,
-        bindings: &mut Vec<TrackedBinding>,
+        bindings: &mut TrackedBindings,
         node: &N,
     ) where
         N: ToSpan + ast::HasEntry,
@@ -267,13 +290,13 @@ impl Compiler<'_> {
                 BindingsKind::Attrs => self.scope_mut().declare_phantom(key_span, false),
             };
 
-            bindings.push(TrackedBinding {
+            bindings.track_new(
                 key_slot,
                 value_slot,
-                binding: Binding::Plain {
+                Binding::Plain {
                     expr: entry.value().unwrap(),
                 },
-            });
+            );
         }
     }
 
@@ -306,10 +329,10 @@ impl Compiler<'_> {
 
     /// Actually binds all tracked bindings by emitting the bytecode that places
     /// them in their stack slots.
-    fn bind_values(&mut self, bindings: Vec<TrackedBinding>) {
+    fn bind_values(&mut self, bindings: TrackedBindings) {
         let mut value_indices: Vec<LocalIdx> = vec![];
 
-        for binding in bindings.into_iter() {
+        for binding in bindings.bindings.into_iter() {
             value_indices.push(binding.value_slot);
 
             match binding.key_slot {
@@ -374,7 +397,7 @@ impl Compiler<'_> {
         self.scope_mut().begin_scope();
 
         // Vector to track all observed bindings.
-        let mut bindings: Vec<TrackedBinding> = vec![];
+        let mut bindings = TrackedBindings::new(kind);
 
         let inherit_froms = self.compile_plain_inherits(slot, kind, &mut count, node);
         self.declare_namespaced_inherits(kind, inherit_froms, &mut bindings);