|
| 1 | +/** |
| 2 | + * Target-neutral data contracts for generated shape recognizers. |
| 3 | + * |
| 4 | + * This module deliberately contains no target runtime. TS, Rust, and Go emitters |
| 5 | + * can share these identities and transaction rules without sharing codegen. |
| 6 | + */ |
| 7 | + |
| 8 | +/** Identity path through RD alternatives, nested inline alternatives, and Pratt events. */ |
| 9 | +export type AltPathPart = |
| 10 | + | { kind: 'rd'; rule: string; alt: number } |
| 11 | + | { kind: 'inline-alt'; branch: number } |
| 12 | + | { kind: 'pratt-nud'; event: 'atom' | 'group' | 'prefix' | 'nudSeq' | 'nudCapped'; index: number } |
| 13 | + | { kind: 'pratt-led'; event: 'binary' | 'postfix' | 'postfixTok' | 'led'; index: number }; |
| 14 | +export type AltPath = readonly AltPathPart[]; |
| 15 | + |
| 16 | +/** A visible value channel. Optional holes retain position instead of disappearing. */ |
| 17 | +export type VisibleSlot<H = unknown> = |
| 18 | + | { kind: 'slot'; value: H } |
| 19 | + | { kind: 'list'; values: H[] } |
| 20 | + | { kind: 'hole'; value: H | null }; |
| 21 | + |
| 22 | +export type PrattEvent<H = unknown> = |
| 23 | + | { kind: 'atom'; value: H } |
| 24 | + | { kind: 'group'; value: H } |
| 25 | + | { kind: 'prefix'; operator: string; argument: H } |
| 26 | + | { kind: 'binary'; left: H; operator: string; right: H } |
| 27 | + | { kind: 'postfix'; left: H; operator: string } |
| 28 | + | { kind: 'postfixTok'; left: H; token: H } |
| 29 | + | { kind: 'led'; left: H; slots: readonly VisibleSlot<H>[] } |
| 30 | + | { kind: 'nudSeq'; slots: readonly VisibleSlot<H>[] } |
| 31 | + | { kind: 'nudCapped'; slots: readonly VisibleSlot<H>[] }; |
| 32 | + |
| 33 | +/** Length snapshots are valid only for append-only channels. */ |
| 34 | +export type AppendOnlyCheckpoint = { |
| 35 | + pos: number; |
| 36 | + kidsLength: number; |
| 37 | + listsLength: number; |
| 38 | + holesLength: number; |
| 39 | + altPathLength: number; |
| 40 | +}; |
| 41 | + |
| 42 | +/** Prior value for a slot overwritten during a speculative transaction. */ |
| 43 | +export type UndoEntry<H = unknown> = { |
| 44 | + channel: 'slot' | 'state'; |
| 45 | + index: number; |
| 46 | + previous: H; |
| 47 | +}; |
| 48 | + |
| 49 | +export type ShapeTransaction<H = unknown> = { |
| 50 | + checkpoint: AppendOnlyCheckpoint; |
| 51 | + undo: UndoEntry<H>[]; |
| 52 | + status: 'open' | 'committed' | 'rolledBack'; |
| 53 | +}; |
| 54 | + |
| 55 | +/** |
| 56 | + * Transaction contract: |
| 57 | + * - append-only arrays roll back by restoring their checkpointed lengths; |
| 58 | + * - overwrites must be recorded in `undo`, or staged and applied only on commit; |
| 59 | + * - parser position and every mutable Pratt/control flag join the same transaction; |
| 60 | + * - function-local `left`/`opText` values need no log when assigned only after success. |
| 61 | + */ |
| 62 | +export const SHAPE_TRANSACTION_CONTRACT = { |
| 63 | + appendOnly: 'restore-lengths', |
| 64 | + overwrite: 'undo-log-or-commit-on-success', |
| 65 | + prattLocals: 'commit-on-success', |
| 66 | +} as const; |
| 67 | + |
| 68 | +/** Local custom context (SH2-0). Full AltPathPart form is deferred. */ |
| 69 | +export type AstCustomCtx = { |
| 70 | + kids: readonly unknown[]; |
| 71 | + altPath: readonly number[]; |
| 72 | + src: string; |
| 73 | + off: number; |
| 74 | + end: number; |
| 75 | +}; |
| 76 | +export type AstCustom = (ctx: AstCustomCtx) => unknown; |
0 commit comments