Commit 6538833f by Aaron Leung

Allowing builtin functions to be overloaded based on number of parameters. Don't…

Allowing builtin functions to be overloaded based on number of parameters. Don't know if it's worth it because only one function appears to need this.
parent 38b47f2f
......@@ -3,10 +3,11 @@
using std::cerr; using std::endl;
namespace Sass {
using std::pair;
Context::Context()
: global_env(Environment()),
function_env(map<string, Function>()),
function_env(map<pair<string, size_t>, Function>()),
source_refs(vector<char*>()),
ref_count(0)
{
......@@ -21,13 +22,17 @@ namespace Sass {
}
inline void Context::register_function(Function_Descriptor d, Implementation ip)
{ function_env[d[0]] = Function(d, ip); }
{
Function f(d, ip);
function_env[pair<string, size_t>(f.name, f.parameters.size())] = f;
}
void Context::register_functions()
{
using namespace Functions;
register_function(rgb_descriptor, rgb);
register_function(rgba_descriptor, rgba);
register_function(rgba_4_descriptor, rgba_4);
register_function(rgba_2_descriptor, rgba_2);
register_function(curse_descriptor, curse);
}
......
#define SASS_CONTEXT_INCLUDED
#include <utility>
#include <map>
#include "functions.hpp"
namespace Sass {
using std::pair;
using std::map;
struct Environment {
......@@ -38,7 +40,7 @@ namespace Sass {
struct Context {
Environment global_env;
map<string, Function> function_env;
map<pair<string, size_t>, Function> function_env;
vector<char*> source_refs;
size_t ref_count;
......
......@@ -5,7 +5,7 @@
namespace Sass {
using std::cerr; using std::endl;
Node eval(Node& expr, Environment& env, map<string, Function>& f_env)
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env)
{
switch (expr.type)
{
......@@ -148,7 +148,8 @@ namespace Sass {
case Node::function_call: {
// TO DO: default-constructed Function should be a generic callback
return apply_function(f_env[expr[0].content.token.to_string()], expr[1], env, f_env);
pair<string, size_t> sig(expr[0].content.token.to_string(), expr[1].size());
return apply_function(f_env[sig], expr[1], env, f_env);
} break;
default: {
......@@ -247,7 +248,7 @@ namespace Sass {
}
}
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<string, Function>& f_env)
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env)
{
Node params(mixin[1]);
Node body(mixin[2].clone());
......@@ -287,7 +288,7 @@ namespace Sass {
return body;
}
Node apply_function(const Function& f, const Node& args, Environment& env, map<string, Function>& f_env)
Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env)
{
map<Token, Node> bindings;
// bind arguments
......
......@@ -11,10 +11,10 @@
namespace Sass {
using std::map;
Node eval(Node& expr, Environment& env, map<string, Function>& f_env);
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node accumulate(Node::Type op, Node& acc, Node& rhs);
double operate(Node::Type op, double lhs, double rhs);
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<string, Function>& f_env);
Node apply_function(const Function& f, const Node& args, Environment& env, map<string, Function>& f_env);
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env);
}
\ No newline at end of file
......@@ -18,9 +18,9 @@ namespace Sass {
return color;
}
Function_Descriptor rgba_descriptor =
Function_Descriptor rgba_4_descriptor =
{ "rgba", "$red", "$green", "$blue", "$alpha", 0 };
Node rgba(const vector<Token>& parameters, map<Token, Node>& bindings) {
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings) {
Node color(Node::numeric_color, 0, 4);
color << bindings[parameters[0]]
<< bindings[parameters[1]]
......@@ -29,6 +29,12 @@ namespace Sass {
return color;
}
Function_Descriptor rgba_2_descriptor =
{ "rgba", "$color", "$alpha", 0 };
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings) {
return bindings[parameters[0]] << bindings[parameters[1]];
}
extern const char* the_curse = "Damn!";
Function_Descriptor curse_descriptor = { "curse", 0 };
Node curse(const vector<Token>& parameters, map<Token, Node>& bindings) {
......
......@@ -46,8 +46,11 @@ namespace Sass {
extern Function_Descriptor rgb_descriptor;
Node rgb(const vector<Token>& parameters, map<Token, Node>& bindings);
extern Function_Descriptor rgba_descriptor;
Node rgba(const vector<Token>& parameters, map<Token, Node>& bindings);
extern Function_Descriptor rgba_4_descriptor;
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings);
extern Function_Descriptor rgba_2_descriptor;
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings);
extern Function_Descriptor curse_descriptor;
Node curse(const vector<Token>& parameters, map<Token, Node>& bindings);
......
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