Skip to content

Commit

Permalink
improve parsing of special functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Jan 12, 2016
1 parent 67641d0 commit 6d4f9a2
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Sass {
extern const char odd_kwd[] = "odd";
extern const char progid_kwd[] = "progid";
extern const char expression_kwd[] = "expression";
extern const char calc_fn_kwd[] = "calc";
extern const char calc_kwd[] = "calc(";
extern const char moz_calc_kwd[] = "-moz-calc(";
extern const char webkit_calc_kwd[] = "-webkit-calc(";
Expand Down
1 change: 1 addition & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ namespace Sass {
extern const char progid_kwd[];
extern const char expression_kwd[];
extern const char calc_kwd[];
extern const char calc_fn_kwd[];
extern const char moz_calc_kwd[];
extern const char webkit_calc_kwd[];
extern const char ms_calc_kwd[];
Expand Down
7 changes: 3 additions & 4 deletions src/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,10 +882,9 @@ namespace Sass {
bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
exp.backtrace_stack.push_back(&here);
// if it's user-defined, eval the body
if (body) { result = body->perform(this); }
// if it's native, invoke the underlying CPP function
else { result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace()); }
// eval the body if user-defined or special, invoke underlying CPP function if native
if (body && !Prelexer::re_special_fun(c->name().c_str())) { result = body->perform(this); }
else if (func) { result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace()); }
if (!result) error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
exp.backtrace_stack.pop_back();
}
Expand Down
45 changes: 44 additions & 1 deletion src/prelexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ namespace Sass {
bool was_number = false;
const char* pos = src;
while (src) {
if (pos = alternatives < quoted_string, identifier, percentage, hex >(src)) {
if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {
was_number = false;
src = pos;
} else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) {
Expand Down Expand Up @@ -1129,6 +1129,41 @@ namespace Sass {
return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);
}

// lexer special_fn: these functions cannot be overloaded
// (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
const char* re_special_fun(const char* src) {
return sequence <
optional <
sequence <
exactly <'-'>,
one_plus <
alternatives <
alpha,
exactly <'+'>,
exactly <'-'>
>
>
>
>,
alternatives <
exactly < calc_fn_kwd >,
exactly < expression_kwd >,
sequence <
sequence <
exactly < progid_kwd >,
exactly <':'>
>,
zero_plus <
alternatives <
char_range <'a', 'z'>,
exactly <'.'>
>
>
>
>
>(src);
}

template <size_t size, prelexer mx, prelexer pad>
const char* padded_token(const char* src)
{
Expand Down Expand Up @@ -1159,5 +1194,13 @@ namespace Sass {
return pos;
}

template <char min, char max>
const char* char_range(const char* src)
{
if (*src < min) return 0;
if (*src > max) return 0;
return src + 1;
}

}
}
4 changes: 4 additions & 0 deletions src/prelexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ namespace Sass {
const char* re_nothing(const char* src);
const char* re_type_selector2(const char* src);

const char* re_special_fun(const char* src);

const char* kwd_warn(const char* src);
const char* kwd_err(const char* src);
Expand Down Expand Up @@ -423,6 +424,9 @@ namespace Sass {
template <size_t min, size_t max, prelexer mx>
const char* minmax_range(const char* src);

template <char min, char max>
const char* char_range(const char* src);

}
}

Expand Down

0 comments on commit 6d4f9a2

Please sign in to comment.