roll-parser 3.0.0-alpha.0 → 3.0.0-beta.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 (80) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +166 -30
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/format.d.ts +1 -1
  5. package/dist/cli/format.d.ts.map +1 -1
  6. package/dist/cli.js +1110 -277
  7. package/dist/cli.js.map +28 -0
  8. package/dist/errors.d.ts +7 -4
  9. package/dist/errors.d.ts.map +1 -1
  10. package/dist/evaluator/evaluator.d.ts +63 -7
  11. package/dist/evaluator/evaluator.d.ts.map +1 -1
  12. package/dist/evaluator/index.d.ts +2 -2
  13. package/dist/evaluator/index.d.ts.map +1 -1
  14. package/dist/evaluator/modifiers/compare.d.ts +1 -1
  15. package/dist/evaluator/modifiers/compare.d.ts.map +1 -1
  16. package/dist/evaluator/modifiers/crit-threshold.d.ts +28 -0
  17. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
  18. package/dist/evaluator/modifiers/explode.d.ts +8 -4
  19. package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
  20. package/dist/evaluator/modifiers/keep-drop.d.ts +1 -1
  21. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
  22. package/dist/evaluator/modifiers/reroll.d.ts +4 -4
  23. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
  24. package/dist/evaluator/modifiers/sort.d.ts +23 -0
  25. package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
  26. package/dist/evaluator/modifiers/success-count.d.ts +1 -1
  27. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
  28. package/dist/index.d.ts +13 -13
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1112 -275
  31. package/dist/index.js.map +26 -0
  32. package/dist/lexer/lexer.d.ts +18 -3
  33. package/dist/lexer/lexer.d.ts.map +1 -1
  34. package/dist/lexer/tokens.d.ts +22 -2
  35. package/dist/lexer/tokens.d.ts.map +1 -1
  36. package/dist/parser/ast.d.ts +209 -24
  37. package/dist/parser/ast.d.ts.map +1 -1
  38. package/dist/parser/parser.d.ts +48 -5
  39. package/dist/parser/parser.d.ts.map +1 -1
  40. package/dist/rng/index.d.ts +2 -2
  41. package/dist/rng/index.d.ts.map +1 -1
  42. package/dist/rng/mock.d.ts +1 -1
  43. package/dist/rng/mock.d.ts.map +1 -1
  44. package/dist/rng/seeded.d.ts +8 -1
  45. package/dist/rng/seeded.d.ts.map +1 -1
  46. package/dist/roll.d.ts +6 -2
  47. package/dist/roll.d.ts.map +1 -1
  48. package/dist/testing.d.ts +1 -1
  49. package/dist/testing.d.ts.map +1 -1
  50. package/dist/testing.js +3 -0
  51. package/dist/testing.js.map +11 -0
  52. package/dist/types.d.ts +143 -2
  53. package/dist/types.d.ts.map +1 -1
  54. package/package.json +22 -18
  55. package/src/cli/args.ts +2 -1
  56. package/src/cli/format.ts +8 -4
  57. package/src/cli/index.ts +22 -5
  58. package/src/errors.ts +15 -3
  59. package/src/evaluator/evaluator.ts +826 -111
  60. package/src/evaluator/index.ts +2 -2
  61. package/src/evaluator/modifiers/compare.ts +1 -1
  62. package/src/evaluator/modifiers/crit-threshold.ts +59 -0
  63. package/src/evaluator/modifiers/explode.ts +29 -25
  64. package/src/evaluator/modifiers/keep-drop.ts +1 -1
  65. package/src/evaluator/modifiers/reroll.ts +18 -25
  66. package/src/evaluator/modifiers/sort.ts +30 -0
  67. package/src/evaluator/modifiers/success-count.ts +2 -2
  68. package/src/index.ts +33 -15
  69. package/src/lexer/lexer.ts +101 -8
  70. package/src/lexer/tokens.ts +42 -2
  71. package/src/parser/ast.ts +397 -30
  72. package/src/parser/parser.ts +590 -67
  73. package/src/rng/index.ts +2 -2
  74. package/src/rng/mock.ts +1 -1
  75. package/src/rng/seeded.ts +31 -1
  76. package/src/roll.ts +14 -6
  77. package/src/testing.ts +1 -1
  78. package/src/types.ts +127 -2
  79. package/dist/index.mjs +0 -1724
  80. package/dist/testing.mjs +0 -39
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * @module lexer/lexer
5
5
  */
6
- import type { RollParserErrorCode } from '../errors';
7
- import { RollParserError } from '../errors';
8
- import { type Token } from './tokens';
6
+ import type { RollParserErrorCode } from '../errors.js';
7
+ import { RollParserError } from '../errors.js';
8
+ import { type Token } from './tokens.js';
9
9
  /**
10
10
  * Error thrown when the lexer encounters an invalid character.
11
11
  */
@@ -47,6 +47,19 @@ export declare class Lexer {
47
47
  * accumulation loop stops naturally and the post-loop check handles it.
48
48
  */
49
49
  private scanIdentifier;
50
+ /**
51
+ * Scans a variable reference introduced by `@`.
52
+ *
53
+ * Two forms:
54
+ * - Bare: `@name` where `name` matches `[A-Za-z_][A-Za-z0-9_]*` (case preserved).
55
+ * - Braced: `@{name}` where `name` is any run of printable characters except
56
+ * `}` and newline (permits spaces, hyphens, digits).
57
+ *
58
+ * Case is preserved — distinct from `scanIdentifier`, which lowercases the
59
+ * captured value. The emitted token's `value` is the variable name without
60
+ * the leading `@` or the surrounding braces.
61
+ */
62
+ private scanAt;
50
63
  private peek;
51
64
  private peekNext;
52
65
  private advance;
@@ -54,6 +67,8 @@ export declare class Lexer {
54
67
  private isAtEnd;
55
68
  private isDigit;
56
69
  private isAlpha;
70
+ private isIdentifierStart;
71
+ private isIdentifierPart;
57
72
  private isWhitespace;
58
73
  private createToken;
59
74
  private createTokenAt;
@@ -1 +1 @@
1
- {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/lexer/lexer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,UAAU,CAAC;AAEjD;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM5F;AAsBD;;;;;GAKG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,MAAM;IAIzB;;OAEG;IACH,QAAQ,IAAI,KAAK,EAAE;IAYnB;;OAEG;IACH,SAAS,IAAI,KAAK;IAyElB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,UAAU;IAoBlB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;CAGtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAE1C"}
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/lexer/lexer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,aAAa,CAAC;AAEpD;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM5F;AA2CD;;;;;GAKG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,MAAM;IAIzB;;OAEG;IACH,QAAQ,IAAI,KAAK,EAAE;IAYnB;;OAEG;IACH,SAAS,IAAI,KAAK;IAuFlB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,UAAU;IAoBlB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAqCtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM;IA+Bd,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;CAGtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAE1C"}
@@ -70,8 +70,22 @@ export declare enum TokenType {
70
70
  FUNCTION = 28,
71
71
  /** Versus operator: 'vs' */
72
72
  VS = 29,
73
+ /** Left brace: '{' */
74
+ LBRACE = 30,
75
+ /** Right brace: '}' */
76
+ RBRACE = 31,
77
+ /** Variable reference prefix: '@' */
78
+ AT = 32,
79
+ /** Ascending sort: 's' or 'sa' */
80
+ SORT_ASC = 33,
81
+ /** Descending sort: 'sd' */
82
+ SORT_DESC = 34,
83
+ /** Critical success threshold: 'cs' */
84
+ CRIT_SUCCESS = 35,
85
+ /** Critical failure threshold: 'cf' */
86
+ CRIT_FAIL = 36,
73
87
  /** End of input marker */
74
- EOF = 30
88
+ EOF = 37
75
89
  }
76
90
  /**
77
91
  * A token produced by the lexer.
@@ -81,7 +95,13 @@ export type Token = {
81
95
  type: TokenType;
82
96
  /** The raw string value from input (lowercased for identifiers) */
83
97
  value: string;
84
- /** Zero-based position in the input string */
98
+ /** Zero-based start offset in the input string (UTF-16 code units) */
85
99
  position: number;
100
+ /**
101
+ * Zero-based end offset (exclusive). Not always `position + value.length` —
102
+ * braced variables (`@{name}` stores only `name`) and case-normalized
103
+ * identifiers consume more input than their `value` retains.
104
+ */
105
+ end: number;
86
106
  };
87
107
  //# sourceMappingURL=tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lexer/tokens.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,oBAAY,SAAS;IAKnB,0CAA0C;IAC1C,MAAM,IAAI;IAMV,gCAAgC;IAChC,IAAI,IAAI;IACR,sDAAsD;IACtD,YAAY,IAAI;IAChB,qCAAqC;IACrC,SAAS,IAAI;IAMb,6BAA6B;IAC7B,IAAI,IAAI;IACR,gCAAgC;IAChC,KAAK,IAAI;IACT,mCAAmC;IACnC,QAAQ,IAAI;IACZ,6BAA6B;IAC7B,MAAM,IAAI;IACV,2BAA2B;IAC3B,MAAM,IAAI;IACV,kCAAkC;IAClC,KAAK,IAAI;IAMT,wBAAwB;IACxB,OAAO,KAAK;IACZ,kCAAkC;IAClC,aAAa,KAAK;IAClB,qBAAqB;IACrB,IAAI,KAAK;IACT,+BAA+B;IAC/B,UAAU,KAAK;IACf,iBAAiB;IACjB,KAAK,KAAK;IAMV,4BAA4B;IAC5B,MAAM,KAAK;IACX,6BAA6B;IAC7B,MAAM,KAAK;IACX,8BAA8B;IAC9B,KAAK,KAAK;IAMV,yCAAyC;IACzC,SAAS,KAAK;IACd,iCAAiC;IACjC,QAAQ,KAAK;IACb,kCAAkC;IAClC,SAAS,KAAK;IACd,iCAAiC;IACjC,QAAQ,KAAK;IAMb,4BAA4B;IAC5B,OAAO,KAAK;IACZ,gCAAgC;IAChC,gBAAgB,KAAK;IACrB,gCAAgC;IAChC,mBAAmB,KAAK;IAMxB,4BAA4B;IAC5B,MAAM,KAAK;IACX,wBAAwB;IACxB,WAAW,KAAK;IAMhB,uBAAuB;IACvB,IAAI,KAAK;IAMT,mEAAmE;IACnE,QAAQ,KAAK;IAMb,4BAA4B;IAC5B,EAAE,KAAK;IAMP,0BAA0B;IAC1B,GAAG,KAAK;CACT;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,6BAA6B;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lexer/tokens.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,oBAAY,SAAS;IAKnB,0CAA0C;IAC1C,MAAM,IAAI;IAMV,gCAAgC;IAChC,IAAI,IAAI;IACR,sDAAsD;IACtD,YAAY,IAAI;IAChB,qCAAqC;IACrC,SAAS,IAAI;IAMb,6BAA6B;IAC7B,IAAI,IAAI;IACR,gCAAgC;IAChC,KAAK,IAAI;IACT,mCAAmC;IACnC,QAAQ,IAAI;IACZ,6BAA6B;IAC7B,MAAM,IAAI;IACV,2BAA2B;IAC3B,MAAM,IAAI;IACV,kCAAkC;IAClC,KAAK,IAAI;IAMT,wBAAwB;IACxB,OAAO,KAAK;IACZ,kCAAkC;IAClC,aAAa,KAAK;IAClB,qBAAqB;IACrB,IAAI,KAAK;IACT,+BAA+B;IAC/B,UAAU,KAAK;IACf,iBAAiB;IACjB,KAAK,KAAK;IAMV,4BAA4B;IAC5B,MAAM,KAAK;IACX,6BAA6B;IAC7B,MAAM,KAAK;IACX,8BAA8B;IAC9B,KAAK,KAAK;IAMV,yCAAyC;IACzC,SAAS,KAAK;IACd,iCAAiC;IACjC,QAAQ,KAAK;IACb,kCAAkC;IAClC,SAAS,KAAK;IACd,iCAAiC;IACjC,QAAQ,KAAK;IAMb,4BAA4B;IAC5B,OAAO,KAAK;IACZ,gCAAgC;IAChC,gBAAgB,KAAK;IACrB,gCAAgC;IAChC,mBAAmB,KAAK;IAMxB,4BAA4B;IAC5B,MAAM,KAAK;IACX,wBAAwB;IACxB,WAAW,KAAK;IAMhB,uBAAuB;IACvB,IAAI,KAAK;IAMT,mEAAmE;IACnE,QAAQ,KAAK;IAMb,4BAA4B;IAC5B,EAAE,KAAK;IAMP,sBAAsB;IACtB,MAAM,KAAK;IACX,uBAAuB;IACvB,MAAM,KAAK;IAMX,qCAAqC;IACrC,EAAE,KAAK;IAMP,kCAAkC;IAClC,QAAQ,KAAK;IACb,4BAA4B;IAC5B,SAAS,KAAK;IAMd,uCAAuC;IACvC,YAAY,KAAK;IACjB,uCAAuC;IACvC,SAAS,KAAK;IAMd,0BAA0B;IAC1B,GAAG,KAAK;CACT;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,6BAA6B;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
@@ -3,11 +3,23 @@
3
3
  *
4
4
  * @module parser/ast
5
5
  */
6
- import type { ComparePoint } from '../types';
6
+ import type { ComparePoint } from '../types.js';
7
+ /**
8
+ * Source span carried by every AST node.
9
+ *
10
+ * `start` is inclusive, `end` exclusive, both in UTF-16 code units into the
11
+ * original notation string. The parser sets both on every node it produces;
12
+ * they are typed optional so hand-constructed ASTs (tests, programmatic
13
+ * consumers) remain valid without positions.
14
+ */
15
+ export type NodeSpan = {
16
+ start?: number;
17
+ end?: number;
18
+ };
7
19
  /**
8
20
  * Numeric literal node.
9
21
  */
10
- export type LiteralNode = {
22
+ export type LiteralNode = NodeSpan & {
11
23
  type: 'Literal';
12
24
  value: number;
13
25
  };
@@ -15,7 +27,7 @@ export type LiteralNode = {
15
27
  * Dice roll node.
16
28
  * Count and sides can be expressions to support computed dice like (1+1)d(3*2).
17
29
  */
18
- export type DiceNode = {
30
+ export type DiceNode = NodeSpan & {
19
31
  type: 'Dice';
20
32
  count: ASTNode;
21
33
  sides: ASTNode;
@@ -24,14 +36,14 @@ export type DiceNode = {
24
36
  * Fate/Fudge dice node (`dF`).
25
37
  * Each die produces a result in {-1, 0, +1}. No configurable sides.
26
38
  */
27
- export type FateDiceNode = {
39
+ export type FateDiceNode = NodeSpan & {
28
40
  type: 'FateDice';
29
41
  count: ASTNode;
30
42
  };
31
43
  /**
32
44
  * Binary operation node.
33
45
  */
34
- export type BinaryOpNode = {
46
+ export type BinaryOpNode = NodeSpan & {
35
47
  type: 'BinaryOp';
36
48
  operator: '+' | '-' | '*' | '/' | '%' | '**';
37
49
  left: ASTNode;
@@ -40,7 +52,7 @@ export type BinaryOpNode = {
40
52
  /**
41
53
  * Unary operation node.
42
54
  */
43
- export type UnaryOpNode = {
55
+ export type UnaryOpNode = NodeSpan & {
44
56
  type: 'UnaryOp';
45
57
  operator: '-';
46
58
  operand: ASTNode;
@@ -49,7 +61,7 @@ export type UnaryOpNode = {
49
61
  * Keep/drop modifier node.
50
62
  * Wraps a dice expression with keep highest/lowest or drop highest/lowest.
51
63
  */
52
- export type ModifierNode = {
64
+ export type ModifierNode = NodeSpan & {
53
65
  type: 'Modifier';
54
66
  modifier: 'keep' | 'drop';
55
67
  selector: 'highest' | 'lowest';
@@ -61,7 +73,7 @@ export type ModifierNode = {
61
73
  * Wraps a dice expression with a standard, compounding, or penetrating
62
74
  * explosion. An absent `threshold` means "explode on the die's maximum face".
63
75
  */
64
- export type ExplodeNode = {
76
+ export type ExplodeNode = NodeSpan & {
65
77
  type: 'Explode';
66
78
  variant: 'standard' | 'compound' | 'penetrating';
67
79
  threshold?: ComparePoint;
@@ -73,7 +85,7 @@ export type ExplodeNode = {
73
85
  * keeps the second result regardless of match; `once: false` for `r`
74
86
  * re-rolls recursively until the condition no longer matches.
75
87
  */
76
- export type RerollNode = {
88
+ export type RerollNode = NodeSpan & {
77
89
  type: 'Reroll';
78
90
  once: boolean;
79
91
  condition: ComparePoint;
@@ -83,11 +95,12 @@ export type RerollNode = {
83
95
  * Success counting node (`>=T`, `>T`, `<T`, `<=T`, `=T`, with optional `f=F`).
84
96
  *
85
97
  * Transforms a dice pool into a success count: each die meeting `threshold`
86
- * adds +1, each die meeting `failThreshold` subtracts 1. Terminal — no further
87
- * postfix modifiers may wrap a `SuccessCountNode`. The `failThreshold`
88
- * operator is always `=` (fail on an exact value).
98
+ * adds +1, each die meeting `failThreshold` subtracts 1. Terminal — a
99
+ * `SuccessCountNode` may not be wrapped by any postfix modifier, binary
100
+ * operator, unary operator, versus operand, or function argument. The
101
+ * `failThreshold` accepts any `CompareOp`; bare `fN` defaults to `operator: '='`.
89
102
  */
90
- export type SuccessCountNode = {
103
+ export type SuccessCountNode = NodeSpan & {
91
104
  type: 'SuccessCount';
92
105
  target: ASTNode;
93
106
  threshold: ComparePoint;
@@ -103,7 +116,7 @@ export type SuccessCountNode = {
103
116
  * rejected at parse time; nesting via parens (`a vs (b vs c)`) is rejected
104
117
  * at evaluation time.
105
118
  */
106
- export type VersusNode = {
119
+ export type VersusNode = NodeSpan & {
107
120
  type: 'Versus';
108
121
  roll: ASTNode;
109
122
  dc: ASTNode;
@@ -116,15 +129,91 @@ export type VersusNode = {
116
129
  * parse time against a static table; by the time the evaluator sees a
117
130
  * `FunctionCallNode`, `args.length` is guaranteed to match the function.
118
131
  */
119
- export type FunctionCallNode = {
132
+ export type FunctionCallNode = NodeSpan & {
120
133
  type: 'FunctionCall';
121
134
  name: string;
122
135
  args: ASTNode[];
123
136
  };
137
+ /**
138
+ * Parenthesized group node (`(<expr>)`).
139
+ *
140
+ * Preserves explicit grouping typed by the user so that
141
+ * `RollResult.expression` and `RollResult.rendered` round-trip through
142
+ * `parse` without losing precedence information. Semantically transparent:
143
+ * evaluation returns the inner expression's value unchanged.
144
+ */
145
+ export type GroupedNode = NodeSpan & {
146
+ type: 'Grouped';
147
+ expression: ASTNode;
148
+ };
149
+ /**
150
+ * Variable reference node (`@name` or `@{name with spaces}`).
151
+ *
152
+ * Resolves to a numeric value from the evaluator's `context` map at
153
+ * evaluation time. Names are case-sensitive (`@StrMod` ≠ `@strmod`) — the
154
+ * lexer preserves case in the `AT` token's `value`, distinct from other
155
+ * identifier tokens which lowercase. Leaf node — no LED, never wraps a
156
+ * sub-expression.
157
+ */
158
+ export type VariableNode = NodeSpan & {
159
+ type: 'Variable';
160
+ name: string;
161
+ };
162
+ /**
163
+ * Grouped-roll node (`{expr}`, `{expr1, expr2, ...}`).
164
+ *
165
+ * Distinct from `GroupedNode` (parenthesized wrapper) — a `GroupNode`
166
+ * collects one or more sub-expressions whose evaluation semantics change
167
+ * with the sub-roll count. `expressions.length === 1` is a passthrough
168
+ * (flat-pool when wrapped by keep/drop); `expressions.length >= 2` treats
169
+ * each sub-roll's subtotal as a compound die for keep/drop selection.
170
+ */
171
+ export type GroupNode = NodeSpan & {
172
+ type: 'Group';
173
+ expressions: ASTNode[];
174
+ };
175
+ /**
176
+ * Sort modifier node (`s`, `sa`, `sd`).
177
+ *
178
+ * Cosmetically reorders the dice produced by `target` in ascending or
179
+ * descending order. Purely visual — does not affect `total`,
180
+ * `successes`/`failures`, or any die-level flag (`kept`/`dropped`/
181
+ * `critical`/`fumble`). Dropped dice retain their `dropped` flag and
182
+ * appear in sorted position alongside kept dice.
183
+ */
184
+ export type SortNode = NodeSpan & {
185
+ type: 'Sort';
186
+ order: 'ascending' | 'descending';
187
+ target: ASTNode;
188
+ };
189
+ /**
190
+ * Sentinel for bare `cs` / `cf` without a ComparePoint. Resolved to
191
+ * `result === sides` (for critical) or `result === 1` (for fumble) at
192
+ * evaluation time, using each die's own `sides`.
193
+ */
194
+ export type CritThreshold = ComparePoint | 'default';
195
+ /**
196
+ * Critical threshold modifier node (`cs`, `cf`).
197
+ *
198
+ * Overrides the default `critical`/`fumble` flag logic for the dice
199
+ * produced by `target`. Bare `cs`/`cf` uses the `'default'` sentinel
200
+ * (max face / 1). Custom thresholds accept any ComparePoint. Chaining
201
+ * collapses into a single node — `1d20cs=20cs=1cf>18` has two success
202
+ * and one fail threshold. Display-only: does not change `total`,
203
+ * explosion triggers, or success counting. `cs` and `cf` are independent
204
+ * overrides — a side with no explicit thresholds keeps the default rule
205
+ * (the evaluator substitutes the `'default'` sentinel at apply time).
206
+ */
207
+ export type CritThresholdNode = NodeSpan & {
208
+ type: 'CritThreshold';
209
+ successThresholds: CritThreshold[];
210
+ failThresholds: CritThreshold[];
211
+ target: ASTNode;
212
+ };
124
213
  /**
125
214
  * Union type of all AST nodes.
126
215
  */
127
- export type ASTNode = LiteralNode | DiceNode | FateDiceNode | BinaryOpNode | UnaryOpNode | ModifierNode | ExplodeNode | RerollNode | SuccessCountNode | VersusNode | FunctionCallNode;
216
+ export type ASTNode = LiteralNode | DiceNode | FateDiceNode | BinaryOpNode | UnaryOpNode | ModifierNode | ExplodeNode | RerollNode | SuccessCountNode | VersusNode | FunctionCallNode | GroupedNode | VariableNode | GroupNode | SortNode | CritThresholdNode;
128
217
  /**
129
218
  * Type guard for LiteralNode.
130
219
  */
@@ -170,14 +259,110 @@ export declare function isVersus(node: ASTNode): node is VersusNode;
170
259
  */
171
260
  export declare function isFunctionCall(node: ASTNode): node is FunctionCallNode;
172
261
  /**
173
- * Returns `true` if the AST contains a `Dice` or `FateDice` node reachable
174
- * through structural composition (BinaryOp, UnaryOp, keep/drop, explode,
175
- * reroll, success-count wrappers). Meta-expressions dice count/sides,
176
- * modifier counts, and ComparePoint values — are treated as leaves and
177
- * never recursed into.
262
+ * Type guard for GroupedNode.
263
+ */
264
+ export declare function isGrouped(node: ASTNode): node is GroupedNode;
265
+ /**
266
+ * Type guard for VariableNode.
267
+ */
268
+ export declare function isVariable(node: ASTNode): node is VariableNode;
269
+ /**
270
+ * Type guard for GroupNode.
271
+ */
272
+ export declare function isGroup(node: ASTNode): node is GroupNode;
273
+ /**
274
+ * Type guard for SortNode.
275
+ */
276
+ export declare function isSort(node: ASTNode): node is SortNode;
277
+ /**
278
+ * Type guard for CritThresholdNode.
279
+ */
280
+ export declare function isCritThreshold(node: ASTNode): node is CritThresholdNode;
281
+ /**
282
+ * Wrapper kinds that `unwrapTransparent` can peel.
283
+ *
284
+ * "Transparent" is relative to the question being asked. `Modifier`/`Sort`/
285
+ * `CritThreshold` are transparent for "what is the underlying operand?" when
286
+ * deciding whether to reject a `Group` target — they preserve `containsDicePool`'s
287
+ * answer for whatever they wrap. They are NOT transparent for "is this a
288
+ * `SuccessCount`?" or "is this a `Versus`?", because the parsers that build
289
+ * those wrappers already reject `SuccessCount`/`Versus` operands upstream.
290
+ */
291
+ export type TransparentWrapperKind = 'Grouped' | 'Modifier' | 'Sort' | 'CritThreshold';
292
+ /**
293
+ * Walks `node` while its `.type` is in `kinds`, returning the first descendant
294
+ * that is not one of the listed wrappers. Each caller picks the subset that
295
+ * matches its rejection semantics — see `TransparentWrapperKind` for guidance.
296
+ *
297
+ * Used by parser reject helpers to look past wrappers when deciding whether
298
+ * an operand violates a rule (e.g., `Group` cannot be the target of `cs`/`cf`,
299
+ * even when wrapped in `Modifier` like `{1d6}kh1cs>5`).
300
+ */
301
+ export declare function unwrapTransparent(node: ASTNode, kinds: readonly TransparentWrapperKind[]): ASTNode;
302
+ /**
303
+ * Returns `true` only when `node`'s direct result is a dice pool —
304
+ * `Dice`, `FateDice`, or a chained pool modifier (`Modifier` / `Explode` /
305
+ * `Reroll`). Does NOT recurse through arithmetic wrappers (`BinaryOp`,
306
+ * `UnaryOp`, `FunctionCall`), so `(1d6+5)` and `floor(1d6/2)` are rejected.
178
307
  *
179
- * Used by the parser to reject success-counting targets that don't actually
180
- * roll any dice (e.g. `1>=3`, `(1+2)>=3`).
308
+ * Used by the parser to reject postfix pool-modifier targets (kh/kl/dh/dl,
309
+ * !/!!/!p, r/ro) that wrap a non-pool expression. Operating on the inner
310
+ * dice pool would silently drop the surrounding arithmetic.
311
+ */
312
+ export declare function containsDicePool(node: ASTNode): boolean;
313
+ /**
314
+ * Deeper variant of `containsDicePool` that recurses through arithmetic and
315
+ * function wrappers. Used from the `Group` case above (ordinary parenthesized
316
+ * arithmetic `(1d6+5)kh1` must still reject, so the shallow `containsDicePool`
317
+ * handles those directly) and from the Sort parser guard (sort accepts
318
+ * `(1d6+2d8)s` per Stage 3 spec).
319
+ */
320
+ export declare function deepContainsDicePool(node: ASTNode): boolean;
321
+ /**
322
+ * Returns `true` if the pool this node resolves to is (or wraps) a `FateDice`
323
+ * pool. Walks through chained pool modifiers (`Modifier` / `Explode` /
324
+ * `Reroll`) but not arithmetic wrappers — callers should run
325
+ * `containsDicePool` first to reject those.
326
+ *
327
+ * Used by the parser to reject `!`, `!!`, `!p` applied to Fate pools
328
+ * (`4dF!`, `(4dF)kh2!`, etc.). Fate explosion semantics are undefined, so
329
+ * parse-time rejection is preferred over a silent evaluator no-op.
330
+ *
331
+ * Inside a `Group`, recursion uses `deepContainsFatePool` to mirror
332
+ * `containsDicePool`'s deep walk through the same case — otherwise
333
+ * `{4dF+1d6}cf` slips past the bare-Fate guard and the default fumble
334
+ * check (`result === 1`) flips `+1` faces into fumbles.
335
+ */
336
+ export declare function containsFatePool(node: ASTNode): boolean;
337
+ /**
338
+ * Deeper variant of `containsFatePool` that recurses through arithmetic and
339
+ * function wrappers. Mirrors `deepContainsDicePool`. Used from
340
+ * `containsFatePool`'s `Group` case so single-sub-roll groups containing
341
+ * arithmetic-wrapped Fate (`{4dF+1d6}cf`) still trip the bare-Fate guard.
342
+ *
343
+ * Outside a `Group`, ordinary parenthesized arithmetic (`(4dF+1d6)cf`) is
344
+ * already rejected upstream by shallow `containsDicePool`, so this helper
345
+ * intentionally stays Group-internal.
346
+ */
347
+ export declare function deepContainsFatePool(node: ASTNode): boolean;
348
+ /**
349
+ * Deep-walks a node to find any descendant `Group` with two or more
350
+ * sub-expressions. Used by `rejectGroupTarget`'s single-sub-roll
351
+ * passthrough so a multi-sub Group buried under arithmetic
352
+ * (`{{1d6,2d8}+0}cs>5`), function calls (`{abs({1d6,2d8})}cs>5`), or any
353
+ * other non-transparent wrapper still rejects with the same error code.
354
+ *
355
+ * Without this walk, the unwrap inside `rejectGroupTarget` only peels
356
+ * `Grouped`/`Modifier`/`Sort`/`CritThreshold` — a multi-sub Group cloaked
357
+ * in a `BinaryOp`/`UnaryOp`/`FunctionCall` revives issue #97.
358
+ */
359
+ export declare function containsMultiSubGroup(node: ASTNode): boolean;
360
+ /**
361
+ * Deep-walks a node to find any descendant `Versus`. Used by
362
+ * `rejectVersusTarget`'s single-sub-roll Group passthrough so a buried
363
+ * Versus (`{1+(1d20 vs 15)}cs>18`, `{abs(1d20 vs 15)}cs>18`,
364
+ * `{-(1d20 vs 15)}kh1`) still rejects with `NESTED_VERSUS` instead of
365
+ * silently dropping `versusMetadata` at the modifier consumer site.
181
366
  */
182
- export declare function containsDice(node: ASTNode): boolean;
367
+ export declare function containsVersus(node: ASTNode): boolean;
183
368
  //# sourceMappingURL=ast.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"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"}
@@ -3,11 +3,11 @@
3
3
  *
4
4
  * @module parser/parser
5
5
  */
6
- import type { RollParserErrorCode } from '../errors';
7
- import { RollParserError } from '../errors';
8
- import { type Token } from '../lexer/tokens';
9
- import type { ComparePoint } from '../types';
10
- import type { ASTNode } from './ast';
6
+ import type { RollParserErrorCode } from '../errors.js';
7
+ import { RollParserError } from '../errors.js';
8
+ import { type Token } from '../lexer/tokens.js';
9
+ import type { ComparePoint } from '../types.js';
10
+ import type { ASTNode } from './ast.js';
11
11
  /**
12
12
  * Error thrown when the parser encounters invalid syntax.
13
13
  */
@@ -25,6 +25,7 @@ export declare class ParseError extends RollParserError {
25
25
  export declare class Parser {
26
26
  private readonly tokens;
27
27
  private pos;
28
+ private depth;
28
29
  constructor(tokens: Token[]);
29
30
  /**
30
31
  * Parse the token stream into an AST.
@@ -44,6 +45,11 @@ export declare class Parser {
44
45
  * Handles tokens that appear between expressions (infix/postfix position).
45
46
  */
46
47
  private parseLed;
48
+ /**
49
+ * Zero-width span for synthetic nodes (implicit counts, `d%` sides) that
50
+ * have no source text of their own — anchored at the governing token.
51
+ */
52
+ private static syntheticLiteral;
47
53
  private parseLiteral;
48
54
  private parseUnaryMinus;
49
55
  private parsePrefixDice;
@@ -53,12 +59,42 @@ export declare class Parser {
53
59
  private parsePrefixFateDice;
54
60
  private parseInfixFateDice;
55
61
  private parseGrouped;
62
+ private parseGroup;
63
+ private parseVariable;
56
64
  private parseFunctionCall;
57
65
  private parseBinaryOp;
66
+ /**
67
+ * Rejects a dice token whose count operand is itself a bare (unparenthesized)
68
+ * dice expression. `4d6d1` would otherwise silently parse as `(4d6)d1` —
69
+ * roll 4d6, then use the result as a count of d1 dice — which is almost
70
+ * never intended: every major dice dialect reads `4d6d1` as "drop lowest 1".
71
+ * Both meanings stay reachable through explicit forms: `4d6dl1` to drop,
72
+ * `(4d6)d1` for nested dice.
73
+ */
74
+ private rejectBareDiceChain;
58
75
  private rejectSuccessCountTarget;
76
+ /**
77
+ * Rejects `GroupNode` (or a wrapper-cloaked group) as the target of `token`.
78
+ * Explode, reroll, and crit-threshold wrap bare dice pools only — a group
79
+ * is a container of sub-expressions, so these modifiers have no defined
80
+ * semantics. Walks `Grouped`/`Modifier`/`Sort`/`CritThreshold` so wrappers
81
+ * cannot smuggle a group past the check (`{1d6}kh1cs>5`, `({1d6})!`,
82
+ * `{1d6}scs>5` all reject the same as `{1d6}!`/`{1d6}cs>5`).
83
+ *
84
+ * `singleSubRollPasses` opts the caller into the Stage 3 single-sub-roll
85
+ * passthrough rule (STAGE3.md "Group Semantics: Single vs Multi Sub-Roll"):
86
+ * a `Group` with one expression is the user's explicit flat-pool escape
87
+ * hatch and is equivalent to its unwrapped form. Currently only
88
+ * `parseCritThreshold` opts in — explode/reroll keep the strict reject so
89
+ * existing notation contracts don't shift.
90
+ */
91
+ private rejectGroupTarget;
92
+ private rejectVersusTarget;
59
93
  private parseModifier;
60
94
  private parseExplode;
61
95
  private parseReroll;
96
+ private parseSort;
97
+ private parseCritThreshold;
62
98
  private parseSuccessCount;
63
99
  private parseVersus;
64
100
  /**
@@ -69,6 +105,13 @@ export declare class Parser {
69
105
  * Parses a comparison operator followed by a value expression.
70
106
  * Called by modifier parsers (explode, reroll, success counting).
71
107
  *
108
+ * The threshold value is parsed at `BP.DICE_LEFT`, which binds tighter than
109
+ * arithmetic. This keeps the comparison bound to the dice pool on the left
110
+ * rather than letting arithmetic to the right be consumed into the
111
+ * threshold. As a consequence, `1d6>=5+2` parses as `(1d6>=5)+2` with
112
+ * threshold `5` — not `7`. Computed thresholds require parens:
113
+ * `1d6>=(5+2)`. Same binding applies to `parseSuccessCount` below.
114
+ *
72
115
  * @returns A ComparePoint with the operator and value AST node
73
116
  * @throws {ParseError} If the next token is not a comparison operator
74
117
  */
@@ -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,WAAW,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EACV,OAAO,EAYR,MAAM,OAAO,CAAC;AAGf;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAMxF;AAkDD;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,GAAG,CAAK;gBAEJ,MAAM,EAAE,KAAK,EAAE;IAI3B;;OAEG;IACH,KAAK,IAAI,OAAO;IAqBhB;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAsChB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAwDhB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,WAAW;IAenB;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAW9B;;;;;;OAMG;IACH,iBAAiB,IAAI,YAAY;IAWjC,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,SAAS;IA8CjB,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,SAAS;CAGlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/C"}
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;AAC3D,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EACV,OAAO,EAkBR,MAAM,UAAU,CAAC;AAYlB;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAMxF;AAwED;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;gBAEN,MAAM,EAAE,KAAK,EAAE;IAI3B;;OAEG;IACH,KAAK,IAAI,OAAO;IAqBhB;;OAEG;IACH,OAAO,CAAC,eAAe;IA8BvB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IA4ChB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAgEhB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IA0DzB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,wBAAwB;IAgBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,aAAa;IAqDrB,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,WAAW;IAyCnB,OAAO,CAAC,SAAS;IAgDjB,OAAO,CAAC,kBAAkB;IA+E1B,OAAO,CAAC,iBAAiB;IA8CzB,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAW9B;;;;;;;;;;;;;OAaG;IACH,iBAAiB,IAAI,YAAY;IAajC,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,SAAS;IA2DjB,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,SAAS;CAGlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/C"}
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * @module rng
5
5
  */
6
- export type { RNG } from './types';
7
- export { SeededRNG } from './seeded';
6
+ export type { RNG } from './types.js';
7
+ export { SeededRNG } from './seeded.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module rng/mock
5
5
  */
6
- import type { RNG } from './types';
6
+ import type { RNG } from './types.js';
7
7
  /**
8
8
  * Error thrown when MockRNG exhausts its predefined values.
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/rng/mock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEnC;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAK7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAsBnD"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/rng/mock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAK7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAsBnD"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module rng/seeded
5
5
  */
6
- import type { RNG } from './types';
6
+ import type { RNG } from './types.js';
7
7
  /**
8
8
  * Seedable pseudo-random number generator using xorshift128.
9
9
  *
@@ -29,5 +29,12 @@ export declare class SeededRNG implements RNG {
29
29
  private nextUint32;
30
30
  next(): number;
31
31
  nextInt(min: number, max: number): number;
32
+ /**
33
+ * Unbiased sampling in `[0, range)` for ranges above 2^32, built from two
34
+ * uint32 draws combined into a 53-bit integer (the largest width JS numbers
35
+ * represent exactly). Ranges beyond 2^53 cannot be sampled without bias —
36
+ * throw instead of silently degrading.
37
+ */
38
+ private nextBoundedWide;
32
39
  }
33
40
  //# sourceMappingURL=seeded.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seeded.d.ts","sourceRoot":"","sources":["../../src/rng/seeded.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEnC;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,YAAW,GAAG;IACnC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;gBAEP,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAelC,OAAO,CAAC,SAAS;IA+BjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;IAgBlB,IAAI,IAAI,MAAM;IAKd,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;CAsB1C"}
1
+ {"version":3,"file":"seeded.d.ts","sourceRoot":"","sources":["../../src/rng/seeded.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,YAAW,GAAG;IACnC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;gBAEP,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAelC,OAAO,CAAC,SAAS;IA+BjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;IAgBlB,IAAI,IAAI,MAAM;IAKd,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IA6BzC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAiBxB"}
package/dist/roll.d.ts CHANGED
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * @module roll
5
5
  */
6
- import type { RNG } from './rng/types';
7
- import type { RollResult } from './types';
6
+ import type { RNG } from './rng/types.js';
7
+ import type { RollResult } from './types.js';
8
8
  /**
9
9
  * Options for the roll function.
10
10
  */
@@ -19,6 +19,10 @@ export type RollOptions = {
19
19
  maxExplodeIterations?: number;
20
20
  /** Maximum reroll iterations allowed per die (default: 1,000) */
21
21
  maxRerollIterations?: number;
22
+ /** Variable context for `@name` / `@{name}` references (default: empty) */
23
+ context?: Record<string, number>;
24
+ /** Behavior when a referenced variable is missing from context (default: 'throw') */
25
+ onMissingVariable?: 'throw' | 'zero';
22
26
  };
23
27
  /**
24
28
  * Parses and evaluates a dice notation string.
@@ -1 +1 @@
1
- {"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,uDAAuD;IACvD,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAa5E"}
1
+ {"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;AAM9D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,uDAAuD;IACvD,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAiB5E"}
package/dist/testing.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @module testing
7
7
  */
8
- import { MockRNGExhaustedError as _MockRNGExhaustedError, createMockRng as _createMockRng } from './rng/mock';
8
+ import { MockRNGExhaustedError as _MockRNGExhaustedError, createMockRng as _createMockRng } from './rng/mock.js';
9
9
  export declare const createMockRng: typeof _createMockRng;
10
10
  export declare const MockRNGExhaustedError: typeof _MockRNGExhaustedError;
11
11
  //# sourceMappingURL=testing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,qBAAqB,IAAI,sBAAsB,EAC/C,aAAa,IAAI,cAAc,EAChC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,aAAa,uBAAiB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,qBAAqB,IAAI,sBAAsB,EAC/C,aAAa,IAAI,cAAc,EAChC,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,aAAa,uBAAiB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC"}