1
//! Hand-written recursive accessor on the `$report_node` entity.
2
//!
3
//! Lives outside the tangled `typed_entity.rs` because the
4
//! `children` field's `PairRef(Entity(ReportNode))` return type
5
//! doesn't fit the simple-ident shape the tangler emits. The
6
//! compile path follows the same template every other accessor
7
//! uses: validate arity, push the entity arg via
8
//! `compile_for_stack`, kind-check, `struct.get`. Field 4 is the
9
//! children pair per the layout in `entity_registry.org`.
10

            
11
use super::super::context::CompileContext;
12
use super::super::emit::FunctionEmitter;
13
use super::NativeSpec;
14
use crate::ast::{EntityKind, Expr, PairElement, WasmType};
15
use crate::error::{Error, Result};
16
use crate::runtime::SymbolTable;
17

            
18
fn node_children_eval(_symbols: &mut SymbolTable, args: &[Expr]) -> Result<Expr> {
19
    if args.len() != 1 {
20
        return Err(Error::Arity {
21
            name: "NODE-CHILDREN".to_string(),
22
            expected: 1,
23
            actual: args.len(),
24
        });
25
    }
26
    Ok(Expr::WasmRuntime(WasmType::PairRef(PairElement::Entity(
27
        EntityKind::ReportNode,
28
    ))))
29
}
30

            
31
fn node_children_stack(
32
    ctx: &mut CompileContext,
33
    emit: &mut FunctionEmitter,
34
    symbols: &mut SymbolTable,
35
    args: &[Expr],
36
) -> Result<WasmType> {
37
    if args.len() != 1 {
38
        return Err(Error::Arity {
39
            name: "NODE-CHILDREN".to_string(),
40
            expected: 1,
41
            actual: args.len(),
42
        });
43
    }
44
    let ty = crate::compiler::expr::compile_for_stack(ctx, emit, symbols, &args[0])?;
45
    let expected = WasmType::EntityRef(EntityKind::ReportNode);
46
    if ty != expected {
47
        return Err(Error::Type {
48
            expected: format!("{expected} for NODE-CHILDREN"),
49
            actual: ty.to_string(),
50
        });
51
    }
52
    emit.struct_get(ctx.ids.ty_report_node, 4);
53
    Ok(WasmType::PairRef(PairElement::Entity(
54
        EntityKind::ReportNode,
55
    )))
56
}
57

            
58
pub(in crate::compiler::native) const NATIVES: &[NativeSpec] = &[NativeSpec {
59
    name: "NODE-CHILDREN",
60
    eval: node_children_eval,
61
    stack: Some(node_children_stack),
62
    effect: None,
63
}];