roll-parser 3.0.0-beta.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -9
- package/MIGRATION.md +147 -0
- package/README.md +960 -154
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +81 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/format.d.ts +15 -3
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +17 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +14 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/main.d.ts +36 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +83 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/errors.d.ts +332 -17
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +141 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator/die.d.ts +26 -0
- package/dist/evaluator/die.d.ts.map +1 -0
- package/dist/evaluator/die.js +19 -0
- package/dist/evaluator/die.js.map +1 -0
- package/dist/evaluator/env.d.ts +58 -0
- package/dist/evaluator/env.d.ts.map +1 -0
- package/dist/evaluator/env.js +11 -0
- package/dist/evaluator/env.js.map +1 -0
- package/dist/evaluator/evaluator.d.ts +41 -75
- package/dist/evaluator/evaluator.d.ts.map +1 -1
- package/dist/evaluator/evaluator.js +906 -0
- package/dist/evaluator/evaluator.js.map +1 -0
- package/dist/evaluator/modifiers/compare.js +15 -0
- package/dist/evaluator/modifiers/compare.js.map +1 -0
- package/dist/evaluator/modifiers/crit-threshold.d.ts +0 -1
- package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.js +23 -0
- package/dist/evaluator/modifiers/crit-threshold.js.map +1 -0
- package/dist/evaluator/modifiers/die-bound.d.ts +26 -0
- package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -0
- package/dist/evaluator/modifiers/die-bound.js +14 -0
- package/dist/evaluator/modifiers/die-bound.js.map +1 -0
- package/dist/evaluator/modifiers/explode.d.ts +13 -5
- package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
- package/dist/evaluator/modifiers/explode.js +103 -0
- package/dist/evaluator/modifiers/explode.js.map +1 -0
- package/dist/evaluator/modifiers/flags.d.ts +37 -0
- package/dist/evaluator/modifiers/flags.d.ts.map +1 -0
- package/dist/evaluator/modifiers/flags.js +18 -0
- package/dist/evaluator/modifiers/flags.js.map +1 -0
- package/dist/evaluator/modifiers/keep-drop.d.ts +12 -28
- package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.js +82 -0
- package/dist/evaluator/modifiers/keep-drop.js.map +1 -0
- package/dist/evaluator/modifiers/reroll.d.ts +12 -4
- package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
- package/dist/evaluator/modifiers/reroll.js +62 -0
- package/dist/evaluator/modifiers/reroll.js.map +1 -0
- package/dist/evaluator/modifiers/sort.d.ts +4 -0
- package/dist/evaluator/modifiers/sort.d.ts.map +1 -1
- package/dist/evaluator/modifiers/sort.js +13 -0
- package/dist/evaluator/modifiers/sort.js.map +1 -0
- package/dist/evaluator/modifiers/success-count.d.ts +2 -6
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
- package/dist/evaluator/modifiers/success-count.js +24 -0
- package/dist/evaluator/modifiers/success-count.js.map +1 -0
- package/dist/index.d.ts +33 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2560
- package/dist/index.js.map +1 -26
- package/dist/lexer/lexer.d.ts +50 -5
- package/dist/lexer/lexer.d.ts.map +1 -1
- package/dist/lexer/lexer.js +260 -0
- package/dist/lexer/lexer.js.map +1 -0
- package/dist/lexer/tokens.d.ts +31 -6
- package/dist/lexer/tokens.d.ts.map +1 -1
- package/dist/lexer/tokens.js +42 -0
- package/dist/lexer/tokens.js.map +1 -0
- package/dist/parser/ast.d.ts +314 -160
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js +52 -0
- package/dist/parser/ast.js.map +1 -0
- package/dist/parser/guards.d.ts +106 -0
- package/dist/parser/guards.d.ts.map +1 -0
- package/dist/parser/guards.js +121 -0
- package/dist/parser/guards.js.map +1 -0
- package/dist/parser/parser.d.ts +118 -14
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +751 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/rng/mock.d.ts +73 -12
- package/dist/rng/mock.d.ts.map +1 -1
- package/dist/rng/mock.js +30 -0
- package/dist/rng/mock.js.map +1 -0
- package/dist/rng/seeded.d.ts +141 -9
- package/dist/rng/seeded.d.ts.map +1 -1
- package/dist/rng/seeded.js +138 -0
- package/dist/rng/seeded.js.map +1 -0
- package/dist/rng/types.d.ts +57 -0
- package/dist/rng/types.d.ts.map +1 -1
- package/dist/rng/types.js +2 -0
- package/dist/rng/types.js.map +1 -0
- package/dist/roll.d.ts +58 -28
- package/dist/roll.d.ts.map +1 -1
- package/dist/roll.js +8 -0
- package/dist/roll.js.map +1 -0
- package/dist/testing.d.ts +5 -4
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +2 -41
- package/dist/testing.js.map +1 -11
- package/dist/types.d.ts +306 -44
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +83 -34
- package/src/cli/args.ts +66 -10
- package/src/cli/format.ts +22 -3
- package/src/cli/index.ts +27 -84
- package/src/cli/main.ts +129 -0
- package/src/errors.ts +480 -27
- package/src/evaluator/die.ts +50 -0
- package/src/evaluator/env.ts +73 -0
- package/src/evaluator/evaluator.ts +653 -421
- package/src/evaluator/modifiers/crit-threshold.ts +3 -6
- package/src/evaluator/modifiers/die-bound.ts +39 -0
- package/src/evaluator/modifiers/explode.ts +60 -58
- package/src/evaluator/modifiers/flags.ts +61 -0
- package/src/evaluator/modifiers/keep-drop.ts +124 -126
- package/src/evaluator/modifiers/reroll.ts +28 -49
- package/src/evaluator/modifiers/sort.ts +14 -1
- package/src/evaluator/modifiers/success-count.ts +5 -8
- package/src/index.ts +56 -35
- package/src/lexer/lexer.ts +107 -34
- package/src/lexer/tokens.ts +31 -6
- package/src/parser/ast.ts +323 -341
- package/src/parser/guards.ts +248 -0
- package/src/parser/parser.ts +419 -242
- package/src/rng/mock.ts +74 -13
- package/src/rng/seeded.ts +299 -64
- package/src/rng/types.ts +57 -0
- package/src/roll.ts +64 -47
- package/src/testing.ts +5 -9
- package/src/types.ts +310 -43
- package/src/version.ts +2 -0
- package/dist/cli.js +0 -2608
- package/dist/cli.js.map +0 -28
- package/dist/evaluator/index.d.ts +0 -8
- package/dist/evaluator/index.d.ts.map +0 -1
- package/dist/rng/index.d.ts +0 -8
- package/dist/rng/index.d.ts.map +0 -1
- package/src/evaluator/index.ts +0 -14
- package/src/rng/index.ts +0 -8
package/dist/parser/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function isLiteral(node) {
|
|
2
|
+
return node.type === 'Literal';
|
|
3
|
+
}
|
|
4
|
+
export function isDice(node) {
|
|
5
|
+
return node.type === 'Dice';
|
|
6
|
+
}
|
|
7
|
+
export function isFateDice(node) {
|
|
8
|
+
return node.type === 'FateDice';
|
|
9
|
+
}
|
|
10
|
+
export function isBinaryOp(node) {
|
|
11
|
+
return node.type === 'BinaryOp';
|
|
12
|
+
}
|
|
13
|
+
export function isUnaryOp(node) {
|
|
14
|
+
return node.type === 'UnaryOp';
|
|
15
|
+
}
|
|
16
|
+
export function isKeepDrop(node) {
|
|
17
|
+
return node.type === 'KeepDrop';
|
|
18
|
+
}
|
|
19
|
+
export function isExplode(node) {
|
|
20
|
+
return node.type === 'Explode';
|
|
21
|
+
}
|
|
22
|
+
export function isReroll(node) {
|
|
23
|
+
return node.type === 'Reroll';
|
|
24
|
+
}
|
|
25
|
+
export function isSuccessCount(node) {
|
|
26
|
+
return node.type === 'SuccessCount';
|
|
27
|
+
}
|
|
28
|
+
export function isVersus(node) {
|
|
29
|
+
return node.type === 'Versus';
|
|
30
|
+
}
|
|
31
|
+
export function isFunctionCall(node) {
|
|
32
|
+
return node.type === 'FunctionCall';
|
|
33
|
+
}
|
|
34
|
+
export function isGrouped(node) {
|
|
35
|
+
return node.type === 'Grouped';
|
|
36
|
+
}
|
|
37
|
+
export function isVariable(node) {
|
|
38
|
+
return node.type === 'Variable';
|
|
39
|
+
}
|
|
40
|
+
export function isGroup(node) {
|
|
41
|
+
return node.type === 'Group';
|
|
42
|
+
}
|
|
43
|
+
export function isSort(node) {
|
|
44
|
+
return node.type === 'Sort';
|
|
45
|
+
}
|
|
46
|
+
export function isCritThreshold(node) {
|
|
47
|
+
return node.type === 'CritThreshold';
|
|
48
|
+
}
|
|
49
|
+
export function isDieBound(node) {
|
|
50
|
+
return node.type === 'DieBound';
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AA+ZA,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;AACtC,CAAC;AAUD,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;AACtC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,OAAO,CAAC,IAAa;IACnC,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;AAC/B,CAAC;AAUD,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAUD,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,OAAO,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AACvC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser-internal AST guards.
|
|
3
|
+
*
|
|
4
|
+
* These helpers answer structural questions the parser's reject rules ask
|
|
5
|
+
* ("does this operand resolve to a dice pool?", "is a Versus buried in
|
|
6
|
+
* here?"). They are implementation detail of `parser.ts` — the public
|
|
7
|
+
* `isXxx` type guards stay in `ast.ts`.
|
|
8
|
+
*
|
|
9
|
+
* @module parser/guards
|
|
10
|
+
*/
|
|
11
|
+
import type { ASTNode } from './ast.js';
|
|
12
|
+
/**
|
|
13
|
+
* Peels nested `Grouped` wrappers, returning the first descendant that is not
|
|
14
|
+
* one. The narrow unwrap for reject helpers whose forbidden node cannot live
|
|
15
|
+
* inside `KeepDrop`/`Sort`/`CritThreshold` — those parsers already reject it
|
|
16
|
+
* upstream, so peeling parentheses is all that is left to see through.
|
|
17
|
+
*/
|
|
18
|
+
export declare function unwrapGrouped(node: ASTNode): ASTNode;
|
|
19
|
+
/**
|
|
20
|
+
* Peels every transparent wrapper — `Grouped`, `KeepDrop`, `Sort`,
|
|
21
|
+
* `CritThreshold`, `DieBound` — returning the first descendant that is none of
|
|
22
|
+
* them.
|
|
23
|
+
*
|
|
24
|
+
* "Transparent" is relative to the question being asked. These wrappers
|
|
25
|
+
* preserve `containsDicePool`'s answer for whatever they wrap, so they are
|
|
26
|
+
* transparent for "what is the underlying operand?" when deciding whether to
|
|
27
|
+
* reject a `Group` target (e.g., `Group` cannot be the target of `cs`/`cf`,
|
|
28
|
+
* even when wrapped in `KeepDrop` like `{1d6}kh1cs>5`). They are NOT
|
|
29
|
+
* transparent for "is this a `SuccessCount`?" or "is this a `Versus`?" —
|
|
30
|
+
* those questions use `unwrapGrouped`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function unwrapAllTransparent(node: ASTNode): ASTNode;
|
|
33
|
+
/**
|
|
34
|
+
* Returns `true` only when `node`'s direct result is a dice pool —
|
|
35
|
+
* `Dice`, `FateDice`, or a chained pool modifier (`KeepDrop` / `Explode` /
|
|
36
|
+
* `Reroll`). Does NOT recurse through arithmetic wrappers (`BinaryOp`,
|
|
37
|
+
* `UnaryOp`, `FunctionCall`), so `(1d6+5)` and `floor(1d6/2)` are rejected.
|
|
38
|
+
*
|
|
39
|
+
* Used by the parser to reject postfix pool-modifier targets (kh/kl/dh/dl,
|
|
40
|
+
* !/!!/!p, r/ro) that wrap a non-pool expression. Operating on the inner
|
|
41
|
+
* dice pool would silently drop the surrounding arithmetic.
|
|
42
|
+
*/
|
|
43
|
+
export declare function containsDicePool(node: ASTNode): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Deeper variant of `containsDicePool` that recurses through arithmetic and
|
|
46
|
+
* function wrappers. Used from the `Group` case above (ordinary parenthesized
|
|
47
|
+
* arithmetic `(1d6+5)kh1` must still reject, so the shallow `containsDicePool`
|
|
48
|
+
* handles those directly) and from the Sort parser guard (sort accepts
|
|
49
|
+
* `(1d6+2d8)s` per Stage 3 spec).
|
|
50
|
+
*
|
|
51
|
+
* A multi-sub-roll `Group` counts as a pool in its own right (compound dice),
|
|
52
|
+
* matching `containsDicePool`'s Group rule.
|
|
53
|
+
*/
|
|
54
|
+
export declare function deepContainsDicePool(node: ASTNode): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Returns `true` if the pool this node resolves to is (or wraps) a `FateDice`
|
|
57
|
+
* pool. Walks through chained pool modifiers (`KeepDrop` / `Explode` /
|
|
58
|
+
* `Reroll`) but not arithmetic wrappers — callers should run
|
|
59
|
+
* `containsDicePool` first to reject those.
|
|
60
|
+
*
|
|
61
|
+
* Used by the parser to reject `!`, `!!`, `!p` applied to Fate pools
|
|
62
|
+
* (`4dF!`, `(4dF)kh2!`, etc.). Fate explosion semantics are undefined, so
|
|
63
|
+
* parse-time rejection is preferred over a silent evaluator no-op.
|
|
64
|
+
*
|
|
65
|
+
* Inside a `Group`, recursion uses `deepContainsFatePool` to mirror
|
|
66
|
+
* `containsDicePool`'s deep walk through the same case — otherwise
|
|
67
|
+
* `{4dF+1d6}cf` slips past the bare-Fate guard and the default fumble
|
|
68
|
+
* check (`result === 1`) flips `+1` faces into fumbles.
|
|
69
|
+
*/
|
|
70
|
+
export declare function containsFatePool(node: ASTNode): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Deeper variant of `containsFatePool` that recurses through arithmetic and
|
|
73
|
+
* function wrappers. Mirrors `deepContainsDicePool`. Used from
|
|
74
|
+
* `containsFatePool`'s `Group` case so single-sub-roll groups containing
|
|
75
|
+
* arithmetic-wrapped Fate (`{4dF+1d6}cf`) still trip the bare-Fate guard.
|
|
76
|
+
*
|
|
77
|
+
* Outside a `Group`, ordinary parenthesized arithmetic (`(4dF+1d6)cf`) is
|
|
78
|
+
* already rejected upstream by shallow `containsDicePool`, so this helper
|
|
79
|
+
* intentionally stays Group-internal.
|
|
80
|
+
*/
|
|
81
|
+
export declare function deepContainsFatePool(node: ASTNode): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Deep-walks a node to find any descendant `Group` with two or more
|
|
84
|
+
* sub-expressions. Used by `rejectGroupTarget`'s single-sub-roll
|
|
85
|
+
* passthrough so a multi-sub Group buried under arithmetic
|
|
86
|
+
* (`{{1d6,2d8}+0}cs>5`), function calls (`{abs({1d6,2d8})}cs>5`), or any
|
|
87
|
+
* other non-transparent wrapper still rejects with the same error code.
|
|
88
|
+
*
|
|
89
|
+
* Without this walk, the unwrap inside `rejectGroupTarget` only peels
|
|
90
|
+
* `Grouped`/`KeepDrop`/`Sort`/`CritThreshold` — a multi-sub Group cloaked
|
|
91
|
+
* in a `BinaryOp`/`UnaryOp`/`FunctionCall` reaches the evaluator, where it
|
|
92
|
+
* flags crits on dice belonging to dropped sub-rolls.
|
|
93
|
+
*/
|
|
94
|
+
export declare function containsMultiSubGroup(node: ASTNode): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Deep-walks a node to find any descendant `Versus`. A buried Versus
|
|
97
|
+
* (`floor(1d20 vs 15)`, `(1d20 vs 15)+0`, `{1+(1d20 vs 15)}`) must reject with
|
|
98
|
+
* `NESTED_VERSUS` rather than silently drop `versusMetadata` at the consumer.
|
|
99
|
+
*
|
|
100
|
+
* Two callers, both on that hole: `rejectVersusMetaOperand` guards every meta
|
|
101
|
+
* operand — dice count and sides, keep/drop count, thresholds, die bounds — and
|
|
102
|
+
* `rejectVersusTarget` uses it for its single-sub-roll Group passthrough.
|
|
103
|
+
* `evalMetaOperand` runs the same walk as the hand-built-AST backstop.
|
|
104
|
+
*/
|
|
105
|
+
export declare function containsVersus(node: ASTNode): boolean;
|
|
106
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/parser/guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAMpD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAiB3D;AA8DD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAyBvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAkBvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAErD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export function unwrapGrouped(node) {
|
|
2
|
+
let current = node;
|
|
3
|
+
while (current.type === 'Grouped') {
|
|
4
|
+
current = current.expression;
|
|
5
|
+
}
|
|
6
|
+
return current;
|
|
7
|
+
}
|
|
8
|
+
export function unwrapAllTransparent(node) {
|
|
9
|
+
let current = node;
|
|
10
|
+
while (true) {
|
|
11
|
+
switch (current.type) {
|
|
12
|
+
case 'Grouped':
|
|
13
|
+
current = current.expression;
|
|
14
|
+
break;
|
|
15
|
+
case 'KeepDrop':
|
|
16
|
+
case 'Sort':
|
|
17
|
+
case 'CritThreshold':
|
|
18
|
+
case 'DieBound':
|
|
19
|
+
current = current.target;
|
|
20
|
+
break;
|
|
21
|
+
default:
|
|
22
|
+
return current;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function someDescendant(node, isHit) {
|
|
27
|
+
if (isHit(node))
|
|
28
|
+
return true;
|
|
29
|
+
switch (node.type) {
|
|
30
|
+
case 'BinaryOp':
|
|
31
|
+
return someDescendant(node.left, isHit) || someDescendant(node.right, isHit);
|
|
32
|
+
case 'UnaryOp':
|
|
33
|
+
return someDescendant(node.operand, isHit);
|
|
34
|
+
case 'KeepDrop':
|
|
35
|
+
case 'Explode':
|
|
36
|
+
case 'Reroll':
|
|
37
|
+
case 'DieBound':
|
|
38
|
+
case 'SuccessCount':
|
|
39
|
+
case 'Sort':
|
|
40
|
+
case 'CritThreshold':
|
|
41
|
+
return someDescendant(node.target, isHit);
|
|
42
|
+
case 'Versus':
|
|
43
|
+
return someDescendant(node.roll, isHit) || someDescendant(node.dc, isHit);
|
|
44
|
+
case 'FunctionCall': {
|
|
45
|
+
for (const arg of node.args) {
|
|
46
|
+
if (someDescendant(arg, isHit))
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
case 'Grouped':
|
|
52
|
+
return someDescendant(node.expression, isHit);
|
|
53
|
+
case 'Group': {
|
|
54
|
+
for (const expression of node.expressions) {
|
|
55
|
+
if (someDescendant(expression, isHit))
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
default:
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const isDicePoolHit = (current) => current.type === 'Dice' ||
|
|
65
|
+
current.type === 'FateDice' ||
|
|
66
|
+
(current.type === 'Group' && current.expressions.length >= 2);
|
|
67
|
+
const isFateDiceHit = (current) => current.type === 'FateDice';
|
|
68
|
+
const isMultiSubGroupHit = (current) => current.type === 'Group' && current.expressions.length >= 2;
|
|
69
|
+
const isVersusHit = (current) => current.type === 'Versus';
|
|
70
|
+
export function containsDicePool(node) {
|
|
71
|
+
switch (node.type) {
|
|
72
|
+
case 'Dice':
|
|
73
|
+
case 'FateDice':
|
|
74
|
+
case 'KeepDrop':
|
|
75
|
+
case 'Explode':
|
|
76
|
+
case 'Reroll':
|
|
77
|
+
case 'DieBound':
|
|
78
|
+
return true;
|
|
79
|
+
case 'Sort':
|
|
80
|
+
case 'CritThreshold':
|
|
81
|
+
return containsDicePool(node.target);
|
|
82
|
+
case 'Grouped':
|
|
83
|
+
return containsDicePool(node.expression);
|
|
84
|
+
case 'Group':
|
|
85
|
+
return node.expressions.length >= 2 || node.expressions.some(deepContainsDicePool);
|
|
86
|
+
default:
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function deepContainsDicePool(node) {
|
|
91
|
+
return someDescendant(node, isDicePoolHit);
|
|
92
|
+
}
|
|
93
|
+
export function containsFatePool(node) {
|
|
94
|
+
switch (node.type) {
|
|
95
|
+
case 'FateDice':
|
|
96
|
+
return true;
|
|
97
|
+
case 'KeepDrop':
|
|
98
|
+
case 'Explode':
|
|
99
|
+
case 'Reroll':
|
|
100
|
+
case 'DieBound':
|
|
101
|
+
case 'Sort':
|
|
102
|
+
case 'CritThreshold':
|
|
103
|
+
return containsFatePool(node.target);
|
|
104
|
+
case 'Grouped':
|
|
105
|
+
return containsFatePool(node.expression);
|
|
106
|
+
case 'Group':
|
|
107
|
+
return node.expressions.some(deepContainsFatePool);
|
|
108
|
+
default:
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function deepContainsFatePool(node) {
|
|
113
|
+
return someDescendant(node, isFateDiceHit);
|
|
114
|
+
}
|
|
115
|
+
export function containsMultiSubGroup(node) {
|
|
116
|
+
return someDescendant(node, isMultiSubGroupHit);
|
|
117
|
+
}
|
|
118
|
+
export function containsVersus(node) {
|
|
119
|
+
return someDescendant(node, isVersusHit);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/parser/guards.ts"],"names":[],"mappings":"AAmBA,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAeD,MAAM,UAAU,oBAAoB,CAAC,IAAa;IAChD,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,OAAO,IAAI,EAAE,CAAC;QACZ,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,SAAS;gBACZ,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;gBAC7B,MAAM;YACR,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC;YACrB,KAAK,UAAU;gBACb,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;gBACzB,MAAM;YACR;gBACE,OAAO,OAAO,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC;AAWD,SAAS,cAAc,CAAC,IAAa,EAAE,KAAiC;IACtE,IAAI,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/E,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,KAAK,UAAU,CAAC;QAChB,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU,CAAC;QAChB,KAAK,cAAc,CAAC;QACpB,KAAK,MAAM,CAAC;QACZ,KAAK,eAAe;YAClB,OAAO,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5C,KAAK,QAAQ;YACX,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5E,KAAK,cAAc,EAAE,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAC;YAC9C,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChD,KAAK,OAAO,EAAE,CAAC;YACb,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC1C,IAAI,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAC;YACrD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAID,MAAM,aAAa,GAAG,CAAC,OAAgB,EAAW,EAAE,CAClD,OAAO,CAAC,IAAI,KAAK,MAAM;IACvB,OAAO,CAAC,IAAI,KAAK,UAAU;IAC3B,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;AAEhE,MAAM,aAAa,GAAG,CAAC,OAAgB,EAAW,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC;AAEjF,MAAM,kBAAkB,GAAG,CAAC,OAAgB,EAAW,EAAE,CACvD,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC;AAE9D,MAAM,WAAW,GAAG,CAAC,OAAgB,EAAW,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;AAY7E,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC;QACZ,KAAK,UAAU,CAAC;QAChB,KAAK,UAAU,CAAC;QAChB,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU;YACb,OAAO,IAAI,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,eAAe;YAClB,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,KAAK,OAAO;YAOV,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACrF;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAYD,MAAM,UAAU,oBAAoB,CAAC,IAAa;IAChD,OAAO,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAiBD,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,IAAI,CAAC;QACd,KAAK,UAAU,CAAC;QAChB,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU,CAAC;QAChB,KAAK,MAAM,CAAC;QACZ,KAAK,eAAe;YAClB,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACrD;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAYD,MAAM,UAAU,oBAAoB,CAAC,IAAa;IAChD,OAAO,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAcD,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,OAAO,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAYD,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/parser/parser.d.ts
CHANGED
|
@@ -6,16 +6,67 @@
|
|
|
6
6
|
import type { RollParserErrorCode } from '../errors.js';
|
|
7
7
|
import { RollParserError } from '../errors.js';
|
|
8
8
|
import { type Token } from '../lexer/tokens.js';
|
|
9
|
-
import type { ComparePoint } from '../types.js';
|
|
10
9
|
import type { ASTNode } from './ast.js';
|
|
11
10
|
/**
|
|
12
11
|
* Error thrown when the parser encounters invalid syntax.
|
|
12
|
+
*
|
|
13
|
+
* `position` is a zero-based UTF-16 offset into the notation. It is
|
|
14
|
+
* deliberately absent from `message` — read it from the field, or uniformly
|
|
15
|
+
* across all roll-parser errors via `getErrorSpan`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { ParseError, roll, TokenType } from 'roll-parser';
|
|
20
|
+
*
|
|
21
|
+
* try {
|
|
22
|
+
* roll('4d6d1');
|
|
23
|
+
* } catch (error) {
|
|
24
|
+
* const typed = error as ParseError;
|
|
25
|
+
* typed.code; // 'AMBIGUOUS_DICE_CHAIN'
|
|
26
|
+
* typed.position; // 3
|
|
27
|
+
* typed.token?.type === TokenType.DICE; // true
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @category Errors
|
|
13
32
|
*/
|
|
14
33
|
export declare class ParseError extends RollParserError {
|
|
34
|
+
/** Zero-based UTF-16 offset in the notation where parsing failed. */
|
|
15
35
|
readonly position: number;
|
|
36
|
+
/**
|
|
37
|
+
* The token the parser was looking at. `undefined` when the failure is not
|
|
38
|
+
* anchored to a token — currently only `UNEXPECTED_END`, raised when the
|
|
39
|
+
* input stops short.
|
|
40
|
+
*/
|
|
16
41
|
readonly token: Token | undefined;
|
|
17
|
-
constructor(message: string, code: RollParserErrorCode, position: number, token?: Token);
|
|
42
|
+
constructor(message: string, code: RollParserErrorCode, position: number, token?: Token, options?: ErrorOptions);
|
|
18
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Maximum expression nesting depth. Far beyond any human-authored notation —
|
|
46
|
+
* exists so adversarial input like 20,000 nested parens throws a typed
|
|
47
|
+
* `ParseError` instead of an uncaught `RangeError` stack overflow (which
|
|
48
|
+
* would also break the `isRollParserError` contract). Bounding parse depth
|
|
49
|
+
* also bounds AST depth, protecting the recursive AST walkers and evaluator.
|
|
50
|
+
*
|
|
51
|
+
* Not configurable — unlike the {@link EvaluationOptions} caps, this one always
|
|
52
|
+
* applies, so untrusted notation can never blow the stack.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* import { isRollParserError, MAX_PARSE_DEPTH, parse } from 'roll-parser';
|
|
57
|
+
*
|
|
58
|
+
* MAX_PARSE_DEPTH; // 128
|
|
59
|
+
*
|
|
60
|
+
* try {
|
|
61
|
+
* parse('('.repeat(20_000) + '1d6' + ')'.repeat(20_000));
|
|
62
|
+
* } catch (error) {
|
|
63
|
+
* isRollParserError(error) && error.code; // 'MAX_DEPTH_EXCEEDED'
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @category Limits
|
|
68
|
+
*/
|
|
69
|
+
export declare const MAX_PARSE_DEPTH = 128;
|
|
19
70
|
/**
|
|
20
71
|
* Pratt parser for dice notation.
|
|
21
72
|
*
|
|
@@ -35,6 +86,11 @@ export declare class Parser {
|
|
|
35
86
|
* Parse an expression with minimum binding power.
|
|
36
87
|
*/
|
|
37
88
|
private parseExpression;
|
|
89
|
+
/**
|
|
90
|
+
* Throw once the AST under construction is deeper than the recursive walkers
|
|
91
|
+
* can safely descend.
|
|
92
|
+
*/
|
|
93
|
+
private guardDepth;
|
|
38
94
|
/**
|
|
39
95
|
* NUD - Null Denotation.
|
|
40
96
|
* Handles tokens that appear at the start of an expression (prefix position).
|
|
@@ -77,30 +133,49 @@ export declare class Parser {
|
|
|
77
133
|
* Rejects `GroupNode` (or a wrapper-cloaked group) as the target of `token`.
|
|
78
134
|
* Explode, reroll, and crit-threshold wrap bare dice pools only — a group
|
|
79
135
|
* is a container of sub-expressions, so these modifiers have no defined
|
|
80
|
-
* semantics. Walks `Grouped`/`
|
|
136
|
+
* semantics. Walks `Grouped`/`KeepDrop`/`Sort`/`CritThreshold` so wrappers
|
|
81
137
|
* cannot smuggle a group past the check (`{1d6}kh1cs>5`, `({1d6})!`,
|
|
82
138
|
* `{1d6}scs>5` all reject the same as `{1d6}!`/`{1d6}cs>5`).
|
|
83
139
|
*
|
|
84
|
-
* `singleSubRollPasses` opts the caller into the
|
|
85
|
-
* passthrough rule (STAGE3.md "Group Semantics: Single vs Multi Sub-Roll"):
|
|
140
|
+
* `singleSubRollPasses` opts the caller into the single-sub-roll passthrough:
|
|
86
141
|
* a `Group` with one expression is the user's explicit flat-pool escape
|
|
87
142
|
* hatch and is equivalent to its unwrapped form. Currently only
|
|
88
143
|
* `parseCritThreshold` opts in — explode/reroll keep the strict reject so
|
|
89
144
|
* existing notation contracts don't shift.
|
|
90
145
|
*/
|
|
91
146
|
private rejectGroupTarget;
|
|
147
|
+
/**
|
|
148
|
+
* Rejects a Versus anywhere inside a meta operand — a dice count, dice sides,
|
|
149
|
+
* a modifier count, or a threshold/bound value.
|
|
150
|
+
*
|
|
151
|
+
* Deep, unlike {@link rejectVersusTarget}: `evalMetaOperand` reduces the
|
|
152
|
+
* operand to a scalar and forwards rolls but not `versusMetadata`, so
|
|
153
|
+
* `floor(1d20 vs 15)` or `(1d20 vs 15)+0` buried in a count loses the degree
|
|
154
|
+
* exactly as a bare one does.
|
|
155
|
+
*/
|
|
156
|
+
private rejectVersusMetaOperand;
|
|
157
|
+
/**
|
|
158
|
+
* The wording the meta-expression rejections share. Not every `NESTED_VERSUS`
|
|
159
|
+
* throw — `parseVersus` says "Cannot chain versus operators" for `a vs b vs c`,
|
|
160
|
+
* a different condition. Routing that one through here would silently rewrite
|
|
161
|
+
* its message, and `expectRollError` asserts only the code.
|
|
162
|
+
*/
|
|
163
|
+
private static throwVersusMetaExpression;
|
|
92
164
|
private rejectVersusTarget;
|
|
93
|
-
private
|
|
165
|
+
private parseKeepDrop;
|
|
94
166
|
private parseExplode;
|
|
95
167
|
private parseReroll;
|
|
168
|
+
private parseDieBound;
|
|
96
169
|
private parseSort;
|
|
97
170
|
private parseCritThreshold;
|
|
98
171
|
private parseSuccessCount;
|
|
172
|
+
/** Parses the `f...` suffix of a success count. Bare `fN` means `f=N`. */
|
|
173
|
+
private parseFailThreshold;
|
|
99
174
|
private parseVersus;
|
|
100
175
|
/**
|
|
101
176
|
* Checks whether the next token is a comparison operator.
|
|
102
177
|
*/
|
|
103
|
-
isComparePointAhead
|
|
178
|
+
private isComparePointAhead;
|
|
104
179
|
/**
|
|
105
180
|
* Parses a comparison operator followed by a value expression.
|
|
106
181
|
* Called by modifier parsers (explode, reroll, success counting).
|
|
@@ -115,7 +190,7 @@ export declare class Parser {
|
|
|
115
190
|
* @returns A ComparePoint with the operator and value AST node
|
|
116
191
|
* @throws {ParseError} If the next token is not a comparison operator
|
|
117
192
|
*/
|
|
118
|
-
parseComparePoint
|
|
193
|
+
private parseComparePoint;
|
|
119
194
|
private getCompareOp;
|
|
120
195
|
private getOperatorSymbol;
|
|
121
196
|
private getLeftBp;
|
|
@@ -126,20 +201,49 @@ export declare class Parser {
|
|
|
126
201
|
private hasTokens;
|
|
127
202
|
}
|
|
128
203
|
/**
|
|
129
|
-
*
|
|
204
|
+
* Parses a dice notation string into an {@link ASTNode} tree, lexing it first.
|
|
205
|
+
*
|
|
206
|
+
* {@link evaluate} never mutates the AST, so parse once and evaluate many times
|
|
207
|
+
* when rolling the same notation repeatedly — that skips the lexer and parser
|
|
208
|
+
* on every roll after the first. Use `parse` alone to validate notation
|
|
209
|
+
* without consuming randomness.
|
|
130
210
|
*
|
|
131
211
|
* @param notation - The dice notation to parse
|
|
132
|
-
* @returns The root AST node
|
|
212
|
+
* @returns The root AST node, with `start`/`end` spans on every node
|
|
133
213
|
* @throws {LexerError} If the input contains invalid characters
|
|
134
214
|
* @throws {ParseError} If the input has invalid syntax
|
|
215
|
+
* @throws {RollParserError} `INVALID_NOTATION_TYPE` when `notation` is not a
|
|
216
|
+
* string — raised before lexing, so it carries no position
|
|
135
217
|
*
|
|
136
218
|
* @example
|
|
137
219
|
* ```typescript
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* //
|
|
220
|
+
* import { parse } from 'roll-parser';
|
|
221
|
+
*
|
|
222
|
+
* parse('2d6+3');
|
|
223
|
+
* // {
|
|
224
|
+
* // type: 'BinaryOp', operator: '+', start: 0, end: 5,
|
|
225
|
+
* // left: {
|
|
226
|
+
* // type: 'Dice', start: 0, end: 3,
|
|
227
|
+
* // count: { type: 'Literal', value: 2, start: 0, end: 1 },
|
|
228
|
+
* // sides: { type: 'Literal', value: 6, start: 2, end: 3 },
|
|
229
|
+
* // },
|
|
230
|
+
* // right: { type: 'Literal', value: 3, start: 4, end: 5 },
|
|
231
|
+
* // }
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* `count` and `sides` are full nodes, not numbers — that is what makes
|
|
235
|
+
* computed dice like `(1d4)d6` expressible.
|
|
236
|
+
*
|
|
237
|
+
* @example Parse once, roll many
|
|
238
|
+
* ```typescript
|
|
239
|
+
* import { evaluate, parse, SeededRNG } from 'roll-parser';
|
|
240
|
+
*
|
|
241
|
+
* const ast = parse('4d6kh3');
|
|
242
|
+
* const rng = new SeededRNG('demo');
|
|
243
|
+
* const scores = Array.from({ length: 6 }, () => evaluate(ast, rng).total);
|
|
142
244
|
* ```
|
|
245
|
+
*
|
|
246
|
+
* @category Core
|
|
143
247
|
*/
|
|
144
248
|
export declare function parse(notation: string): ASTNode;
|
|
145
249
|
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EACV,OAAO,EAmBR,MAAM,UAAU,CAAC;AAYlB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IAElC,YACE,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,YAAY,EAMvB;CACF;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AAgDnC;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;IAElB,YAAY,MAAM,EAAE,KAAK,EAAE,EAE1B;IAED;;OAEG;IACH,KAAK,IAAI,OAAO,CAkBf;IAED;;OAEG;IACH,OAAO,CAAC,eAAe;IA6BvB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAWlB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IA4ChB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAuEhB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAmDzB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,wBAAwB;IAehC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;IASxC,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,aAAa;IAiDrB,OAAO,CAAC,YAAY;IA4DpB,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,aAAa;IA4DrB,OAAO,CAAC,SAAS;IA4CjB,OAAO,CAAC,kBAAkB;IA+E1B,OAAO,CAAC,iBAAiB;IAyCzB,0EAA0E;IAC1E,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,WAAW;IA+BnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,SAAS;IAyDjB,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,SAAS;CAGlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/C"}
|