feat(tvix): implement string interpolation

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>
This commit is contained in:
Vincent Ambo 2022-08-09 17:44:34 +03:00 committed by tazjin
parent 3577841bde
commit a93933b487
3 changed files with 25 additions and 1 deletions

View file

@ -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)]