about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-09T14·44+0300
committertazjin <tazjin@tvl.su>2022-08-13T18·28+0000
commita93933b487cf710400c9126d97450264138695df (patch)
tree3b8f747de27f73acb6c87893233335b60ca9a6c5 /tvix/eval/src/vm.rs
parent3577841bdedddffb411c07ed050b25b986d1d0d6 (diff)
feat(tvix): implement string interpolation r/4434
This adds a new instruction which assembles an interpolated string
from a specified number of fragments, which are already going to be
located on the stack in the right position.

This will raise a type error if any of the fragments do not evaluate
to a string.

Change-Id: I5756248fa3e9fcc3d063c14db40b332f7e20a588
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6098
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval/src/vm.rs')
-rw-r--r--tvix/eval/src/vm.rs15
1 files changed, 15 insertions, 0 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index d328900a34c5..e4597807cea4 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -118,6 +118,7 @@ impl VM {
                 OpCode::OpFalse => self.push(Value::Bool(false)),
                 OpCode::OpAttrs(count) => self.run_attrset(count)?,
                 OpCode::OpList(count) => self.run_list(count)?,
+                OpCode::OpInterpolate(count) => self.run_interpolate(count)?,
             }
 
             if self.ip == self.chunk.code.len() {
@@ -154,6 +155,20 @@ impl VM {
         self.push(Value::List(NixList(list)));
         Ok(())
     }
+
+    // Interpolate string fragments by popping the specified number of
+    // fragments of the stack, evaluating them to strings, and pushing
+    // the concatenated result string back on the stack.
+    fn run_interpolate(&mut self, count: usize) -> EvalResult<()> {
+        let mut out = String::new();
+
+        for _ in 0..count {
+            out.push_str(&self.pop().as_string()?.0);
+        }
+
+        self.push(Value::String(NixString(out)));
+        Ok(())
+    }
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]