about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/opcode.rs3
-rw-r--r--tvix/eval/src/vm.rs18
2 files changed, 20 insertions, 1 deletions
diff --git a/tvix/eval/src/opcode.rs b/tvix/eval/src/opcode.rs
index 58372f61cb17..adfa2433fcc3 100644
--- a/tvix/eval/src/opcode.rs
+++ b/tvix/eval/src/opcode.rs
@@ -32,4 +32,7 @@ pub enum OpCode {
 
     // Attribute sets
     OpAttrs(usize),
+
+    // Lists
+    OpList(usize),
 }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index e8c0551caf67..d328900a34c5 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -7,7 +7,7 @@ use crate::{
     chunk::Chunk,
     errors::{Error, EvalResult},
     opcode::OpCode,
-    value::{NixAttrs, NixString, Value},
+    value::{NixAttrs, NixList, NixString, Value},
 };
 
 pub struct VM {
@@ -117,6 +117,7 @@ impl VM {
                 OpCode::OpTrue => self.push(Value::Bool(true)),
                 OpCode::OpFalse => self.push(Value::Bool(false)),
                 OpCode::OpAttrs(count) => self.run_attrset(count)?,
+                OpCode::OpList(count) => self.run_list(count)?,
             }
 
             if self.ip == self.chunk.code.len() {
@@ -138,6 +139,21 @@ impl VM {
         self.push(Value::Attrs(Rc::new(NixAttrs::Map(attrs))));
         Ok(())
     }
+
+    // Construct runtime representation of a list. Because the list
+    // items are on the stack in reverse order, the vector is created
+    // initialised and elements are directly assigned to their
+    // respective indices.
+    fn run_list(&mut self, count: usize) -> EvalResult<()> {
+        let mut list = vec![Value::Null; count];
+
+        for idx in 0..count {
+            list[count - idx - 1] = self.pop();
+        }
+
+        self.push(Value::List(NixList(list)));
+        Ok(())
+    }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]