-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscope-stack.js
More file actions
93 lines (76 loc) · 1.95 KB
/
Copy pathscope-stack.js
File metadata and controls
93 lines (76 loc) · 1.95 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
'use strict'
module.exports = ScopeStack
function ScopeStack(cfg, root) {
if(!(this instanceof ScopeStack)) {
return new ScopeStack(cfg, root)
}
this.cfg = cfg
this._membraneMap = new Map()
this._root = root
this._current = root
}
var proto = ScopeStack.prototype
proto.current = function() {
return this._current
}
proto.push = function(block) {
this._current = this.cfg.makeScope(block.type, this._current || null)
}
proto.set = function(scope) {
this._current = scope
}
proto.pushBranch = function(branchID) {
this._current = this.cfg.makeMembrane(this._current)
this._membraneMap.set(branchID, this._current)
}
proto.endBranch = function(branchID, stack) {
var membrane = this._membraneMap.get(branchID)
if (membrane !== this._current) {
throw new Error('should not attempt to close membrane')
}
this._current = membrane.unwrapAll(stack)
}
proto.pop = function() {
this._current = this._current._prototype
}
proto.root = function() {
return this._root
}
proto.newprop = function(str, kind) {
if (kind === 'imaginary') {
var current = this._current
while (current) {
var blockType = current.getBlockType()
if (blockType === 'Program' || blockType === '(Branch)') {
break
}
current = current._prototype
}
if (!current) {
throw new Error('out of blocks: ' + str + ' looking for ' + kind)
}
return current.newprop(str)
}
if (kind !== 'var') {
return this._current.newprop(str)
}
var current = this._current
var okay = false
do {
switch(current.getBlockType()) {
case 'Program':
case 'FunctionDeclaration':
case 'FunctionExpression':
case 'ArrowExpression':
okay = false
break
default:
okay = true
}
if (okay) current = current._prototype
} while(current && okay)
return current.newprop(str)
}
proto.getprop = function(str, immediate) {
return this._current.getprop(str, immediate)
}