//! TreeLowering: consumes `&[TIROp]` and produces tree-structured output.
//!
//! Each tree-machine target implements `TreeLowering` to translate
//! stack-based IR operations into combinator expressions (Nock formulas,
//! or similar tree representations).
//!
//! This is the tree-machine counterpart of:
//! - `tir::lower::StackLowering` โ€” stack targets โ†’ assembly text
//! - `lir::lower::RegisterLowering` โ€” register targets โ†’ machine code
//! - `kir::lower::KernelLowering` โ€” GPU targets โ†’ kernel source

use crate::tir::TIROp;

/// A Nock noun โ€” the universal data type for tree machines.
///
/// All data in Nock is a noun: either an atom (unsigned integer)
/// or a cell (ordered pair of nouns). This recursive structure
/// is the "assembly language" of tree machines.
#[derive(Debug, Clone, PartialEq)]
pub enum Noun {
    /// An atom โ€” an unsigned integer of arbitrary width.
    Atom(u64),
    /// A cell โ€” an ordered pair `[head tail]`.
    Cell(Box<Noun>, Box<Noun>),
}

impl Noun {
    /// Create an atom noun.
    pub fn atom(value: u64) -> Self {
        Noun::Atom(value)
    }

    /// Create a cell noun `[a b]`.
    pub fn cell(head: Noun, tail: Noun) -> Self {
        Noun::Cell(Box::new(head), Box::new(tail))
    }

    /// Nock formula: `[0 axis]` โ€” slot lookup in subject tree.
    pub fn slot(axis: u64) -> Self {
        Noun::cell(Noun::atom(0), Noun::atom(axis))
    }

    /// Nock formula: `[1 constant]` โ€” produce a constant, ignore subject.
    pub fn constant(value: Noun) -> Self {
        Noun::cell(Noun::atom(1), value)
    }

    /// Nock formula: `[2 subject formula]` โ€” evaluate formula against subject.
    pub fn evaluate(subject: Noun, formula: Noun) -> Self {
        Noun::cell(Noun::atom(2), Noun::cell(subject, formula))
    }

    /// Nock formula: `[3 noun]` โ€” cell test (0 if cell, 1 if atom).
    pub fn cell_test(noun: Noun) -> Self {
        Noun::cell(Noun::atom(3), noun)
    }

    /// Nock formula: `[4 noun]` โ€” increment atom.
    pub fn increment(noun: Noun) -> Self {
        Noun::cell(Noun::atom(4), noun)
    }

    /// Nock formula: `[5 a b]` โ€” equality test.
    pub fn equals(a: Noun, b: Noun) -> Self {
        Noun::cell(Noun::atom(5), Noun::cell(a, b))
    }

    /// Nock formula: `[6 test yes no]` โ€” conditional branch.
    pub fn branch(test: Noun, yes: Noun, no: Noun) -> Self {
        Noun::cell(Noun::atom(6), Noun::cell(test, Noun::cell(yes, no)))
    }

    /// Nock formula: `[7 a b]` โ€” compose: evaluate b against result of a.
    pub fn compose(a: Noun, b: Noun) -> Self {
        Noun::cell(Noun::atom(7), Noun::cell(a, b))
    }

    /// Nock formula: `[8 a b]` โ€” push: evaluate b with [result-of-a subject].
    pub fn push(a: Noun, b: Noun) -> Self {
        Noun::cell(Noun::atom(8), Noun::cell(a, b))
    }

    /// Nock formula: `[9 axis core]` โ€” invoke: pull formula from core and eval.
    pub fn invoke(axis: u64, core: Noun) -> Self {
        Noun::cell(Noun::atom(9), Noun::cell(Noun::atom(axis), core))
    }

    /// Nock formula: `[10 [axis value] target]` โ€” edit: replace axis in target.
    pub fn edit(axis: u64, value: Noun, target: Noun) -> Self {
        Noun::cell(
            Noun::atom(10),
            Noun::cell(Noun::cell(Noun::atom(axis), value), target),
        )
    }

    /// Nock formula: `[11 hint formula]` โ€” hint (advisory, doesn't change result).
    pub fn hint(hint: Noun, formula: Noun) -> Self {
        Noun::cell(Noun::atom(11), Noun::cell(hint, formula))
    }
}

impl std::fmt::Display for Noun {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Noun::Atom(v) => write!(f, "{}", v),
            Noun::Cell(h, t) => write!(f, "[{} {}]", h, t),
        }
    }
}

/// Lowers TIR operations into tree-structured output for combinator VMs.
///
/// Unlike stack and register lowering, tree lowering produces a `Noun` โ€”
/// a recursive tree structure that IS the program. There is no assembly
/// text or machine code; the program is data.
pub trait TreeLowering {
    /// The target name (e.g. "nock").
    fn target_name(&self) -> &str;

    /// Lower a sequence of TIR operations into a Nock formula (noun tree).
    fn lower(&self, ops: &[TIROp]) -> Noun;

    /// Serialize the lowered noun to bytes (.jam format for Nock).
    fn serialize(&self, noun: &Noun) -> Vec<u8>;
}

/// Create a tree-lowering backend for the given target name.
pub fn create_tree_lowering(_target: &str) -> Option<Box<dyn TreeLowering>> {
    // No backends implemented yet. Implementers add match arms here.
    None
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_noun_display() {
        assert_eq!(format!("{}", Noun::atom(42)), "42");
        assert_eq!(
            format!("{}", Noun::cell(Noun::atom(1), Noun::atom(2))),
            "[1 2]"
        );
        assert_eq!(format!("{}", Noun::slot(7)), "[0 7]");
        assert_eq!(format!("{}", Noun::constant(Noun::atom(42))), "[1 42]");
    }

    #[test]
    fn test_noun_formulas() {
        // [6 [0 2] [1 1] [1 0]] โ€” if slot 2 then 1 else 0
        let formula = Noun::branch(
            Noun::slot(2),
            Noun::constant(Noun::atom(1)),
            Noun::constant(Noun::atom(0)),
        );
        assert_eq!(format!("{}", formula), "[6 [[0 2] [[1 1] [1 0]]]]");
    }

    #[test]
    fn test_noun_compose() {
        // [7 [1 42] [4 [0 1]]] โ€” push 42, then increment
        let formula = Noun::compose(
            Noun::constant(Noun::atom(42)),
            Noun::increment(Noun::slot(1)),
        );
        assert_eq!(format!("{}", formula), "[7 [[1 42] [4 [0 1]]]]");
    }

    #[test]
    fn test_create_tree_lowering() {
        assert!(create_tree_lowering("nock").is_none());
        assert!(create_tree_lowering("triton").is_none());
    }
}

Dimensions

trident/src/diagnostic/mod.rs
trident/src/ir/mod.rs
trident/src/deploy/mod.rs
trident/src/syntax/mod.rs
trident/src/api/mod.rs
nebu/rs/extension/mod.rs
optica/src/render/mod.rs
trident/src/config/mod.rs
trident/src/field/mod.rs
trident/src/cli/mod.rs
optica/src/parser/mod.rs
trident/src/neural/mod.rs
trident/src/cost/mod.rs
trident/src/typecheck/mod.rs
optica/src/server/mod.rs
trident/src/package/mod.rs
optica/src/scanner/mod.rs
optica/src/output/mod.rs
trident/src/verify/mod.rs
optica/src/graph/mod.rs
trident/src/ast/mod.rs
trident/src/lsp/mod.rs
trident/src/runtime/mod.rs
trident/src/gpu/mod.rs
optica/src/query/mod.rs
trident/src/lsp/semantic/mod.rs
trident/src/verify/equiv/mod.rs
trident/src/package/hash/mod.rs
trident/src/neural/training/mod.rs
trident/src/verify/synthesize/mod.rs
trident/src/ir/tir/mod.rs
rs/macros/src/addressed/mod.rs
trident/src/package/registry/mod.rs
rs/rsc/src/lints/mod.rs
trident/src/verify/report/mod.rs
trident/src/config/resolve/mod.rs
trident/src/verify/solve/mod.rs
rs/macros/src/registers/mod.rs
trident/src/verify/smt/mod.rs
rs/macros/src/cell/mod.rs
rs/core/src/fixed_point/mod.rs
trident/src/neural/data/mod.rs
rs/core/src/bounded/mod.rs
trident/src/lsp/util/mod.rs
trident/src/typecheck/tests/mod.rs
trident/src/neural/model/mod.rs
trident/src/cost/stack_verifier/mod.rs
trident/src/syntax/grammar/mod.rs
trident/src/package/manifest/mod.rs
trident/src/syntax/parser/mod.rs
trident/src/ir/kir/mod.rs
trident/src/neural/inference/mod.rs
trident/src/syntax/lexer/mod.rs
trident/src/cost/model/mod.rs
trident/src/ir/lir/mod.rs
trident/src/syntax/format/mod.rs
trident/src/config/scaffold/mod.rs
trident/src/verify/sym/mod.rs
trident/src/api/tests/mod.rs
trident/src/package/store/mod.rs
trident/src/ir/tree/mod.rs
trident/src/ir/kir/lower/mod.rs
trident/src/ir/lir/lower/mod.rs
trident/src/ir/tir/lower/mod.rs
trident/src/ir/tir/builder/mod.rs
trident/src/ir/tir/neural/mod.rs
trident/src/neural/data/tir_graph/mod.rs
trident/src/syntax/parser/tests/mod.rs
cw-cyber/packages/cyber-std/src/tokenfactory/mod.rs
trident/src/ir/tir/stack/mod.rs
cw-cyber/contracts/cybernet/src/tests/mod.rs
trident/src/ir/tir/optimize/mod.rs

Local Graph