From 5763b62172e81122e88560f93f3d1d8755d9cbfb Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 9 Aug 2022 17:11:02 +0300 Subject: feat(tvix/vm): implement list construction Change-Id: Iec2b4910800ab29daae6d71b58a8acd14ccb1cc1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6094 Tested-by: BuildkiteCI Reviewed-by: grfn Autosubmit: tazjin --- tvix/eval/src/opcode.rs | 3 +++ tvix/eval/src/vm.rs | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tvix/eval/src/opcode.rs b/tvix/eval/src/opcode.rs index 58372f61cb..adfa2433fc 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 e8c0551caf..d328900a34 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)] -- cgit 1.4.1