about summary refs log tree commit diff
path: root/tvix/eval/src/compiler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r--tvix/eval/src/compiler.rs38
1 files changed, 25 insertions, 13 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 1d56e227f41d..b9e850a36b7e 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -448,22 +448,34 @@ impl Compiler {
         //
         // Otherwise, the right hand side is the (only) key expression
         // itself and can be compiled directly.
-        let rhs = node.rhs().unwrap();
+        let mut next = node.rhs().unwrap();
+        let mut fragments = vec![];
+
+        loop {
+            if matches!(next.kind(), rnix::SyntaxKind::NODE_SELECT) {
+                // Keep nesting deeper until we encounter something
+                // different than `NODE_SELECT` on the left side. This is
+                // required because `rnix` parses nested keys as select
+                // expressions, instead of as a key expression.
+                //
+                // The parsed tree will nest something like `a.b.c.d.e.f`
+                // as (((((a, b), c), d), e), f).
+                fragments.push(next.last_child().unwrap());
+                next = next.first_child().unwrap();
+            } else {
+                self.compile_with_literal_ident(next)?;
+
+                for fragment in fragments.into_iter().rev() {
+                    println!("fragment: {}", fragment);
+                    self.chunk.add_op(OpCode::OpAttrsSelect);
+                    self.compile_with_literal_ident(fragment)?;
+                }
 
-        if matches!(rhs.kind(), rnix::SyntaxKind::NODE_SELECT) {
-            // Keep nesting deeper until we encounter something
-            // different than `NODE_SELECT` on the left side. This is
-            // required because `rnix` parses nested keys as select
-            // expressions, instead of as a key expression.
-            //
-            // The parsed tree will nest something like `a.b.c.d.e.f`
-            // as (((((a, b), c), d), e), f).
-            todo!("nested '?' check")
-        } else {
-            self.compile_with_literal_ident(rhs)?;
+                self.chunk.add_op(OpCode::OpAttrsIsSet);
+                break;
+            }
         }
 
-        self.chunk.add_op(OpCode::OpAttrsIsSet);
         Ok(())
     }