60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
"use strict"
|
|
|
|
const acorn = require("acorn")
|
|
const tt = acorn.tokTypes
|
|
const isIdentifierStart = acorn.isIdentifierStart
|
|
|
|
module.exports = function(Parser) {
|
|
return class extends Parser {
|
|
parseLiteral(value) {
|
|
const node = super.parseLiteral(value)
|
|
if (node.raw.charCodeAt(node.raw.length - 1) == 110) node.bigint = this.getNumberInput(node.start, node.end)
|
|
return node
|
|
}
|
|
|
|
readRadixNumber(radix) {
|
|
let start = this.pos
|
|
this.pos += 2 // 0x
|
|
let val = this.readInt(radix)
|
|
if (val === null) this.raise(this.start + 2, `Expected number in radix ${radix}`)
|
|
if (this.input.charCodeAt(this.pos) == 110) {
|
|
let str = this.getNumberInput(start, this.pos)
|
|
val = typeof BigInt !== "undefined" ? BigInt(str) : null
|
|
++this.pos
|
|
} else if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number")
|
|
return this.finishToken(tt.num, val)
|
|
}
|
|
|
|
readNumber(startsWithDot) {
|
|
let start = this.pos
|
|
|
|
// Not an int
|
|
if (startsWithDot) return super.readNumber(startsWithDot)
|
|
|
|
// Legacy octal
|
|
if (this.input.charCodeAt(start) === 48 && this.input.charCodeAt(start + 1) !== 110) {
|
|
return super.readNumber(startsWithDot)
|
|
}
|
|
|
|
if (this.readInt(10) === null) this.raise(start, "Invalid number")
|
|
|
|
// Not a BigInt, reset and parse again
|
|
if (this.input.charCodeAt(this.pos) != 110) {
|
|
this.pos = start
|
|
return super.readNumber(startsWithDot)
|
|
}
|
|
|
|
let str = this.getNumberInput(start, this.pos)
|
|
let val = typeof BigInt !== "undefined" ? BigInt(str) : null
|
|
++this.pos
|
|
return this.finishToken(tt.num, val)
|
|
}
|
|
|
|
// This is basically a hook for acorn-numeric-separator
|
|
getNumberInput(start, end) {
|
|
if (super.getNumberInput) return super.getNumberInput(start, end)
|
|
return this.input.slice(start, end)
|
|
}
|
|
}
|
|
}
|