From 75a22321ce55512d5f436168a2f913cf9f8f8ee3 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 11 Aug 2022 11:50:38 +0300 Subject: feat(tvix/eval): implement list concatenation Change-Id: Icdf715d116371a9f139bdf95266410bf967bef25 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6144 Reviewed-by: sterni Tested-by: BuildkiteCI --- tvix/eval/src/compiler.rs | 1 + tvix/eval/src/opcode.rs | 1 + tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp | 1 + tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix | 1 + tvix/eval/src/value/list.rs | 9 +++++++++ tvix/eval/src/value/mod.rs | 10 ++++++++++ tvix/eval/src/vm.rs | 7 +++++++ 7 files changed, 30 insertions(+) create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp create mode 100644 tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix (limited to 'tvix') diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 6054bd3fda..91eb1bda12 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -141,6 +141,7 @@ impl Compiler { BinOpKind::LessOrEq => self.chunk.add_op(OpCode::OpLessOrEq), BinOpKind::More => self.chunk.add_op(OpCode::OpMore), BinOpKind::MoreOrEq => self.chunk.add_op(OpCode::OpMoreOrEq), + BinOpKind::Concat => self.chunk.add_op(OpCode::OpConcat), BinOpKind::NotEqual => { self.chunk.add_op(OpCode::OpEqual); diff --git a/tvix/eval/src/opcode.rs b/tvix/eval/src/opcode.rs index 6800e8411f..b1e6d32593 100644 --- a/tvix/eval/src/opcode.rs +++ b/tvix/eval/src/opcode.rs @@ -41,6 +41,7 @@ pub enum OpCode { // Lists OpList(usize), + OpConcat, // Strings OpInterpolate(usize), diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp new file mode 100644 index 0000000000..3bed31f76e --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp @@ -0,0 +1 @@ +[ 1 2 3 4 ] diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix new file mode 100644 index 0000000000..de332cd29f --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix @@ -0,0 +1 @@ +[ 1 2 ] ++ [ 3 4 ] diff --git a/tvix/eval/src/value/list.rs b/tvix/eval/src/value/list.rs index d5f7c8b2ba..f9d8522941 100644 --- a/tvix/eval/src/value/list.rs +++ b/tvix/eval/src/value/list.rs @@ -18,3 +18,12 @@ impl Display for NixList { f.write_str("]") } } + +impl NixList { + pub fn concat(&self, other: &Self) -> Self { + let mut lhs = self.clone(); + let mut rhs = other.clone(); + lhs.0.append(&mut rhs.0); + lhs + } +} diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index 2a89f1c358..0c9042dbfe 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -81,6 +81,16 @@ impl Value { }), } } + + pub fn as_list(self) -> EvalResult { + match self { + Value::List(l) => Ok(l), + other => Err(Error::TypeError { + expected: "list", + actual: other.type_of(), + }), + } + } } impl Display for Value { diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 30f2c5a4a4..540845d2c6 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -151,6 +151,13 @@ impl VM { } OpCode::OpList(count) => self.run_list(count)?, + + OpCode::OpConcat => { + let rhs = self.pop().as_list()?; + let lhs = self.pop().as_list()?; + self.push(Value::List(lhs.concat(&rhs))) + } + OpCode::OpInterpolate(count) => self.run_interpolate(count)?, } -- cgit 1.4.1