Commit 7db55551 by Aaron Leung

Handling values with embedded interpolants.

parent 0936e9d8
......@@ -670,11 +670,12 @@ namespace Sass {
return result;
}
if (peek< value_schema >())
if (lex< value_schema >())
{
// TO DO: handle value schemas!
return Node(Node::identifier, line_number, lexed);
return parse_value_schema();
cerr << "parsing value schema: " << lexed.to_string() << endl;
Document schema_doc(path, line_number, lexed, context);
return schema_doc.parse_value_schema();
}
if (lex< sequence< true_kwd, negate< identifier > > >())
......@@ -724,37 +725,31 @@ namespace Sass {
return var;
}
if (lex< interpolant >())
{
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
Document interp(path, line_number, insides, context);
return interp.parse_list();
}
syntax_error("error reading values after " + lexed.to_string());
}
Node Document::parse_value_schema()
{
Node schema;
// just an interpolant
if (lex< interpolant >()) {
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
Document interp_doc(path, line_number, insides, context);
Node interp_node(interp_doc.parse_list());
if (peek< alternatives< spaces, comment,
exactly<';'>, exactly<','>,
exactly<'('>, exactly<')'> > >()) {
return interp_node;
}
// interpolant with stuff immediately behind it
else {
schema = Node(Node::value_schema, context.registry, line_number, 2);
schema << interp_node;
}
}
// Node schema;
// if (lex< interpolant >()) {
// Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
// Document interp_doc(path, line_number, insides, context);
// Node interp_node(interp_doc.parse_list());
// if (position >= end) {
// return interp_node;
// }
// else {
// schema = Node(Node::value_schema, context.registry, line_number, 2);
// schema << interp_node;
// }
// }
// else {
// schema = Node(Node::value_schema, context.registry, line_number, 2);
// }
Node schema(Node::value_schema, context.registry, line_number, 1);
while (true) {
while (position < end) {
if (lex< interpolant >()) {
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
Document interp_doc(path, line_number, insides, context);
......@@ -785,12 +780,8 @@ namespace Sass {
else {
syntax_error("error parsing interpolated value");
}
if (peek< alternatives< spaces, comment,
exactly<';'>, exactly<','>,
exactly<'('>, exactly<')'> > >()) {
break;
}
}
schema.eval_me = true;
return schema;
}
......
......@@ -86,6 +86,9 @@ namespace Sass {
if (rhs[i].eval_me) rhs[i] = eval(rhs[i], env, f_env, registry);
}
}
else if (rhs.type == Node::value_schema) {
eval(rhs, env, f_env, registry);
}
else {
if (rhs.eval_me) expr[1] = eval(rhs, env, f_env, registry);
}
......@@ -221,6 +224,7 @@ namespace Sass {
} break;
case Node::value_schema: {
cerr << "evaluating schema of size " << expr.size() << endl;
for (int i = 0; i < expr.size(); ++i) {
expr[i] = eval(expr[i], env, f_env, registry);
}
......
......@@ -452,6 +452,7 @@ namespace Sass {
type.content.token = Token::make(bool_name);
break;
case Node::string_constant:
case Node::value_schema:
type.content.token = Token::make(string_name);
break;
case Node::numeric_color:
......
......@@ -83,9 +83,9 @@ namespace Sass {
// Match interpolant schemas
const char* value_schema(const char* src) {
// follows this pattern: ([xyz]*i[xyz]*)+
return one_plus< sequence< zero_plus< alternatives< identifier, number > >,
return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > >,
interpolant,
zero_plus< alternatives< identifier, number > > > >(src);
zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > > > >(src);
}
// Match CSS '@' keywords.
......
......@@ -151,6 +151,34 @@ namespace Sass {
return rslt;
}
// Same as above, but with 7 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6,
prelexer mx7>
const char* alternatives(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) || (rslt = mx2(rslt)) ||
(rslt = mx3(rslt)) || (rslt = mx4(rslt)) ||
(rslt = mx5(rslt)) || (rslt = mx6(rslt)) ||
(rslt = mx7(rslt));
return rslt;
}
// Same as above, but with 8 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6,
prelexer mx7, prelexer mx8>
const char* alternatives(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) || (rslt = mx2(rslt)) ||
(rslt = mx3(rslt)) || (rslt = mx4(rslt)) ||
(rslt = mx5(rslt)) || (rslt = mx6(rslt)) ||
(rslt = mx7(rslt)) || (rslt = mx8(rslt));
return rslt;
}
// Tries the matchers in sequence and succeeds if they all succeed.
template <prelexer mx1, prelexer mx2>
const char* sequence(const char* src) {
......
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