Skip to main content

Module plan

Module plan 

Source
Expand description

Parser plans: the flat runtime representation of a parser AST.

After validation and type synthesis, a ParserAst is lowered into a ParserPlan — a flat arena of PlanNodes that the runtime interpreter (praxis-runtime::parser) walks against the input buffer. The compiled plan is registered in a process-wide arena and identified by a PlanId; MIR passes that id as an i64 immediate (no pointer-as-immediate needed).

Design constraints:

  • Flat and self-contained: nodes reference children by index (no Box, no owned String on the hot path). Separators and template literals are interned into a parallel &'static [&'static str] slice so the runtime reads them without dereferencing Rust owned data.
  • Record schemas for named-capture templates are built at runtime (the interpreter knows the field descriptors from the child plans’ result types); the plan stores only field names as &'static str.

Not #[repr(C)]. These are ordinary Rust enums and slices with the default representation, and nothing here crosses an FFI boundary: the plan is consumed by praxis-runtime, which is Rust and links against this crate, and only the plan id is passed as a JIT immediate. If a plan ever does need to be read by generated code, that is a real representation change (explicit #[repr(C)], no enums with payloads, no &str fat pointers) and not something to assume from this comment.

§Ownership

Each CompiledPlan owns a bumpalo arena holding everything the plan’s &'static fields point into, so a plan is reclaimable at all; registration is bounded and checked, so a long enough compile cannot wrap the index and hand the runtime a different plan; and a PlanId is a NonZeroU32, so “no plan” is not spelled 0 — it is not spellable at all.

Reclamation has the same ordering obligation as the JIT generation arena: record schemas the runtime builds for named-capture templates borrow their field names from plan storage, so plans may only be retired once the heap is drained. praxis_runtime::retire_parser_plans is the gate; see retire_all_plans.

Structs§

CompiledPlan
A lowered plan together with the arena that owns everything it points at.
ParserPlan
A compiled parser plan: the node arena plus auxiliary interned data.
PlanId
The identity of a registered parser plan.
SourceOrder
The order the parser wrote them in — FieldOrder for a plan lowered outside a compilation, where there is no other spelling to agree with.
TooManyPlans
Registration refused: the process has compiled more parser plans than the arena admits.

Enums§

BlockItemNode
One item of a block(...) (§7.5), in plan form.
PlanNode
One node in the flattened parser plan. Index-based: children refer to other nodes by their position in the ParserPlan::nodes slice.
SectionItemNode
One named argument of a heterogeneous sections(...) other than its unbounded tail (§7.5), in plan form.
TemplatePartNode
One part of a template, in plan form.
TemplateShape
What a lowered template’s parts add up to (§7.3).

Constants§

MAX_PLANS
The registration bound. Chosen so an id always fits a u32 with room to spare, and so a runaway registration loop is caught long before the narrowing could matter.

Traits§

FieldOrder
Who decides the layout order of the anonymous record a named-capture parser builds (§5.6, ADR-152).

Functions§

get_plan
Look up a plan by id. None if the id names no registered plan (the caller treats that as a parse fault).
lower_to_plan
Lower a validated ParserAst into a self-owning CompiledPlan.
plan_count
How many plans are registered. For tests and diagnostics.
register_plan
Register a compiled plan, returning its id.
retire_all_plans
Drop every registered plan, releasing its arena.