roll-parser 3.0.0-beta.0 → 3.1.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 (164) hide show
  1. package/CHANGELOG.md +142 -9
  2. package/MIGRATION.md +219 -0
  3. package/README.md +1026 -154
  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 +15 -3
  9. package/dist/cli/format.d.ts.map +1 -1
  10. package/dist/cli/format.js +18 -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 -17
  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 +27 -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 +89 -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 +41 -75
  33. package/dist/evaluator/evaluator.d.ts.map +1 -1
  34. package/dist/evaluator/evaluator.js +914 -0
  35. package/dist/evaluator/evaluator.js.map +1 -0
  36. package/dist/evaluator/modifiers/compare.js +15 -0
  37. package/dist/evaluator/modifiers/compare.js.map +1 -0
  38. package/dist/evaluator/modifiers/crit-threshold.d.ts +57 -5
  39. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
  40. package/dist/evaluator/modifiers/crit-threshold.js +42 -0
  41. package/dist/evaluator/modifiers/crit-threshold.js.map +1 -0
  42. package/dist/evaluator/modifiers/die-bound.d.ts +29 -0
  43. package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -0
  44. package/dist/evaluator/modifiers/die-bound.js +17 -0
  45. package/dist/evaluator/modifiers/die-bound.js.map +1 -0
  46. package/dist/evaluator/modifiers/explode.d.ts +13 -5
  47. package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
  48. package/dist/evaluator/modifiers/explode.js +105 -0
  49. package/dist/evaluator/modifiers/explode.js.map +1 -0
  50. package/dist/evaluator/modifiers/flags.d.ts +47 -0
  51. package/dist/evaluator/modifiers/flags.d.ts.map +1 -0
  52. package/dist/evaluator/modifiers/flags.js +25 -0
  53. package/dist/evaluator/modifiers/flags.js.map +1 -0
  54. package/dist/evaluator/modifiers/keep-drop.d.ts +15 -29
  55. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
  56. package/dist/evaluator/modifiers/keep-drop.js +82 -0
  57. package/dist/evaluator/modifiers/keep-drop.js.map +1 -0
  58. package/dist/evaluator/modifiers/reroll.d.ts +12 -4
  59. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
  60. package/dist/evaluator/modifiers/reroll.js +68 -0
  61. package/dist/evaluator/modifiers/reroll.js.map +1 -0
  62. package/dist/evaluator/modifiers/sort.d.ts +5 -1
  63. package/dist/evaluator/modifiers/sort.d.ts.map +1 -1
  64. package/dist/evaluator/modifiers/sort.js +13 -0
  65. package/dist/evaluator/modifiers/sort.js.map +1 -0
  66. package/dist/evaluator/modifiers/success-count.d.ts +6 -7
  67. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
  68. package/dist/evaluator/modifiers/success-count.js +25 -0
  69. package/dist/evaluator/modifiers/success-count.js.map +1 -0
  70. package/dist/index.d.ts +33 -11
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +12 -2560
  73. package/dist/index.js.map +1 -26
  74. package/dist/lexer/lexer.d.ts +50 -5
  75. package/dist/lexer/lexer.d.ts.map +1 -1
  76. package/dist/lexer/lexer.js +260 -0
  77. package/dist/lexer/lexer.js.map +1 -0
  78. package/dist/lexer/tokens.d.ts +31 -6
  79. package/dist/lexer/tokens.d.ts.map +1 -1
  80. package/dist/lexer/tokens.js +42 -0
  81. package/dist/lexer/tokens.js.map +1 -0
  82. package/dist/parser/ast.d.ts +324 -165
  83. package/dist/parser/ast.d.ts.map +1 -1
  84. package/dist/parser/ast.js +52 -0
  85. package/dist/parser/ast.js.map +1 -0
  86. package/dist/parser/guards.d.ts +106 -0
  87. package/dist/parser/guards.d.ts.map +1 -0
  88. package/dist/parser/guards.js +121 -0
  89. package/dist/parser/guards.js.map +1 -0
  90. package/dist/parser/parser.d.ts +118 -14
  91. package/dist/parser/parser.d.ts.map +1 -1
  92. package/dist/parser/parser.js +751 -0
  93. package/dist/parser/parser.js.map +1 -0
  94. package/dist/render.d.ts +95 -0
  95. package/dist/render.d.ts.map +1 -0
  96. package/dist/render.js +227 -0
  97. package/dist/render.js.map +1 -0
  98. package/dist/rng/mock.d.ts +73 -12
  99. package/dist/rng/mock.d.ts.map +1 -1
  100. package/dist/rng/mock.js +30 -0
  101. package/dist/rng/mock.js.map +1 -0
  102. package/dist/rng/seeded.d.ts +141 -9
  103. package/dist/rng/seeded.d.ts.map +1 -1
  104. package/dist/rng/seeded.js +138 -0
  105. package/dist/rng/seeded.js.map +1 -0
  106. package/dist/rng/types.d.ts +57 -0
  107. package/dist/rng/types.d.ts.map +1 -1
  108. package/dist/rng/types.js +2 -0
  109. package/dist/rng/types.js.map +1 -0
  110. package/dist/roll.d.ts +58 -28
  111. package/dist/roll.d.ts.map +1 -1
  112. package/dist/roll.js +8 -0
  113. package/dist/roll.js.map +1 -0
  114. package/dist/testing.d.ts +5 -4
  115. package/dist/testing.d.ts.map +1 -1
  116. package/dist/testing.js +2 -41
  117. package/dist/testing.js.map +1 -11
  118. package/dist/types.d.ts +349 -47
  119. package/dist/types.d.ts.map +1 -1
  120. package/dist/types.js +8 -0
  121. package/dist/types.js.map +1 -0
  122. package/dist/version.d.ts +2 -0
  123. package/dist/version.d.ts.map +1 -0
  124. package/dist/version.js +2 -0
  125. package/dist/version.js.map +1 -0
  126. package/package.json +93 -34
  127. package/src/cli/args.ts +66 -10
  128. package/src/cli/format.ts +37 -26
  129. package/src/cli/index.ts +27 -84
  130. package/src/cli/main.ts +129 -0
  131. package/src/errors.ts +480 -27
  132. package/src/evaluator/die.ts +51 -0
  133. package/src/evaluator/env.ts +105 -0
  134. package/src/evaluator/evaluator.ts +693 -434
  135. package/src/evaluator/modifiers/crit-threshold.ts +96 -14
  136. package/src/evaluator/modifiers/die-bound.ts +48 -0
  137. package/src/evaluator/modifiers/explode.ts +70 -62
  138. package/src/evaluator/modifiers/flags.ts +78 -0
  139. package/src/evaluator/modifiers/keep-drop.ts +129 -127
  140. package/src/evaluator/modifiers/reroll.ts +44 -56
  141. package/src/evaluator/modifiers/sort.ts +21 -2
  142. package/src/evaluator/modifiers/success-count.ts +24 -12
  143. package/src/index.ts +56 -35
  144. package/src/lexer/lexer.ts +107 -34
  145. package/src/lexer/tokens.ts +31 -6
  146. package/src/parser/ast.ts +333 -346
  147. package/src/parser/guards.ts +248 -0
  148. package/src/parser/parser.ts +419 -242
  149. package/src/render.ts +392 -0
  150. package/src/rng/mock.ts +74 -13
  151. package/src/rng/seeded.ts +299 -64
  152. package/src/rng/types.ts +57 -0
  153. package/src/roll.ts +64 -47
  154. package/src/testing.ts +5 -9
  155. package/src/types.ts +353 -46
  156. package/src/version.ts +2 -0
  157. package/dist/cli.js +0 -2608
  158. package/dist/cli.js.map +0 -28
  159. package/dist/evaluator/index.d.ts +0 -8
  160. package/dist/evaluator/index.d.ts.map +0 -1
  161. package/dist/rng/index.d.ts +0 -8
  162. package/dist/rng/index.d.ts.map +0 -1
  163. package/src/evaluator/index.ts +0 -14
  164. package/src/rng/index.ts +0 -8
@@ -8,11 +8,40 @@ import { RollParserError } from '../errors.js';
8
8
  import { type Token } from './tokens.js';
9
9
  /**
10
10
  * Error thrown when the lexer encounters an invalid character.
11
+ *
12
+ * `position` is a zero-based UTF-16 offset into the input. It is deliberately
13
+ * absent from `message` — read it from the field, or uniformly across all
14
+ * roll-parser errors via `getErrorSpan`.
15
+ *
16
+ * Codes: `UNEXPECTED_CHARACTER` for a character that cannot start any token,
17
+ * `UNEXPECTED_IDENTIFIER` for a word that is not a known keyword.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { LexerError, roll } from 'roll-parser';
22
+ *
23
+ * try {
24
+ * roll('2d6+&');
25
+ * } catch (error) {
26
+ * const typed = error as LexerError;
27
+ * typed.code; // 'UNEXPECTED_CHARACTER'
28
+ * typed.character; // '&'
29
+ * typed.position; // 4
30
+ * }
31
+ * ```
32
+ *
33
+ * @category Errors
11
34
  */
12
35
  export declare class LexerError extends RollParserError {
36
+ /** Zero-based UTF-16 offset of the offending character in the input. */
13
37
  readonly position: number;
38
+ /**
39
+ * The offending text — a single character for `UNEXPECTED_CHARACTER` (the
40
+ * whole code point, so astral symbols are not split into surrogates), or
41
+ * the unrecognized word for `UNEXPECTED_IDENTIFIER`.
42
+ */
14
43
  readonly character: string;
15
- constructor(message: string, code: RollParserErrorCode, position: number, character: string);
44
+ constructor(message: string, code: RollParserErrorCode, position: number, character: string, options?: ErrorOptions);
16
45
  }
17
46
  /**
18
47
  * Lexer for dice notation.
@@ -74,17 +103,33 @@ export declare class Lexer {
74
103
  private createTokenAt;
75
104
  }
76
105
  /**
77
- * Tokenize a dice notation string.
106
+ * Tokenizes a dice notation string. The first stage of the pipeline —
107
+ * {@link parse} calls it for you; reach for `lex` directly only to build a
108
+ * syntax highlighter or an editor integration.
109
+ *
110
+ * Notation is case-insensitive and whitespace-tolerant: `2D20 + 5` and
111
+ * `2d20+5` produce the same tokens, and identifier tokens carry a lowercased
112
+ * `value`. The one exception is `@name`, whose case is preserved.
78
113
  *
79
114
  * @param input - The dice notation to tokenize
80
- * @returns Array of tokens including EOF
81
- * @throws {LexerError} If an invalid character is encountered
115
+ * @returns Every token in source order, always ending with one
116
+ * `TokenType.EOF` token
117
+ * @throws {LexerError} If an invalid character or unknown identifier is found
118
+ * @throws {RollParserError} `INVALID_NOTATION_TYPE` when `input` is not a
119
+ * string — raised before scanning, so it carries no position
82
120
  *
83
121
  * @example
84
122
  * ```typescript
123
+ * import { lex, TokenType } from 'roll-parser';
124
+ *
85
125
  * const tokens = lex('2d20+5');
86
- * // [NUMBER(2), DICE, NUMBER(20), PLUS, NUMBER(5), EOF]
126
+ * tokens.length; // 6 — NUMBER DICE NUMBER PLUS NUMBER EOF
127
+ * tokens[0]; // { type: TokenType.NUMBER, value: '2', position: 0, end: 1 }
128
+ * tokens[1].type === TokenType.DICE; // true
129
+ * tokens.at(-1)?.type === TokenType.EOF; // true
87
130
  * ```
131
+ *
132
+ * @category Core
88
133
  */
89
134
  export declare function lex(input: string): Token[];
90
135
  //# sourceMappingURL=lexer.d.ts.map
@@ -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,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"}
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,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YACE,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,mBAAmB,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,EAMvB;CACF;AA0DD;;;;;GAKG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,EAAE,MAAM,EAExB;IAED;;OAEG;IACH,QAAQ,IAAI,KAAK,EAAE,CAUlB;IAED;;OAEG;IACH,SAAS,IAAI,KAAK,CA8EjB;IAMD,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAiBlB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAkCtB;;;;;;;;;;;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;IAMf,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;CAGtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAU1C"}
@@ -0,0 +1,260 @@
1
+ import { describeValue, RollParserError } from '../errors.js';
2
+ import { TokenType } from './tokens.js';
3
+ export class LexerError extends RollParserError {
4
+ position;
5
+ character;
6
+ constructor(message, code, position, character, options) {
7
+ super(`${message}: '${character}'`, code, options);
8
+ this.name = 'LexerError';
9
+ this.position = position;
10
+ this.character = character;
11
+ }
12
+ }
13
+ const CHAR_DIGIT_0 = 48;
14
+ const CHAR_DIGIT_9 = 57;
15
+ const CHAR_UPPER_A = 65;
16
+ const CHAR_UPPER_Z = 90;
17
+ const CHAR_LOWER_A = 97;
18
+ const CHAR_LOWER_Z = 122;
19
+ const IDENTIFIER_KEYWORDS = {
20
+ kh: TokenType.KEEP_HIGH,
21
+ kl: TokenType.KEEP_LOW,
22
+ k: TokenType.KEEP_HIGH,
23
+ dh: TokenType.DROP_HIGH,
24
+ dl: TokenType.DROP_LOW,
25
+ d: TokenType.DICE,
26
+ r: TokenType.REROLL,
27
+ ro: TokenType.REROLL_ONCE,
28
+ f: TokenType.FAIL,
29
+ vs: TokenType.VS,
30
+ floor: TokenType.FUNCTION,
31
+ ceil: TokenType.FUNCTION,
32
+ round: TokenType.FUNCTION,
33
+ abs: TokenType.FUNCTION,
34
+ sqrt: TokenType.FUNCTION,
35
+ pow: TokenType.FUNCTION,
36
+ max: TokenType.FUNCTION,
37
+ min: TokenType.FUNCTION,
38
+ s: TokenType.SORT_ASC,
39
+ sa: TokenType.SORT_ASC,
40
+ sd: TokenType.SORT_DESC,
41
+ cs: TokenType.CRIT_SUCCESS,
42
+ cf: TokenType.CRIT_FAIL,
43
+ };
44
+ function buildIdentifierHint(identifier) {
45
+ for (let length = identifier.length - 1; length >= 1; length--) {
46
+ const prefix = identifier.slice(0, length);
47
+ if (IDENTIFIER_KEYWORDS[prefix] == null)
48
+ continue;
49
+ const rest = identifier.slice(length);
50
+ return ` (did you mean '${prefix}' followed by '${rest}'? separate modifiers with a count or space, e.g. '${prefix}1${rest}')`;
51
+ }
52
+ return '';
53
+ }
54
+ export class Lexer {
55
+ pos = 0;
56
+ input;
57
+ constructor(input) {
58
+ this.input = input;
59
+ }
60
+ tokenize() {
61
+ const tokens = [];
62
+ while (true) {
63
+ const token = this.nextToken();
64
+ tokens.push(token);
65
+ if (token.type === TokenType.EOF)
66
+ break;
67
+ }
68
+ return tokens;
69
+ }
70
+ nextToken() {
71
+ this.skipWhitespace();
72
+ if (this.isAtEnd()) {
73
+ return this.createToken(TokenType.EOF, '');
74
+ }
75
+ const startPos = this.pos;
76
+ const char = this.peek();
77
+ if (this.isDigit(char)) {
78
+ return this.scanNumber();
79
+ }
80
+ if (this.isAlpha(char)) {
81
+ return this.scanIdentifier();
82
+ }
83
+ if (char === '@') {
84
+ return this.scanAt();
85
+ }
86
+ this.advance();
87
+ switch (char) {
88
+ case '+':
89
+ return this.createTokenAt(TokenType.PLUS, char, startPos);
90
+ case '-':
91
+ return this.createTokenAt(TokenType.MINUS, char, startPos);
92
+ case '*':
93
+ if (this.match('*')) {
94
+ return this.createTokenAt(TokenType.POWER, '**', startPos);
95
+ }
96
+ return this.createTokenAt(TokenType.MULTIPLY, char, startPos);
97
+ case '/':
98
+ return this.createTokenAt(TokenType.DIVIDE, char, startPos);
99
+ case '%':
100
+ return this.createTokenAt(TokenType.MODULO, char, startPos);
101
+ case '^':
102
+ return this.createTokenAt(TokenType.POWER, char, startPos);
103
+ case '(':
104
+ return this.createTokenAt(TokenType.LPAREN, char, startPos);
105
+ case ')':
106
+ return this.createTokenAt(TokenType.RPAREN, char, startPos);
107
+ case ',':
108
+ return this.createTokenAt(TokenType.COMMA, char, startPos);
109
+ case '{':
110
+ return this.createTokenAt(TokenType.LBRACE, char, startPos);
111
+ case '}':
112
+ return this.createTokenAt(TokenType.RBRACE, char, startPos);
113
+ case '>':
114
+ if (this.match('=')) {
115
+ return this.createTokenAt(TokenType.GREATER_EQUAL, '>=', startPos);
116
+ }
117
+ return this.createTokenAt(TokenType.GREATER, char, startPos);
118
+ case '<':
119
+ if (this.match('=')) {
120
+ return this.createTokenAt(TokenType.LESS_EQUAL, '<=', startPos);
121
+ }
122
+ return this.createTokenAt(TokenType.LESS, char, startPos);
123
+ case '=':
124
+ return this.createTokenAt(TokenType.EQUAL, char, startPos);
125
+ case '!':
126
+ if (this.match('!')) {
127
+ return this.createTokenAt(TokenType.EXPLODE_COMPOUND, '!!', startPos);
128
+ }
129
+ if (this.match('p') || this.match('P')) {
130
+ return this.createTokenAt(TokenType.EXPLODE_PENETRATING, '!p', startPos);
131
+ }
132
+ return this.createTokenAt(TokenType.EXPLODE, char, startPos);
133
+ default: {
134
+ const codePoint = this.input.codePointAt(startPos);
135
+ const display = codePoint == null ? char : String.fromCodePoint(codePoint);
136
+ throw new LexerError('Unexpected character', 'UNEXPECTED_CHARACTER', startPos, display);
137
+ }
138
+ }
139
+ }
140
+ skipWhitespace() {
141
+ while (!this.isAtEnd() && this.isWhitespace(this.peek())) {
142
+ this.advance();
143
+ }
144
+ }
145
+ scanNumber() {
146
+ const startPos = this.pos;
147
+ while (!this.isAtEnd() && this.isDigit(this.peek())) {
148
+ this.pos++;
149
+ }
150
+ if (!this.isAtEnd() && this.peek() === '.' && this.isDigit(this.peekNext())) {
151
+ this.pos++;
152
+ while (!this.isAtEnd() && this.isDigit(this.peek())) {
153
+ this.pos++;
154
+ }
155
+ }
156
+ return this.createTokenAt(TokenType.NUMBER, this.input.slice(startPos, this.pos), startPos);
157
+ }
158
+ scanIdentifier() {
159
+ const startPos = this.pos;
160
+ const first = this.peek();
161
+ const second = this.peekNext();
162
+ if ((first === 'd' || first === 'D') && (second === 'f' || second === 'F')) {
163
+ this.pos += 2;
164
+ return this.createTokenAt(TokenType.DICE_FATE, 'df', startPos);
165
+ }
166
+ while (!this.isAtEnd() && this.isAlpha(this.peek())) {
167
+ this.pos++;
168
+ }
169
+ const lower = this.input.slice(startPos, this.pos).toLowerCase();
170
+ if (lower === 'd' && !this.isAtEnd() && this.peek() === '%') {
171
+ this.advance();
172
+ return this.createTokenAt(TokenType.DICE_PERCENT, 'd%', startPos);
173
+ }
174
+ const tokenType = IDENTIFIER_KEYWORDS[lower];
175
+ if (tokenType != null) {
176
+ return this.createTokenAt(tokenType, lower, startPos);
177
+ }
178
+ throw new LexerError(`Unexpected identifier${buildIdentifierHint(lower)}`, 'UNEXPECTED_IDENTIFIER', startPos, lower);
179
+ }
180
+ scanAt() {
181
+ const startPos = this.pos;
182
+ this.advance();
183
+ let name;
184
+ if (!this.isAtEnd() && this.peek() === '{') {
185
+ this.advance();
186
+ const nameStart = this.pos;
187
+ while (!this.isAtEnd() && this.peek() !== '}' && this.peek() !== '\n') {
188
+ this.advance();
189
+ }
190
+ if (this.isAtEnd() || this.peek() !== '}') {
191
+ throw new LexerError('Unterminated @{...} variable', 'UNEXPECTED_CHARACTER', startPos, '@');
192
+ }
193
+ name = this.input.slice(nameStart, this.pos);
194
+ this.advance();
195
+ }
196
+ else {
197
+ const nameStart = this.pos;
198
+ if (this.isAtEnd() || !this.isIdentifierStart(this.peek())) {
199
+ throw new LexerError('Empty @ variable name', 'UNEXPECTED_CHARACTER', startPos, '@');
200
+ }
201
+ this.advance();
202
+ while (!this.isAtEnd() && this.isIdentifierPart(this.peek())) {
203
+ this.advance();
204
+ }
205
+ name = this.input.slice(nameStart, this.pos);
206
+ }
207
+ return this.createTokenAt(TokenType.AT, name, startPos);
208
+ }
209
+ peek() {
210
+ return this.input[this.pos] ?? '';
211
+ }
212
+ peekNext() {
213
+ return this.input[this.pos + 1] ?? '';
214
+ }
215
+ advance() {
216
+ return this.input[this.pos++] ?? '';
217
+ }
218
+ match(expected) {
219
+ if (this.isAtEnd())
220
+ return false;
221
+ if (this.input[this.pos] !== expected)
222
+ return false;
223
+ this.pos++;
224
+ return true;
225
+ }
226
+ isAtEnd() {
227
+ return this.pos >= this.input.length;
228
+ }
229
+ isDigit(char) {
230
+ const code = char.charCodeAt(0);
231
+ return code >= CHAR_DIGIT_0 && code <= CHAR_DIGIT_9;
232
+ }
233
+ isAlpha(char) {
234
+ const code = char.charCodeAt(0);
235
+ return ((code >= CHAR_LOWER_A && code <= CHAR_LOWER_Z) ||
236
+ (code >= CHAR_UPPER_A && code <= CHAR_UPPER_Z));
237
+ }
238
+ isIdentifierStart(char) {
239
+ return this.isAlpha(char) || char === '_';
240
+ }
241
+ isIdentifierPart(char) {
242
+ return this.isAlpha(char) || this.isDigit(char) || char === '_';
243
+ }
244
+ isWhitespace(char) {
245
+ return char === ' ' || char === '\t' || char === '\n' || char === '\r';
246
+ }
247
+ createToken(type, value) {
248
+ return { type, value, position: this.pos, end: this.pos };
249
+ }
250
+ createTokenAt(type, value, position) {
251
+ return { type, value, position, end: this.pos };
252
+ }
253
+ }
254
+ export function lex(input) {
255
+ if (typeof input !== 'string') {
256
+ throw new RollParserError(`Notation must be a string, received ${describeValue(input)}`, 'INVALID_NOTATION_TYPE');
257
+ }
258
+ return new Lexer(input).tokenize();
259
+ }
260
+ //# sourceMappingURL=lexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/lexer/lexer.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@
8
8
  *
9
9
  * Grouped semantically. Numeric values are stable identifiers — the specific
10
10
  * numbers don't matter, but they must be unique.
11
+ *
12
+ * @category AST
11
13
  */
12
14
  export declare enum TokenType {
13
15
  /** Numeric literal: integer or decimal */
@@ -66,7 +68,11 @@ export declare enum TokenType {
66
68
  REROLL_ONCE = 26,
67
69
  /** Fail marker: 'f' */
68
70
  FAIL = 27,
69
- /** Math function: 'floor', 'ceil', 'round', 'abs', 'max', 'min' */
71
+ /**
72
+ * Math function: 'floor', 'ceil', 'round', 'abs', 'sqrt', 'pow', 'max',
73
+ * 'min'. In postfix position, 'min'/'max' double as per-die clamp
74
+ * modifiers (`4d6min2`) — the parser decides by position, not the lexer.
75
+ */
70
76
  FUNCTION = 28,
71
77
  /** Versus operator: 'vs' */
72
78
  VS = 29,
@@ -88,20 +94,39 @@ export declare enum TokenType {
88
94
  EOF = 37
89
95
  }
90
96
  /**
91
- * A token produced by the lexer.
97
+ * A token produced by {@link lex}: what it is, the text it came from, and
98
+ * where in the input that text sits.
99
+ *
100
+ * `position`/`end` are a half-open range, so `input.slice(position, end)`
101
+ * recovers the original source text — useful for syntax highlighting, where
102
+ * `value` alone is lossy.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * import { lex, TokenType } from 'roll-parser';
107
+ *
108
+ * const input = '4D6KH3';
109
+ * const tokens = lex(input);
110
+ * tokens[1]; // { type: TokenType.DICE, value: 'd', position: 1, end: 2 }
111
+ * tokens[3].type === TokenType.KEEP_HIGH; // true
112
+ * input.slice(tokens[3].position, tokens[3].end); // 'KH' — original casing
113
+ * tokens[3].value; // 'kh' — normalized
114
+ * ```
115
+ *
116
+ * @category AST
92
117
  */
93
118
  export type Token = {
94
119
  /** The type of this token */
95
- type: TokenType;
120
+ readonly type: TokenType;
96
121
  /** The raw string value from input (lowercased for identifiers) */
97
- value: string;
122
+ readonly value: string;
98
123
  /** Zero-based start offset in the input string (UTF-16 code units) */
99
- position: number;
124
+ readonly position: number;
100
125
  /**
101
126
  * Zero-based end offset (exclusive). Not always `position + value.length` —
102
127
  * braced variables (`@{name}` stores only `name`) and case-normalized
103
128
  * identifiers consume more input than their `value` retains.
104
129
  */
105
- end: number;
130
+ readonly end: number;
106
131
  };
107
132
  //# 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,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"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lexer/tokens.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;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;;;;OAIG;IACH,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;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -0,0 +1,42 @@
1
+ export var TokenType;
2
+ (function (TokenType) {
3
+ TokenType[TokenType["NUMBER"] = 0] = "NUMBER";
4
+ TokenType[TokenType["DICE"] = 1] = "DICE";
5
+ TokenType[TokenType["DICE_PERCENT"] = 2] = "DICE_PERCENT";
6
+ TokenType[TokenType["DICE_FATE"] = 3] = "DICE_FATE";
7
+ TokenType[TokenType["PLUS"] = 4] = "PLUS";
8
+ TokenType[TokenType["MINUS"] = 5] = "MINUS";
9
+ TokenType[TokenType["MULTIPLY"] = 6] = "MULTIPLY";
10
+ TokenType[TokenType["DIVIDE"] = 7] = "DIVIDE";
11
+ TokenType[TokenType["MODULO"] = 8] = "MODULO";
12
+ TokenType[TokenType["POWER"] = 9] = "POWER";
13
+ TokenType[TokenType["GREATER"] = 10] = "GREATER";
14
+ TokenType[TokenType["GREATER_EQUAL"] = 11] = "GREATER_EQUAL";
15
+ TokenType[TokenType["LESS"] = 12] = "LESS";
16
+ TokenType[TokenType["LESS_EQUAL"] = 13] = "LESS_EQUAL";
17
+ TokenType[TokenType["EQUAL"] = 14] = "EQUAL";
18
+ TokenType[TokenType["LPAREN"] = 15] = "LPAREN";
19
+ TokenType[TokenType["RPAREN"] = 16] = "RPAREN";
20
+ TokenType[TokenType["COMMA"] = 17] = "COMMA";
21
+ TokenType[TokenType["KEEP_HIGH"] = 18] = "KEEP_HIGH";
22
+ TokenType[TokenType["KEEP_LOW"] = 19] = "KEEP_LOW";
23
+ TokenType[TokenType["DROP_HIGH"] = 20] = "DROP_HIGH";
24
+ TokenType[TokenType["DROP_LOW"] = 21] = "DROP_LOW";
25
+ TokenType[TokenType["EXPLODE"] = 22] = "EXPLODE";
26
+ TokenType[TokenType["EXPLODE_COMPOUND"] = 23] = "EXPLODE_COMPOUND";
27
+ TokenType[TokenType["EXPLODE_PENETRATING"] = 24] = "EXPLODE_PENETRATING";
28
+ TokenType[TokenType["REROLL"] = 25] = "REROLL";
29
+ TokenType[TokenType["REROLL_ONCE"] = 26] = "REROLL_ONCE";
30
+ TokenType[TokenType["FAIL"] = 27] = "FAIL";
31
+ TokenType[TokenType["FUNCTION"] = 28] = "FUNCTION";
32
+ TokenType[TokenType["VS"] = 29] = "VS";
33
+ TokenType[TokenType["LBRACE"] = 30] = "LBRACE";
34
+ TokenType[TokenType["RBRACE"] = 31] = "RBRACE";
35
+ TokenType[TokenType["AT"] = 32] = "AT";
36
+ TokenType[TokenType["SORT_ASC"] = 33] = "SORT_ASC";
37
+ TokenType[TokenType["SORT_DESC"] = 34] = "SORT_DESC";
38
+ TokenType[TokenType["CRIT_SUCCESS"] = 35] = "CRIT_SUCCESS";
39
+ TokenType[TokenType["CRIT_FAIL"] = 36] = "CRIT_FAIL";
40
+ TokenType[TokenType["EOF"] = 37] = "EOF";
41
+ })(TokenType || (TokenType = {}));
42
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/lexer/tokens.ts"],"names":[],"mappings":"AAcA,MAAM,CAAN,IAAY,SAgKX;AAhKD,WAAY,SAAS;IAMnB,6CAAU,CAAA;IAOV,yCAAQ,CAAA;IAER,yDAAgB,CAAA;IAEhB,mDAAa,CAAA;IAOb,yCAAQ,CAAA;IAER,2CAAS,CAAA;IAET,iDAAY,CAAA;IAEZ,6CAAU,CAAA;IAEV,6CAAU,CAAA;IAEV,2CAAS,CAAA;IAOT,gDAAY,CAAA;IAEZ,4DAAkB,CAAA;IAElB,0CAAS,CAAA;IAET,sDAAe,CAAA;IAEf,4CAAU,CAAA;IAOV,8CAAW,CAAA;IAEX,8CAAW,CAAA;IAEX,4CAAU,CAAA;IAOV,oDAAc,CAAA;IAEd,kDAAa,CAAA;IAEb,oDAAc,CAAA;IAEd,kDAAa,CAAA;IAOb,gDAAY,CAAA;IAEZ,kEAAqB,CAAA;IAErB,wEAAwB,CAAA;IAOxB,8CAAW,CAAA;IAEX,wDAAgB,CAAA;IAOhB,0CAAS,CAAA;IAWT,kDAAa,CAAA;IAOb,sCAAO,CAAA;IAOP,8CAAW,CAAA;IAEX,8CAAW,CAAA;IAOX,sCAAO,CAAA;IAOP,kDAAa,CAAA;IAEb,oDAAc,CAAA;IAOd,0DAAiB,CAAA;IAEjB,oDAAc,CAAA;IAOd,wCAAQ,CAAA;AACV,CAAC,EAhKW,SAAS,KAAT,SAAS,QAgKpB"}