From 6f31c895ffe2dc5dd8281d812252d5db0644ec77 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 23 Aug 2022 22:54:25 +0300 Subject: refactor(tvix/eval): return a lambda from the compiler 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 --- tvix/eval/src/chunk.rs | 2 +- tvix/eval/src/compiler.rs | 13 +++++++------ tvix/eval/src/eval.rs | 4 ++-- tvix/eval/src/value/lambda.rs | 19 +++++++++++++++---- tvix/eval/src/vm.rs | 6 +++--- 5 files changed, 28 insertions(+), 16 deletions(-) (limited to 'tvix/eval/src') diff --git a/tvix/eval/src/chunk.rs b/tvix/eval/src/chunk.rs index 03071b3008..7526add169 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, pub constants: Vec, diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 7ccb004327..167ac731d6 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, pub errors: Vec, } @@ -90,7 +90,7 @@ struct Scope { } struct Compiler { - chunk: Chunk, + lambda: Lambda, scope: Scope, warnings: Vec, @@ -102,7 +102,8 @@ struct Compiler { // structures of the compiler. impl Compiler { fn chunk(&mut self) -> &mut Chunk { - &mut self.chunk + std::rc::Rc::::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) -> EvalResult) -> EvalResult) -> EvalResult { 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) -> EvalResult { 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 2cecb4f537..d8609f50f3 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, - chunk: Rc, + // name: Option, + pub(crate) chunk: Rc, +} + +impl Lambda { + pub fn new_anonymous() -> Self { + Lambda { + // name: None, + chunk: Default::default(), + } + } + + pub fn chunk(&mut self) -> &mut Rc { + &mut self.chunk + } } diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 7a6a6454ea..c9b09be82b 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 { +pub fn run_lambda(lambda: Lambda) -> EvalResult { let mut vm = VM { - chunk, + chunk: Rc::::try_unwrap(lambda.chunk).unwrap(), ip: 0, stack: vec![], with_stack: vec![], -- cgit 1.4.1