-
Notifications
You must be signed in to change notification settings - Fork 3
/
scope.h
92 lines (68 loc) · 1.49 KB
/
scope.h
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
#ifndef VAIVEN_VISITOR_HEADER_SCOPE
#define VAIVEN_VISITOR_HEADER_SCOPE
#include <map>
#include <string>
#include <stack>
#include <unordered_set>
using std::map;
using std::string;
using std::stack;
using std::unordered_set;
namespace vaiven {
template<typename V>
class Scope;
template<typename V>
class ScopeFrame {
public:
ScopeFrame(Scope<V>& scope) : scope(scope) {
scope.newFrame();
}
~ScopeFrame() {
scope.endFrame();
}
private:
Scope<V>& scope;
};
template<typename V>
class Scope {
public:
Scope() {
newFrame();
}
void newFrame() {
frames.push(unordered_set<string>());
}
void endFrame() {
for (unordered_set<string>::iterator it = frames.top().begin(); it != frames.top().end(); ++it) {
currentVars.erase(*it);
}
frames.pop();
}
void put(string name, V v) {
if (currentVars.find(name) != currentVars.end()) {
throw "already in scope";
}
frames.top().insert(name);
currentVars[name] = v;
}
void replace(string name, V v) {
currentVars[name] = v;
}
bool contains(string name) {
return currentVars.find(name) != currentVars.end();
}
bool inHigherScope(string name) {
return frames.top().find(name) == frames.top().end();
}
V get(string name) {
return currentVars[name];
}
void fill(map<string, V>& toFill) {
toFill.insert(currentVars.begin(), currentVars.end());
}
private:
map<string, V> currentVars;
stack<unordered_set<string> > frames;
};
}
#endif