in src/scanner.ts [777:854]
private scanNumericLiteral(): RawToken {
const start = this.index;
let ch = this.source[start];
assert(Character.isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
'Numeric literal must start with a decimal digit or a decimal point');
let num = '';
if (ch !== '.') {
num = this.source[this.index++];
ch = this.source[this.index];
// Hex number starts with '0x'.
// Octal number starts with '0'.
// Octal number in ES6 starts with '0o'.
// Binary number in ES6 starts with '0b'.
if (num === '0') {
if (ch === 'x' || ch === 'X') {
++this.index;
return this.scanHexLiteral(start);
}
if (ch === 'b' || ch === 'B') {
++this.index;
return this.scanBinaryLiteral(start);
}
if (ch === 'o' || ch === 'O') {
return this.scanOctalLiteral(ch, start);
}
if (ch && Character.isOctalDigit(ch.charCodeAt(0))) {
if (this.isImplicitOctalLiteral()) {
return this.scanOctalLiteral(ch, start);
}
}
}
while (Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
num += this.source[this.index++];
}
ch = this.source[this.index];
}
if (ch === '.') {
num += this.source[this.index++];
while (Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
num += this.source[this.index++];
}
ch = this.source[this.index];
}
if (ch === 'e' || ch === 'E') {
num += this.source[this.index++];
ch = this.source[this.index];
if (ch === '+' || ch === '-') {
num += this.source[this.index++];
}
if (Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
while (Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
num += this.source[this.index++];
}
} else {
this.throwUnexpectedToken();
}
}
if (Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
this.throwUnexpectedToken();
}
return {
type: Token.NumericLiteral,
value: parseFloat(num),
lineNumber: this.lineNumber,
lineStart: this.lineStart,
start: start,
end: this.index
};
}