lambda-ref-cat 0.1.0

Lambda calculus with mutable reference cells and a pure-functional mark-sweep garbage collector, built on comp-cat-rs. Spike 2 of a web-engine reformulation targeting Tauri.
Documentation
//! Runtime values.
//!
//! Extends the spike-1 `Value` with [`Value::Ref`], a first-class cell
//! reference.  Cells live in the [`Heap`], so a `Ref` carries only an
//! [`Address`] and the actual contents are looked up against the heap at
//! deref time.
//!
//! [`Heap`]: crate::heap::Heap

use crate::env::Env;
use crate::heap::Address;
use crate::syntax::{Expr, VarName};

/// A runtime value.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Value {
    /// A function closed over its lexical environment.
    Closure {
        /// The parameter the function binds when applied.
        param: VarName,
        /// The function body.
        body: Expr,
        /// The captured environment.
        env: Env,
    },
    /// A reference to a cell on the heap.
    Ref(Address),
}

impl Value {
    /// Build a closure value.
    #[must_use]
    pub fn closure(param: VarName, body: Expr, env: Env) -> Self {
        Self::Closure { param, body, env }
    }

    /// Build a reference value.
    #[must_use]
    pub fn reference(address: Address) -> Self {
        Self::Ref(address)
    }
}

impl std::fmt::Display for Value {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Closure { param, body, .. } => write!(f, "\\{param}. {body}"),
            Self::Ref(address) => write!(f, "ref({address})"),
        }
    }
}