diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-23T19·54+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-01T21·56+0000 |
commit | 6f31c895ffe2dc5dd8281d812252d5db0644ec77 (patch) | |
tree | 9e45e371bc7d066b8666a3df532c6d241ee1165b | |
parent | 4715f9a3a0135e1b6bc1f24fbafc9b1ce1a9bc20 (diff) |
refactor(tvix/eval): return a lambda from the compiler r/4576
Changes the internal compiler plumbing to not just return a chunk of code, but the same chunk wrapped inside of a lambda value. This is one more step towards compiling runtime lambdas. Change-Id: If0035f8e65a2970c5ae123fc068a2396e1d8fd72 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6240 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
-rw-r--r-- | tvix/eval/src/chunk.rs | 2 | ||||
-rw-r--r-- | tvix/eval/src/compiler.rs | 13 | ||||
-rw-r--r-- | tvix/eval/src/eval.rs | 4 | ||||
-rw-r--r-- | tvix/eval/src/value/lambda.rs | 19 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 6 |
5 files changed, 28 insertions, 16 deletions
diff --git a/tvix/eval/src/chunk.rs b/tvix/eval/src/chunk.rs index 03071b3008de..7526add169d6 100644 --- a/tvix/eval/src/chunk.rs +++ b/tvix/eval/src/chunk.rs @@ -1,7 +1,7 @@ use crate::opcode::{CodeIdx, ConstantIdx, OpCode}; use crate::value::Value; -#[derive(Debug, Default)] +#[derive(Clone, Debug, Default)] pub struct Chunk { pub code: Vec<OpCode>, pub constants: Vec<Value>, diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 7ccb00432782..167ac731d68c 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -21,14 +21,14 @@ use std::path::{Path, PathBuf}; use crate::chunk::Chunk; use crate::errors::{Error, ErrorKind, EvalResult}; use crate::opcode::{CodeIdx, OpCode}; -use crate::value::Value; +use crate::value::{Lambda, Value}; use crate::warnings::{EvalWarning, WarningKind}; /// Represents the result of compiling a piece of Nix code. If /// compilation was successful, the resulting bytecode can be passed /// to the VM. pub struct CompilationResult { - pub chunk: Chunk, + pub lambda: Lambda, pub warnings: Vec<EvalWarning>, pub errors: Vec<Error>, } @@ -90,7 +90,7 @@ struct Scope { } struct Compiler { - chunk: Chunk, + lambda: Lambda, scope: Scope, warnings: Vec<EvalWarning>, @@ -102,7 +102,8 @@ struct Compiler { // structures of the compiler. impl Compiler { fn chunk(&mut self) -> &mut Chunk { - &mut self.chunk + std::rc::Rc::<Chunk>::get_mut(self.lambda.chunk()) + .expect("compiler flaw: long-lived chunk reference") } fn emit_constant(&mut self, value: Value) { @@ -910,7 +911,7 @@ pub fn compile(expr: ast::Expr, location: Option<PathBuf>) -> EvalResult<Compila let mut c = Compiler { root_dir, - chunk: Chunk::default(), + lambda: Lambda::new_anonymous(), warnings: vec![], errors: vec![], scope: Default::default(), @@ -919,7 +920,7 @@ pub fn compile(expr: ast::Expr, location: Option<PathBuf>) -> EvalResult<Compila c.compile(expr); Ok(CompilationResult { - chunk: c.chunk, + lambda: c.lambda, warnings: c.warnings, errors: c.errors, }) diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs index 10d36904e4b4..d81744220568 100644 --- a/tvix/eval/src/eval.rs +++ b/tvix/eval/src/eval.rs @@ -31,7 +31,7 @@ pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> { let result = crate::compiler::compile(root_expr, location)?; #[cfg(feature = "disassembler")] - crate::disassembler::disassemble_chunk(&result.chunk); + crate::disassembler::disassemble_chunk(&result.lambda.chunk); for warning in result.warnings { eprintln!( @@ -49,5 +49,5 @@ pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> { return Err(err.clone()); } - crate::vm::run_chunk(result.chunk) + crate::vm::run_lambda(result.lambda) } diff --git a/tvix/eval/src/value/lambda.rs b/tvix/eval/src/value/lambda.rs index 2cecb4f5373b..d8609f50f367 100644 --- a/tvix/eval/src/value/lambda.rs +++ b/tvix/eval/src/value/lambda.rs @@ -3,10 +3,21 @@ use std::rc::Rc; use crate::chunk::Chunk; -use super::NixString; - #[derive(Clone, Debug)] pub struct Lambda { - name: Option<NixString>, - chunk: Rc<Chunk>, + // name: Option<NixString>, + pub(crate) chunk: Rc<Chunk>, +} + +impl Lambda { + pub fn new_anonymous() -> Self { + Lambda { + // name: None, + chunk: Default::default(), + } + } + + pub fn chunk(&mut self) -> &mut Rc<Chunk> { + &mut self.chunk + } } diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 7a6a6454eadc..c9b09be82b1c 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -7,7 +7,7 @@ use crate::{ chunk::Chunk, errors::{ErrorKind, EvalResult}, opcode::OpCode, - value::{NixAttrs, NixList, Value}, + value::{Lambda, NixAttrs, NixList, Value}, }; #[cfg(feature = "disassembler")] @@ -365,9 +365,9 @@ impl VM { } } -pub fn run_chunk(chunk: Chunk) -> EvalResult<Value> { +pub fn run_lambda(lambda: Lambda) -> EvalResult<Value> { let mut vm = VM { - chunk, + chunk: Rc::<Chunk>::try_unwrap(lambda.chunk).unwrap(), ip: 0, stack: vec![], with_stack: vec![], |