Skip to content

Commit cfce077

Browse files
committed
Merge pull request #990 from mgreter/refactor/prelexer
Refactor prelexer
2 parents 6ab00d9 + 9fb564e commit cfce077

18 files changed

+882
-650
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ SOURCES = \
122122
file.cpp \
123123
functions.cpp \
124124
inspect.cpp \
125+
lexer.cpp \
125126
node.cpp \
126127
json.cpp \
127128
emitter.cpp \

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ libsass_la_SOURCES = \
6565
file.cpp file.hpp \
6666
functions.cpp functions.hpp \
6767
inspect.cpp inspect.hpp \
68+
lexer.cpp lexer.hpp \
6869
node.cpp node.hpp \
6970
json.cpp json.hpp \
7071
emitter.cpp emitter.hpp \

ast.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,14 +460,14 @@ namespace Sass {
460460
class Assignment : public Statement {
461461
ADD_PROPERTY(string, variable);
462462
ADD_PROPERTY(Expression*, value);
463-
ADD_PROPERTY(bool, is_guarded);
463+
ADD_PROPERTY(bool, is_default);
464464
ADD_PROPERTY(bool, is_global);
465465
public:
466466
Assignment(ParserState pstate,
467467
string var, Expression* val,
468-
bool guarded = false,
469-
bool global = false)
470-
: Statement(pstate), variable_(var), value_(val), is_guarded_(guarded), is_global_(global)
468+
bool is_default = false,
469+
bool is_global = false)
470+
: Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
471471
{ }
472472
ATTACH_OPERATIONS();
473473
};

bind.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Sass {
2020
Parameter* p = (*ps)[i];
2121
param_map[p->name()] = p;
2222
// if (p->default_value()) {
23-
// env->current_frame()[p->name()] = p->default_value()->perform(eval->with(env));
23+
// env->local_frame()[p->name()] = p->default_value()->perform(eval->with(env));
2424
// }
2525
}
2626

@@ -41,12 +41,12 @@ namespace Sass {
4141
if (p->is_rest_parameter()) {
4242
if (a->is_rest_argument()) {
4343
// rest param and rest arg -- just add one to the other
44-
if (env->current_frame_has(p->name())) {
45-
*static_cast<List*>(env->current_frame()[p->name()])
44+
if (env->has_local(p->name())) {
45+
*static_cast<List*>(env->local_frame()[p->name()])
4646
+= static_cast<List*>(a->value());
4747
}
4848
else {
49-
env->current_frame()[p->name()] = a->value();
49+
env->local_frame()[p->name()] = a->value();
5050
}
5151
} else {
5252

@@ -55,7 +55,7 @@ namespace Sass {
5555
0,
5656
List::COMMA,
5757
true);
58-
env->current_frame()[p->name()] = arglist;
58+
env->local_frame()[p->name()] = arglist;
5959
while (ia < LA) {
6060
a = (*as)[ia];
6161
(*arglist) << new (ctx.mem) Argument(a->pstate(),
@@ -99,7 +99,7 @@ namespace Sass {
9999
msg << callee << " has no parameter named " << name;
100100
error(msg.str(), a->pstate());
101101
}
102-
env->current_frame()[name] = argmap->at(key);
102+
env->local_frame()[name] = argmap->at(key);
103103
}
104104
++ia;
105105
continue;
@@ -108,14 +108,14 @@ namespace Sass {
108108
}
109109

110110
if (a->name().empty()) {
111-
if (env->current_frame_has(p->name())) {
111+
if (env->has_local(p->name())) {
112112
stringstream msg;
113113
msg << "parameter " << p->name()
114114
<< " provided more than once in call to " << callee;
115115
error(msg.str(), a->pstate());
116116
}
117117
// ordinal arg -- bind it to the next param
118-
env->current_frame()[p->name()] = a->value();
118+
env->local_frame()[p->name()] = a->value();
119119
++ip;
120120
}
121121
else {
@@ -131,13 +131,13 @@ namespace Sass {
131131
<< "cannot be used as named argument";
132132
error(msg.str(), a->pstate());
133133
}
134-
if (env->current_frame_has(a->name())) {
134+
if (env->has_local(a->name())) {
135135
stringstream msg;
136136
msg << "parameter " << p->name()
137137
<< "provided more than once in call to " << callee;
138138
error(msg.str(), a->pstate());
139139
}
140-
env->current_frame()[a->name()] = a->value();
140+
env->local_frame()[a->name()] = a->value();
141141
}
142142
}
143143

@@ -150,9 +150,9 @@ namespace Sass {
150150
// cerr << "env for default params:" << endl;
151151
// env->print();
152152
// cerr << "********" << endl;
153-
if (!env->current_frame_has(leftover->name())) {
153+
if (!env->has_local(leftover->name())) {
154154
if (leftover->is_rest_parameter()) {
155-
env->current_frame()[leftover->name()] = new (ctx.mem) List(leftover->pstate(),
155+
env->local_frame()[leftover->name()] = new (ctx.mem) List(leftover->pstate(),
156156
0,
157157
List::COMMA,
158158
true);
@@ -167,7 +167,7 @@ namespace Sass {
167167
eval->backtrace = old_bt;
168168
eval->contextualize = old_context;
169169
// dv->perform(&to_string);
170-
env->current_frame()[leftover->name()] = dv;
170+
env->local_frame()[leftover->name()] = dv;
171171
}
172172
else {
173173
// param is unbound and has no default value -- error

environment.hpp

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,83 +18,148 @@ namespace Sass {
1818
template <typename T>
1919
class Environment {
2020
// TODO: test with unordered_map
21-
map<string, T> current_frame_;
21+
map<string, T> local_frame_;
2222
ADD_PROPERTY(Environment*, parent);
2323

2424
public:
2525
Memory_Manager<AST_Node> mem;
26-
Environment() : current_frame_(map<string, T>()), parent_(0) { }
27-
28-
map<string, T>& current_frame() { return current_frame_; }
26+
Environment() : local_frame_(map<string, T>()), parent_(0) { }
2927

28+
// link parent to create a stack
3029
void link(Environment& env) { parent_ = &env; }
3130
void link(Environment* env) { parent_ = env; }
3231

33-
bool has(const string key) const
32+
// this is used to find the global frame
33+
// which is the second last on the stack
34+
bool is_lexical() const
3435
{
35-
if (current_frame_.count(key)) return true;
36-
else if (parent_) return parent_->has(key);
37-
else return false;
36+
return !! parent_ && parent_->parent_;
3837
}
3938

40-
bool current_frame_has(const string key) const
41-
{ return !!current_frame_.count(key); }
42-
43-
void current_frame_set(const string key, T val)
44-
{ current_frame_[key] = val; }
39+
// only match the real root scope
40+
// there is still a parent around
41+
// not sure what it is actually use for
42+
// I guess we store functions etc. there
43+
bool is_root_scope() const
44+
{
45+
return parent_ && ! parent_->parent_;
46+
}
4547

46-
void global_frame_set(const string key, T val)
47-
{ global_frame()->current_frame_[key] = val; }
48+
// scope operates on the current frame
4849

49-
Environment* grandparent() const
50-
{
51-
if(parent_ && parent_->parent_) return parent_->parent_;
52-
else return 0;
50+
map<string, T>& local_frame() {
51+
return local_frame_;
5352
}
5453

55-
Environment* global_frame()
54+
bool has_local(const string& key) const
55+
{ return local_frame_.count(key); }
56+
57+
T& get_local(const string& key)
58+
{ return local_frame_[key]; }
59+
60+
void set_local(const string& key, T val)
61+
{ local_frame_[key] = val; }
62+
63+
void del_local(const string& key)
64+
{ local_frame_.erase(key); }
65+
66+
67+
// global operates on the global frame
68+
// which is the second last on the stack
69+
70+
Environment* global_env()
5671
{
5772
Environment* cur = this;
58-
// looks like global variables
59-
// are in the second last parent
60-
while (cur->grandparent()) {
73+
while (cur->is_lexical()) {
6174
cur = cur->parent_;
6275
}
6376
return cur;
6477
}
6578

66-
bool global_frame_has(const string key) const
79+
bool has_global(const string& key)
80+
{ return global_env()->has(key); }
81+
82+
T& get_global(const string& key)
83+
{ return (*global_env())[key]; }
84+
85+
void set_global(const string& key, T val)
86+
{ global_env()->local_frame_[key] = val; }
87+
88+
void del_global(const string& key)
89+
{ global_env()->local_frame_.erase(key); }
90+
91+
// see if we have a lexical variable
92+
// move down the stack but stop before we
93+
// reach the global frame (is not included)
94+
bool has_lexical(const string& key) const
95+
{
96+
auto cur = this;
97+
while (cur->is_lexical()) {
98+
if (cur->has_local(key)) return true;
99+
cur = cur->parent_;
100+
}
101+
return false;
102+
}
103+
104+
// see if we have a lexical we could update
105+
// either update already existing lexical value
106+
// or if flag is set, we create one if no lexical found
107+
void set_lexical(const string& key, T val, bool global = false)
67108
{
68-
if(parent_ && !grandparent()) {
69-
return has(key);
109+
auto cur = this;
110+
while (cur->is_lexical()) {
111+
if (cur->has_local(key)) {
112+
cur->set_local(key, val);
113+
return;
114+
}
115+
cur = cur->parent_;
70116
}
71-
else if(parent_) {
72-
return parent_->global_frame_has(key);
117+
if (global) {
118+
set_global(key, val);
119+
} else {
120+
set_local(key, val);
73121
}
74-
else {
75-
return false;
122+
}
123+
124+
// look on the full stack for key
125+
// include all scopes available
126+
bool has(const string& key) const
127+
{
128+
auto cur = this;
129+
while (cur) {
130+
if (cur->has_local(key)) {
131+
return true;
132+
}
133+
cur = cur->parent_;
76134
}
135+
return false;
77136
}
78137

79-
T& operator[](const string key)
138+
// use array access for getter and setter functions
139+
T& operator[](const string& key)
80140
{
81-
if (current_frame_.count(key)) return current_frame_[key];
82-
else if (parent_) return (*parent_)[key];
83-
else return current_frame_[key];
141+
auto cur = this;
142+
while (cur) {
143+
if (cur->has_local(key)) {
144+
return cur->get_local(key);
145+
}
146+
cur = cur->parent_;
147+
}
148+
return get_local(key);
84149
}
85150

86-
#ifdef DEBUG
151+
#ifdef DEBUG
87152
void print()
88153
{
89-
for (typename map<string, T>::iterator i = current_frame_.begin(); i != current_frame_.end(); ++i) {
154+
for (typename map<string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
90155
cerr << i->first << endl;
91156
}
92157
if (parent_) {
93158
cerr << "---" << endl;
94159
parent_->print();
95160
}
96161
}
97-
#endif
162+
#endif
98163

99164
};
100165
}

0 commit comments

Comments
 (0)