From 3d9eb14e7ab929fb80b28f89b16bc2158c09399a Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 24 Sep 2022 15:18:37 +0300 Subject: feat(tvix/eval): add KeySlot::Dynamic variant for dynamic keys 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 --- tvix/eval/src/compiler/bindings.rs | 43 +++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'tvix/eval/src') diff --git a/tvix/eval/src/compiler/bindings.rs b/tvix/eval/src/compiler/bindings.rs index d7a5513934..94dae5fb95 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, + 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 { -- cgit 1.4.1