Commit 1fdd95f3 by Aaron Leung

Cloning the predicates and loop lists in the control directives inside the…

Cloning the predicates and loop lists in the control directives inside the function evaluator. Necessary in case they get modified during the in-place evaluation.
parent fb430b74
...@@ -787,7 +787,8 @@ namespace Sass { ...@@ -787,7 +787,8 @@ namespace Sass {
case Node::if_directive: { case Node::if_directive: {
for (size_t j = 0, S = stm.size(); j < S; j += 2) { for (size_t j = 0, S = stm.size(); j < S; j += 2) {
if (stm[j].type() != Node::block) { if (stm[j].type() != Node::block) {
Node predicate_val(eval(stm[j], Node(), bindings, ctx.function_env, new_Node, ctx)); Node pred(new_Node(stm[j]));
Node predicate_val(eval(pred, Node(), bindings, ctx.function_env, new_Node, ctx));
if ((predicate_val.type() != Node::boolean) || predicate_val.boolean_value()) { if ((predicate_val.type() != Node::boolean) || predicate_val.boolean_value()) {
Node v(function_eval(name, stm[j+1], bindings, new_Node, ctx)); Node v(function_eval(name, stm[j+1], bindings, new_Node, ctx));
if (v.is_null_ptr()) break; if (v.is_null_ptr()) break;
...@@ -806,8 +807,8 @@ namespace Sass { ...@@ -806,8 +807,8 @@ namespace Sass {
case Node::for_to_directive: { case Node::for_to_directive: {
Node::Type for_type = stm.type(); Node::Type for_type = stm.type();
Node iter_var(stm[0]); Node iter_var(stm[0]);
Node lower_bound(eval(stm[1], Node(), bindings, ctx.function_env, new_Node, ctx)); Node lower_bound(eval(new_Node(stm[1]), Node(), bindings, ctx.function_env, new_Node, ctx));
Node upper_bound(eval(stm[2], Node(), bindings, ctx.function_env, new_Node, ctx)); Node upper_bound(eval(new_Node(stm[2]), Node(), bindings, ctx.function_env, new_Node, ctx));
Node for_body(stm[3]); Node for_body(stm[3]);
Environment for_env; // re-use this env for each iteration Environment for_env; // re-use this env for each iteration
for_env.link(bindings); for_env.link(bindings);
...@@ -823,7 +824,7 @@ namespace Sass { ...@@ -823,7 +824,7 @@ namespace Sass {
case Node::each_directive: { case Node::each_directive: {
Node iter_var(stm[0]); Node iter_var(stm[0]);
Node list(eval(stm[1], Node(), bindings, ctx.function_env, new_Node, ctx)); Node list(eval(new_Node(stm[1]), Node(), bindings, ctx.function_env, new_Node, ctx));
if (list.type() != Node::comma_list && list.type() != Node::space_list) { if (list.type() != Node::comma_list && list.type() != Node::space_list) {
list = (new_Node(Node::space_list, list.path(), list.line(), 1) << list); list = (new_Node(Node::space_list, list.path(), list.line(), 1) << list);
} }
...@@ -843,7 +844,7 @@ namespace Sass { ...@@ -843,7 +844,7 @@ namespace Sass {
} break; } break;
case Node::while_directive: { case Node::while_directive: {
Node pred_expr(stm[0]); Node pred_expr(new_Node(stm[0]));
Node while_body(stm[1]); Node while_body(stm[1]);
Environment while_env; // re-use this env for each iteration Environment while_env; // re-use this env for each iteration
while_env.link(bindings); while_env.link(bindings);
...@@ -851,7 +852,7 @@ namespace Sass { ...@@ -851,7 +852,7 @@ namespace Sass {
while ((pred_val.type() != Node::boolean) || pred_val.boolean_value()) { while ((pred_val.type() != Node::boolean) || pred_val.boolean_value()) {
Node v(function_eval(name, while_body, while_env, new_Node, ctx)); Node v(function_eval(name, while_body, while_env, new_Node, ctx));
if (v.is_null_ptr()) { if (v.is_null_ptr()) {
pred_val = eval(pred_expr, Node(), bindings, ctx.function_env, new_Node, ctx); pred_val = eval(new_Node(stm[0]), Node(), bindings, ctx.function_env, new_Node, ctx);
continue; continue;
} }
else return v; else return v;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment