Runtime support library for P programs compiled to Elixir / the BEAM by the P compiler's Elixir backend.
P models communicating state machines that exchange asynchronous, typed events — a shape
the BEAM was built for. The Elixir backend generates one :gen_statem per P machine; this
library carries the cross-cutting pieces that do not vary with the .p source:
- Registry — addresses machines by their P name rather than pid.
- Trace — an in-memory, ordered recorder of runtime events, used by tests to assert a program's observable event trace.
- Spawner — serializes
new MachineName(args)so id allocation is race-free. - Specs — the spec-monitor subscription table and the synchronous fan-out of observed events.
- Log — emits each trace entry as a structured, PObserve-friendly
key=valueline. PRuntimehelpers —goto/halt/raise_event/defer/ignorebuild the:gen_statemreturn tuples,send_event/announceare the (halt-aware, spec-fan-out) delivery wrappers, andcreated/entered/dequeued/observesrecord the trace and register monitors.
Logging is a runtime concern here, never inline in generated code — mirroring how PChecker's C# runtime logs as a side effect of base-class operations.
Through M7: machine creation, state entry, goto, raise halt, payloads/types (including any),
cross-machine sends (new + registry), defer/ignore, non-halt raise, spec monitors with
synchronous announce/send fan-out plus a PObserve-compatible key=value log shape, and faithful
failure surfacing — an unhandled event raises PRuntime.UnhandledEvent (rather than being dropped)
and an abnormal process crash is recorded/logged via terminated/3. Foreign types/functions (M6)
run entirely in the host's PForeign module. A Hex release is deferred; depend on this library via
its GitHub ref for now.
Add as a dependency of a generated P/Elixir project (or its host):
def deps do
[{:p_runtime, "~> 0.1"}]
endThe library starts its own supervision tree (Registry + Trace + Specs + Spawner) on boot.
mix deps.get
mix compile
mix test