diff options
author | Vincent Ambo <mail@tazj.in> | 2022-09-28T10·11+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-29T11·47+0000 |
commit | 82df0b432ae85b04d48c4c4352c2173de251e6e5 (patch) | |
tree | 925f7252c716d1211c14f4501342982e8b2e1ec3 | |
parent | e96f94ac88638c0fb2b9575a5b631eebdc70c1d8 (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
-rw-r--r-- | tvix/eval/src/compiler/bindings.rs | 45 |
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); |