From 3577841bdedddffb411c07ed050b25b986d1d0d6 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 9 Aug 2022 17:37:38 +0300 Subject: feat(tvix/compiler): compile non-interpolated string literals This sets up the scaffolding for compiling interpolation, but those instructions do not yet exist. Change-Id: Ife41bbbf432d9661abe566c92437409dd0da44e7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6097 Tested-by: BuildkiteCI Reviewed-by: grfn --- tvix/eval/src/compiler.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index ce3642b585..5ad8215b10 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -27,6 +27,11 @@ impl Compiler { self.compile_literal(value.to_value().expect("TODO")) } + rnix::SyntaxKind::NODE_STRING => { + let op = rnix::types::Str::cast(node).unwrap(); + self.compile_string(op) + } + rnix::SyntaxKind::NODE_BIN_OP => { let op = rnix::types::BinOp::cast(node).expect("TODO (should not be possible)"); self.compile_binop(op) @@ -83,6 +88,36 @@ impl Compiler { } } + fn compile_string(&mut self, string: rnix::types::Str) -> EvalResult<()> { + let mut count = 0; + + // The string parts are produced in literal order, however + // they need to be reversed on the stack in order to + // efficiently create the real string in case of + // interpolation. + for part in string.parts().into_iter().rev() { + count += 1; + + match part { + // Interpolated expressions are compiled as normal and + // dealt with by the VM before being assembled into + // the final string. + rnix::StrPart::Ast(node) => self.compile(node)?, + + rnix::StrPart::Literal(lit) => { + let idx = self.chunk.add_constant(Value::String(NixString(lit))); + self.chunk.add_op(OpCode::OpConstant(idx)); + } + } + } + + if count != 1 { + todo!("assemble string interpolation instruction") + } + + Ok(()) + } + fn compile_binop(&mut self, op: rnix::types::BinOp) -> EvalResult<()> { self.compile(op.lhs().unwrap())?; self.compile(op.rhs().unwrap())?; -- cgit 1.4.1