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.
Files changed (101) hide show
  1. package/README.md +47 -178
  2. package/dist/cli/args.d.ts +35 -0
  3. package/dist/cli/args.d.ts.map +1 -0
  4. package/dist/cli/format.d.ts +20 -0
  5. package/dist/cli/format.d.ts.map +1 -0
  6. package/dist/cli/index.d.ts +8 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli.js +1775 -0
  9. package/dist/errors.d.ts +39 -0
  10. package/dist/errors.d.ts.map +1 -0
  11. package/dist/evaluator/evaluator.d.ts +65 -0
  12. package/dist/evaluator/evaluator.d.ts.map +1 -0
  13. package/dist/evaluator/index.d.ts +8 -0
  14. package/dist/evaluator/index.d.ts.map +1 -0
  15. package/dist/evaluator/modifiers/compare.d.ts +15 -0
  16. package/dist/evaluator/modifiers/compare.d.ts.map +1 -0
  17. package/dist/evaluator/modifiers/explode.d.ts +44 -0
  18. package/dist/evaluator/modifiers/explode.d.ts.map +1 -0
  19. package/dist/evaluator/modifiers/keep-drop.d.ts +44 -0
  20. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -0
  21. package/dist/evaluator/modifiers/reroll.d.ts +33 -0
  22. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -0
  23. package/dist/evaluator/modifiers/success-count.d.ts +28 -0
  24. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -0
  25. package/dist/index.d.ts +20 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +1723 -0
  28. package/dist/index.mjs +1724 -0
  29. package/dist/lexer/lexer.d.ts +75 -0
  30. package/dist/lexer/lexer.d.ts.map +1 -0
  31. package/dist/lexer/tokens.d.ts +87 -0
  32. package/dist/lexer/tokens.d.ts.map +1 -0
  33. package/dist/parser/ast.d.ts +183 -0
  34. package/dist/parser/ast.d.ts.map +1 -0
  35. package/dist/parser/parser.d.ts +102 -0
  36. package/dist/parser/parser.d.ts.map +1 -0
  37. package/dist/rng/index.d.ts +8 -0
  38. package/dist/rng/index.d.ts.map +1 -0
  39. package/dist/rng/mock.d.ts +36 -0
  40. package/dist/rng/mock.d.ts.map +1 -0
  41. package/dist/rng/seeded.d.ts +33 -0
  42. package/dist/rng/seeded.d.ts.map +1 -0
  43. package/dist/rng/types.d.ts +24 -0
  44. package/dist/rng/types.d.ts.map +1 -0
  45. package/dist/roll.d.ts +47 -0
  46. package/dist/roll.d.ts.map +1 -0
  47. package/dist/testing.d.ts +11 -0
  48. package/dist/testing.d.ts.map +1 -0
  49. package/dist/testing.js +38 -0
  50. package/dist/testing.mjs +39 -0
  51. package/dist/types.d.ts +105 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/package.json +62 -43
  54. package/src/cli/args.ts +72 -0
  55. package/src/cli/format.ts +45 -0
  56. package/src/cli/index.ts +75 -0
  57. package/src/errors.ts +78 -0
  58. package/src/evaluator/evaluator.ts +837 -0
  59. package/src/evaluator/index.ts +14 -0
  60. package/src/evaluator/modifiers/compare.ts +29 -0
  61. package/src/evaluator/modifiers/explode.ts +215 -0
  62. package/src/evaluator/modifiers/keep-drop.ts +151 -0
  63. package/src/evaluator/modifiers/reroll.ts +172 -0
  64. package/src/evaluator/modifiers/success-count.ts +59 -0
  65. package/src/index.ts +72 -0
  66. package/src/lexer/lexer.ts +281 -0
  67. package/src/lexer/tokens.ts +147 -0
  68. package/src/parser/ast.ts +261 -0
  69. package/src/parser/parser.ts +716 -0
  70. package/src/rng/index.ts +8 -0
  71. package/src/rng/mock.ts +65 -0
  72. package/src/rng/seeded.ts +127 -0
  73. package/src/rng/types.ts +25 -0
  74. package/src/roll.ts +66 -0
  75. package/src/testing.ts +16 -0
  76. package/src/types.ts +112 -0
  77. package/bin/help.txt +0 -19
  78. package/bin/roll-parser.js +0 -23
  79. package/dist/roll-parser.js +0 -697
  80. package/dist/roll-parser.min.js +0 -1
  81. package/index.js +0 -24
  82. package/src/complex/parse.js +0 -37
  83. package/src/complex/parseAndRoll.js +0 -21
  84. package/src/complex/parseAndRollClassic.js +0 -20
  85. package/src/complex/parseAndRollSimple.js +0 -19
  86. package/src/complex/parseAndRollWod.js +0 -20
  87. package/src/complex/parseClassicRoll.js +0 -22
  88. package/src/complex/parseSimpleRoll.js +0 -21
  89. package/src/complex/parseWodRoll.js +0 -21
  90. package/src/converter.js +0 -45
  91. package/src/grammar.js +0 -14
  92. package/src/mapper.js +0 -50
  93. package/src/normalizer.js +0 -51
  94. package/src/object/Result.js +0 -23
  95. package/src/object/Roll.js +0 -26
  96. package/src/object/Type.js +0 -5
  97. package/src/object/WodRoll.js +0 -29
  98. package/src/parser.js +0 -43
  99. package/src/random.js +0 -22
  100. package/src/roller.js +0 -106
  101. 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
+ }