diff options
author | Vincent Ambo <mail@tazj.in> | 2022-09-24T12·18+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-29T00·48+0000 |
commit | 3d9eb14e7ab929fb80b28f89b16bc2158c09399a (patch) | |
tree | 5c845cd2c7bc1f5479058ae24c50ac0d17ab80ed /tvix/eval/src/compiler | |
parent | d0636f1e2483bc85b0a1929fbb94c206ad45a7b7 (diff) |
feat(tvix/eval): add KeySlot::Dynamic variant for dynamic keys r/4986
Another slice of the salami, but no functionality changes yet (other than opening a code path that can reach a `todo!()`, but this will be removed soon). Change-Id: I56b4ed323f70754ed1ab27964ee3c99cf3bf3292 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6780 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src/compiler')
-rw-r--r-- | tvix/eval/src/compiler/bindings.rs | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/tvix/eval/src/compiler/bindings.rs b/tvix/eval/src/compiler/bindings.rs index d7a5513934a1..94dae5fb951a 100644 --- a/tvix/eval/src/compiler/bindings.rs +++ b/tvix/eval/src/compiler/bindings.rs @@ -20,13 +20,20 @@ enum Binding { }, } -struct KeySlot { - slot: LocalIdx, - name: SmolStr, +enum KeySlot { + /// There is no key slot (`let`-expressions do not emit their key). + None, + + /// The key is statically known and has a slot. + Static { slot: LocalIdx, name: SmolStr }, + + /// The key is dynamic, i.e. only known at runtime, and must be compiled + /// into its slot. + Dynamic { slot: LocalIdx, expr: ast::Expr }, } struct TrackedBinding { - key_slot: Option<KeySlot>, + key_slot: KeySlot, value_slot: LocalIdx, binding: Binding, } @@ -168,12 +175,12 @@ impl Compiler<'_> { // In an attribute set, the keys themselves are placed on the // stack but their stack slot is inaccessible (it is only // consumed by `OpAttrs`). - Some(KeySlot { + KeySlot::Static { slot: self.scope_mut().declare_phantom(span, false), name: name.clone(), - }) + } } else { - None + KeySlot::None }; let value_slot = match kind { @@ -239,12 +246,12 @@ impl Compiler<'_> { let key_span = self.span_for(&path[0]); let key_slot = if kind.is_attrs() { - Some(KeySlot { + KeySlot::Static { name: name.clone(), slot: self.scope_mut().declare_phantom(key_span, false), - }) + } } else { - None + KeySlot::None }; let value_slot = match kind { @@ -431,10 +438,18 @@ impl Compiler<'_> { for binding in bindings.into_iter() { value_indices.push(binding.value_slot); - if let Some(key_slot) = binding.key_slot { - let span = self.scope()[key_slot.slot].span; - self.emit_constant(Value::String(key_slot.name.into()), &span); - self.scope_mut().mark_initialised(key_slot.slot); + match binding.key_slot { + KeySlot::None => {} // nothing to do here + + KeySlot::Static { slot, name } => { + let span = self.scope()[slot].span; + self.emit_constant(Value::String(name.into()), &span); + self.scope_mut().mark_initialised(slot); + } + + KeySlot::Dynamic { .. } => { + todo!("dynamic keys not ye timplemented") + } } match binding.binding { |