-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathshape-machine.ts
More file actions
93 lines (85 loc) · 3.49 KB
/
Copy pathshape-machine.ts
File metadata and controls
93 lines (85 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Target-neutral data contracts for generated shape recognizers.
*
* This module deliberately contains no target runtime. TS, Rust, and Go emitters
* can share these identities and transaction rules without sharing codegen.
*/
/** Identity path through RD alternatives, nested inline alternatives, and Pratt events. */
export type AltPathPart =
| { kind: 'rd'; rule: string; alt: number }
| { kind: 'inline-alt'; branch: number }
| { kind: 'pratt-nud'; event: 'atom' | 'group' | 'prefix' | 'nudSeq' | 'nudCapped'; index: number }
| { kind: 'pratt-led'; event: 'binary' | 'postfix' | 'postfixTok' | 'led'; index: number };
export type AltPath = readonly AltPathPart[];
/** A visible value channel. Optional holes retain position instead of disappearing. */
export type VisibleSlot<H = unknown> =
| { kind: 'slot'; value: H }
| { kind: 'list'; values: H[] }
| { kind: 'hole'; value: H | null };
export type PrattEvent<H = unknown> =
| { kind: 'atom'; value: H }
| { kind: 'group'; value: H }
| { kind: 'prefix'; operator: string; argument: H }
| { kind: 'binary'; left: H; operator: string; right: H }
| { kind: 'postfix'; left: H; operator: string }
| { kind: 'postfixTok'; left: H; token: H }
| { kind: 'led'; left: H; slots: readonly VisibleSlot<H>[] }
| { kind: 'nudSeq'; slots: readonly VisibleSlot<H>[] }
| { kind: 'nudCapped'; slots: readonly VisibleSlot<H>[] }
/** Template product: kids are head, expr, optional middle/expr pairs, and tail — or a lone no-subst leaf. */
| { kind: 'template'; slots: readonly VisibleSlot<H>[] };
/** Length snapshots are valid only for append-only channels. */
export type AppendOnlyCheckpoint = {
pos: number;
kidsLength: number;
listsLength: number;
holesLength: number;
altPathLength: number;
};
/** Prior value for a slot overwritten during a speculative transaction. */
export type UndoEntry<H = unknown> = {
channel: 'slot' | 'state';
index: number;
previous: H;
};
export type ShapeTransaction<H = unknown> = {
checkpoint: AppendOnlyCheckpoint;
undo: UndoEntry<H>[];
status: 'open' | 'committed' | 'rolledBack';
};
/**
* Transaction contract:
* - append-only arrays roll back by restoring their checkpointed lengths;
* - overwrites must be recorded in `undo`, or staged and applied only on commit;
* - parser position and every mutable Pratt/control flag (`_suppressNext` /
* `_suppressCur` / capped) join the same transaction;
* - function-local `left`/`opText` values need no log when assigned only after success.
*/
export const SHAPE_TRANSACTION_CONTRACT = {
appendOnly: 'restore-lengths',
overwrite: 'undo-log-or-commit-on-success',
prattLocals: 'commit-on-success',
controlFlags: 'restore-with-checkpoint',
} as const;
/**
* Local custom context, populated only after the recognizer has successfully
* finished the current rule/Pratt event.
*
* `kids` preserves star/sep groups as arrays and absent optional values as
* null holes. `off`/`end` cover the consumed source range. `altPath` is filled
* outermost-first with the selected RD/Pratt arm followed by nested inline
* alternatives. Pratt LED callbacks additionally receive the committed
* `left` value and connector `opText`. `state` is present only when the
* enclosing shape explicitly declares a parent fold.
*/
export type AstCustomCtx = {
src: string;
kids: readonly unknown[];
altPath: readonly number[];
off: number;
end: number;
opText?: string;
left?: unknown;
state?: unknown;
};
export type AstCustom = (ctx: AstCustomCtx) => unknown;