Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit b8fe029

Browse files
author
Aaron Leung
committed
Finished the expand/eval/apply reorganization. Let's see if it actually does any good.
1 parent 0259be6 commit b8fe029

File tree

3 files changed

+50
-41
lines changed

3 files changed

+50
-41
lines changed

document_parser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ namespace Sass {
10161016
if (lex< interpolant >()) {
10171017
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
10181018
Node interp_node(Document::make_from_token(context, insides, path, line).parse_list());
1019+
interp_node.should_eval() = true;
10191020
schema << interp_node;
10201021
}
10211022
else if (lex< identifier >()) {
@@ -1076,6 +1077,7 @@ namespace Sass {
10761077
else if (lex< interpolant >()) {
10771078
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
10781079
Node interp_node(Document::make_from_token(context, insides, path, line).parse_list());
1080+
interp_node.should_eval() = true;
10791081
schema << interp_node;
10801082
}
10811083
else if (lex< sequence< identifier, exactly<':'> > >()) {

eval_apply.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ namespace Sass {
129129
Node var(expr[0]);
130130
if (expr.is_guarded() && env.query(var.token())) return;
131131
Node val(expr[1]);
132-
val = eval(val, prefix, env, f_env, new_Node, ctx);
133-
// if (val.type() == Node::list) {
134-
// for (size_t i = 0, S = val.size(); i < S; ++i) {
135-
// if (val[i].should_eval()) val[i] = eval(val[i], prefix, env, f_env, new_Node, ctx);
136-
// }
137-
// }
138-
// else {
139-
// val = eval(val, prefix, env, f_env, new_Node, ctx);
140-
// }
132+
// val = eval(val, prefix, env, f_env, new_Node, ctx);
133+
if (val.type() == Node::list) {
134+
for (size_t i = 0, S = val.size(); i < S; ++i) {
135+
if (val[i].should_eval()) val[i] = eval(val[i], prefix, env, f_env, new_Node, ctx);
136+
}
137+
}
138+
else {
139+
val = eval(val, prefix, env, f_env, new_Node, ctx);
140+
}
141141

142142
// If a binding exists (possible upframe), then update it.
143143
// Otherwise, make a new on in the current frame.
@@ -155,20 +155,16 @@ namespace Sass {
155155
expr[0] = eval(lhs, prefix, env, f_env, new_Node, ctx);
156156
}
157157
Node rhs(expr[1]);
158-
if (rhs.is_schema() || rhs.should_eval()) {
158+
if (rhs.type() == Node::list) {
159+
for (size_t i = 0, S = rhs.size(); i < S; ++i) {
160+
if (rhs[i].should_eval()) {
161+
rhs[i] = eval(rhs[i], prefix, env, f_env, new_Node, ctx);
162+
}
163+
}
164+
}
165+
else if (rhs.is_schema() || rhs.should_eval()) {
159166
expr[1] = eval(rhs, prefix, env, f_env, new_Node, ctx);
160167
}
161-
// if (rhs.type() == Node::list) {
162-
// for (size_t i = 0, S = rhs.size(); i < S; ++i) {
163-
// if (rhs[i].should_eval()) rhs[i] = eval(rhs[i], prefix, env, f_env, new_Node, ctx);
164-
// }
165-
// }
166-
// else if (rhs.type() == Node::value_schema || rhs.type() == Node::string_schema) {
167-
// eval(rhs, prefix, env, f_env, new_Node, ctx);
168-
// }
169-
// else {
170-
// if (rhs.should_eval()) expr[1] = eval(rhs, prefix, env, f_env, new_Node, ctx);
171-
// }
172168
} break;
173169

174170
case Node::if_directive: {
@@ -306,13 +302,16 @@ namespace Sass {
306302

307303
case Node::list: {
308304
if (expr.should_eval()) {
309-
result = new_Node(expr);
310-
result[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
305+
result = new_Node(Node::list, expr.path(), expr.line(), expr.size());
306+
result << eval(expr[0], prefix, env, f_env, new_Node, ctx);
307+
for (size_t i = 1, S = expr.size(); i < S; ++i) result << expr[i];
308+
}
309+
else {
310+
result = expr;
311311
}
312312
} break;
313313

314314
case Node::disjunction: {
315-
Node result;
316315
for (size_t i = 0, S = expr.size(); i < S; ++i) {
317316
result = eval(expr[i], prefix, env, f_env, new_Node, ctx);
318317
if (result.is_false()) continue;
@@ -321,7 +320,6 @@ namespace Sass {
321320
} break;
322321

323322
case Node::conjunction: {
324-
Node result;
325323
for (size_t i = 0, S = expr.size(); i < S; ++i) {
326324
result = eval(expr[i], prefix, env, f_env, new_Node, ctx);
327325
if (result.is_false()) break;
@@ -339,12 +337,12 @@ namespace Sass {
339337

340338
switch (op.type())
341339
{
342-
case Node::eq: result = ((lhs == rhs) ? T : F);
343-
case Node::neq: result = ((lhs != rhs) ? T : F);
344-
case Node::gt: result = ((lhs > rhs) ? T : F);
345-
case Node::gte: result = ((lhs >= rhs) ? T : F);
346-
case Node::lt: result = ((lhs < rhs) ? T : F);
347-
case Node::lte: result = ((lhs <= rhs) ? T : F);
340+
case Node::eq: result = ((lhs == rhs) ? T : F); break;
341+
case Node::neq: result = ((lhs != rhs) ? T : F); break;
342+
case Node::gt: result = ((lhs > rhs) ? T : F); break;
343+
case Node::gte: result = ((lhs >= rhs) ? T : F); break;
344+
case Node::lt: result = ((lhs < rhs) ? T : F); break;
345+
case Node::lte: result = ((lhs <= rhs) ? T : F); break;
348346
default:
349347
throw_eval_error("unknown comparison operator " + expr.token().to_string(), expr.path(), expr.line());
350348
}
@@ -366,6 +364,9 @@ namespace Sass {
366364
}
367365
result = reduce(list, 1, list[0], new_Node);
368366
}
367+
else {
368+
result = expr;
369+
}
369370
} break;
370371

371372
// case Node::textual_percentage: {
@@ -476,6 +477,9 @@ namespace Sass {
476477
b.numeric_value(),
477478
a.numeric_value());
478479
}
480+
else {
481+
result = expr;
482+
}
479483
} break;
480484

481485
case Node::string_schema:
@@ -485,6 +489,7 @@ namespace Sass {
485489
for (size_t i = 0, S = expr.size(); i < S; ++i) {
486490
result << eval(expr[i], prefix, env, f_env, new_Node, ctx);
487491
}
492+
result.is_quoted() = expr.is_quoted();
488493
} break;
489494

490495
case Node::css_import: {
@@ -686,18 +691,18 @@ namespace Sass {
686691
// Apply a mixin -- bind the arguments in a new environment, link the new
687692
// environment to the current one, then copy the body and eval in the new
688693
// environment.
689-
Node apply_mixin(Node mixin, const Node aargs, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope)
694+
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope)
690695
{
691696
Node params(mixin[1]);
692697
Node body(new_Node(mixin[2])); // clone the body
693-
Node args = new_Node(aargs);
694698
// evaluate arguments in the current environment
695-
for (size_t i = 0, S = args.size(); i < S; ++i) {
696-
if (args[i].type() != Node::assignment) {
697-
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
699+
Node evaluated_args = new_Node(args);
700+
for (size_t i = 0, S = evaluated_args.size(); i < S; ++i) {
701+
if (evaluated_args[i].type() != Node::assignment) {
702+
evaluated_args[i] = eval(evaluated_args[i], prefix, env, f_env, new_Node, ctx);
698703
}
699704
else {
700-
args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
705+
evaluated_args[i][1] = eval(evaluated_args[i][1], prefix, env, f_env, new_Node, ctx);
701706
}
702707
}
703708
// need to eval twice because some expressions get delayed
@@ -726,11 +731,12 @@ namespace Sass {
726731
stringstream mixin_name;
727732
mixin_name << "mixin";
728733
if (!mixin[0].is_null()) mixin_name << " " << mixin[0].to_string();
729-
bind_arguments(mixin_name.str(), params, args, prefix, bindings, f_env, new_Node, ctx);
734+
bind_arguments(mixin_name.str(), params, evaluated_args, prefix, bindings, f_env, new_Node, ctx);
730735
// evaluate the mixin's body
731-
for (size_t i = 0, S = body.size(); i < S; ++i) {
732-
body[i] = eval(body[i], prefix, bindings, f_env, new_Node, ctx);
733-
}
736+
expand(body, prefix, bindings, f_env, new_Node, ctx);
737+
// for (size_t i = 0, S = body.size(); i < S; ++i) {
738+
// expand(body[i], prefix, bindings, f_env, new_Node, ctx);
739+
// }
734740
// cerr << "expanded " << mixin_name.str() << endl;
735741
return body;
736742
}

node_emitters.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ namespace Sass {
124124
if (size() == 0) return "";
125125
string result(at(0).to_string());
126126
for (size_t i = 1, S = size(); i < S; ++i) {
127+
if (at(i).is_null()) continue;
127128
if (at(i).type() == list && at(i).size() == 0) continue;
128129
result += is_comma_separated() ? ", " : " ";
129130
result += at(i).to_string();

0 commit comments

Comments
 (0)