Commit efb5a2d0 by Aaron Leung

Adding infrastructure for pure Sass functions. Necessary to pass more contextual…

Adding infrastructure for pure Sass functions. Necessary to pass more contextual data around during parsing, since the set of expressions permitted in functions is relatively limited.
parent 8840431b
...@@ -65,13 +65,13 @@ namespace Sass { ...@@ -65,13 +65,13 @@ namespace Sass {
// cerr << "Deallocated " << i << " source string(s)." << endl; // cerr << "Deallocated " << i << " source string(s)." << endl;
} }
inline void Context::register_function(Function_Descriptor d, Implementation ip) inline void Context::register_function(Function_Descriptor d, Primitive ip)
{ {
Function f(d, ip); Function f(d, ip);
function_env[pair<string, size_t>(f.name, f.parameters.size())] = f; function_env[pair<string, size_t>(f.name, f.parameters.size())] = f;
} }
inline void Context::register_function(Function_Descriptor d, Implementation ip, size_t arity) inline void Context::register_function(Function_Descriptor d, Primitive ip, size_t arity)
{ {
Function f(d, ip); Function f(d, ip);
function_env[pair<string, size_t>(f.name, arity)] = f; function_env[pair<string, size_t>(f.name, arity)] = f;
......
...@@ -57,8 +57,8 @@ namespace Sass { ...@@ -57,8 +57,8 @@ namespace Sass {
Context(const char* paths_str = 0); Context(const char* paths_str = 0);
~Context(); ~Context();
void register_function(Function_Descriptor d, Implementation ip); void register_function(Function_Descriptor d, Primitive ip);
void register_function(Function_Descriptor d, Implementation ip, size_t arity); void register_function(Function_Descriptor d, Primitive ip, size_t arity);
void register_functions(); void register_functions();
}; };
......
...@@ -128,14 +128,15 @@ namespace Sass { ...@@ -128,14 +128,15 @@ namespace Sass {
Node parse_import(); Node parse_import();
Node parse_include(); Node parse_include();
Node parse_mixin_definition(); Node parse_mixin_definition();
Node parse_mixin_parameters(); Node parse_function_definition();
Node parse_parameters();
Node parse_parameter(); Node parse_parameter();
Node parse_mixin_call(); Node parse_mixin_call();
Node parse_arguments(); Node parse_arguments();
Node parse_argument(); Node parse_argument();
Node parse_assignment(); Node parse_assignment();
Node parse_propset(); Node parse_propset();
Node parse_ruleset(Selector_Lookahead lookahead, bool in_definition = false); Node parse_ruleset(Selector_Lookahead lookahead, Node::Type inside_of = Node::none);
Node parse_selector_schema(const char* end_of_selector); Node parse_selector_schema(const char* end_of_selector);
Node parse_selector_group(); Node parse_selector_group();
Node parse_selector(); Node parse_selector();
...@@ -144,7 +145,7 @@ namespace Sass { ...@@ -144,7 +145,7 @@ namespace Sass {
Node parse_simple_selector(); Node parse_simple_selector();
Node parse_pseudo(); Node parse_pseudo();
Node parse_attribute_selector(); Node parse_attribute_selector();
Node parse_block(Node surrounding_rulesetbool, bool in_definition = false); Node parse_block(Node surrounding_rulesetbool, Node::Type inside_of = Node::none);
Node parse_rule(); Node parse_rule();
Node parse_values(); Node parse_values();
Node parse_list(); Node parse_list();
...@@ -160,10 +161,10 @@ namespace Sass { ...@@ -160,10 +161,10 @@ namespace Sass {
Node parse_function_call(); Node parse_function_call();
Node parse_string(); Node parse_string();
Node parse_value_schema(); Node parse_value_schema();
Node parse_if_directive(Node surrounding_ruleset); Node parse_if_directive(Node surrounding_ruleset, Node::Type inside_of);
Node parse_for_directive(Node surrounding_ruleset); Node parse_for_directive(Node surrounding_ruleset, Node::Type inside_of);
Node parse_each_directive(Node surrounding_ruleset); Node parse_each_directive(Node surrounding_ruleset, Node::Type inside_of);
Node parse_while_directive(Node surrounding_ruleset); Node parse_while_directive(Node surrounding_ruleset, Node::Type inside_of);
Selector_Lookahead lookahead_for_selector(const char* start = 0); Selector_Lookahead lookahead_for_selector(const char* start = 0);
......
...@@ -27,6 +27,11 @@ namespace Sass { ...@@ -27,6 +27,11 @@ namespace Sass {
env[expr[0].token()] = expr; env[expr[0].token()] = expr;
return expr; return expr;
} break; } break;
case Node::function: {
f_env[pair<string, size_t>(expr[0].to_string(), expr[1].size())] = Function(expr);
return expr;
} break;
case Node::expansion: { case Node::expansion: {
Token name(expr[0].token()); Token name(expr[0].token());
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace Sass { namespace Sass {
using std::map; using std::map;
typedef Node (*Implementation)(const vector<Token>&, map<Token, Node>&, Node_Factory& new_Node); typedef Node (*Primitive)(const vector<Token>&, map<Token, Node>&, Node_Factory& new_Node);
typedef const char* str; typedef const char* str;
typedef str Function_Descriptor[]; typedef str Function_Descriptor[];
...@@ -16,15 +16,24 @@ namespace Sass { ...@@ -16,15 +16,24 @@ namespace Sass {
string name; string name;
vector<Token> parameters; vector<Token> parameters;
Implementation implementation; Node definition;
Primitive primitive;
Function() Function()
{ /* TO DO: set up the generic callback here */ } { /* TO DO: set up the generic callback here */ }
Function(Node def)
: name(def[0].to_string()),
parameters(vector<Token>()),
definition(def),
primitive(0)
{ }
Function(Function_Descriptor d, Implementation ip) Function(Function_Descriptor d, Primitive ip)
: name(d[0]), : name(d[0]),
parameters(vector<Token>()), parameters(vector<Token>()),
implementation(ip) definition(Node()),
primitive(ip)
{ {
size_t len = 0; size_t len = 0;
while (d[len+1]) ++len; while (d[len+1]) ++len;
...@@ -38,7 +47,10 @@ namespace Sass { ...@@ -38,7 +47,10 @@ namespace Sass {
} }
Node operator()(map<Token, Node>& bindings, Node_Factory& new_Node) const Node operator()(map<Token, Node>& bindings, Node_Factory& new_Node) const
{ return implementation(parameters, bindings, new_Node); } {
if (primitive) return primitive(parameters, bindings, new_Node);
else return Node();
}
}; };
......
...@@ -143,6 +143,7 @@ namespace Sass { ...@@ -143,6 +143,7 @@ namespace Sass {
css_import, css_import,
function_call, function_call,
mixin, mixin,
function,
parameters, parameters,
expansion, expansion,
arguments, arguments,
......
...@@ -107,6 +107,14 @@ namespace Sass { ...@@ -107,6 +107,14 @@ namespace Sass {
const char* mixin(const char* src) { const char* mixin(const char* src) {
return exactly<mixin_kwd>(src); return exactly<mixin_kwd>(src);
} }
extern const char function_kwd[] = "@function";
const char* function(const char* src) {
return exactly<function_kwd>(src);
}
extern const char return_kwd[] = "@return";
const char* ret(const char* src) {
return exactly<return_kwd>(src);
}
extern const char include_kwd[] = "@include"; extern const char include_kwd[] = "@include";
const char* include(const char* src) { const char* include(const char* src) {
return exactly<include_kwd>(src); return exactly<include_kwd>(src);
......
...@@ -309,6 +309,8 @@ namespace Sass { ...@@ -309,6 +309,8 @@ namespace Sass {
const char* at_keyword(const char* src); const char* at_keyword(const char* src);
const char* import(const char* src); const char* import(const char* src);
const char* mixin(const char* src); const char* mixin(const char* src);
const char* function(const char* src);
const char* ret(const char* src);
const char* include(const char* src); const char* include(const char* src);
const char* extend(const char* src); const char* extend(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