diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-11T08·50+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-25T12·07+0000 |
commit | 75a22321ce55512d5f436168a2f913cf9f8f8ee3 (patch) | |
tree | a8d262bfa633226c99435e8aeba0bffdd259247b | |
parent | 4eafaae9e66c66a7765ff3854890039d7536a9b9 (diff) |
feat(tvix/eval): implement list concatenation r/4479
Change-Id: Icdf715d116371a9f139bdf95266410bf967bef25 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6144 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/eval/src/compiler.rs | 1 | ||||
-rw-r--r-- | tvix/eval/src/opcode.rs | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-concat-lists.nix | 1 | ||||
-rw-r--r-- | tvix/eval/src/value/list.rs | 9 | ||||
-rw-r--r-- | tvix/eval/src/value/mod.rs | 10 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 7 |
7 files changed, 30 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 6054bd3fdaff..91eb1bda12eb 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 6800e8411f5c..b1e6d3259363 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 000000000000..3bed31f76e3f --- /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 000000000000..de332cd29f3a --- /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 d5f7c8b2ba44..f9d85229410a 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 2a89f1c35890..0c9042dbfe25 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<NixList> { + 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 30f2c5a4a414..540845d2c668 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)?, } |