Commit a087ed82 by Andrew Nesbitt

Updated libsass, closes #52

parent 119743ae
......@@ -41,6 +41,17 @@ namespace Sass {
return ss.str();
}
size_t depth()
{
size_t d = 0;
Backtrace* p = parent;
while (p) {
++d;
p = p->parent;
}
return d-1;
}
};
}
\ No newline at end of file
......@@ -86,6 +86,7 @@ namespace Sass {
extern const char rparen[] = ")";
extern const char sign_chars[] = "-+";
extern const char hyphen[] = "-";
extern const char ellipsis[] = "...";
// type names
extern const char numeric_name[] = "numeric value";
......@@ -96,6 +97,7 @@ namespace Sass {
extern const char bool_name[] = "bool";
extern const char color_name[] = "color";
extern const char list_name[] = "list";
extern const char arglist_name[] = "arglist";
}
}
\ No newline at end of file
......@@ -86,6 +86,7 @@ namespace Sass {
extern const char rparen[];
extern const char sign_chars[];
extern const char hyphen[];
extern const char ellipsis[];
// type names
extern const char numeric_name[];
......@@ -96,5 +97,6 @@ namespace Sass {
extern const char bool_name[];
extern const char color_name[];
extern const char list_name[];
extern const char arglist_name[];
}
}
\ No newline at end of file
......@@ -177,23 +177,32 @@ namespace Sass {
Node::Type param_type = Node::none;
if (lex< exactly<'('> >()) {
if (peek< variable >()) {
Node param(parse_parameter(param_type));
if (param.type() == Node::assignment) param_type = Node::assignment;
params << param;
while (lex< exactly<','> >()) {
do {
if (!peek< variable >()) throw_syntax_error("expected a variable name (e.g. $x) for the parameter list for " + name.to_string());
Node param(parse_parameter(param_type));
if (param.type() == Node::assignment) param_type = Node::assignment;
params << param;
if (param.type() == Node::rest) {
param_type = Node::rest;
break;
}
} while (lex< exactly<','> >());
if (!lex< exactly<')'> >()) {
if (params.back().type() == Node::rest && peek< exactly<','> >()) {
throw_syntax_error("variable-length parameter must appear last in a parameter list");
}
else {
throw_syntax_error("parameter list for " + name.to_string() + " requires a ')'");
}
}
if (!lex< exactly<')'> >()) throw_syntax_error("parameter list for " + name.to_string() + " requires a ')'");
}
else if (!lex< exactly<')'> >()) throw_syntax_error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name.to_string());
}
return params;
}
Node Document::parse_parameter(Node::Type param_type) {
Node Document::parse_parameter(Node::Type param_type)
{
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
if (param_type == Node::assignment) {
......@@ -213,6 +222,9 @@ namespace Sass {
par_and_val << var << val;
return par_and_val;
}
else if (lex< exactly< ellipsis > >()) {
return context.new_Node(Node::rest, var.path(), var.line(), var.token());
}
return var;
}
......@@ -241,16 +253,26 @@ namespace Sass {
Node::Type arg_type = Node::none;
if (lex< exactly<'('> >()) {
if (!peek< exactly<')'> >(position)) {
Node arg(parse_argument(Node::none));
args << arg;
if (arg.type() == Node::assignment) arg_type = Node::assignment;
while (lex< exactly<','> >()) {
do {
Node arg(parse_argument(arg_type));
args << arg;
if (arg.type() == Node::assignment) arg_type = Node::assignment;
if (arg.type() == Node::assignment) {
arg_type = Node::assignment;
}
else if (arg.type() == Node::rest) {
arg_type = Node::rest;
break;
}
} while (lex< exactly<','> >());
}
if (!lex< exactly<')'> >()) {
if (args.back().is_arglist() && peek< exactly<','> >()) {
throw_syntax_error("variable-length argument must appear last in an argument list");
}
else {
throw_syntax_error("improperly terminated argument list for " + name.to_string());
}
}
if (!lex< exactly<')'> >()) throw_syntax_error("improperly terminated argument list for " + name.to_string());
}
return args;
}
......@@ -274,7 +296,7 @@ namespace Sass {
}
}
// otherwise accept either, and let the caller set the arg_type flag
if (arg_type == Node::none &&
else if (arg_type == Node::none &&
peek< sequence < variable, spaces_and_comments, exactly<':'> > >()) {
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
......@@ -285,8 +307,18 @@ namespace Sass {
assn << var << val;
return assn;
}
// else if (arg_type == Node::none &&
// peek< sequence < variable, spaces_and_comments, exactly< ellipsis > > >()) {
// lex< variable >();
// lex< exactly< ellipsis > >();
// return context.new_Node(Node::rest, path, line, lexed);
// }
Node val(parse_space_list());
val.should_eval() = true;
if (lex< exactly< ellipsis > >()) {
val.is_arglist() = true;
val.is_splat() = true;
}
return val;
}
......@@ -711,7 +743,8 @@ namespace Sass {
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position))
peek< exactly<')'> >(position) ||
peek< exactly<ellipsis> >(position))
{ return context.new_Node(Node::list, path, line, 0); }
Node list1(parse_space_list());
// if it's a singleton, return it directly; don't wrap it
......@@ -741,6 +774,7 @@ namespace Sass {
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position) ||
peek< exactly<ellipsis> >(position) ||
peek< default_flag >(position))
{ return disj1; }
......@@ -753,6 +787,7 @@ namespace Sass {
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position) ||
peek< exactly<ellipsis> >(position) ||
peek< default_flag >(position)))
{
Node disj(parse_disjunction());
......
......@@ -1049,6 +1049,12 @@ namespace Sass {
type_name = Token::make(color_name);
} break;
case Node::list: {
// cerr << val.to_string() << endl;
// cerr << val.is_arglist() << endl;
// throw (42);
if (val.is_arglist())
type_name = Token::make(arglist_name);
else
type_name = Token::make(list_name);
} break;
default: {
......
......@@ -158,6 +158,7 @@ namespace Sass {
mixin_content,
parameters,
arguments,
rest,
extend_directive,
......@@ -199,6 +200,8 @@ namespace Sass {
bool& has_been_extended() const;
bool is_false() const;
bool& is_comma_separated() const;
bool& is_arglist() const;
bool& is_splat() const;
string& path() const;
size_t line() const;
......@@ -240,7 +243,7 @@ namespace Sass {
bool operator>(Node rhs) const;
bool operator>=(Node rhs) const;
string to_string(Type inside_of = none, const string space = " ") const;
string to_string(Type inside_of = none, const string space = " ", const bool in_media_feature = false) const;
void emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel = false, bool in_media_query = false, bool source_comments = false);
void emit_propset(stringstream& buf, size_t depth, const string& prefix, const bool compressed = false);
void echo(stringstream& buf, size_t depth = 0);
......@@ -277,6 +280,8 @@ namespace Sass {
bool is_quoted;
bool has_been_extended;
bool is_comma_separated;
bool is_arglist;
bool is_splat;
Node_Impl()
: /* value(value_t()),
......@@ -294,7 +299,9 @@ namespace Sass {
should_eval(false),
is_quoted(false),
has_been_extended(false),
is_comma_separated(false)
is_comma_separated(false),
is_arglist(false),
is_splat(false)
{ }
bool is_numeric()
......@@ -467,6 +474,8 @@ namespace Sass {
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
inline bool Node::is_false() const { return (type() == boolean) && (boolean_value() == false); }
inline bool& Node::is_comma_separated() const { return ip_->is_comma_separated; }
inline bool& Node::is_arglist() const { return ip_->is_arglist; }
inline bool& Node::is_splat() const { return ip_->is_splat; }
inline string& Node::path() const { return ip_->path; }
inline size_t Node::line() const { return ip_->line; }
......
......@@ -15,7 +15,7 @@ using std::endl;
namespace Sass {
string Node::to_string(Type inside_of, const string space) const
string Node::to_string(Type inside_of, const string space, const bool in_media_feature) const
{
if (is_null()) return "";
switch (type())
......@@ -39,22 +39,27 @@ namespace Sass {
string result;
if (at(0).type() == rule) {
result += "(";
result += at(0).to_string(none, space);
result += at(0).to_string(none, space, true);
result += ")";
}
else {
result += at(0).to_string(none, space);
string tmp = at(0).to_string(none, space);
result += tmp;
if (tmp == "and" && space == "") result += " ";
}
for (size_t i = 1, S = size(); i < S; ++i) {
if (at(i).type() == rule) {
result += space;
result += "(";
result += at(i).to_string(none, space);
result += at(i).to_string(none, space, true);
result += ")";
}
else {
result += " ";
result += at(i).to_string(none, space);
// result += at(i).to_string(none, space);
string tmp = at(i).to_string(none, space);
result += tmp;
if (tmp == "and" && space == "") result += " ";
}
}
return result;
......@@ -125,6 +130,7 @@ namespace Sass {
string result(at(0).to_string(property, space));
result += ":";
result += space;
if (space == "" && in_media_feature) result += " ";
result += at(1).to_string(none, space);
return result;
} break;
......
This diff was suppressed by a .gitattributes entry.
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