Commit 93d29fee by Aaron Leung

Mixin stuff. Better commit and push while I have network connectivity.

parent 828b44b3
...@@ -111,6 +111,7 @@ namespace Sass { ...@@ -111,6 +111,7 @@ namespace Sass {
void parse_scss(); void parse_scss();
Node parse_import(); Node parse_import();
Node parse_include(bool delay = false);
void parse_mixin_def(); void parse_mixin_def();
Node parse_mixin_params(); Node parse_mixin_params();
void parse_var_def(); void parse_var_def();
......
...@@ -16,6 +16,14 @@ namespace Sass { ...@@ -16,6 +16,14 @@ namespace Sass {
root += parse_import(); root += parse_import();
lex< exactly<';'> >(); lex< exactly<';'> >();
} }
else if (peek< include >(position)) {
Node to_include(parse_include());
root += to_include;
root.has_rules_or_comments |= to_include.has_rules_or_comments;
root.has_rulesets |= to_include.has_rulesets;
root.has_propsets |= to_include.has_propsets;
lex< exactly<';'> >();
}
else if (peek< mixin >(position)) { else if (peek< mixin >(position)) {
parse_mixin_def(); parse_mixin_def();
} }
...@@ -44,7 +52,36 @@ namespace Sass { ...@@ -44,7 +52,36 @@ namespace Sass {
return importee.root; return importee.root;
} }
void Document::parse_mixin_def() { Node Document::parse_include(bool delay)
{
lex< include >();
lex< identifier >();
Node name(line_number, Node::identifier, lexed);
Node args(line_number, Node::arguments, parse_arguments(delay));
Node call(line_number, Node::mixin_call, 2);
call << name << args;
if (!delay) {
cerr << "including " << string(name.token) << endl;
// expand the mixin
return name;
}
else {
return call;
}
}
Node Document::parse_arguments(bool delay)
{
lex< exactly<'('> >();
if (lex< sequence < variable, spaces_and_comments, exactly<':'> > >()) { // check for keyword arg
lex< exactly<')'> )();
}
void Document::parse_mixin_def()
{
lex< mixin >(); lex< mixin >();
lex< identifier >(); lex< identifier >();
Node name(line_number, Node::identifier, lexed); Node name(line_number, Node::identifier, lexed);
...@@ -65,11 +102,21 @@ namespace Sass { ...@@ -65,11 +102,21 @@ namespace Sass {
cerr << ")" << endl; cerr << ")" << endl;
} }
Node Document::parse_mixin_params() { Node Document::parse_mixin_params()
{
Node params(line_number, Node::parameters); Node params(line_number, Node::parameters);
lex< exactly<'('> >(); lex< exactly<'('> >();
if (lex< variable >()) { if (lex< variable >()) {
params << Node(line_number, Node::variable, lexed); Node var(line_number, Node::variable, lexed);
if (lex< exactly<':'> >()) { // default value
Node val(parse_space_list(true));
Node par_val(line_number, Node::assignment, 2);
par_val << var << val;
params << par_val;
}
else {
params << var;
}
while (lex< exactly<','> >()) { while (lex< exactly<','> >()) {
lex< variable >(); lex< variable >();
params << Node(line_number, Node::variable, lexed); params << Node(line_number, Node::variable, lexed);
...@@ -79,21 +126,28 @@ namespace Sass { ...@@ -79,21 +126,28 @@ namespace Sass {
return params; return params;
} }
void Document::parse_var_def() Node Document::parse_var_def(bool delay)
{ {
lex< variable >(); lex< variable >();
const Token key(lexed); const Token key(lexed);
lex< exactly<':'> >(); lex< exactly<':'> >();
// context.environment[key] = parse_values(); // context.environment[key] = parse_values();
Node val(parse_list()); Node val(parse_list(delay));
val.from_variable = true; val.from_variable = true;
val.eval_me = true; val.eval_me = true;
Node evaled(eval(val)); if (delay) {
evaled.from_variable = true; Node def(line_number, Node::assignment, 2);
val.eval_me = true; def << Node(line_number, Node::variable, key) << val;
return def;
context.environment[key] = evaled; }
else {
Node evaled(eval(val));
evaled.from_variable = true;
val.eval_me = true;
context.environment[key] = evaled;
return Node();
}
// context.environment[key] = val; // context.environment[key] = val;
} }
...@@ -252,15 +306,28 @@ namespace Sass { ...@@ -252,15 +306,28 @@ namespace Sass {
} }
else if (peek< import >(position)) { else if (peek< import >(position)) {
Node imported_tree(parse_import()); Node imported_tree(parse_import());
for (int i = 0; i < imported_tree.children->size(); ++i) { for (int i = 0; i < imported_tree.size(); ++i) {
if (imported_tree.children->at(i).type == Node::comment || if (imported_tree[i].type == Node::comment ||
imported_tree.children->at(i).type == Node::rule) { imported_tree[i].type == Node::rule) {
block.has_rules_or_comments = true; block.has_rules_or_comments = true;
} }
else if (imported_tree.children->at(i).type == Node::ruleset) { else if (imported_tree[i].type == Node::ruleset) {
block.has_rulesets = true; block.has_rulesets = true;
} }
block << imported_tree.children->at(i); block << imported_tree[i];
}
semicolon = true;
}
else if (peek< include >(position)) {
Node to_include(parse_include(delay));
if (!delay) {
block += to_include;
block.has_rules_or_comments |= to_include.has_rules_or_comments;
block.has_rulesets |= to_include.has_rulesets;
block.has_propsets |= to_include.has_propsets;
}
else {
block << to_include;
} }
semicolon = true; semicolon = true;
} }
...@@ -527,7 +594,7 @@ namespace Sass { ...@@ -527,7 +594,7 @@ namespace Sass {
if (lex< variable >()) { if (lex< variable >()) {
if (delay) { if (delay) {
return Node(line_number, Node::var_ref, lexed); return Node(line_number, Node::variable, lexed);
} }
else { else {
return context.environment[lexed]; return context.environment[lexed];
......
...@@ -26,7 +26,7 @@ div { ...@@ -26,7 +26,7 @@ div {
@include foo(1, 2); @include foo(1, 2);
@include foo(1); @include foo(1);
@include foogoo(1, 2); @include foogoo(1, 2);
@include foogoo($y: kwd-y, $z: kwd-z); @include foogoo($y /* blah */ : kwd-y, $z: kwd-z);
} }
div { div {
...@@ -64,3 +64,22 @@ div { ...@@ -64,3 +64,22 @@ div {
@include foo(arg1, arg2, $x: kwdarg1, $y: kwdarg2); @include foo(arg1, arg2, $x: kwdarg1, $y: kwdarg2);
@include foo($x: kwdarg1, $y: kwdarg2, arg1, arg2); @include foo($x: kwdarg1, $y: kwdarg2, arg1, arg2);
} }
@mixin ruleset() {
hoo {
color: boo;
}
}
@include ruleset();
$da: default argument;
@mixin default_args($x, $y: $da) {
blah: $x $y;
}
$da: some other default;
div {
@include default_args(boogoo);
}
\ No newline at end of file
...@@ -65,8 +65,8 @@ namespace Sass { ...@@ -65,8 +65,8 @@ namespace Sass {
mixin, mixin,
parameters, parameters,
variable, variable,
var_ref, assignment,
include mixin_call
}; };
static size_t fresh; static size_t fresh;
...@@ -220,10 +220,13 @@ namespace Sass { ...@@ -220,10 +220,13 @@ namespace Sass {
//~Node() { delete children; } //~Node() { delete children; }
size_t size() size_t size() const
{ return children->size(); } { return children->size(); }
Node& operator[](const size_t i) Node& operator[](const size_t i) const
{ return children->at(i); }
Node& at(const size_t i) const
{ return children->at(i); } { return children->at(i); }
Node& operator=(const Node& n) Node& operator=(const Node& n)
......
...@@ -91,6 +91,10 @@ namespace Sass { ...@@ -91,6 +91,10 @@ namespace Sass {
const char* mixin(const char* src) { const char* mixin(const char* src) {
return exactly<mixin_kwd>(src); return exactly<mixin_kwd>(src);
} }
extern const char include_kwd[] = "@include";
const char* include(const char* src) {
return exactly<include_kwd>(src);
}
const char* name(const char* src) { const char* name(const char* src) {
return one_plus< alternatives< alnum, return one_plus< alternatives< alnum,
......
...@@ -276,6 +276,7 @@ namespace Sass { ...@@ -276,6 +276,7 @@ namespace Sass {
const char* at_keyword(const char* src); const char* at_keyword(const char* src);
const char* import(const char* src); const char* import(const char* src);
const char* mixin(const char* src); const char* mixin(const char* src);
const char* include(const char* src);
// Match CSS type selectors // Match CSS type selectors
const char* namespace_prefix(const char* src); const char* namespace_prefix(const char* src);
const char* type_selector(const char* src); const char* type_selector(const char* src);
......
$blah: bloo blee; $blah: bloo blee;
$blip: "a 'red' and \"blue\" value"; $blip: "a 'red' and \"blue\" value";
@mixin foo($arg) { @mixin foo($arg, $blarg) {
whatever: $arg; whatever: $blarg $arg;
} }
/* top level comment -- should be preserved */ /* top level comment -- should be preserved */
......
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