1
//! Reflective / introspection special forms — `COMPILE`, `EVAL`,
2
//! `DESCRIBE`, `PP`, `APROPOS`, `DEFTEST`, `ASSERT-EQUAL`,
3
//! `RUN-TESTS`, `COVERAGE-DUMP`.
4
//!
5
//! Split by feature so each submodule stays under the ~500-line
6
//! CLAUDE.md guideline:
7
//! - [`compile_eval_forms`] — COMPILE + EVAL (handlers in both
8
//!   directions, plus their value-position counterparts).
9
//! - [`describe_pp`] — DESCRIBE + PP (both produce String summaries).
10
//! - [`apropos`] — symbol-table search returning a sorted quoted list.
11
//! - [`test_framework`] — DEFTEST + ASSERT-EQUAL + RUN-TESTS.
12
//! - [`coverage`] — COVERAGE-DUMP snapshot of native-fn references.
13

            
14
mod apropos;
15
mod compile_eval_forms;
16
mod coverage;
17
mod describe_pp;
18
mod test_framework;
19

            
20
#[cfg(test)]
21
mod tests;
22

            
23
use crate::ast::{Expr, WasmType};
24
use crate::compiler::context::CompileContext;
25
use crate::compiler::emit::FunctionEmitter;
26
use crate::compiler::expr::{compile_for_stack, format_expr};
27
use crate::error::Result;
28
use crate::runtime::SymbolTable;
29

            
30
use super::SpecialFormSpec;
31

            
32
/// Compiles a constant-folded Expr result onto the wasm stack. Forms
33
/// like PP / DESCRIBE / RUN-TESTS already return `Expr::String`, but
34
/// COMPILE / DEFTEST / APROPOS return `Expr::Quote(...)`. Both flavours
35
/// need to land on the stack as a single StringRef at value position;
36
/// Quote results get formatted to their textual form via `format_expr`
37
/// so the eval-mode client receives a presentable wire payload.
38
816
pub(in crate::compiler::special::compile_eval) fn compile_static_result_for_stack(
39
816
    ctx: &mut CompileContext,
40
816
    emit: &mut FunctionEmitter,
41
816
    symbols: &mut SymbolTable,
42
816
    result: &Expr,
43
816
) -> Result<WasmType> {
44
816
    let staged = match result {
45
204
        Expr::Quote(_) => Expr::String(format_expr(result)),
46
612
        other => other.clone(),
47
    };
48
816
    compile_for_stack(ctx, emit, symbols, &staged)
49
816
}
50

            
51
pub(super) const FORMS: &[SpecialFormSpec] = &[
52
    SpecialFormSpec {
53
        name: "COMPILE",
54
        eval: compile_eval_forms::compile_form,
55
        compile: compile_eval_forms::compile_compile_form,
56
        stack: Some(compile_eval_forms::compile_compile_form_for_stack),
57
        effect: None,
58
    },
59
    SpecialFormSpec {
60
        name: "EVAL",
61
        eval: compile_eval_forms::eval_form,
62
        compile: compile_eval_forms::compile_eval_form,
63
        stack: Some(compile_eval_forms::compile_eval_form_for_stack),
64
        effect: None,
65
    },
66
    SpecialFormSpec {
67
        name: "DESCRIBE",
68
        eval: describe_pp::describe,
69
        compile: describe_pp::compile_describe,
70
        stack: Some(describe_pp::compile_describe_for_stack),
71
        effect: None,
72
    },
73
    SpecialFormSpec {
74
        name: "PP",
75
        eval: describe_pp::pp,
76
        compile: describe_pp::compile_pp,
77
        stack: Some(describe_pp::compile_pp_for_stack),
78
        effect: None,
79
    },
80
    SpecialFormSpec {
81
        name: "APROPOS",
82
        eval: apropos::apropos,
83
        compile: apropos::compile_apropos,
84
        stack: Some(apropos::compile_apropos_for_stack),
85
        effect: None,
86
    },
87
    SpecialFormSpec {
88
        name: "DEFTEST",
89
        eval: test_framework::deftest,
90
        compile: test_framework::compile_deftest,
91
        stack: Some(test_framework::compile_deftest_for_stack),
92
        effect: None,
93
    },
94
    SpecialFormSpec {
95
        name: "ASSERT-EQUAL",
96
        eval: test_framework::assert_equal,
97
        compile: test_framework::compile_assert_equal,
98
        stack: Some(test_framework::compile_assert_equal_for_stack),
99
        effect: None,
100
    },
101
    SpecialFormSpec {
102
        name: "RUN-TESTS",
103
        eval: test_framework::run_tests,
104
        compile: test_framework::compile_run_tests,
105
        stack: Some(test_framework::compile_run_tests_for_stack),
106
        effect: None,
107
    },
108
    SpecialFormSpec {
109
        name: "COVERAGE-DUMP",
110
        eval: coverage::coverage_dump,
111
        compile: coverage::compile_coverage_dump,
112
        stack: Some(coverage::compile_coverage_dump_for_stack),
113
        effect: None,
114
    },
115
];