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.rs24
1 files changed, 20 insertions, 4 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 1bfd765a07..3a6c685c7d 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -75,6 +75,11 @@ impl Compiler {
                 self.compile_attr_set(node)
             }
 
+            rnix::SyntaxKind::NODE_SELECT => {
+                let node = rnix::types::Select::cast(node).unwrap();
+                self.compile_select(node)
+            }
+
             rnix::SyntaxKind::NODE_LIST => {
                 let node = rnix::types::List::cast(node).unwrap();
                 self.compile_list(node)
@@ -85,10 +90,7 @@ impl Compiler {
                 self.compile_if_else(node)
             }
 
-            kind => {
-                println!("visiting unsupported node: {:?}", kind);
-                Ok(())
-            }
+            kind => panic!("visiting unsupported node: {:?}", kind),
         }
     }
 
@@ -282,6 +284,20 @@ impl Compiler {
         Ok(())
     }
 
+    fn compile_select(&mut self, node: rnix::types::Select) -> EvalResult<()> {
+        // Push the set onto the stack
+        self.compile(node.set().unwrap())?;
+
+        // Push the key and emit the access instruction.
+        //
+        // This order matters because the key needs to be evaluated
+        // first to fail in the correct order on type errors.
+        self.compile(node.index().unwrap())?;
+        self.chunk.add_op(OpCode::OpAttrsSelect);
+
+        Ok(())
+    }
+
     // Compile list literals into equivalent bytecode. List
     // construction is fairly simple, composing of pushing code for
     // each literal element and an instruction with the element count.