import { AgencyNode, VariableType } from "../types.js"; /** * Rewrite every `guardBlock` construct into the legacy * `functionCall` + `blockArgument` shape calling the prelude impl * `_guard` — the EXACT node shape `guard(...) as { ... }` used to * parse to (spec Part 5). After this pass the rest of the compiler * cannot tell the construct ever existed: the block goes through the * same `__block_N` lifting, the call gets the same frame and step * structure, and the runtime is untouched. * * MUTATES IN PLACE, deliberately. The TypeChecker desugars in its * constructor, but the CompilationUnit built beforehand already holds * references to the same def/node objects (ctx.functionDefs etc.), and * a copying rewrite would leave those references pointing at stale * guardBlock bodies — half the pipeline desugared, half not. Mutating * the body arrays and value fields in place keeps every capture * consistent. Idempotent: a second run finds no guardBlock nodes. * * The walk is bodySlots-driven with one extension: `guardBlock` only * occurs as a statement, an assignment value, or a return value (the * parser's three registration points), so `value` fields are followed * in addition to registered body slots. The walk threads a context — * the current return target (#580) — so annotated guards can stamp * their yield type onto the block argument they desugar to. */ /** The walk context: the type a `return` statement at this point in * the tree yields to. Captured from the declared return when the * walk enters a def/node body; RESET at every return-retargeting * slot (block arguments, inline handler bodies, finalize bodies — * marked by BodySlot.retargetsReturn) to that slot's own yield: the * stamp a guard block just received, nothing for any other closure. * Absent at top level. */ type DesugarContext = { returnTarget?: VariableType; }; export declare function desugarGuardsInBody(body: AgencyNode[], ctx?: DesugarContext): AgencyNode[]; export {};