roll-parser 2.3.2 → 3.0.0-alpha.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/README.md +47 -178
- package/dist/cli/args.d.ts +35 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/format.d.ts +20 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli.js +1775 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/evaluator/evaluator.d.ts +65 -0
- package/dist/evaluator/evaluator.d.ts.map +1 -0
- package/dist/evaluator/index.d.ts +8 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/modifiers/compare.d.ts +15 -0
- package/dist/evaluator/modifiers/compare.d.ts.map +1 -0
- package/dist/evaluator/modifiers/explode.d.ts +44 -0
- package/dist/evaluator/modifiers/explode.d.ts.map +1 -0
- package/dist/evaluator/modifiers/keep-drop.d.ts +44 -0
- package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -0
- package/dist/evaluator/modifiers/reroll.d.ts +33 -0
- package/dist/evaluator/modifiers/reroll.d.ts.map +1 -0
- package/dist/evaluator/modifiers/success-count.d.ts +28 -0
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1723 -0
- package/dist/index.mjs +1724 -0
- package/dist/lexer/lexer.d.ts +75 -0
- package/dist/lexer/lexer.d.ts.map +1 -0
- package/dist/lexer/tokens.d.ts +87 -0
- package/dist/lexer/tokens.d.ts.map +1 -0
- package/dist/parser/ast.d.ts +183 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/parser.d.ts +102 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/rng/index.d.ts +8 -0
- package/dist/rng/index.d.ts.map +1 -0
- package/dist/rng/mock.d.ts +36 -0
- package/dist/rng/mock.d.ts.map +1 -0
- package/dist/rng/seeded.d.ts +33 -0
- package/dist/rng/seeded.d.ts.map +1 -0
- package/dist/rng/types.d.ts +24 -0
- package/dist/rng/types.d.ts.map +1 -0
- package/dist/roll.d.ts +47 -0
- package/dist/roll.d.ts.map +1 -0
- package/dist/testing.d.ts +11 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +38 -0
- package/dist/testing.mjs +39 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +62 -43
- package/src/cli/args.ts +72 -0
- package/src/cli/format.ts +45 -0
- package/src/cli/index.ts +75 -0
- package/src/errors.ts +78 -0
- package/src/evaluator/evaluator.ts +837 -0
- package/src/evaluator/index.ts +14 -0
- package/src/evaluator/modifiers/compare.ts +29 -0
- package/src/evaluator/modifiers/explode.ts +215 -0
- package/src/evaluator/modifiers/keep-drop.ts +151 -0
- package/src/evaluator/modifiers/reroll.ts +172 -0
- package/src/evaluator/modifiers/success-count.ts +59 -0
- package/src/index.ts +72 -0
- package/src/lexer/lexer.ts +281 -0
- package/src/lexer/tokens.ts +147 -0
- package/src/parser/ast.ts +261 -0
- package/src/parser/parser.ts +716 -0
- package/src/rng/index.ts +8 -0
- package/src/rng/mock.ts +65 -0
- package/src/rng/seeded.ts +127 -0
- package/src/rng/types.ts +25 -0
- package/src/roll.ts +66 -0
- package/src/testing.ts +16 -0
- package/src/types.ts +112 -0
- package/bin/help.txt +0 -19
- package/bin/roll-parser.js +0 -23
- package/dist/roll-parser.js +0 -697
- package/dist/roll-parser.min.js +0 -1
- package/index.js +0 -24
- package/src/complex/parse.js +0 -37
- package/src/complex/parseAndRoll.js +0 -21
- package/src/complex/parseAndRollClassic.js +0 -20
- package/src/complex/parseAndRollSimple.js +0 -19
- package/src/complex/parseAndRollWod.js +0 -20
- package/src/complex/parseClassicRoll.js +0 -22
- package/src/complex/parseSimpleRoll.js +0 -21
- package/src/complex/parseWodRoll.js +0 -21
- package/src/converter.js +0 -45
- package/src/grammar.js +0 -14
- package/src/mapper.js +0 -50
- package/src/normalizer.js +0 -51
- package/src/object/Result.js +0 -23
- package/src/object/Roll.js +0 -26
- package/src/object/Type.js +0 -5
- package/src/object/WodRoll.js +0 -29
- package/src/parser.js +0 -43
- package/src/random.js +0 -22
- package/src/roller.js +0 -106
- package/src/stringifier.js +0 -33
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST node type definitions for the dice notation parser.
|
|
3
|
+
*
|
|
4
|
+
* @module parser/ast
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ComparePoint } from '../types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Numeric literal node.
|
|
11
|
+
*/
|
|
12
|
+
export type LiteralNode = {
|
|
13
|
+
type: 'Literal';
|
|
14
|
+
value: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Dice roll node.
|
|
19
|
+
* Count and sides can be expressions to support computed dice like (1+1)d(3*2).
|
|
20
|
+
*/
|
|
21
|
+
export type DiceNode = {
|
|
22
|
+
type: 'Dice';
|
|
23
|
+
count: ASTNode;
|
|
24
|
+
sides: ASTNode;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fate/Fudge dice node (`dF`).
|
|
29
|
+
* Each die produces a result in {-1, 0, +1}. No configurable sides.
|
|
30
|
+
*/
|
|
31
|
+
export type FateDiceNode = {
|
|
32
|
+
type: 'FateDice';
|
|
33
|
+
count: ASTNode;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Binary operation node.
|
|
38
|
+
*/
|
|
39
|
+
export type BinaryOpNode = {
|
|
40
|
+
type: 'BinaryOp';
|
|
41
|
+
operator: '+' | '-' | '*' | '/' | '%' | '**';
|
|
42
|
+
left: ASTNode;
|
|
43
|
+
right: ASTNode;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Unary operation node.
|
|
48
|
+
*/
|
|
49
|
+
export type UnaryOpNode = {
|
|
50
|
+
type: 'UnaryOp';
|
|
51
|
+
operator: '-';
|
|
52
|
+
operand: ASTNode;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Keep/drop modifier node.
|
|
57
|
+
* Wraps a dice expression with keep highest/lowest or drop highest/lowest.
|
|
58
|
+
*/
|
|
59
|
+
export type ModifierNode = {
|
|
60
|
+
type: 'Modifier';
|
|
61
|
+
modifier: 'keep' | 'drop';
|
|
62
|
+
selector: 'highest' | 'lowest';
|
|
63
|
+
count: ASTNode;
|
|
64
|
+
target: ASTNode;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Exploding dice node (`!`, `!!`, `!p`, `!>Y`).
|
|
69
|
+
* Wraps a dice expression with a standard, compounding, or penetrating
|
|
70
|
+
* explosion. An absent `threshold` means "explode on the die's maximum face".
|
|
71
|
+
*/
|
|
72
|
+
export type ExplodeNode = {
|
|
73
|
+
type: 'Explode';
|
|
74
|
+
variant: 'standard' | 'compound' | 'penetrating';
|
|
75
|
+
threshold?: ComparePoint;
|
|
76
|
+
target: ASTNode;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Reroll node (`r<COND>`, `ro<COND>`).
|
|
81
|
+
* Re-rolls dice that match a comparison condition. `once: true` for `ro`
|
|
82
|
+
* keeps the second result regardless of match; `once: false` for `r`
|
|
83
|
+
* re-rolls recursively until the condition no longer matches.
|
|
84
|
+
*/
|
|
85
|
+
export type RerollNode = {
|
|
86
|
+
type: 'Reroll';
|
|
87
|
+
once: boolean;
|
|
88
|
+
condition: ComparePoint;
|
|
89
|
+
target: ASTNode;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Success counting node (`>=T`, `>T`, `<T`, `<=T`, `=T`, with optional `f=F`).
|
|
94
|
+
*
|
|
95
|
+
* Transforms a dice pool into a success count: each die meeting `threshold`
|
|
96
|
+
* adds +1, each die meeting `failThreshold` subtracts 1. Terminal — no further
|
|
97
|
+
* postfix modifiers may wrap a `SuccessCountNode`. The `failThreshold`
|
|
98
|
+
* operator is always `=` (fail on an exact value).
|
|
99
|
+
*/
|
|
100
|
+
export type SuccessCountNode = {
|
|
101
|
+
type: 'SuccessCount';
|
|
102
|
+
target: ASTNode;
|
|
103
|
+
threshold: ComparePoint;
|
|
104
|
+
failThreshold?: ComparePoint;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Versus node (`<roll> vs <dc>`) — PF2e Degrees of Success.
|
|
109
|
+
*
|
|
110
|
+
* Both sides are full expressions. The `roll` side is evaluated and compared
|
|
111
|
+
* against the `dc` side total, producing a `DegreeOfSuccess` with natural
|
|
112
|
+
* d20 upgrade/downgrade applied when exactly one kept d20 appears on the
|
|
113
|
+
* roll side. Lowest-precedence operator — chaining (`a vs b vs c`) is
|
|
114
|
+
* rejected at parse time; nesting via parens (`a vs (b vs c)`) is rejected
|
|
115
|
+
* at evaluation time.
|
|
116
|
+
*/
|
|
117
|
+
export type VersusNode = {
|
|
118
|
+
type: 'Versus';
|
|
119
|
+
roll: ASTNode;
|
|
120
|
+
dc: ASTNode;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Math function call node (`floor(expr)`, `max(a, b, ...)`, etc.).
|
|
125
|
+
*
|
|
126
|
+
* Supports the fixed-arity functions `floor`, `ceil`, `round`, `abs`, and the
|
|
127
|
+
* variadic functions `max`, `min` (minimum 2 args). Arity is validated at
|
|
128
|
+
* parse time against a static table; by the time the evaluator sees a
|
|
129
|
+
* `FunctionCallNode`, `args.length` is guaranteed to match the function.
|
|
130
|
+
*/
|
|
131
|
+
export type FunctionCallNode = {
|
|
132
|
+
type: 'FunctionCall';
|
|
133
|
+
name: string;
|
|
134
|
+
args: ASTNode[];
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Union type of all AST nodes.
|
|
139
|
+
*/
|
|
140
|
+
export type ASTNode =
|
|
141
|
+
| LiteralNode
|
|
142
|
+
| DiceNode
|
|
143
|
+
| FateDiceNode
|
|
144
|
+
| BinaryOpNode
|
|
145
|
+
| UnaryOpNode
|
|
146
|
+
| ModifierNode
|
|
147
|
+
| ExplodeNode
|
|
148
|
+
| RerollNode
|
|
149
|
+
| SuccessCountNode
|
|
150
|
+
| VersusNode
|
|
151
|
+
| FunctionCallNode;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Type guard for LiteralNode.
|
|
155
|
+
*/
|
|
156
|
+
export function isLiteral(node: ASTNode): node is LiteralNode {
|
|
157
|
+
return node.type === 'Literal';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Type guard for DiceNode.
|
|
162
|
+
*/
|
|
163
|
+
export function isDice(node: ASTNode): node is DiceNode {
|
|
164
|
+
return node.type === 'Dice';
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Type guard for FateDiceNode.
|
|
169
|
+
*/
|
|
170
|
+
export function isFateDice(node: ASTNode): node is FateDiceNode {
|
|
171
|
+
return node.type === 'FateDice';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Type guard for BinaryOpNode.
|
|
176
|
+
*/
|
|
177
|
+
export function isBinaryOp(node: ASTNode): node is BinaryOpNode {
|
|
178
|
+
return node.type === 'BinaryOp';
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Type guard for UnaryOpNode.
|
|
183
|
+
*/
|
|
184
|
+
export function isUnaryOp(node: ASTNode): node is UnaryOpNode {
|
|
185
|
+
return node.type === 'UnaryOp';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Type guard for ModifierNode.
|
|
190
|
+
*/
|
|
191
|
+
export function isModifier(node: ASTNode): node is ModifierNode {
|
|
192
|
+
return node.type === 'Modifier';
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Type guard for ExplodeNode.
|
|
197
|
+
*/
|
|
198
|
+
export function isExplode(node: ASTNode): node is ExplodeNode {
|
|
199
|
+
return node.type === 'Explode';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Type guard for RerollNode.
|
|
204
|
+
*/
|
|
205
|
+
export function isReroll(node: ASTNode): node is RerollNode {
|
|
206
|
+
return node.type === 'Reroll';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Type guard for SuccessCountNode.
|
|
211
|
+
*/
|
|
212
|
+
export function isSuccessCount(node: ASTNode): node is SuccessCountNode {
|
|
213
|
+
return node.type === 'SuccessCount';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Type guard for VersusNode.
|
|
218
|
+
*/
|
|
219
|
+
export function isVersus(node: ASTNode): node is VersusNode {
|
|
220
|
+
return node.type === 'Versus';
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Type guard for FunctionCallNode.
|
|
225
|
+
*/
|
|
226
|
+
export function isFunctionCall(node: ASTNode): node is FunctionCallNode {
|
|
227
|
+
return node.type === 'FunctionCall';
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Returns `true` if the AST contains a `Dice` or `FateDice` node reachable
|
|
232
|
+
* through structural composition (BinaryOp, UnaryOp, keep/drop, explode,
|
|
233
|
+
* reroll, success-count wrappers). Meta-expressions — dice count/sides,
|
|
234
|
+
* modifier counts, and ComparePoint values — are treated as leaves and
|
|
235
|
+
* never recursed into.
|
|
236
|
+
*
|
|
237
|
+
* Used by the parser to reject success-counting targets that don't actually
|
|
238
|
+
* roll any dice (e.g. `1>=3`, `(1+2)>=3`).
|
|
239
|
+
*/
|
|
240
|
+
export function containsDice(node: ASTNode): boolean {
|
|
241
|
+
switch (node.type) {
|
|
242
|
+
case 'Dice':
|
|
243
|
+
case 'FateDice':
|
|
244
|
+
return true;
|
|
245
|
+
case 'Literal':
|
|
246
|
+
return false;
|
|
247
|
+
case 'BinaryOp':
|
|
248
|
+
return containsDice(node.left) || containsDice(node.right);
|
|
249
|
+
case 'UnaryOp':
|
|
250
|
+
return containsDice(node.operand);
|
|
251
|
+
case 'Modifier':
|
|
252
|
+
case 'Explode':
|
|
253
|
+
case 'Reroll':
|
|
254
|
+
case 'SuccessCount':
|
|
255
|
+
return containsDice(node.target);
|
|
256
|
+
case 'Versus':
|
|
257
|
+
return containsDice(node.roll) || containsDice(node.dc);
|
|
258
|
+
case 'FunctionCall':
|
|
259
|
+
return node.args.some(containsDice);
|
|
260
|
+
}
|
|
261
|
+
}
|