Skip to content

Commit 6f591a2

Browse files
authored
Added support for binary, octadecimal and hexadecimal numbers (#12)
* Added support for binary, octadecimal and hexadecimal numbers by Tokenizer * Fixed indentation and switch statement
1 parent e66a634 commit 6f591a2

File tree

1 file changed

+85
-2
lines changed

1 file changed

+85
-2
lines changed

src/tokenizer.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,78 @@ export class Tokenizer {
196196
private isDigit(c: string): boolean {
197197
return /^[0-9]/.test(c);
198198
}
199-
199+
200+
private isHexa(c: string) : boolean {
201+
return /^[0-9A-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+
200212
private isIdentifier(c: string): boolean {
201213
return c === '_' || this.isAlpha(c) || this.isDigit(c);
202214
}
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+
204271
private number() {
205272
while (this.isDigit(this.peek())) {
206273
this.advance();
@@ -212,6 +279,20 @@ export class Tokenizer {
212279
this.advance();
213280
}
214281
}
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+
215296
this.addToken(TokenType.NUMBER);
216297
}
217298

@@ -356,6 +437,8 @@ export class Tokenizer {
356437
break;
357438
// Number... I wish JS had match statements :(
358439
case '0':
440+
this.baseNumber();
441+
break;
359442
case '1':
360443
case '2':
361444
case '3':

0 commit comments

Comments
 (0)