Commit 93d29fee by Aaron Leung

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

parent 828b44b3
......@@ -111,6 +111,7 @@ namespace Sass {
void parse_scss();
Node parse_import();
Node parse_include(bool delay = false);
void parse_mixin_def();
Node parse_mixin_params();
void parse_var_def();
......
......@@ -16,6 +16,14 @@ namespace Sass {
root += parse_import();
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)) {
parse_mixin_def();
}
......@@ -44,7 +52,36 @@ namespace Sass {
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< identifier >();
Node name(line_number, Node::identifier, lexed);
......@@ -65,11 +102,21 @@ namespace Sass {
cerr << ")" << endl;
}
Node Document::parse_mixin_params() {
Node Document::parse_mixin_params()
{
Node params(line_number, Node::parameters);
lex< exactly<'('> >();
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<','> >()) {
lex< variable >();
params << Node(line_number, Node::variable, lexed);
......@@ -79,21 +126,28 @@ namespace Sass {
return params;
}
void Document::parse_var_def()
Node Document::parse_var_def(bool delay)
{
lex< variable >();
const Token key(lexed);
lex< exactly<':'> >();
// context.environment[key] = parse_values();
Node val(parse_list());
Node val(parse_list(delay));
val.from_variable = true;
val.eval_me = true;
if (delay) {
Node def(line_number, Node::assignment, 2);
def << Node(line_number, Node::variable, key) << val;
return def;
}
else {
Node evaled(eval(val));
evaled.from_variable = true;
val.eval_me = true;
context.environment[key] = evaled;
return Node();
}
// context.environment[key] = val;
}
......@@ -252,15 +306,28 @@ namespace Sass {
}
else if (peek< import >(position)) {
Node imported_tree(parse_import());
for (int i = 0; i < imported_tree.children->size(); ++i) {
if (imported_tree.children->at(i).type == Node::comment ||
imported_tree.children->at(i).type == Node::rule) {
for (int i = 0; i < imported_tree.size(); ++i) {
if (imported_tree[i].type == Node::comment ||
imported_tree[i].type == Node::rule) {
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 << 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;
}
......@@ -527,7 +594,7 @@ namespace Sass {
if (lex< variable >()) {
if (delay) {
return Node(line_number, Node::var_ref, lexed);
return Node(line_number, Node::variable, lexed);
}
else {
return context.environment[lexed];
......
......@@ -26,7 +26,7 @@ div {
@include foo(1, 2);
@include foo(1);
@include foogoo(1, 2);
@include foogoo($y: kwd-y, $z: kwd-z);
@include foogoo($y /* blah */ : kwd-y, $z: kwd-z);
}
div {
......@@ -64,3 +64,22 @@ div {
@include foo(arg1, arg2, $x: kwdarg1, $y: kwdarg2);
@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 {
mixin,
parameters,
variable,
var_ref,
include
assignment,
mixin_call
};
static size_t fresh;
......@@ -220,10 +220,13 @@ namespace Sass {
//~Node() { delete children; }
size_t size()
size_t size() const
{ 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); }
Node& operator=(const Node& n)
......
......@@ -91,6 +91,10 @@ namespace Sass {
const char* mixin(const char* 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) {
return one_plus< alternatives< alnum,
......
......@@ -276,6 +276,7 @@ namespace Sass {
const char* at_keyword(const char* src);
const char* import(const char* src);
const char* mixin(const char* src);
const char* include(const char* src);
// Match CSS type selectors
const char* namespace_prefix(const char* src);
const char* type_selector(const char* src);
......
$blah: bloo blee;
$blip: "a 'red' and \"blue\" value";
@mixin foo($arg) {
whatever: $arg;
@mixin foo($arg, $blarg) {
whatever: $blarg $arg;
}
/* 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