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 <grfn@gws.fyi>
This commit is contained in:
parent
4715f9a3a0
commit
6f31c895ff
5 changed files with 28 additions and 16 deletions
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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![],
|
||||
|
|
Loading…
Reference in a new issue