diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-09T14·37+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-13T18·28+0000 |
commit | 3577841bdedddffb411c07ed050b25b986d1d0d6 (patch) | |
tree | 42213c84158d4263966ad91fc43ba71faae69d18 /tvix/eval/src/compiler.rs | |
parent | 72863d81fcf51aed0fd5b4cffd378c30d7fbfb43 (diff) |
feat(tvix/compiler): compile non-interpolated string literals r/4433
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 <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index ce3642b585e6..5ad8215b10d3 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())?; |