diff --git a/parser.cpp b/parser.cpp index 2332bf8306..b6c0bf605b 100644 --- a/parser.cpp +++ b/parser.cpp @@ -415,7 +415,13 @@ namespace Sass { string name(Util::normalize_underscores(lexed)); ParserState var_source_position = pstate; if (!lex< exactly<':'> >()) error("expected ':' after " + name + " in assignment statement", pstate); - Expression* val = parse_list(); + Expression* val; + Selector_Lookahead lookahead = lookahead_for_value(position); + if (lookahead.has_interpolants && lookahead.found) { + val = parse_value_schema(lookahead.found); + } else { + val = parse_list(); + } val->is_delayed(false); bool is_default = false; bool is_global = false; @@ -1564,12 +1570,18 @@ namespace Sass { else if (lex< hex >()) { (*schema) << new (ctx.mem) Textual(pstate, Textual::HEX, unquote(lexed)); } + else if (lex < exactly < '-' > >()) { + (*schema) << new (ctx.mem) String_Constant(pstate, lexed); + } else if (lex< quoted_string >()) { (*schema) << new (ctx.mem) String_Quoted(pstate, lexed); } else if (lex< variable >()) { (*schema) << new (ctx.mem) Variable(pstate, Util::normalize_underscores(lexed)); } + else if (peek< parenthese_scope >()) { + (*schema) << parse_factor(); + } else { error("error parsing interpolated value", pstate); } @@ -2171,12 +2183,13 @@ namespace Sass { (q = peek< percentage >(p)) || (q = peek< dimension >(p)) || (q = peek< quoted_string >(p)) || - (q = peek< variable >(p)) || + (q = peek< variable >(p)) || (q = peek< exactly<'*'> >(p)) || (q = peek< exactly<'+'> >(p)) || (q = peek< exactly<'~'> >(p)) || (q = peek< exactly<'>'> >(p)) || (q = peek< exactly<','> >(p)) || + (q = peek< sequence>(p)) || (saw_stuff && (q = peek< exactly<'-'> >(p))) || (q = peek< binomial >(p)) || (q = peek< block_comment >(p)) || @@ -2184,10 +2197,10 @@ namespace Sass { zero_plus, exactly<'n'> > >(p)) || (q = peek< sequence< optional, - one_plus > >(p)) || + one_plus > >(p)) || (q = peek< number >(p)) || (q = peek< sequence< exactly<'&'>, - identifier_alnums > >(p)) || + identifier_alnums > >(p)) || (q = peek< exactly<'&'> >(p)) || (q = peek< exactly<'%'> >(p)) || (q = peek< sequence< exactly<'.'>, interpolant > >(p)) || diff --git a/prelexer.cpp b/prelexer.cpp index e13c56d850..aa9f94f0d1 100644 --- a/prelexer.cpp +++ b/prelexer.cpp @@ -729,5 +729,16 @@ namespace Sass { alternatives< exactly<';'>, exactly<'}'> > >(src); } + + const char* parenthese_scope(const char* src) { + return sequence < + exactly < '(' >, + skip_over_scopes < + exactly < '(' >, + exactly < ')' > + > + >(src); + } + } } diff --git a/prelexer.hpp b/prelexer.hpp index 2f7e15a3c0..d5242d40b5 100644 --- a/prelexer.hpp +++ b/prelexer.hpp @@ -58,7 +58,7 @@ namespace Sass { // recursive skip stuff delimited by start/stop // first start/opener must be consumed already! template - const char* skip_over_scopes(const char* src, const char* end = 0) { + const char* skip_over_scopes(const char* src, const char* end) { size_t level = 0; bool in_squote = false; @@ -105,6 +105,19 @@ namespace Sass { return 0; } + // skip to a skip delimited by parentheses + // uses smart `skip_over_scopes` internally + const char* parenthese_scope(const char* src); + + // skip to delimiter (mx) inside given range + // this will savely skip over all quoted strings + // recursive skip stuff delimited by start/stop + // first start/opener must be consumed already! + template + const char* skip_over_scopes(const char* src) { + return skip_over_scopes(src, 0); + } + // Match a sequence of characters delimited by the supplied chars. template const char* recursive_scopes(const char* src) {