forked from sass/libsass
/
environment.hpp
75 lines (63 loc) · 1.79 KB
/
environment.hpp
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
#define SASS_ENVIRONMENT
#include <string>
#include <map>
#include "ast_def_macros.hpp"
#include <iostream>
namespace Sass {
using std::string;
using std::map;
using std::cerr;
using std::endl;
template <typename T>
class Environment {
// TODO: test with unordered_map
map<string, T> current_frame_;
ADD_PROPERTY(Environment*, parent);
public:
Environment() : current_frame_(map<string, T>()), parent_(0) { }
map<string, T>& current_frame() { return current_frame_; }
void link(Environment& env) { parent_ = &env; }
void link(Environment* env) { parent_ = env; }
bool has(const string key) const
{
if (current_frame_.count(key)) return true;
else if (parent_) return parent_->has(key);
else return false;
}
bool current_frame_has(const string key) const
{ return current_frame_.count(key); }
Environment* grandparent() const
{
if(parent_ && parent_->parent_) return parent_->parent_;
else return 0;
}
bool global_frame_has(const string key) const
{
if(parent_ && !grandparent()) {
return has(key);
}
else if(parent_) {
return parent_->global_frame_has(key);
}
else {
return false;
}
}
T& operator[](const string key)
{
if (current_frame_.count(key)) return current_frame_[key];
else if (parent_) return (*parent_)[key];
else return current_frame_[key];
}
void print()
{
for (typename map<string, T>::iterator i = current_frame_.begin(); i != current_frame_.end(); ++i) {
cerr << i->first << endl;
}
if (parent_) {
cerr << "---" << endl;
parent_->print();
}
}
};
}