diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 2167dce77..bbf97ccae 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -89,10 +89,23 @@ struct Scope { poisoned_null: usize, } -struct Compiler { +/// Represents the lambda currently being compiled. +struct LambdaCtx { lambda: Lambda, scope: Scope, +} +impl LambdaCtx { + fn new() -> Self { + LambdaCtx { + lambda: Lambda::new_anonymous(), + scope: Default::default(), + } + } +} + +struct Compiler { + contexts: Vec, warnings: Vec, errors: Vec, root_dir: PathBuf, @@ -101,17 +114,26 @@ struct Compiler { // Helper functions for emitting code and metadata to the internal // structures of the compiler. impl Compiler { + fn context(&self) -> &LambdaCtx { + &self.contexts[self.contexts.len() - 1] + } + + fn context_mut(&mut self) -> &mut LambdaCtx { + let idx = self.contexts.len() - 1; + &mut self.contexts[idx] + } + fn chunk(&mut self) -> &mut Chunk { - std::rc::Rc::::get_mut(self.lambda.chunk()) + std::rc::Rc::::get_mut(self.context_mut().lambda.chunk()) .expect("compiler flaw: long-lived chunk reference") } fn scope(&self) -> &Scope { - &self.scope + &self.context().scope } fn scope_mut(&mut self) -> &mut Scope { - &mut self.scope + &mut self.context_mut().scope } fn emit_constant(&mut self, value: Value) { @@ -915,16 +937,15 @@ pub fn compile(expr: ast::Expr, location: Option) -> EvalResult