Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80555 views
1
import {LooseParser} from "./state"
2
import {Node, SourceLocation, lineBreak, isNewLine, tokTypes as tt} from ".."
3
4
const lp = LooseParser.prototype
5
6
lp.startNode = function() {
7
let node = new Node
8
node.start = this.tok.start
9
if (this.options.locations)
10
node.loc = new SourceLocation(this.toks, this.tok.loc.start)
11
if (this.options.directSourceFile)
12
node.sourceFile = this.options.directSourceFile
13
if (this.options.ranges)
14
node.range = [this.tok.start, 0]
15
return node
16
}
17
18
lp.storeCurrentPos = function() {
19
return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start
20
}
21
22
lp.startNodeAt = function(pos) {
23
let node = new Node
24
if (this.options.locations) {
25
node.start = pos[0]
26
node.loc = new SourceLocation(this.toks, pos[1])
27
pos = pos[0]
28
} else {
29
node.start = pos
30
}
31
if (this.options.directSourceFile)
32
node.sourceFile = this.options.directSourceFile
33
if (this.options.ranges)
34
node.range = [pos, 0]
35
return node
36
}
37
38
lp.finishNode = function(node, type) {
39
node.type = type
40
node.end = this.last.end
41
if (this.options.locations)
42
node.loc.end = this.last.loc.end
43
if (this.options.ranges)
44
node.range[1] = this.last.end
45
return node
46
}
47
48
lp.dummyIdent = function() {
49
let dummy = this.startNode()
50
dummy.name = "✖"
51
return this.finishNode(dummy, "Identifier")
52
}
53
54
export function isDummy(node) { return node.name == "✖" }
55
56
lp.eat = function(type) {
57
if (this.tok.type === type) {
58
this.next()
59
return true
60
} else {
61
return false
62
}
63
}
64
65
lp.isContextual = function(name) {
66
return this.tok.type === tt.name && this.tok.value === name
67
}
68
69
lp.eatContextual = function(name) {
70
return this.tok.value === name && this.eat(tt.name)
71
}
72
73
lp.canInsertSemicolon = function() {
74
return this.tok.type === tt.eof || this.tok.type === tt.braceR ||
75
lineBreak.test(this.input.slice(this.last.end, this.tok.start))
76
}
77
78
lp.semicolon = function() {
79
return this.eat(tt.semi)
80
}
81
82
lp.expect = function(type) {
83
if (this.eat(type)) return true
84
for (let i = 1; i <= 2; i++) {
85
if (this.lookAhead(i).type == type) {
86
for (let j = 0; j < i; j++) this.next()
87
return true
88
}
89
}
90
}
91
92
lp.pushCx = function() {
93
this.context.push(this.curIndent)
94
}
95
lp.popCx = function() {
96
this.curIndent = this.context.pop()
97
}
98
99
lp.lineEnd = function(pos) {
100
while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos
101
return pos
102
}
103
104
lp.indentationAfter = function(pos) {
105
for (let count = 0;; ++pos) {
106
let ch = this.input.charCodeAt(pos)
107
if (ch === 32) ++count
108
else if (ch === 9) count += this.options.tabSize
109
else return count
110
}
111
}
112
113
lp.closes = function(closeTok, indent, line, blockHeuristic) {
114
if (this.tok.type === closeTok || this.tok.type === tt.eof) return true
115
return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() &&
116
(!blockHeuristic || this.nextLineStart >= this.input.length ||
117
this.indentationAfter(this.nextLineStart) < indent)
118
}
119
120
lp.tokenStartsLine = function() {
121
for (let p = this.tok.start - 1; p >= this.curLineStart; --p) {
122
let ch = this.input.charCodeAt(p)
123
if (ch !== 9 && ch !== 32) return false
124
}
125
return true
126
}
127
128