@@ -196,11 +196,78 @@ export class Tokenizer {
196
196
private isDigit ( c : string ) : boolean {
197
197
return / ^ [ 0 - 9 ] / . test ( c ) ;
198
198
}
199
-
199
+
200
+ private isHexa ( c : string ) : boolean {
201
+ return / ^ [ 0 - 9 A - F ] $ / i. test ( c ) ;
202
+ }
203
+
204
+ private isOcta ( c : string ) : boolean {
205
+ return / ^ [ 0 - 7 ] / . test ( c ) ;
206
+ }
207
+
208
+ private isBinary ( c : string ) : boolean {
209
+ return / ^ [ 0 - 1 ] / . test ( c ) ;
210
+ }
211
+
200
212
private isIdentifier ( c : string ) : boolean {
201
213
return c === '_' || this . isAlpha ( c ) || this . isDigit ( c ) ;
202
214
}
203
-
215
+
216
+ private baseNumber ( ) {
217
+ switch ( this . peek ( ) ) {
218
+ case 'x' :
219
+ this . advance ( ) ;
220
+ if ( ! this . isHexa ( this . peek ( ) ) ) {
221
+ throw new TokenizerErrors . InvalidNumberError ( this . line , this . col , this . source , this . start , this . current ) ;
222
+ }
223
+ while ( this . isHexa ( this . peek ( ) ) ) {
224
+ this . advance ( ) ;
225
+ }
226
+ break ;
227
+ case 'o' :
228
+ this . advance ( ) ;
229
+ if ( ! this . isOcta ( this . peek ( ) ) ) {
230
+ throw new TokenizerErrors . InvalidNumberError ( this . line , this . col , this . source , this . start , this . current ) ;
231
+ }
232
+ while ( this . isOcta ( this . peek ( ) ) ) {
233
+ this . advance ( ) ;
234
+ }
235
+ break ;
236
+ case 'b' :
237
+ this . advance ( ) ;
238
+ if ( ! this . isBinary ( this . peek ( ) ) ) {
239
+ throw new TokenizerErrors . InvalidNumberError ( this . line , this . col , this . source , this . start , this . current ) ;
240
+ }
241
+ while ( this . isBinary ( this . peek ( ) ) ) {
242
+ this . advance ( ) ;
243
+ }
244
+ break ;
245
+ default :
246
+ while ( this . isDigit ( this . peek ( ) ) ) {
247
+ this . advance ( ) ;
248
+ }
249
+ if ( this . peek ( ) === '.' ) {
250
+ this . advance ( ) ;
251
+ while ( this . isDigit ( this . peek ( ) ) ) {
252
+ this . advance ( ) ;
253
+ }
254
+ }
255
+ if ( this . peek ( ) === 'e' ) {
256
+ this . advance ( ) ;
257
+ if ( this . peek ( ) === '-' ) {
258
+ this . advance ( ) ;
259
+ }
260
+ if ( ! this . isDigit ( this . peek ( ) ) ) {
261
+ throw new TokenizerErrors . InvalidNumberError ( this . line , this . col , this . source , this . start , this . current ) ;
262
+ }
263
+ while ( this . isDigit ( this . peek ( ) ) ) {
264
+ this . advance ( ) ;
265
+ }
266
+ }
267
+ }
268
+ this . addToken ( TokenType . NUMBER ) ;
269
+ }
270
+
204
271
private number ( ) {
205
272
while ( this . isDigit ( this . peek ( ) ) ) {
206
273
this . advance ( ) ;
@@ -212,6 +279,20 @@ export class Tokenizer {
212
279
this . advance ( ) ;
213
280
}
214
281
}
282
+ // Exponent part
283
+ if ( this . peek ( ) === 'e' ) {
284
+ this . advance ( ) ;
285
+ if ( this . peek ( ) === '-' ) {
286
+ this . advance ( ) ;
287
+ }
288
+ if ( ! this . isDigit ( this . peek ( ) ) ) {
289
+ throw new TokenizerErrors . InvalidNumberError ( this . line , this . col , this . source , this . start , this . current ) ;
290
+ }
291
+ while ( this . isDigit ( this . peek ( ) ) ) {
292
+ this . advance ( ) ;
293
+ }
294
+ }
295
+
215
296
this . addToken ( TokenType . NUMBER ) ;
216
297
}
217
298
@@ -356,6 +437,8 @@ export class Tokenizer {
356
437
break ;
357
438
// Number... I wish JS had match statements :(
358
439
case '0' :
440
+ this . baseNumber ( ) ;
441
+ break ;
359
442
case '1' :
360
443
case '2' :
361
444
case '3' :
0 commit comments