@@ -24,7 +24,7 @@ export function createLexer<TOptions>(
24
24
source : Source ,
25
25
options : TOptions ,
26
26
) : Lexer < TOptions > {
27
- const startOfFileToken = new Tok ( SOF , 0 , 0 , 0 , 0 , null ) ;
27
+ const startOfFileToken = new Tok ( TokenKind . SOF , 0 , 0 , 0 , 0 , null ) ;
28
28
const lexer : Lexer < TOptions > = {
29
29
source,
30
30
options,
@@ -46,11 +46,11 @@ function advanceLexer() {
46
46
47
47
function lookahead ( ) {
48
48
let token = this . token ;
49
- if ( token . kind !== EOF ) {
49
+ if ( token . kind !== TokenKind . EOF ) {
50
50
do {
51
51
// Note: next is only mutable during parsing, so we cast to allow this.
52
52
token = token . next || ( ( token : any ) . next = readToken ( this , token ) ) ;
53
- } while ( token . kind === COMMENT ) ;
53
+ } while ( token . kind === TokenKind . COMMENT ) ;
54
54
}
55
55
return token ;
56
56
}
@@ -94,58 +94,39 @@ export type Lexer<TOptions> = {
94
94
lookahead ( ) : Token ,
95
95
} ;
96
96
97
- // Each kind of token.
98
- const SOF = '<SOF>' ;
99
- const EOF = '<EOF>' ;
100
- const BANG = '!' ;
101
- const DOLLAR = '$' ;
102
- const AMP = '&' ;
103
- const PAREN_L = '(' ;
104
- const PAREN_R = ')' ;
105
- const SPREAD = '...' ;
106
- const COLON = ':' ;
107
- const EQUALS = '=' ;
108
- const AT = '@' ;
109
- const BRACKET_L = '[' ;
110
- const BRACKET_R = ']' ;
111
- const BRACE_L = '{' ;
112
- const PIPE = '|' ;
113
- const BRACE_R = '}' ;
114
- const NAME = 'Name' ;
115
- const INT = 'Int' ;
116
- const FLOAT = 'Float' ;
117
- const STRING = 'String' ;
118
- const BLOCK_STRING = 'BlockString' ;
119
- const COMMENT = 'Comment' ;
120
-
121
97
/**
122
98
* An exported enum describing the different kinds of tokens that the
123
99
* lexer emits.
124
100
*/
125
- export const TokenKind = {
126
- SOF ,
127
- EOF ,
128
- BANG ,
129
- DOLLAR ,
130
- AMP ,
131
- PAREN_L ,
132
- PAREN_R ,
133
- SPREAD ,
134
- COLON ,
135
- EQUALS ,
136
- AT ,
137
- BRACKET_L ,
138
- BRACKET_R ,
139
- BRACE_L ,
140
- PIPE ,
141
- BRACE_R ,
142
- NAME ,
143
- INT ,
144
- FLOAT ,
145
- STRING ,
146
- BLOCK_STRING ,
147
- COMMENT ,
148
- } ;
101
+ export const TokenKind = Object . freeze ( {
102
+ SOF : '<SOF>' ,
103
+ EOF : '<EOF>' ,
104
+ BANG : '!' ,
105
+ DOLLAR : '$' ,
106
+ AMP : '&' ,
107
+ PAREN_L : '(' ,
108
+ PAREN_R : ')' ,
109
+ SPREAD : '...' ,
110
+ COLON : ':' ,
111
+ EQUALS : '=' ,
112
+ AT : '@' ,
113
+ BRACKET_L : '[' ,
114
+ BRACKET_R : ']' ,
115
+ BRACE_L : '{' ,
116
+ PIPE : '|' ,
117
+ BRACE_R : '}' ,
118
+ NAME : 'Name' ,
119
+ INT : 'Int' ,
120
+ FLOAT : 'Float' ,
121
+ STRING : 'String' ,
122
+ BLOCK_STRING : 'BlockString' ,
123
+ COMMENT : 'Comment' ,
124
+ } ) ;
125
+
126
+ /**
127
+ * The enum type representing the token kinds values.
128
+ */
129
+ export type TokenKindEnum = $Values < typeof TokenKind > ;
149
130
150
131
/**
151
132
* A helper function to describe a token as a string for debugging
@@ -162,7 +143,7 @@ const slice = String.prototype.slice;
162
143
* Helper function for constructing the Token object.
163
144
*/
164
145
function Tok (
165
- kind ,
146
+ kind : TokenKindEnum ,
166
147
start : number ,
167
148
end : number ,
168
149
line : number ,
@@ -194,7 +175,7 @@ function printCharCode(code) {
194
175
return (
195
176
// NaN/undefined represents access beyond the end of the file.
196
177
isNaN ( code )
197
- ? EOF
178
+ ? TokenKind . EOF
198
179
: // Trust JSON for ASCII.
199
180
code < 0x007f
200
181
? JSON . stringify ( String . fromCharCode ( code ) )
@@ -220,7 +201,7 @@ function readToken(lexer: Lexer<*>, prev: Token): Token {
220
201
const col = 1 + position - lexer . lineStart ;
221
202
222
203
if ( position >= bodyLength ) {
223
- return new Tok ( EOF , bodyLength , bodyLength , line , col , prev ) ;
204
+ return new Tok ( TokenKind . EOF , bodyLength , bodyLength , line , col , prev ) ;
224
205
}
225
206
226
207
const code = charCodeAt . call ( body , position ) ;
@@ -234,58 +215,62 @@ function readToken(lexer: Lexer<*>, prev: Token): Token {
234
215
) ;
235
216
}
236
217
218
+ function literalTok ( kind : TokenKindEnum ) {
219
+ return new Tok ( kind , position , position + kind . length , line , col , prev ) ;
220
+ }
221
+
237
222
switch ( code ) {
238
223
// !
239
224
case 33 :
240
- return new Tok ( BANG , position , position + 1 , line , col , prev ) ;
225
+ return literalTok ( TokenKind . BANG ) ;
241
226
// #
242
227
case 35 :
243
228
return readComment ( source , position , line , col , prev ) ;
244
229
// $
245
230
case 36 :
246
- return new Tok ( DOLLAR , position , position + 1 , line , col , prev ) ;
231
+ return literalTok ( TokenKind . DOLLAR ) ;
247
232
// &
248
233
case 38 :
249
- return new Tok ( AMP , position , position + 1 , line , col , prev ) ;
234
+ return literalTok ( TokenKind . AMP ) ;
250
235
// (
251
236
case 40 :
252
- return new Tok ( PAREN_L , position , position + 1 , line , col , prev ) ;
237
+ return literalTok ( TokenKind . PAREN_L ) ;
253
238
// )
254
239
case 41 :
255
- return new Tok ( PAREN_R , position , position + 1 , line , col , prev ) ;
240
+ return literalTok ( TokenKind . PAREN_R ) ;
256
241
// .
257
242
case 46 :
258
243
if (
259
244
charCodeAt . call ( body , position + 1 ) === 46 &&
260
245
charCodeAt . call ( body , position + 2 ) === 46
261
246
) {
262
- return new Tok ( SPREAD , position , position + 3 , line , col , prev ) ;
247
+ return literalTok ( TokenKind . SPREAD ) ;
263
248
}
264
249
break ;
265
250
// :
266
251
case 58 :
267
- return new Tok ( COLON , position , position + 1 , line , col , prev ) ;
252
+ return literalTok ( TokenKind . COLON ) ;
268
253
// =
269
254
case 61 :
270
- return new Tok ( EQUALS , position , position + 1 , line , col , prev ) ;
255
+ return literalTok ( TokenKind . EQUALS ) ;
271
256
// @
272
257
case 64 :
273
- return new Tok ( AT , position , position + 1 , line , col , prev ) ;
258
+ return literalTok ( TokenKind . AT ) ;
274
259
// [
275
260
case 91 :
276
- return new Tok ( BRACKET_L , position , position + 1 , line , col , prev ) ;
261
+ return literalTok ( TokenKind . BRACKET_L ) ;
277
262
// ]
278
263
case 93 :
279
- return new Tok ( BRACKET_R , position , position + 1 , line , col , prev ) ;
264
+ return literalTok ( TokenKind . BRACKET_R ) ;
280
265
// {
281
266
case 123 :
282
- return new Tok ( BRACE_L , position , position + 1 , line , col , prev ) ;
267
+ return literalTok ( TokenKind . BRACE_L ) ;
283
268
// |
284
269
case 124 :
285
- return new Tok ( PIPE , position , position + 1 , line , col , prev ) ;
270
+ return literalTok ( TokenKind . PIPE ) ;
286
271
// }
287
272
case 125 :
288
- return new Tok ( BRACE_R , position , position + 1 , line , col , prev ) ;
273
+ return literalTok ( TokenKind . BRACE_R ) ;
289
274
// A-Z _ a-z
290
275
case 65 :
291
276
case 66 :
@@ -440,7 +425,7 @@ function readComment(source, start, line, col, prev): Token {
440
425
) ;
441
426
442
427
return new Tok (
443
- COMMENT ,
428
+ TokenKind . COMMENT ,
444
429
start ,
445
430
position ,
446
431
line ,
@@ -505,7 +490,7 @@ function readNumber(source, start, firstCode, line, col, prev): Token {
505
490
}
506
491
507
492
return new Tok (
508
- isFloat ? FLOAT : INT ,
493
+ isFloat ? TokenKind . FLOAT : TokenKind . INT ,
509
494
start ,
510
495
position ,
511
496
line ,
@@ -558,7 +543,15 @@ function readString(source, start, line, col, prev): Token {
558
543
// Closing Quote (")
559
544
if ( code === 34 ) {
560
545
value += slice . call ( body , chunkStart , position ) ;
561
- return new Tok ( STRING , start , position + 1 , line , col , prev , value ) ;
546
+ return new Tok (
547
+ TokenKind . STRING ,
548
+ start ,
549
+ position + 1 ,
550
+ line ,
551
+ col ,
552
+ prev ,
553
+ value ,
554
+ ) ;
562
555
}
563
556
564
557
// SourceCharacter
@@ -659,7 +652,7 @@ function readBlockString(source, start, line, col, prev): Token {
659
652
) {
660
653
rawValue += slice . call ( body , chunkStart , position ) ;
661
654
return new Tok (
662
- BLOCK_STRING ,
655
+ TokenKind . BLOCK_STRING ,
663
656
start ,
664
657
position + 3 ,
665
658
line ,
@@ -756,7 +749,7 @@ function readName(source, position, line, col, prev): Token {
756
749
++ end ;
757
750
}
758
751
return new Tok (
759
- NAME ,
752
+ TokenKind . NAME ,
760
753
position ,
761
754
end ,
762
755
line ,
0 commit comments