-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscope.cpp
110 lines (92 loc) · 2.75 KB
/
scope.cpp
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "include/scope.h"
ScopeNode::ScopeNode() : enclosing_scope_(nullptr) {
ScopeNode(nullptr);
}
ScopeNode::ScopeNode(ScopeNode *enclosing_scope) : enclosing_scope_(enclosing_scope) {
if (enclosing_scope == nullptr) {
level_ = 0;
} else {
level_ = enclosing_scope->level() + 1;
}
}
Symbol &ScopeNode::resolve(const std::string &name) {
std::map<std::string, Symbol>::iterator it = symbols_.find(name);
if (it != symbols_.end()) {
return it->second;
} else {
ScopeNode *enclosing_scope = get_enclosing_scope();
if (enclosing_scope) {
return enclosing_scope->resolve(name);
} else {
throw scope_not_found();
}
}
}
ScopeNode *ScopeNode::resolve_scope(const std::string &name) {
std::map<std::string, Symbol>::iterator it = symbols_.find(name);
if (it != symbols_.end()) {
return this;
} else {
ScopeNode *enclosing_scope = get_enclosing_scope();
if (enclosing_scope) {
return enclosing_scope->resolve_scope(name);
} else {
throw scope_not_found();
}
}
}
void ScopeNode::define(const Symbol &symbol) {
if (symbols_.find(symbol.name()) == symbols_.end()) {
symbols_.insert(std::pair<std::string, Symbol>(symbol.name(), symbol));
} else {
throw scope_name_exists();
}
}
ScopeNode *ScopeNode::get_enclosing_scope() const {
return enclosing_scope_;
}
ScopeNode *ScopeNode::push(ScopeNode *child) {
children_.push_back(child);
return children_.back();
}
int ScopeNode::level() const {
return level_;
}
void ScopeNode::print() const {
std::cout << "--------------------------" << std::endl;
std::cout << "Level: " << level() << std::endl;
std::cout << "--------------------------" << std::endl;
for (std::map<std::string, Symbol>::const_iterator it = symbols_.begin(); it != symbols_.end(); ++it) {
it->second.print();
std::cout << std::endl;
}
for (std::list<ScopeNode *>::const_iterator it = children_.begin(); it != children_.end(); ++it) {
(*it)->print();
}
}
ScopeTree::ScopeTree() {
root_ = new ScopeNode();
current_ = root_;
}
Symbol &ScopeTree::resolve(const std::string &name) {
return current_->resolve(name);
}
ScopeNode *ScopeTree::resolve_scope(const std::string &name) {
return current_->resolve_scope(name);
}
void ScopeTree::define(const Symbol &symbol) {
current_->define(symbol);
}
void ScopeTree::push() {
ScopeNode *node = new ScopeNode(current_);
current_ = current_->push(node);
}
void ScopeTree::pop() {
current_ = current_->get_enclosing_scope();
}
ScopeNode *ScopeTree::current() {
return current_;
}
void ScopeTree::print() const {
root_->print();
}