From 82df0b432ae85b04d48c4c4352c2173de251e6e5 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 28 Sep 2022 13:11:15 +0300 Subject: refactor(tvix/eval): introduce `TrackedBindings` struct 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 Tested-by: BuildkiteCI --- tvix/eval/src/compiler/bindings.rs | 45 ++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'tvix') 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, +} + +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, + 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, + 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) { + fn bind_values(&mut self, bindings: TrackedBindings) { let mut value_indices: Vec = 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 = 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); -- cgit 1.4.1