summaryrefslogtreecommitdiff
path: root/deps/acorn-plugins/acorn-bigint/index.js
blob: 8e63515e11bbc5b889fb22ce6aaf10236bc16cde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"use strict"

const acorn = require('internal/deps/acorn/acorn/dist/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)
    }
  }
}