Skip to content

Commit 937ccf8

Browse files
committed
Merge pull request #986 from mgreter/feature/global-assignments
Implement `!global` assignments
2 parents 50fbda1 + b221b40 commit 937ccf8

File tree

5 files changed

+39
-11
lines changed

5 files changed

+39
-11
lines changed

debugger.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
6969
case Complex_Selector::ADJACENT_TO: cerr << "{+}"; break;
7070
case Complex_Selector::ANCESTOR_OF: cerr << "{ }"; break;
7171
}
72-
cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl;
72+
cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
7373
debug_ast(selector->head(), ind + " ", env);
7474
debug_ast(selector->tail(), ind + "-", env);
7575
} else if (dynamic_cast<Compound_Selector*>(node)) {
@@ -81,7 +81,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
8181
<< (selector->is_optional() ? " [is_optional]": " -")
8282
<< (selector->has_line_break() ? " [line-break]": " -")
8383
<< (selector->has_line_feed() ? " [line-feed]": " -") <<
84-
" <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl;
84+
" <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
8585
for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }
8686
} else if (dynamic_cast<Propset*>(node)) {
8787
Propset* selector = dynamic_cast<Propset*>(node);
@@ -105,7 +105,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
105105
} else if (dynamic_cast<Type_Selector*>(node)) {
106106
Type_Selector* selector = dynamic_cast<Type_Selector*>(node);
107107
cerr << ind << "Type_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") <<
108-
" <" << prettyprint(selector->pstate().token.ws_before()) << "> X <" << prettyprint(selector->pstate().token.ws_after()) << ">" << endl;
108+
" <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
109109
} else if (dynamic_cast<Selector_Placeholder*>(node)) {
110110

111111
Selector_Placeholder* selector = dynamic_cast<Selector_Placeholder*>(node);
@@ -187,7 +187,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
187187
} else if (dynamic_cast<Comment*>(node)) {
188188
Comment* block = dynamic_cast<Comment*>(node);
189189
cerr << ind << "Comment " << block << " " << block->tabs() <<
190-
" <" << prettyprint(block->pstate().token.ws_before()) << "> X <" << prettyprint(block->pstate().token.ws_after()) << ">" << endl;
190+
" <" << prettyprint(block->pstate().token.ws_before()) << ">" << endl;
191191
debug_ast(block->text(), ind + "// ", env);
192192
} else if (dynamic_cast<If*>(node)) {
193193
If* block = dynamic_cast<If*>(node);
@@ -322,13 +322,13 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
322322
(expression->is_delayed() ? " {delayed}" : "") <<
323323
(expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
324324
(expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") <<
325-
" <" << prettyprint(expression->pstate().token.ws_before()) << "> X <" << prettyprint(expression->pstate().token.ws_after()) << ">" << endl;
325+
" <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
326326
} else if (dynamic_cast<String_Constant*>(node)) {
327327
String_Constant* expression = dynamic_cast<String_Constant*>(node);
328328
cerr << ind << "String_Constant : " << expression << " [" << prettyprint(expression->value()) << "]" <<
329329
(expression->is_delayed() ? " {delayed}" : "") <<
330330
(expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
331-
" <" << prettyprint(expression->pstate().token.ws_before()) << "> X <" << prettyprint(expression->pstate().token.ws_after()) << ">" << endl;
331+
" <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
332332
} else if (dynamic_cast<String_Schema*>(node)) {
333333
String_Schema* expression = dynamic_cast<String_Schema*>(node);
334334
cerr << ind << "String_Schema " << expression << " " << expression->concrete_type() <<

environment.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,29 @@ namespace Sass {
4040
bool current_frame_has(const string key) const
4141
{ return !!current_frame_.count(key); }
4242

43+
void current_frame_set(const string key, T val)
44+
{ current_frame_[key] = val; }
45+
46+
void global_frame_set(const string key, T val)
47+
{ global_frame()->current_frame_[key] = val; }
48+
4349
Environment* grandparent() const
4450
{
4551
if(parent_ && parent_->parent_) return parent_->parent_;
4652
else return 0;
4753
}
4854

55+
Environment* global_frame()
56+
{
57+
Environment* cur = this;
58+
// looks like global variables
59+
// are in the second last parent
60+
while (cur->grandparent()) {
61+
cur = cur->parent_;
62+
}
63+
return cur;
64+
}
65+
4966
bool global_frame_has(const string key) const
5067
{
5168
if(parent_ && !grandparent()) {
@@ -66,6 +83,7 @@ namespace Sass {
6683
else return current_frame_[key];
6784
}
6885

86+
#ifdef DEBUG
6987
void print()
7088
{
7189
for (typename map<string, T>::iterator i = current_frame_.begin(); i != current_frame_.end(); ++i) {
@@ -76,6 +94,8 @@ namespace Sass {
7694
parent_->print();
7795
}
7896
}
97+
#endif
98+
7999
};
80100
}
81101

eval.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,15 @@ namespace Sass {
6464
Expression* Eval::operator()(Assignment* a)
6565
{
6666
string var(a->variable());
67-
if (env->has(var)) {
67+
if (a->is_global()) {
68+
env->global_frame_set(var, a->value()->perform(this));
69+
}
70+
else if (env->has(var)) {
6871
Expression* v = static_cast<Expression*>((*env)[var]);
6972
if (!a->is_guarded() || v->concrete_type() == Expression::NULL_VAL) (*env)[var] = a->value()->perform(this);
7073
}
7174
else {
72-
env->current_frame()[var] = a->value()->perform(this);
75+
env->current_frame_set(var, a->value()->perform(this));
7376
}
7477
return 0;
7578
}

expand.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,15 @@ namespace Sass {
219219
{
220220
string var(a->variable());
221221
Selector* p = selector_stack.size() <= 1 ? 0 : selector_stack.back();
222-
if (env->has(var)) {
222+
if (a->is_global()) {
223+
env->global_frame_set(var, a->value()->perform(eval->with(p, env, backtrace)));
224+
}
225+
else if (env->has(var)) {
223226
Expression* v = static_cast<Expression*>((*env)[var]);
224227
if (!a->is_guarded() || v->concrete_type() == Expression::NULL_VAL) (*env)[var] = a->value()->perform(eval->with(p, env, backtrace));
225228
}
226229
else {
227-
env->current_frame()[var] = a->value()->perform(eval->with(p, env, backtrace));
230+
env->current_frame_set(var, a->value()->perform(eval->with(p, env, backtrace)));
228231
}
229232
return 0;
230233
}

functions.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ namespace Sass {
145145
static mt19937 rand(static_cast<unsigned int>(GetSeed()));
146146

147147
// features
148-
static set<string> features;
148+
static set<string> features {
149+
"global-variable-shadowing"
150+
};
149151

150152
////////////////
151153
// RGB FUNCTIONS

0 commit comments

Comments
 (0)