roll-parser 3.0.0-alpha.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.
Files changed (163) hide show
  1. package/CHANGELOG.md +189 -0
  2. package/MIGRATION.md +147 -0
  3. package/README.md +985 -43
  4. package/dist/cli/args.d.ts +1 -0
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +81 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/format.d.ts +16 -4
  9. package/dist/cli/format.d.ts.map +1 -1
  10. package/dist/cli/format.js +17 -0
  11. package/dist/cli/format.js.map +1 -0
  12. package/dist/cli/index.d.ts +3 -0
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +14 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/cli/main.d.ts +36 -0
  17. package/dist/cli/main.d.ts.map +1 -0
  18. package/dist/cli/main.js +83 -0
  19. package/dist/cli/main.js.map +1 -0
  20. package/dist/errors.d.ts +332 -14
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +141 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/evaluator/die.d.ts +26 -0
  25. package/dist/evaluator/die.d.ts.map +1 -0
  26. package/dist/evaluator/die.js +19 -0
  27. package/dist/evaluator/die.js.map +1 -0
  28. package/dist/evaluator/env.d.ts +58 -0
  29. package/dist/evaluator/env.d.ts.map +1 -0
  30. package/dist/evaluator/env.js +11 -0
  31. package/dist/evaluator/env.js.map +1 -0
  32. package/dist/evaluator/evaluator.d.ts +62 -40
  33. package/dist/evaluator/evaluator.d.ts.map +1 -1
  34. package/dist/evaluator/evaluator.js +906 -0
  35. package/dist/evaluator/evaluator.js.map +1 -0
  36. package/dist/evaluator/modifiers/compare.d.ts +1 -1
  37. package/dist/evaluator/modifiers/compare.d.ts.map +1 -1
  38. package/dist/evaluator/modifiers/compare.js +15 -0
  39. package/dist/evaluator/modifiers/compare.js.map +1 -0
  40. package/dist/evaluator/modifiers/crit-threshold.d.ts +27 -0
  41. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
  42. package/dist/evaluator/modifiers/crit-threshold.js +23 -0
  43. package/dist/evaluator/modifiers/crit-threshold.js.map +1 -0
  44. package/dist/evaluator/modifiers/die-bound.d.ts +26 -0
  45. package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -0
  46. package/dist/evaluator/modifiers/die-bound.js +14 -0
  47. package/dist/evaluator/modifiers/die-bound.js.map +1 -0
  48. package/dist/evaluator/modifiers/explode.d.ts +18 -6
  49. package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
  50. package/dist/evaluator/modifiers/explode.js +103 -0
  51. package/dist/evaluator/modifiers/explode.js.map +1 -0
  52. package/dist/evaluator/modifiers/flags.d.ts +37 -0
  53. package/dist/evaluator/modifiers/flags.d.ts.map +1 -0
  54. package/dist/evaluator/modifiers/flags.js +18 -0
  55. package/dist/evaluator/modifiers/flags.js.map +1 -0
  56. package/dist/evaluator/modifiers/keep-drop.d.ts +12 -28
  57. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
  58. package/dist/evaluator/modifiers/keep-drop.js +82 -0
  59. package/dist/evaluator/modifiers/keep-drop.js.map +1 -0
  60. package/dist/evaluator/modifiers/reroll.d.ts +14 -6
  61. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
  62. package/dist/evaluator/modifiers/reroll.js +62 -0
  63. package/dist/evaluator/modifiers/reroll.js.map +1 -0
  64. package/dist/evaluator/modifiers/sort.d.ts +27 -0
  65. package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
  66. package/dist/evaluator/modifiers/sort.js +13 -0
  67. package/dist/evaluator/modifiers/sort.js.map +1 -0
  68. package/dist/evaluator/modifiers/success-count.d.ts +2 -6
  69. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
  70. package/dist/evaluator/modifiers/success-count.js +24 -0
  71. package/dist/evaluator/modifiers/success-count.js.map +1 -0
  72. package/dist/index.d.ts +35 -13
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +12 -1723
  75. package/dist/index.js.map +1 -0
  76. package/dist/lexer/lexer.d.ts +68 -8
  77. package/dist/lexer/lexer.d.ts.map +1 -1
  78. package/dist/lexer/lexer.js +260 -0
  79. package/dist/lexer/lexer.js.map +1 -0
  80. package/dist/lexer/tokens.d.ts +52 -7
  81. package/dist/lexer/tokens.d.ts.map +1 -1
  82. package/dist/lexer/tokens.js +42 -0
  83. package/dist/lexer/tokens.js.map +1 -0
  84. package/dist/parser/ast.d.ts +419 -80
  85. package/dist/parser/ast.d.ts.map +1 -1
  86. package/dist/parser/ast.js +52 -0
  87. package/dist/parser/ast.js.map +1 -0
  88. package/dist/parser/guards.d.ts +106 -0
  89. package/dist/parser/guards.d.ts.map +1 -0
  90. package/dist/parser/guards.js +121 -0
  91. package/dist/parser/guards.js.map +1 -0
  92. package/dist/parser/parser.d.ts +162 -15
  93. package/dist/parser/parser.d.ts.map +1 -1
  94. package/dist/parser/parser.js +751 -0
  95. package/dist/parser/parser.js.map +1 -0
  96. package/dist/rng/mock.d.ts +74 -13
  97. package/dist/rng/mock.d.ts.map +1 -1
  98. package/dist/rng/mock.js +30 -0
  99. package/dist/rng/mock.js.map +1 -0
  100. package/dist/rng/seeded.d.ts +149 -10
  101. package/dist/rng/seeded.d.ts.map +1 -1
  102. package/dist/rng/seeded.js +138 -0
  103. package/dist/rng/seeded.js.map +1 -0
  104. package/dist/rng/types.d.ts +57 -0
  105. package/dist/rng/types.d.ts.map +1 -1
  106. package/dist/rng/types.js +2 -0
  107. package/dist/rng/types.js.map +1 -0
  108. package/dist/roll.d.ts +59 -25
  109. package/dist/roll.d.ts.map +1 -1
  110. package/dist/roll.js +8 -0
  111. package/dist/roll.js.map +1 -0
  112. package/dist/testing.d.ts +5 -4
  113. package/dist/testing.d.ts.map +1 -1
  114. package/dist/testing.js +2 -38
  115. package/dist/testing.js.map +1 -0
  116. package/dist/types.d.ts +427 -24
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +8 -0
  119. package/dist/types.js.map +1 -0
  120. package/dist/version.d.ts +2 -0
  121. package/dist/version.d.ts.map +1 -0
  122. package/dist/version.js +2 -0
  123. package/dist/version.js.map +1 -0
  124. package/package.json +93 -40
  125. package/src/cli/args.ts +66 -9
  126. package/src/cli/format.ts +30 -7
  127. package/src/cli/index.ts +27 -67
  128. package/src/cli/main.ts +129 -0
  129. package/src/errors.ts +488 -23
  130. package/src/evaluator/die.ts +50 -0
  131. package/src/evaluator/env.ts +73 -0
  132. package/src/evaluator/evaluator.ts +1296 -349
  133. package/src/evaluator/modifiers/compare.ts +1 -1
  134. package/src/evaluator/modifiers/crit-threshold.ts +56 -0
  135. package/src/evaluator/modifiers/die-bound.ts +39 -0
  136. package/src/evaluator/modifiers/explode.ts +82 -76
  137. package/src/evaluator/modifiers/flags.ts +61 -0
  138. package/src/evaluator/modifiers/keep-drop.ts +124 -126
  139. package/src/evaluator/modifiers/reroll.ts +36 -64
  140. package/src/evaluator/modifiers/sort.ts +43 -0
  141. package/src/evaluator/modifiers/success-count.ts +6 -9
  142. package/src/index.ts +73 -34
  143. package/src/lexer/lexer.ts +201 -35
  144. package/src/lexer/tokens.ts +72 -7
  145. package/src/parser/ast.ts +453 -104
  146. package/src/parser/guards.ts +248 -0
  147. package/src/parser/parser.ts +835 -135
  148. package/src/rng/mock.ts +75 -14
  149. package/src/rng/seeded.ts +323 -58
  150. package/src/rng/types.ts +57 -0
  151. package/src/roll.ts +66 -41
  152. package/src/testing.ts +5 -9
  153. package/src/types.ts +416 -24
  154. package/src/version.ts +2 -0
  155. package/dist/cli.js +0 -1775
  156. package/dist/evaluator/index.d.ts +0 -8
  157. package/dist/evaluator/index.d.ts.map +0 -1
  158. package/dist/index.mjs +0 -1724
  159. package/dist/rng/index.d.ts +0 -8
  160. package/dist/rng/index.d.ts.map +0 -1
  161. package/dist/testing.mjs +0 -39
  162. package/src/evaluator/index.ts +0 -14
  163. package/src/rng/index.ts +0 -8
@@ -3,63 +3,85 @@
3
3
  *
4
4
  * @module evaluator/evaluator
5
5
  */
6
- import type { RollParserErrorCode } from '../errors';
7
- import { RollParserError } from '../errors';
8
- import type { ASTNode } from '../parser/ast';
9
- import type { RNG } from '../rng/types';
10
- import type { EvaluateOptions, RollResult } from '../types';
11
- import { DEFAULT_MAX_EXPLODE_ITERATIONS } from './modifiers/explode';
12
- import { DEFAULT_MAX_REROLL_ITERATIONS } from './modifiers/reroll';
6
+ import { EvaluatorError } from '../errors.js';
7
+ import type { ASTNode } from '../parser/ast.js';
8
+ import type { RNG } from '../rng/types.js';
9
+ import type { DieResult, EvaluateOptions, RollResult } from '../types.js';
10
+ import { DegreeOfSuccess } from '../types.js';
11
+ import { DEFAULT_MAX_EXPLODE_ITERATIONS } from './modifiers/explode.js';
12
+ import { DEFAULT_MAX_REROLL_ITERATIONS } from './modifiers/reroll.js';
13
+ export { EvaluatorError };
13
14
  /**
14
- * Error thrown during AST evaluation.
15
+ * Default value of `EvaluationOptions.maxDice`: the number of dice a single
16
+ * evaluation may roll before `DICE_LIMIT_EXCEEDED` is thrown.
17
+ *
18
+ * Counted across the whole expression, not per pool, so `6000d6+6000d6`
19
+ * breaches it. Includes dice rolled by explosions, rerolls, and
20
+ * meta-expressions.
21
+ *
22
+ * @category Limits
15
23
  */
16
- export declare class EvaluatorError extends RollParserError {
17
- readonly nodeType: string | undefined;
18
- constructor(message: string, code: RollParserErrorCode, nodeType?: string);
19
- }
20
- /** Default maximum total dice allowed per evaluation. */
21
24
  export declare const DEFAULT_MAX_DICE = 10000;
22
25
  export { DEFAULT_MAX_EXPLODE_ITERATIONS, DEFAULT_MAX_REROLL_ITERATIONS };
23
26
  /**
24
- * Per-evaluation shared environment (created once, shared across all branches).
27
+ * Per-branch mutable accumulator for tracking rolls and output during recursion.
25
28
  *
26
- * Exported for use by modifier implementations under `./modifiers/*`. Not part
27
- * of the public library API.
29
+ * Module-level export, deliberately absent from `src/index.ts` the package
30
+ * surface never mentions it. See {@link mergeMetaRolls} for why the export
31
+ * exists at all.
28
32
  */
29
- export type EvalEnv = {
30
- readonly maxDice: number;
31
- readonly maxExplodeIterations: number;
32
- readonly maxRerollIterations: number;
33
- totalDiceRolled: number;
33
+ export type EvalContext = {
34
+ rolls: DieResult[];
35
+ expressionParts: string[];
36
+ renderedParts: string[];
34
37
  /**
35
- * Set to `true` by `evalSuccessCount`. Propagates through the shared env
36
- * so `evaluate()` can include `successes`/`failures` fields even when no
37
- * die was tagged (impossible threshold).
38
+ * Populated by `evalVersus` with the resolved degree and natural value.
39
+ * `evaluate()` reads this from the top-level ctx to surface `degree` and
40
+ * `natural` on the final `RollResult`. Only populated when `vs` is the
41
+ * root of the expression.
38
42
  */
39
- hasSuccessCount: boolean;
40
- /**
41
- * `true` while the evaluator is inside a `VersusNode`'s roll or DC
42
- * sub-evaluation. `evalVersus` rejects nesting via this flag — catches
43
- * paren-nested versus (`1d20 vs (5 vs 3)`) that slip past the parser's
44
- * left-chain check.
45
- */
46
- insideVersus: boolean;
43
+ versusMetadata?: {
44
+ degree: DegreeOfSuccess;
45
+ natural: number | undefined;
46
+ dcTotal: number;
47
+ };
47
48
  };
48
49
  /**
49
- * Evaluates a parsed AST and returns the roll result.
50
+ * Evaluates a parsed AST against an {@link RNG} and returns the roll result.
51
+ *
52
+ * The second half of the pipeline — {@link roll} is `evaluate(parse(...))`.
53
+ * Call it directly to reuse one AST across many rolls, or to drive a
54
+ * hand-built AST.
50
55
  *
51
- * @param ast - The parsed AST node
52
- * @param rng - Random number generator to use for dice rolls
53
- * @param options - Optional evaluation options
54
- * @returns Complete roll result with total and metadata
56
+ * Unlike `roll`, the RNG is required: `evaluate` never invents a randomness
57
+ * source, so a caller can never accidentally get an unseeded roll.
58
+ *
59
+ * @param ast - The AST to evaluate, from {@link parse} or hand-built
60
+ * @param rng - Randomness source; one `nextInt` call per die
61
+ * @param options - Evaluation limits plus the original `notation` string,
62
+ * which the AST cannot supply
63
+ * @returns Complete {@link RollResult}
64
+ * @throws {EvaluatorError} On a limit breach, division by zero, an undefined
65
+ * variable, or a non-finite total
66
+ * @throws {RollParserError} `INVALID_EVALUATION_LIMIT` when a supplied limit is
67
+ * not an integer in range — raised before any die is rolled
55
68
  *
56
69
  * @example
57
70
  * ```typescript
71
+ * import { evaluate, parse } from 'roll-parser';
72
+ * import { createMockRng } from 'roll-parser/testing';
73
+ *
58
74
  * const ast = parse('2d6+3');
59
- * const rng = new SeededRNG('test');
60
- * const result = evaluate(ast, rng);
61
- * console.log(result.total); // Sum of dice plus 3
75
+ * const result = evaluate(ast, createMockRng([4, 2]), { notation: '2d6+3' });
76
+ * result.total; // 9
77
+ * result.rendered; // '2d6[4, 2] + 3 = 9'
62
78
  * ```
79
+ *
80
+ * Omitting `notation` falls back to the normalized `expression`, which is
81
+ * reconstructed from the AST — so `RollResult.notation` is always a string,
82
+ * just not necessarily the one the user typed.
83
+ *
84
+ * @category Core
63
85
  */
64
86
  export declare function evaluate(ast: ASTNode, rng: RNG, options?: EvaluateOptions): RollResult;
65
87
  //# sourceMappingURL=evaluator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EACV,OAAO,EAWR,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAA2B,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErF,OAAO,EAKL,8BAA8B,EAC/B,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAGL,6BAA6B,EAC9B,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,qBAAa,cAAe,SAAQ,eAAe;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE1B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,MAAM;CAK1E;AAED,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAspBF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,eAAoB,GAAG,UAAU,CAqE1F"}
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiB,cAAc,EAAuC,MAAM,cAAc,CAAC;AAClG,OAAO,KAAK,EACV,OAAO,EAmBR,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAIV,SAAS,EACT,eAAe,EAKf,UAAU,EACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,EAKL,8BAA8B,EAC/B,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAGL,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,cAAc,EAAE,CAAC;AAM1B;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAmCvC,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,CAAC;AAMzE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QACf,MAAM,EAAE,eAAe,CAAC;QACxB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AA++CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,eAAoB,GAAG,UAAU,CA4D1F"}