diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/opcode.rs | 3 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 18 |
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)] |