Permalink
Browse files

Workin' on mixin content.

  • Loading branch information...
1 parent c062aee commit 2b815275698d44b8859c67edff624ecf0cb41604 Aaron Leung committed Nov 22, 2012
Showing with 30 additions and 18 deletions.
  1. +2 −2 document_parser.cpp
  2. +15 −7 eval_apply.cpp
  3. +2 −2 eval_apply.hpp
  4. +2 −0 node.cpp
  5. +9 −7 node.hpp
View
@@ -604,11 +604,11 @@ namespace Sass {
block << parse_mixin_call();
semicolon = true;
}
- else if (peek< content >(position)) {
+ else if (lex< content >()) {
if (inside_of != Node::mixin) {
throw_syntax_error("@content may only be used within a mixin");
}
- block << context.new_Node(Node::mixin_content, path, line, Token::make()); // just a stub
+ block << context.new_Node(Node::mixin_content, path, line, 0); // just an expansion stub
semicolon = true;
}
else if (peek< sequence< identifier, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
View
@@ -25,7 +25,7 @@ namespace Sass {
}
// Expansion function for nodes in an expansion context.
- void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name)
+ void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name, const Node content)
{
switch (expr.type())
{
@@ -46,14 +46,22 @@ namespace Sass {
case Node::mixin_call: { // mixin invocation
Token name(expr[0].token());
Node args(expr[1]);
+ Node this_content = expr.size() == 3 ? expr[2] : Node();
+ if (!this_content.is_null()) expand(this_content, prefix, env, f_env, new_Node, ctx, bt);
if (!env.query(name)) throw_eval_error(bt, "mixin " + name.to_string() + " is undefined", expr.path(), expr.line());
Node mixin(env[name]);
Backtrace here(&bt, expr.path(), expr.line(), ", in mixin '" + name.to_string() + "'");
- Node expansion(apply_mixin(mixin, args, prefix, env, f_env, new_Node, ctx, here));
+ Node expansion(apply_mixin(mixin, args, this_content, prefix, env, f_env, new_Node, ctx, here));
expr.pop_all(); // pop the mixin metadata
expr += expansion; // push the expansion
} break;
+ case Node::mixin_content: {
+ cerr << "HEY" << endl;
+ expr += content;
+ cerr << "HO" << endl;
+ } break;
+
case Node::propset: {
// TO DO: perform the property expansion here, rather than in the emitter (also requires the parser to allow interpolants in the property names)
expand(expr[1], prefix, env, f_env, new_Node, ctx, bt);
@@ -266,7 +274,7 @@ namespace Sass {
Node i_node(new_Node(expr.path(), expr.line(), i));
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 1));
fake_arg << i_node;
- expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, bt, true);
+ expr += apply_mixin(fake_mixin, fake_arg, Node(), prefix, env, f_env, new_Node, ctx, bt, true);
}
} break;
@@ -286,7 +294,7 @@ namespace Sass {
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 1));
list[i].should_eval() = true;
fake_arg << eval(list[i], prefix, env, f_env, new_Node, ctx, bt);
- expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, bt, true);
+ expr += apply_mixin(fake_mixin, fake_arg, Node(), prefix, env, f_env, new_Node, ctx, bt, true);
}
} break;
@@ -302,7 +310,7 @@ namespace Sass {
expr.pop_back();
Node ev_pred(eval(pred, prefix, env, f_env, new_Node, ctx, bt));
while (!ev_pred.is_false()) {
- expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, bt, true);
+ expr += apply_mixin(fake_mixin, fake_arg, Node(), prefix, env, f_env, new_Node, ctx, bt, true);
ev_pred = eval(pred, prefix, env, f_env, new_Node, ctx, bt);
}
} break;
@@ -831,7 +839,7 @@ namespace Sass {
// 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.
- Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool dynamic_scope)
+ Node apply_mixin(Node mixin, const Node args, const Node content, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool dynamic_scope)
{
Node params(mixin[1]);
Node body(new_Node(mixin[2])); // clone the body
@@ -852,7 +860,7 @@ namespace Sass {
if (!mixin[0].is_null()) mixin_name << " " << mixin[0].to_string();
bind_arguments(mixin_name.str(), params, evaluated_args, prefix, bindings, f_env, new_Node, ctx, bt);
// evaluate the mixin's body
- expand(body, prefix, bindings, f_env, new_Node, ctx, bt);
+ expand(body, prefix, bindings, f_env, new_Node, ctx, bt, false, content);
return body;
}
View
@@ -17,14 +17,14 @@
namespace Sass {
using std::map;
- void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name = false);
+ void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name = false, const Node content = Node());
Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name = false);
Node eval_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt);
Node eval_function(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool toplevel = false);
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node, Backtrace& bt);
double operate(Node op, double lhs, double rhs, Backtrace& bt);
- Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool dynamic_scope = false);
+ Node apply_mixin(Node mixin, const Node args, const Node content, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool dynamic_scope = false);
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, string& path, size_t line);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
Node expand_backref(Node sel, Node pre);
View
@@ -19,6 +19,7 @@ namespace Sass {
{
case block:
case mixin_call:
+ case mixin_content:
case root:
case if_directive:
case for_through_directive:
@@ -35,6 +36,7 @@ namespace Sass {
switch (at(i).type())
{
case mixin_call:
+ case mixin_content:
case block:
case if_directive:
case for_through_directive:
View
@@ -381,7 +381,8 @@ namespace Sass {
case Node::for_to_directive:
case Node::each_directive:
case Node::while_directive:
- case Node::mixin_call: {
+ case Node::mixin_call:
+ case Node::mixin_content: {
has_expansions = true;
} break;
@@ -400,25 +401,26 @@ namespace Sass {
has_children = true;
switch (n.type())
{
- case Node::comment: has_comments = true; break;
+ case Node::comment: has_comments = true; break;
case Node::css_import:
case Node::rule:
- case Node::propset: has_statements = true; break;
+ case Node::propset: has_statements = true; break;
case Node::media_query:
- case Node::ruleset: has_blocks = true; break;
+ case Node::ruleset: has_blocks = true; break;
case Node::if_directive:
case Node::for_through_directive:
case Node::for_to_directive:
case Node::each_directive:
case Node::while_directive:
- case Node::mixin_call: has_expansions = true; break;
+ case Node::mixin_call:
+ case Node::mixin_content: has_expansions = true; break;
- case Node::backref: has_backref = true; break;
+ case Node::backref: has_backref = true; break;
- default: break;
+ default: break;
}
if (n.has_backref()) has_backref = true;
}

0 comments on commit 2b81527

Please sign in to comment.