Commit 086ea341 by Aaron Leung

Bam, re-did argument binding. More robust, and allows default arg values to…

Bam, re-did argument binding. More robust, and allows default arg values to refer to previoius args.
parent e9478c64
...@@ -620,12 +620,17 @@ namespace Sass { ...@@ -620,12 +620,17 @@ namespace Sass {
// correctness further down // correctness further down
for (size_t i = 0, S = params.size(); i < S; ++i) { for (size_t i = 0, S = params.size(); i < S; ++i) {
Node param(params[i]); Node param(params[i]);
env[param.type() == Node::variable ? param.token() : param[0].token()] = Node(); env.current_frame[param.type() == Node::variable ? param.token() : param[0].token()] = Node();
} }
// now do the actual binding // now do the actual binding
size_t args_bound = 0; size_t args_bound = 0, num_params = params.size();
for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) { for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) {
if (j >= num_params) {
stringstream msg;
msg << callee_name << " only takes " << num_params << " arguments";
throw_eval_error(msg.str(), args.path(), args.line());
}
Node arg(args[i]), param(params[j]); Node arg(args[i]), param(params[j]);
// ordinal argument; just bind and keep going // ordinal argument; just bind and keep going
if (arg.type() != Node::assignment) { if (arg.type() != Node::assignment) {
...@@ -646,7 +651,6 @@ namespace Sass { ...@@ -646,7 +651,6 @@ namespace Sass {
++args_bound; ++args_bound;
} }
} }
// TODO: check for superfluous arguments
// now plug in the holes with default values, if any // now plug in the holes with default values, if any
for (size_t i = 0, S = params.size(); i < S; ++i) { for (size_t i = 0, S = params.size(); i < S; ++i) {
Node param(params[i]); Node param(params[i]);
...@@ -671,6 +675,7 @@ namespace Sass { ...@@ -671,6 +675,7 @@ namespace Sass {
Environment bindings; Environment bindings;
// TO DO: REFACTOR THE ARG-BINDER // TO DO: REFACTOR THE ARG-BINDER
// bind arguments // bind arguments
/*
for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) { for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) {
if (args[i].type() == Node::assignment) { if (args[i].type() == Node::assignment) {
Node arg(args[i]); Node arg(args[i]);
...@@ -713,8 +718,20 @@ namespace Sass { ...@@ -713,8 +718,20 @@ namespace Sass {
} }
} }
} }
*/
// END ARG-BINDER // END ARG-BINDER
// link the new environment and eval the mixin's body // link the new environment and eval the mixin's body
// evaluate arguments in the current environment
for (size_t i = 0, S = args.size(); i < S; ++i) {
if (args[i].type() != Node::assignment) {
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
}
else {
args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
}
}
// link the mixin's new environment
if (dynamic_scope) { if (dynamic_scope) {
bindings.link(env); bindings.link(env);
} }
...@@ -723,6 +740,9 @@ namespace Sass { ...@@ -723,6 +740,9 @@ namespace Sass {
// to implement full lexical scope someday. // to implement full lexical scope someday.
bindings.link(env.global ? *env.global : env); bindings.link(env.global ? *env.global : env);
} }
// bind arguments in the extended environment
bind_arguments("mixin " + mixin[0].to_string(), params, args, prefix, bindings, f_env, new_Node, ctx);
// evaluate the mixin's body
for (size_t i = 0, S = body.size(); i < S; ++i) { for (size_t i = 0, S = body.size(); i < S; ++i) {
body[i] = eval(body[i], prefix, bindings, f_env, new_Node, ctx); body[i] = eval(body[i], prefix, bindings, f_env, new_Node, ctx);
} }
......
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