8.5 KiB
PBS Lowering IRBackend Specification
Status: Draft v1 (Frontend Scope + Backend Handoff Addendum)
Applies to: first lowering boundary from bound PBS frontend model into IRBackend/IRBackendFile, plus executable-backend handoff obligations at this boundary
1. Purpose
This document defines the normative frontend lowering contract from PBS source semantics to IRBackend.
Its purpose is to keep the first lowering deterministic and shared across implementations while PBS and backend design evolve.
2. Scope
This document defines:
- required preconditions before lowering starts,
- AST invariants that lowering may assume as hard contract,
- semantic obligations preserved in
IRBackend, - deterministic rejection behavior for unsupported frontend-lowering forms,
- diagnostics attribution obligations for lowering failures in frontend scope,
- and executable-backend handoff obligations at the
IRBackendboundary.
This document does not define:
- VM lowering (
IRVM), - bytecode/PBX mapping,
- runtime execution behavior,
- verifier/loader internals.
Those concerns belong to shared acceptance specs under docs/specs/compiler.
3. Authority and Precedence
Normative precedence:
3. Core Syntax Specification.md4. Static Semantics Specification.md11. AST Specification.md12. Diagnostics Specification.md- This document
If a lowering rule here conflicts with higher-precedence syntax/semantics rules, the higher-precedence rule wins.
4. Normative Inputs
This document depends on:
3. Core Syntax Specification.md4. Static Semantics Specification.md11. AST Specification.md12. Diagnostics Specification.mddocs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md
5. Lowering Preconditions
Frontend lowering into IRBackend may start only when:
- source has been tokenized and parsed,
- required syntax diagnostics have been emitted,
- AST output satisfies
11required invariants for this source unit, including:- one root per file,
- deterministic child ordering,
- mandatory node attribution (
file/start/end) on nodes consumed by lowering, - mandatory declaration metadata on declaration nodes required by the active source slice,
- and structural coherence after any parser recovery.
- linking/name-resolution outcomes required for the current lowering slice are available,
- and no unresolved semantic ambiguity is deferred to lowering.
Lowering must not invent unresolved semantic answers that belong to syntax/static/linking phases.
6. IRBackend Preserved Obligations
For each admitted source unit and callable in the current lowering slice, IRBackend must preserve at minimum:
- callable identity (name/category as applicable),
- callable arity,
- declared return surface information,
- source attribution anchor (
file + span) for diagnostics and traceability, - source-observable parse intent for statement/expression structure (including precedence/associativity outcome already fixed by AST shape).
- deterministic
requiredCapabilitiesderived from admitted host-binding metadata for packer/runtime-manifest assistance. - compiler-selected published-wrapper entrypoint identity for backend handoff,
- explicit global and synthetic lifecycle structure required by executable lowering.
Lowering must not collapse source categories in a way that erases required declaration/callable identity needed by downstream diagnostics or conformance assertions.
The normative contract is obligation-based, not tied to one mandatory in-memory class graph.
7. Deterministic Rejection Policy
If a source form is outside current frontend-lowering support:
- rejection must be deterministic,
- diagnostics must expose stable
code,severity,phase,message template id, and primary attribution, - and unsupported forms must not silently degrade into different valid lowered behavior.
Lowering must not convert a required syntax/static rejection into accepted lowered behavior.
For multi-module builds, lowering admission must apply dependency-scoped fail-fast:
- a module rejected in syntax, static semantics, linking, host-admission, or load-facing gates must not be emitted;
- any module that imports a rejected module (directly or transitively) must also be excluded from
IRBackendemission; - modules independent from the rejected dependency subgraph may continue to lower and emit in the same build.
8. Conformance Boundary
IRBackend is the first lowering boundary (frontend responsibility).
Conformance-valid claims at this boundary require Gate U evidence from docs/specs/compiler/13. Conformance Test Specification.md.
For this frontier, Gate U evidence is expected to cover at minimum:
- lexer behavior for covered inputs,
- parser behavior and AST shape invariants required by
11, - lowering outcomes at
IRBackendboundary, - and deterministic diagnostics identity/attribution for rejection cases.
Conformance at this boundary may be claimed only when the full claimed PBS source surface is implemented at IRBackend level.
9. Explicit Deferrals
The following are intentionally out of scope for this document:
IRBackend -> IRVMlowering,- artifact encoding and binary layout,
- runtime lifecycle behavior,
- verifier and loader checks.
10. Non-Goals
- Freezing one optimizer strategy.
- Freezing one compiler architecture.
- Repeating runtime or bytecode authority.
11. Exit Criteria
This document is healthy when:
- lowering preconditions are explicit,
- preserved
IRBackendobligations are explicit, - deterministic rejection policy is explicit and test-backed,
- and scope boundaries with general/backend acceptance specs are explicit.
12. Executable Backend Handoff Addendum (v1)
For executable backends, the IRBackend output from this frontend boundary must satisfy the additional handoff obligations below.
12.1 Callable obligations
For each executable callable admitted into IRBackend, the frontend must preserve:
- stable callable identity in the current build graph,
- observable callable signature (input arity and return shape),
- callable category needed by downstream lowering,
- source attribution anchor (
fileId,start,end), - and executable body representation that is backend-lowerable.
12.2 Callsite classification obligations
Each executable callsite in IRBackend must be classified into exactly one category:
CALL_FUNC,CALL_HOST,CALL_INTRINSIC.
Backend lowering must not infer this category by textual heuristics.
12.3 Host-backed metadata obligations
Each host-backed callsite admitted at this boundary must preserve canonical host identity:
module,name,version.
When available at this boundary, declared host ABI shape (arg_slots, ret_slots) must also be preserved for downstream validation.
12.4 VM-owned metadata obligations
VM-owned intrinsic callsites admitted at this boundary must preserve canonical intrinsic identity:
canonicalName,canonicalVersion.
VM-owned builtin projections/constants/intrinsics must not be reclassified as host bindings.
12.5 Deterministic capability obligations
requiredCapabilities derived at this boundary must be deterministic for the same admitted input graph.
12.6 Boundary with backend lowering specs
This addendum defines obligations preserved at the IRBackend boundary only.
It does not replace:
docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md,docs/specs/compiler/21. IRVM Optimization Pipeline Specification.md,- or
docs/specs/compiler/15. Bytecode and PBX Mapping Specification.md.
12.7 Executable Lifecycle and Published Wrapper Obligation
For executable PBS frontends, backend handoff must preserve the compiler-selected published wrapper rather than a frontend-declared nominal entrypoint.
At IRBackend emission time:
- the lowered graph must contain explicit lifecycle structure for:
- user-authored globals,
- file init fragments,
- module init,
- project init when present,
- and the published frame wrapper,
- the published frame wrapper must be the effective entrypoint identity handed to backend stages,
- the userland callable marked with
[Frame]must remain distinguishable as the logical frame root, - the wrapper must own final
FRAME_RET, - backend stages must not reintroduce manifest-owned or
FrontendSpec-owned nominal entrypoint authority, - and hidden compiler-owned lifecycle state such as the boot guard must remain structurally distinguishable from user globals.