Commit 6823077e by Aaron Leung

More work on function call resolution.

parent a4fcf741
...@@ -42,7 +42,7 @@ namespace Sass { ...@@ -42,7 +42,7 @@ namespace Sass {
Context::Context(const char* paths_str) Context::Context(const char* paths_str)
: global_env(Environment()), : global_env(Environment()),
function_env(map<pair<string, size_t>, Function>()), function_env(map<string, Function>()),
extensions(multimap<Node, Node>()), extensions(multimap<Node, Node>()),
pending_extensions(vector<pair<Node, Node> >()), pending_extensions(vector<pair<Node, Node> >()),
source_refs(vector<char*>()), source_refs(vector<char*>()),
...@@ -67,14 +67,16 @@ namespace Sass { ...@@ -67,14 +67,16 @@ namespace Sass {
inline void Context::register_function(Function_Descriptor d, Primitive ip) inline void Context::register_function(Function_Descriptor d, Primitive ip)
{ {
Function f(d, ip); Function f(d, ip, new_Node);
function_env[pair<string, size_t>(f.name, f.parameters.size())] = f; // function_env[pair<string, size_t>(f.name, f.parameters.size())] = f;
function_env[f.name] = f;
} }
inline void Context::register_function(Function_Descriptor d, Primitive 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, new_Node);
function_env[pair<string, size_t>(f.name, arity)] = f; // function_env[pair<string, size_t>(f.name, arity)] = f;
function_env[f.name] = f;
} }
void Context::register_functions() void Context::register_functions()
......
...@@ -42,7 +42,7 @@ namespace Sass { ...@@ -42,7 +42,7 @@ namespace Sass {
struct Context { struct Context {
Environment global_env; Environment global_env;
map<pair<string, size_t>, Function> function_env; map<string, Function> function_env;
multimap<Node, Node> extensions; multimap<Node, Node> extensions;
vector<pair<Node, Node> > pending_extensions; vector<pair<Node, Node> > pending_extensions;
vector<char*> source_refs; // all the source c-strings vector<char*> source_refs; // all the source c-strings
......
...@@ -19,7 +19,7 @@ namespace Sass { ...@@ -19,7 +19,7 @@ namespace Sass {
// Evaluate the parse tree in-place (mostly). Most nodes will be left alone. // Evaluate the parse tree in-place (mostly). Most nodes will be left alone.
Node eval(Node expr, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx) Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{ {
switch (expr.type()) switch (expr.type())
{ {
...@@ -29,7 +29,7 @@ namespace Sass { ...@@ -29,7 +29,7 @@ namespace Sass {
} break; } break;
case Node::function: { case Node::function: {
f_env[pair<string, size_t>(expr[0].to_string(), expr[1].size())] = Function(expr); f_env[expr[0].to_string()] = Function(expr);
return expr; return expr;
} break; } break;
...@@ -292,8 +292,8 @@ namespace Sass { ...@@ -292,8 +292,8 @@ namespace Sass {
// TO DO: default-constructed Function should be a generic callback (maybe) // TO DO: default-constructed Function should be a generic callback (maybe)
// eval the function name in case it's interpolated // eval the function name in case it's interpolated
expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx); expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
pair<string, size_t> sig(expr[0].to_string(), expr[1].size()); string name(expr[0].to_string());
if (!f_env.count(sig)) { if (!f_env.count(name)) {
Node args(expr[1]); Node args(expr[1]);
for (size_t i = 0, S = args.size(); i < S; ++i) { for (size_t i = 0, S = args.size(); i < S; ++i) {
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx); args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
...@@ -301,7 +301,7 @@ namespace Sass { ...@@ -301,7 +301,7 @@ namespace Sass {
return expr; return expr;
} }
else { else {
return apply_function(f_env[sig], expr[1], prefix, env, f_env, new_Node, ctx); return apply_function(f_env[name], expr[1], prefix, env, f_env, new_Node, ctx);
} }
} break; } break;
...@@ -582,7 +582,7 @@ namespace Sass { ...@@ -582,7 +582,7 @@ namespace Sass {
// environment to the current one, then copy the body and eval in the new // environment to the current one, then copy the body and eval in the new
// environment. // environment.
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope) Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope)
{ {
Node params(mixin[1]); Node params(mixin[1]);
Node body(new_Node(mixin[2])); // clone the body Node body(new_Node(mixin[2])); // clone the body
...@@ -650,7 +650,7 @@ namespace Sass { ...@@ -650,7 +650,7 @@ namespace Sass {
// Apply a function -- bind the arguments and pass them to the underlying // Apply a function -- bind the arguments and pass them to the underlying
// primitive function implementation, then return its value. // primitive function implementation, then return its value.
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx) Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{ {
if (f.primitive) { if (f.primitive) {
map<Token, Node> bindings; map<Token, Node> bindings;
...@@ -663,7 +663,7 @@ namespace Sass { ...@@ -663,7 +663,7 @@ namespace Sass {
} }
else { else {
// TO DO: ensure (j < f.parameters.size()) // TO DO: ensure (j < f.parameters.size())
bindings[f.parameters[j]] = eval(args[i], prefix, env, f_env, new_Node, ctx); bindings[f.parameters[j].token()] = eval(args[i], prefix, env, f_env, new_Node, ctx);
++j; ++j;
} }
} }
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
namespace Sass { namespace Sass {
using std::map; using std::map;
Node eval(Node expr, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx); Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx);
Node function_eval(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, bool toplevel = false); Node function_eval(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, bool toplevel = false);
Node accumulate(Node::Type op, Node acc, Node rhs, Node_Factory& new_Node); Node accumulate(Node::Type op, Node acc, Node rhs, Node_Factory& new_Node);
double operate(Node::Type op, double lhs, double rhs); double operate(Node::Type op, double lhs, double rhs);
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope = false); Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope = false);
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx); Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node); Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
Node expand_backref(Node sel, Node pre); Node expand_backref(Node sel, Node pre);
void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&); void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&);
......
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