Commit f7c3321b by Aaron Leung

Refactoring the apply functions a bit.

parent d3795e66
...@@ -673,11 +673,11 @@ namespace Sass { ...@@ -673,11 +673,11 @@ namespace Sass {
// Apply a mixin -- bind the arguments in a new environment, link the new // Apply a mixin -- bind the arguments in a new environment, link the new
// environment to the current one, then copy the body and eval in the new // environment to the current one, then copy the body and eval in the new
// environment. // environment.
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) 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)
{ {
Node params(mixin[1]); Node params(mixin[1]);
Node body(new_Node(mixin[2])); // clone the body Node body(new_Node(mixin[2])); // clone the body
Node args = new_Node(aargs);
// evaluate arguments in the current environment // evaluate arguments in the current environment
for (size_t i = 0, S = args.size(); i < S; ++i) { for (size_t i = 0, S = args.size(); i < S; ++i) {
if (args[i].type() != Node::assignment) { if (args[i].type() != Node::assignment) {
...@@ -687,6 +687,17 @@ namespace Sass { ...@@ -687,6 +687,17 @@ namespace Sass {
args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx); args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
} }
} }
// need to eval twice because some expressions get delayed
// for (size_t i = 0, S = args.size(); i < S; ++i) {
// if (args[i].type() != Node::assignment) {
// args[i].should_eval() = true;
// args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
// }
// else {
// args[i][1].should_eval() = true;
// args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
// }
// }
// Create a new environment for the mixin and link it to the appropriate parent // Create a new environment for the mixin and link it to the appropriate parent
Environment bindings; Environment bindings;
...@@ -713,46 +724,42 @@ namespace Sass { ...@@ -713,46 +724,42 @@ namespace Sass {
// Apply a function -- bind the arguments and pass them to the underlying // Apply a function -- bind the arguments and pass them to the underlying
// primitive function implementation, then return its value. // primitive function implementation, then return its value.
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line) Node apply_function(const Function& f, const Node aargs, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line)
{ {
if (f.primitive) { Node args = new_Node(aargs);
// evaluate arguments in the current environment // evaluate arguments in the current environment
for (size_t i = 0, S = args.size(); i < S; ++i) { for (size_t i = 0, S = args.size(); i < S; ++i) {
if (args[i].type() != Node::assignment) { if (args[i].type() != Node::assignment) {
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx); args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
} }
else { else {
args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx); args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
}
} }
// bind arguments
Environment bindings;
bindings.link(env.global ? *env.global : env);
bind_arguments("function " + f.name, f.parameters, args, prefix, bindings, f_env, new_Node, ctx);
return f.primitive(f.parameter_names, bindings, new_Node, path, line);
} }
else { // need to eval twice because some expressions get delayed
Node params(f.definition[1]); // for (size_t i = 0, S = args.size(); i < S; ++i) {
Node body(new_Node(f.definition[2])); // if (args[i].type() != Node::assignment) {
// args[i].should_eval() = true;
// args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
// }
// else {
// args[i][1].should_eval() = true;
// args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
// }
// }
// evaluate arguments in the current environment // bind arguments
for (size_t i = 0, S = args.size(); i < S; ++i) { Environment bindings;
if (args[i].type() != Node::assignment) { Node params(f.primitive ? f.parameters : f.definition[1]);
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx); bindings.link(env.global ? *env.global : env);
} bind_arguments("function " + f.name, params, args, prefix, bindings, f_env, new_Node, ctx);
else {
args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
}
}
// create a new environment for the function and link it to the global env if (f.primitive) {
// (C-style scope -- no full-blown lexical scope yet) return f.primitive(f.parameter_names, bindings, new_Node, path, line);
Environment bindings; }
bindings.link(env.global ? *env.global : env); else {
// bind the arguments // TO DO: consider cloning the function body?
bind_arguments("function " + f.name, params, args, prefix, bindings, f_env, new_Node, ctx); return function_eval(f.name, f.definition[2], bindings, new_Node, ctx, true);
// TO DO: consider cloning the function body
return function_eval(f.name, body, bindings, new_Node, ctx, true);
} }
} }
......
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