Commit de3aadc3 by Aaron Leung

Oy, converted all existing built-in functions to use the new-and-improved infrastructure.

parent 863cddce
#include "context.hpp"
#include <cstring>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include "prelexer.hpp"
#include "color_names.hpp"
......@@ -73,27 +74,20 @@ namespace Sass {
}
delete[] image_path;
new_Node.free();
// cerr << "Deallocated " << i << " source string(s)." << endl;
}
inline void Context::register_function(Function_Descriptor d, Primitive ip)
inline void Context::register_function(Signature sig, Primitive ip)
{
Function f(d, ip, new_Node);
// function_env[pair<string, size_t>(f.name, f.parameters.size())] = f;
Function f(const_cast<char*>(sig), ip, *this);
function_env[f.name] = f;
}
inline void Context::register_function(Function_Descriptor d, Primitive ip, size_t arity)
{
Function f(d, ip, new_Node);
// function_env[pair<string, size_t>(f.name, arity)] = f;
function_env[f.name] = f;
}
inline void Context::register_function_2(const char* sig, Primitive_2 ip)
inline void Context::register_function(Signature sig, Primitive ip, size_t arity)
{
Function f(const_cast<char*>(sig), ip, *this);
function_env[f.name] = f;
std::stringstream stub;
stub << f.name << " " << arity;
function_env[stub.str()] = f;
}
inline void Context::register_overload_stub(string name)
......@@ -105,69 +99,50 @@ namespace Sass {
{
using namespace Functions;
register_function_2(foo_sig, foo);
// RGB Functions
register_function(rgb_descriptor, rgb);
register_function(rgb_sig, rgb);
register_overload_stub("rgba");
register_function(rgba_4_descriptor, rgba_4);
register_function(rgba_2_descriptor, rgba_2);
register_function(red_descriptor, red);
register_function(green_descriptor, green);
register_function(blue_descriptor, blue);
register_overload_stub("mix");
register_function(mix_2_descriptor, mix_2);
register_function(mix_3_descriptor, mix_3);
register_function(rgba_4_sig, rgba_4, 4);
register_function(rgba_2_sig, rgba_2, 2);
register_function(red_sig, red);
register_function(green_sig, green);
register_function(blue_sig, blue);
register_function(mix_sig, mix);
// HSL Functions
register_function(hsla_descriptor, hsla);
register_function(hsl_descriptor, hsl);
register_function(adjust_hue_descriptor, adjust_hue);
register_function(invert_descriptor, invert);
register_function(hsla_sig, hsla);
register_function(hsl_sig, hsl);
register_function(adjust_hue_sig, adjust_hue);
register_function(invert_sig, invert);
// Opacity Functions
register_function(alpha_descriptor, alpha);
register_function(opacity_descriptor, alpha);
register_function(opacify_descriptor, opacify);
register_function(fade_in_descriptor, opacify);
register_function(transparentize_descriptor, transparentize);
register_function(fade_out_descriptor, transparentize);
register_function(alpha_sig, alpha);
register_function(opacity_sig, alpha);
register_function(opacify_sig, opacify);
register_function(fade_in_sig, opacify);
register_function(transparentize_sig, transparentize);
register_function(fade_out_sig, transparentize);
// String Functions
register_function(unquote_descriptor, unquote);
register_function(quote_descriptor, quote);
register_function(unquote_sig, unquote);
register_function(quote_sig, quote);
// Number Functions
register_function(percentage_descriptor, percentage);
register_function(round_descriptor, round);
register_function(ceil_descriptor, ceil);
register_function(floor_descriptor, floor);
register_function(abs_descriptor, abs);
register_function(percentage_sig, percentage);
register_function(round_sig, round);
register_function(ceil_sig, ceil);
register_function(floor_sig, floor);
register_function(abs_sig, abs);
// List Functions
register_function(length_descriptor, length);
register_function(nth_descriptor, nth);
register_overload_stub("join");
register_function(join_2_descriptor, join_2);
register_function(join_3_descriptor, join_3);
register_overload_stub("append");
register_function(append_2_descriptor, append_2);
register_function(append_3_descriptor, append_3);
register_overload_stub("compact");
register_function(compact_1_descriptor, compact);
register_function(compact_2_descriptor, compact);
register_function(compact_3_descriptor, compact);
register_function(compact_4_descriptor, compact);
register_function(compact_5_descriptor, compact);
register_function(compact_6_descriptor, compact);
register_function(compact_7_descriptor, compact);
register_function(compact_8_descriptor, compact);
register_function(compact_9_descriptor, compact);
register_function(compact_10_descriptor, compact);
register_function(compact_11_descriptor, compact);
register_function(compact_12_descriptor, compact);
register_function(length_sig, length);
register_function(nth_sig, nth);
register_function(join_sig, join);
register_function(append_sig, append);
register_function(compact_sig, compact);
// Introspection Functions
register_function(type_of_descriptor, type_of);
register_function(unit_descriptor, unit);
register_function(unitless_descriptor, unitless);
register_function(comparable_descriptor, comparable);
register_function(type_of_sig, type_of);
register_function(unit_sig, unit);
register_function(unitless_sig, unitless);
register_function(comparable_sig, comparable);
// Boolean Functions
register_function(not_descriptor, not_impl);
register_function(if_descriptor, if_impl);
register_function(not_sig, not_impl);
register_function(if_sig, if_impl);
}
void Context::setup_color_map()
......
......@@ -38,9 +38,8 @@ namespace Sass {
Context(const char* paths_str = 0, const char* img_path_str = 0);
~Context();
void register_function_2(const char* sig, Primitive_2 ip);
void register_function(Function_Descriptor d, Primitive ip);
void register_function(Function_Descriptor d, Primitive ip, size_t arity);
void register_function(Signature sig, Primitive ip);
void register_function(Signature sig, Primitive ip, size_t arity);
void register_overload_stub(string name);
void register_functions();
void setup_color_map();
......
......@@ -706,7 +706,7 @@ namespace Sass {
// primitive function implementation, then return its value.
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_2) {
if (f.primitive) {
// evaluate arguments in the current environment
for (size_t i = 0, S = args.size(); i < S; ++i) {
if (args[i].type() != Node::assignment) {
......@@ -720,25 +720,25 @@ namespace Sass {
Environment bindings;
bindings.link(env.global ? *env.global : env);
bind_arguments("function " + f.name, f.parameters, args, prefix, bindings, f_env, new_Node, ctx);
return f.primitive_2(f.parameter_names, bindings, new_Node);
}
else if (f.primitive) {
map<Token, Node> bindings;
// bind arguments
for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) {
if (args[i].type() == Node::assignment) {
Node arg(args[i]);
Token name(arg[0].token());
bindings[name] = eval(arg[1], prefix, env, f_env, new_Node, ctx);
}
else {
// TO DO: ensure (j < f.parameters.size())
bindings[f.parameters[j].token()] = eval(args[i], prefix, env, f_env, new_Node, ctx);
++j;
}
}
return f(bindings, new_Node);
return f.primitive(f.parameter_names, bindings, new_Node);
}
// else if (f.primitive) {
// map<Token, Node> bindings;
// // bind arguments
// for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) {
// if (args[i].type() == Node::assignment) {
// Node arg(args[i]);
// Token name(arg[0].token());
// bindings[name] = eval(arg[1], prefix, env, f_env, new_Node, ctx);
// }
// else {
// // TO DO: ensure (j < f.parameters.size())
// bindings[f.parameters[j].token()] = eval(args[i], prefix, env, f_env, new_Node, ctx);
// ++j;
// }
// }
// return f(bindings, new_Node);
// }
else {
Node params(f.definition[1]);
Node body(new_Node(f.definition[2]));
......
......@@ -17,8 +17,9 @@ using std::cerr; using std::endl;
namespace Sass {
// this constructor needs context.hpp, so it can't be defined in functions.hpp
Function::Function(char* signature, Primitive_2 ip, Context& ctx)
: primitive_2(ip),
Function::Function(char* signature, Primitive ip, Context& ctx)
: definition(Node()),
primitive(ip),
overloaded(false)
{
Document sig_doc(Document::make_from_source_chars(ctx, signature));
......@@ -33,7 +34,7 @@ namespace Sass {
}
else {
parameter_names << param[0];
// assuming default args for primitives can be evaluated only once at init
// assume it's safe to evaluate default args just once at initialization
param[1] = eval(param[1], Node(), ctx.global_env, ctx.function_env, ctx.new_Node, ctx);
}
}
......@@ -50,7 +51,7 @@ namespace Sass {
throw Error(Error::evaluation, path, line, message);
}
extern const char foo_sig[] = "foo($x, $y, $z: \"hey\")";
extern Signature foo_sig = "foo($x, $y, $z: \"hey\")";
Node foo(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node arg1(bindings[parameter_names[0].token()]);
Node arg2(bindings[parameter_names[1].token()]);
......@@ -63,107 +64,88 @@ namespace Sass {
// RGB Functions ///////////////////////////////////////////////////////
Function_Descriptor rgb_descriptor =
{ "rgb", "$red", "$green", "$blue", 0 };
Node rgb(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node r(bindings[parameters[0].token()]);
Node g(bindings[parameters[1].token()]);
Node b(bindings[parameters[2].token()]);
extern Signature rgb_sig = "rgb($red, $green, $blue)";
Node rgb(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node r(bindings[parameter_names[0].token()]);
Node g(bindings[parameter_names[1].token()]);
Node b(bindings[parameter_names[2].token()]);
if (!(r.type() == Node::number && g.type() == Node::number && b.type() == Node::number)) {
throw_eval_error("arguments for rgb must be numbers", r.path(), r.line());
}
return new_Node(r.path(), r.line(), r.numeric_value(), g.numeric_value(), b.numeric_value(), 1.0);
}
Function_Descriptor rgba_4_descriptor =
{ "rgba 4", "$red", "$green", "$blue", "$alpha", 0 };
Node rgba_4(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node r(bindings[parameters[0].token()]);
Node g(bindings[parameters[1].token()]);
Node b(bindings[parameters[2].token()]);
Node a(bindings[parameters[3].token()]);
// TODO: SOMETHING SPECIAL FOR OVERLOADED FUNCTIONS
extern Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
Node rgba_4(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node r(bindings[parameter_names[0].token()]);
Node g(bindings[parameter_names[1].token()]);
Node b(bindings[parameter_names[2].token()]);
Node a(bindings[parameter_names[3].token()]);
if (!(r.type() == Node::number && g.type() == Node::number && b.type() == Node::number && a.type() == Node::number)) {
throw_eval_error("arguments for rgba must be numbers", r.path(), r.line());
}
return new_Node(r.path(), r.line(), r.numeric_value(), g.numeric_value(), b.numeric_value(), a.numeric_value());
}
Function_Descriptor rgba_2_descriptor =
{ "rgba 2", "$color", "$alpha", 0 };
Node rgba_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
extern Signature rgba_2_sig = "rgba($color, $alpha)";
Node rgba_2(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
Node r(color[0]);
Node g(color[1]);
Node b(color[2]);
Node a(bindings[parameters[1].token()]);
Node a(bindings[parameter_names[1].token()]);
if (color.type() != Node::numeric_color || a.type() != Node::number) throw_eval_error("arguments to rgba must be a color and a number", color.path(), color.line());
return new_Node(color.path(), color.line(), r.numeric_value(), g.numeric_value(), b.numeric_value(), a.numeric_value());
}
Function_Descriptor red_descriptor =
{ "red", "$color", 0 };
Node red(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
extern Signature red_sig = "red($color)";
Node red(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
if (color.type() != Node::numeric_color) throw_eval_error("argument to red must be a color", color.path(), color.line());
return color[0];
}
Function_Descriptor green_descriptor =
{ "green", "$color", 0 };
Node green(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
extern Signature green_sig = "green($color)";
Node green(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
if (color.type() != Node::numeric_color) throw_eval_error("argument to green must be a color", color.path(), color.line());
return color[1];
}
Function_Descriptor blue_descriptor =
{ "blue", "$color", 0 };
Node blue(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
extern Signature blue_sig = "blue($color)";
Node blue(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
if (color.type() != Node::numeric_color) throw_eval_error("argument to blue must be a color", color.path(), color.line());
return color[2];
}
Node mix_impl(Node color1, Node color2, double weight, Node_Factory& new_Node) {
if (!(color1.type() == Node::numeric_color && color2.type() == Node::numeric_color)) {
throw_eval_error("first two arguments to mix must be colors", color1.path(), color1.line());
}
double p = weight/100;
extern Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)";
Node mix(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color1(bindings[parameter_names[0].token()]);
Node color2(bindings[parameter_names[1].token()]);
Node weight(bindings[parameter_names[2].token()]);
if (color1.type() != Node::numeric_color) throw_eval_error("first argument to mix must be a color", color1.path(), color1.line());
if (color2.type() != Node::numeric_color) throw_eval_error("second argument to mix must be a color", color2.path(), color2.line());
if (!weight.is_numeric()) throw_eval_error("third argument to mix must be numeric", weight.path(), weight.line());
double p = weight.numeric_value()/100;
double w = 2*p - 1;
double a = color1[3].numeric_value() - color2[3].numeric_value();
double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
double w2 = 1 - w1;
Node mixed(new_Node(Node::numeric_color, color1.path(), color1.line(), 4));
for (int i = 0; i < 3; ++i) {
mixed << new_Node(mixed.path(), mixed.line(),
w1*color1[i].numeric_value() + w2*color2[i].numeric_value());
mixed << new_Node(mixed.path(), mixed.line(), w1*color1[i].numeric_value() + w2*color2[i].numeric_value());
}
double alpha = color1[3].numeric_value()*p + color2[3].numeric_value()*(1-p);
mixed << new_Node(mixed.path(), mixed.line(), alpha);
return mixed;
}
Function_Descriptor mix_2_descriptor =
{ "mix 2", "$color1", "$color2", 0 };
Node mix_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
return mix_impl(bindings[parameters[0].token()], bindings[parameters[1].token()], 50, new_Node);
}
Function_Descriptor mix_3_descriptor =
{ "mix 3", "$color1", "$color2", "$weight", 0 };
Node mix_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node percentage(bindings[parameters[2].token()]);
if (!(percentage.type() == Node::number || percentage.type() == Node::numeric_percentage || percentage.type() == Node::numeric_dimension)) {
throw_eval_error("third argument to mix must be numeric", percentage.path(), percentage.line());
}
return mix_impl(bindings[parameters[0].token()],
bindings[parameters[1].token()],
percentage.numeric_value(),
new_Node);
}
// HSL Functions ///////////////////////////////////////////////////////
// Utility rgb to hsl function so we can do hsl operations
......@@ -200,14 +182,6 @@ namespace Sass {
return new_Node("", 0, static_cast<int>(h*360)%360, s*100, l*100);
}
// Function_Descriptor adjust_color_descriptor =
// { "adjust_color 1", "$color", 0 }
// Function_Descriptor adjust_color_2_descriptor =
// { "adjust_color 2", "$color", "2")
// Node adjust_color_impl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
// blah;
// }
double h_to_rgb(double m1, double m2, double h) {
if (h < 0) ++h;
if (h > 1) --h;
......@@ -233,45 +207,40 @@ namespace Sass {
return new_Node("", 0, r, g, b, a);
}
Function_Descriptor hsla_descriptor =
{ "hsla", "$hue", "$saturation", "$lightness", "$alpha", 0 };
Node hsla(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
if (!(bindings[parameters[0].token()].is_numeric() &&
bindings[parameters[1].token()].is_numeric() &&
bindings[parameters[2].token()].is_numeric() &&
bindings[parameters[3].token()].is_numeric())) {
throw_eval_error("arguments to hsla must be numeric", bindings[parameters[0].token()].path(), bindings[parameters[0].token()].line());
extern Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)";
Node hsla(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
if (!(bindings[parameter_names[0].token()].is_numeric() &&
bindings[parameter_names[1].token()].is_numeric() &&
bindings[parameter_names[2].token()].is_numeric() &&
bindings[parameter_names[3].token()].is_numeric())) {
throw_eval_error("arguments to hsla must be numeric", bindings[parameter_names[0].token()].path(), bindings[parameter_names[0].token()].line());
}
double h = bindings[parameters[0].token()].numeric_value();
double s = bindings[parameters[1].token()].numeric_value();
double l = bindings[parameters[2].token()].numeric_value();
double a = bindings[parameters[3].token()].numeric_value();
double h = bindings[parameter_names[0].token()].numeric_value();
double s = bindings[parameter_names[1].token()].numeric_value();
double l = bindings[parameter_names[2].token()].numeric_value();
double a = bindings[parameter_names[3].token()].numeric_value();
Node color(hsla_impl(h, s, l, a, new_Node));
// color.line() = bindings[parameters[0].token()].line();
return color;
}
Function_Descriptor hsl_descriptor =
{ "hsl", "$hue", "$saturation", "$lightness", 0 };
Node hsl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
if (!(bindings[parameters[0].token()].is_numeric() &&
bindings[parameters[1].token()].is_numeric() &&
bindings[parameters[2].token()].is_numeric())) {
throw_eval_error("arguments to hsl must be numeric", bindings[parameters[0].token()].path(), bindings[parameters[0].token()].line());
extern Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
Node hsl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
if (!(bindings[parameter_names[0].token()].is_numeric() &&
bindings[parameter_names[1].token()].is_numeric() &&
bindings[parameter_names[2].token()].is_numeric())) {
throw_eval_error("arguments to hsl must be numeric", bindings[parameter_names[0].token()].path(), bindings[parameter_names[0].token()].line());
}
double h = bindings[parameters[0].token()].numeric_value();
double s = bindings[parameters[1].token()].numeric_value();
double l = bindings[parameters[2].token()].numeric_value();
double h = bindings[parameter_names[0].token()].numeric_value();
double s = bindings[parameter_names[1].token()].numeric_value();
double l = bindings[parameter_names[2].token()].numeric_value();
Node color(hsla_impl(h, s, l, 1, new_Node));
// color.line() = bindings[parameters[0].token()].line();
return color;
}
Function_Descriptor adjust_hue_descriptor =
{ "adjust-hue", "$color", "$degrees", 0 };
Node adjust_hue(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node rgb_col(bindings[parameters[0].token()]);
Node degrees(bindings[parameters[1].token()]);
extern Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
Node adjust_hue(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node rgb_col(bindings[parameter_names[0].token()]);
Node degrees(bindings[parameter_names[1].token()]);
if (rgb_col.type() != Node::numeric_color) throw_eval_error("first argument to adjust-hue must be a color", rgb_col.path(), rgb_col.line());
if (!degrees.is_numeric()) throw_eval_error("second argument to adjust-hue must be numeric", degrees.path(), degrees.line());
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
......@@ -285,10 +254,9 @@ namespace Sass {
new_Node);
}
Function_Descriptor invert_descriptor =
{ "invert", "$color", 0 };
Node invert(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature invert_sig = "invert($color)";
Node invert(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
if (orig.type() != Node::numeric_color) throw_eval_error("argument to invert must be a color", orig.path(), orig.line());
return new_Node(orig.path(), orig.line(),
255 - orig[0].numeric_value(),
......@@ -299,23 +267,19 @@ namespace Sass {
// Opacity Functions ///////////////////////////////////////////////////
Function_Descriptor alpha_descriptor =
{ "alpha", "$color", 0 };
Function_Descriptor opacity_descriptor =
{ "opacity", "$color", 0 };
Node alpha(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
if (color.type() != Node::numeric_color) throw_eval_error("argument to alpha must be a color", color.path(), color.line());
extern Signature alpha_sig = "alpha($color)";
extern Signature opacity_sig = "opacity($color)";
Node alpha(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
if (color.type() != Node::numeric_color) throw_eval_error("argument to alpha/opacity must be a color", color.path(), color.line());
return color[3];
}
Function_Descriptor opacify_descriptor =
{ "opacify", "$color", "$amount", 0 };
Function_Descriptor fade_in_descriptor =
{ "fade_in", "$color", "$amount", 0 };
Node opacify(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
Node delta(bindings[parameters[1].token()]);
extern Signature opacify_sig = "opacify($color, $amount)";
extern Signature fade_in_sig = "fade-in($color, $amount)";
Node opacify(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
Node delta(bindings[parameter_names[1].token()]);
if (color.type() != Node::numeric_color || !delta.is_numeric()) {
throw_eval_error("arguments to opacify/fade_in must be a color and a numeric value", color.path(), color.line());
}
......@@ -329,13 +293,11 @@ namespace Sass {
color[0].numeric_value(), color[1].numeric_value(), color[2].numeric_value(), alpha);
}
Function_Descriptor transparentize_descriptor =
{ "transparentize", "$color", "$amount", 0 };
Function_Descriptor fade_out_descriptor =
{ "fade_out", "$color", "$amount", 0 };
Node transparentize(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node color(bindings[parameters[0].token()]);
Node delta(bindings[parameters[1].token()]);
extern Signature transparentize_sig = "transparentize($color, $amount)";
extern Signature fade_out_sig = "fade-out($color, $amount)";
Node transparentize(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node color(bindings[parameter_names[0].token()]);
Node delta(bindings[parameter_names[1].token()]);
if (color.type() != Node::numeric_color || !delta.is_numeric()) {
throw_eval_error("arguments to transparentize/fade_out must be a color and a numeric value", color.path(), color.line());
}
......@@ -351,10 +313,9 @@ namespace Sass {
// String Functions ////////////////////////////////////////////////////
Function_Descriptor unquote_descriptor =
{ "unquote", "$string", 0 };
Node unquote(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node cpy(new_Node(bindings[parameters[0].token()]));
extern Signature unquote_sig = "unquote($string)";
Node unquote(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node cpy(new_Node(bindings[parameter_names[0].token()]));
// if (cpy.type() != Node::string_constant /* && cpy.type() != Node::concatenation */) {
// throw_eval_error("argument to unquote must be a string", cpy.path(), cpy.line());
// }
......@@ -363,10 +324,9 @@ namespace Sass {
return cpy;
}
Function_Descriptor quote_descriptor =
{ "quote", "$string", 0 };
Node quote(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature quote_sig = "quote($string)";
Node quote(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
switch (orig.type())
{
default: {
......@@ -389,20 +349,18 @@ namespace Sass {
// Number Functions ////////////////////////////////////////////////////
Function_Descriptor percentage_descriptor =
{ "percentage", "$value", 0 };
Node percentage(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature percentage_sig = "percentage($value)";
Node percentage(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
if (orig.type() != Node::number) {
throw_eval_error("argument to percentage must be a unitless number", orig.path(), orig.line());
}
return new_Node(orig.path(), orig.line(), orig.numeric_value() * 100, Node::numeric_percentage);
}
Function_Descriptor round_descriptor =
{ "round", "$value", 0 };
Node round(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature round_sig = "round($value)";
Node round(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
switch (orig.type())
{
case Node::numeric_dimension: {
......@@ -429,10 +387,9 @@ namespace Sass {
return Node();
}
Function_Descriptor ceil_descriptor =
{ "ceil", "$value", 0 };
Node ceil(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature ceil_sig = "ceil($value)";
Node ceil(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
switch (orig.type())
{
case Node::numeric_dimension: {
......@@ -459,10 +416,9 @@ namespace Sass {
return Node();
}
Function_Descriptor floor_descriptor =
{ "floor", "$value", 0 };
Node floor(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature floor_sig = "floor($value)";
Node floor(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
switch (orig.type())
{
case Node::numeric_dimension: {
......@@ -489,10 +445,9 @@ namespace Sass {
return Node();
}
Function_Descriptor abs_descriptor =
{ "abs", "$value", 0 };
Node abs(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0].token()]);
extern Signature abs_sig = "abs($value)";
Node abs(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameter_names[0].token()]);
switch (orig.type())
{
case Node::numeric_dimension: {
......@@ -521,10 +476,9 @@ namespace Sass {
// List Functions //////////////////////////////////////////////////////
Function_Descriptor length_descriptor =
{ "length", "$list", 0 };
Node length(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node arg(bindings[parameters[0].token()]);
extern Signature length_sig = "length($list)";
Node length(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node arg(bindings[parameter_names[0].token()]);
switch (arg.type())
{
case Node::space_list:
......@@ -545,11 +499,10 @@ namespace Sass {
return Node();
}
Function_Descriptor nth_descriptor =
{ "nth", "$list", "$n", 0 };
Node nth(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node l(bindings[parameters[0].token()]);
Node n(bindings[parameters[1].token()]);
extern Signature nth_sig = "nth($list, $n)";
Node nth(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node l(bindings[parameter_names[0].token()]);
Node n(bindings[parameter_names[1].token()]);
if (n.type() != Node::number) {
throw_eval_error("second argument to nth must be a number", n.path(), n.line());
}
......@@ -566,15 +519,15 @@ namespace Sass {
}
return l[n_prim - 1];
}
extern const char separator_kwd[] = "$separator";
Node join_impl(const Node parameters, map<Token, Node>& bindings, bool has_sep, Node_Factory& new_Node) {
extern Signature join_sig = "join($list1, $list2, $separator: auto)";
Node join(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
// if the args aren't lists, turn them into singleton lists
Node l1(bindings[parameters[0].token()]);
Node l1(bindings[parameter_names[0].token()]);
if (l1.type() != Node::space_list && l1.type() != Node::comma_list && l1.type() != Node::nil) {
l1 = new_Node(Node::space_list, l1.path(), l1.line(), 1) << l1;
}
Node l2(bindings[parameters[1].token()]);
Node l2(bindings[parameter_names[1].token()]);
if (l2.type() != Node::space_list && l2.type() != Node::comma_list && l2.type() != Node::nil) {
l2 = new_Node(Node::space_list, l2.path(), l2.line(), 1) << l2;
}
......@@ -588,38 +541,25 @@ namespace Sass {
if (l2.type() != Node::nil) size += l2.size();
// figure out the result type in advance
Node::Type rtype = Node::space_list;
if (has_sep) {
string sep(bindings[parameters[2].token()].token().unquote());
if (sep == "comma") rtype = Node::comma_list;
else if (sep == "space") rtype = Node::space_list;
else if (sep == "auto") rtype = l1.type();
else {
throw_eval_error("third argument to join must be 'space', 'comma', or 'auto'", l2.path(), l2.line());
}
string sep(bindings[parameter_names[2].token()].token().unquote());
if (sep == "comma") rtype = Node::comma_list;
else if (sep == "space") rtype = Node::space_list;
else if (sep == "auto") rtype = l1.type();
else {
throw_eval_error("third argument to join must be 'space', 'comma', or 'auto'", l2.path(), l2.line());
}
else if (l1.type() != Node::nil) rtype = l1.type();
else if (l2.type() != Node::nil) rtype = l2.type();
if (rtype == Node::nil) rtype = l2.type();
// accumulate the result
Node lr(new_Node(rtype, l1.path(), l1.line(), size));
if (l1.type() != Node::nil) lr += l1;
if (l2.type() != Node::nil) lr += l2;
return lr;
}
Function_Descriptor join_2_descriptor =
{ "join 2", "$list1", "$list2", 0 };
Node join_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
return join_impl(parameters, bindings, false, new_Node);
}
Function_Descriptor join_3_descriptor =
{ "join 3", "$list1", "$list2", "$separator", 0 };
Node join_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
return join_impl(parameters, bindings, true, new_Node);
}
Node append_impl(const Node parameters, map<Token, Node>& bindings, bool has_sep, Node_Factory& new_Node) {
Node list(bindings[parameters[0].token()]);
extern Signature append_sig = "append($list1, $list2, $separator: auto)";
Node append(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node list(bindings[parameter_names[0].token()]);
switch (list.type())
{
case Node::space_list:
......@@ -632,37 +572,26 @@ namespace Sass {
list = (new_Node(Node::space_list, list.path(), list.line(), 1) << list);
} break;
}
Node::Type sep_type = list.type();
if (has_sep) {
string sep_string = bindings[parameters[2].token()].token().unquote();
if (sep_string == "comma") sep_type = Node::comma_list;
else if (sep_string == "space") sep_type = Node::space_list;
else if (sep_string == "auto") sep_type = list.type();
else throw_eval_error("third argument to append must be 'space', 'comma', or 'auto'", list.path(), list.line());
}
Node::Type sep_type;
string sep_string = bindings[parameter_names[2].token()].token().unquote();
if (sep_string == "comma") sep_type = Node::comma_list;
else if (sep_string == "space") sep_type = Node::space_list;
else if (sep_string == "auto") sep_type = list.type();
else throw_eval_error("third argument to append must be 'space', 'comma', or 'auto'", list.path(), list.line());
Node new_list(new_Node(sep_type, list.path(), list.line(), list.size() + 1));
new_list += list;
new_list << bindings[parameters[1].token()];
new_list << bindings[parameter_names[1].token()];
return new_list;
}
Function_Descriptor append_2_descriptor =
{ "append 2", "$list", "$val", 0 };
Node append_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
return append_impl(parameters, bindings, false, new_Node);
}
Function_Descriptor append_3_descriptor =
{ "append 3", "$list", "$val", "$separator", 0 };
Node append_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
return append_impl(parameters, bindings, true, new_Node);
}
Node compact(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
size_t num_args = bindings.size();
extern Signature compact_sig = "compact($arg1: false, $arg2: false, $arg3: false, $arg4: false, $arg5: false, $arg6: false, $arg7: false, $arg8: false, $arg9: false, $arg10: false, $arg11: false, $arg12: false)";
Node compact(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
size_t num_args = bindings.current_frame.size();
Node::Type sep_type = Node::comma_list;
Node list;
Node arg1(bindings[parameters[0].token()]);
Node arg1(bindings[parameter_names[0].token()]);
if (num_args == 1 && (arg1.type() == Node::space_list ||
arg1.type() == Node::comma_list ||
arg1.type() == Node::nil)) {
......@@ -672,7 +601,7 @@ namespace Sass {
else {
list = new_Node(sep_type, arg1.path(), arg1.line(), num_args);
for (size_t i = 0; i < num_args; ++i) {
list << bindings[parameters[i].token()];
list << bindings[parameter_names[i].token()];
}
}
Node new_list(new_Node(list.type(), list.path(), list.line(), 0));
......@@ -684,40 +613,6 @@ namespace Sass {
return new_list.size() ? new_list : new_Node(Node::nil, list.path(), list.line(), 0);
}
Function_Descriptor compact_1_descriptor =
{ "compact 1", "$arg1", 0 };
Function_Descriptor compact_2_descriptor =
{ "compact 2", "$arg1", "$arg2", 0 };
Function_Descriptor compact_3_descriptor =
{ "compact 3", "$arg1", "$arg2", "$arg3", 0 };
Function_Descriptor compact_4_descriptor =
{ "compact 4", "$arg1", "$arg2", "$arg3", "$arg4", 0 };
Function_Descriptor compact_5_descriptor =
{ "compact 5", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5", 0 };
Function_Descriptor compact_6_descriptor =
{ "compact 6", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5",
"$arg6", 0 };
Function_Descriptor compact_7_descriptor =
{ "compact 7", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5",
"$arg6", "$arg7", 0 };
Function_Descriptor compact_8_descriptor =
{ "compact 8", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5",
"$arg6", "$arg7", "$arg8", 0 };
Function_Descriptor compact_9_descriptor =
{ "compact 9", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5",
"$arg6", "$arg7", "$arg8", "$arg9", 0 };
Function_Descriptor compact_10_descriptor =
{ "compact 10", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5",
"$arg6", "$arg7", "$arg8", "$arg9", "$arg10", 0 };
Function_Descriptor compact_11_descriptor =
{ "compact 11", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5", "$arg6",
"$arg7", "$arg8", "$arg9", "$arg10", "$arg11", 0 };
Function_Descriptor compact_12_descriptor =
{ "compact 12", "$arg1", "$arg2", "$arg3", "$arg4", "$arg5", "arg6",
"$arg7", "$arg8", "$arg9", "$arg10", "$arg11", "$arg12", 0 };
// Introspection Functions /////////////////////////////////////////////
extern const char number_name[] = "number";
......@@ -726,10 +621,9 @@ namespace Sass {
extern const char color_name[] = "color";
extern const char list_name[] = "list";
Function_Descriptor type_of_descriptor =
{ "type-of", "$value", 0 };
Node type_of(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node val(bindings[parameters[0].token()]);
extern Signature type_of_sig = "type-of($value)";
Node type_of(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node val(bindings[parameter_names[0].token()]);
Token type_name;
switch (val.type())
{
......@@ -765,10 +659,9 @@ namespace Sass {
extern const char empty_str[] = "";
extern const char percent_str[] = "%";
Function_Descriptor unit_descriptor =
{ "unit", "$number", 0 };
Node unit(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node val(bindings[parameters[0].token()]);
extern Signature unit_sig = "unit($number)";
Node unit(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node val(bindings[parameter_names[0].token()]);
switch (val.type())
{
case Node::number: {
......@@ -791,10 +684,9 @@ namespace Sass {
extern const char true_str[] = "true";
extern const char false_str[] = "false";
Function_Descriptor unitless_descriptor =
{ "unitless", "$number", 0 };
Node unitless(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node val(bindings[parameters[0].token()]);
extern Signature unitless_sig = "unitless($number)";
Node unitless(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node val(bindings[parameter_names[0].token()]);
switch (val.type())
{
case Node::number: {
......@@ -814,11 +706,10 @@ namespace Sass {
return Node();
}
Function_Descriptor comparable_descriptor =
{ "comparable", "$number_1", "$number_2", 0 };
Node comparable(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node n1(bindings[parameters[0].token()]);
Node n2(bindings[parameters[1].token()]);
extern Signature comparable_sig = "comparable($number-1, $number-2)";
Node comparable(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node n1(bindings[parameter_names[0].token()]);
Node n2(bindings[parameter_names[1].token()]);
Node::Type t1 = n1.type();
Node::Type t2 = n2.type();
if ((t1 == Node::number && n2.is_numeric()) ||
......@@ -849,10 +740,9 @@ namespace Sass {
}
// Boolean Functions ///////////////////////////////////////////////////
Function_Descriptor not_descriptor =
{ "not", "$value", 0 };
Node not_impl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node val(bindings[parameters[0].token()]);
extern Signature not_sig = "not($value)";
Node not_impl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node val(bindings[parameter_names[0].token()]);
if (val.type() == Node::boolean && val.boolean_value() == false) {
return new_Node(Node::boolean, val.path(), val.line(), true);
}
......@@ -861,12 +751,11 @@ namespace Sass {
}
}
Function_Descriptor if_descriptor =
{ "if", "$predicate", "$consequent", "$alternative", 0 };
Node if_impl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node predicate(bindings[parameters[0].token()]);
Node consequent(bindings[parameters[1].token()]);
Node alternative(bindings[parameters[2].token()]);
extern Signature if_sig = "if($condition, $if-true, $if-false)";
Node if_impl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node) {
Node predicate(bindings[parameter_names[0].token()]);
Node consequent(bindings[parameter_names[1].token()]);
Node alternative(bindings[parameter_names[2].token()]);
if (predicate.type() == Node::boolean && predicate.boolean_value() == false) return alternative;
return consequent;
......
......@@ -13,10 +13,10 @@ namespace Sass {
using std::map;
typedef Node (*Primitive)(const Node, map<Token, Node>&, Node_Factory& new_Node);
typedef Node (*Primitive_2)(const Node, Environment&, Node_Factory&);
// typedef Node (*Primitive)(const Node, map<Token, Node>&, Node_Factory& new_Node);
typedef Node (*Primitive)(const Node, Environment&, Node_Factory&);
typedef const char* str;
typedef str Function_Descriptor[];
typedef const char Signature[];
struct Function {
......@@ -26,7 +26,7 @@ namespace Sass {
Node parameter_names;
Node definition;
Primitive primitive;
Primitive_2 primitive_2;
// Primitive_2 primitive_2;
bool overloaded;
Function()
......@@ -38,7 +38,6 @@ namespace Sass {
parameters(def[1]),
definition(def),
primitive(0),
primitive_2(0),
overloaded(false)
{ }
......@@ -48,30 +47,28 @@ namespace Sass {
parameters(Node()),
definition(Node()),
primitive(0),
primitive_2(0),
overloaded(overloaded)
{ }
Function(char* signature, Primitive_2 ip, Context& ctx);
Function(Function_Descriptor d, Primitive ip, Node_Factory& new_Node)
: name(d[0]),
parameters(new_Node(Node::parameters, "[PRIMITIVE FUNCTIONS]", 0, 0)),
definition(Node()),
primitive(ip),
primitive_2(0),
overloaded(false)
{
size_t len = 0;
while (d[len+1]) ++len;
Function(char* signature, Primitive ip, Context& ctx);
// Function(Function_Descriptor d, Primitive ip, Node_Factory& new_Node)
// : name(d[0]),
// parameters(new_Node(Node::parameters, "[PRIMITIVE FUNCTIONS]", 0, 0)),
// definition(Node()),
// primitive(ip),
// overloaded(false)
// {
// size_t len = 0;
// while (d[len+1]) ++len;
for (size_t i = 0; i < len; ++i) {
const char* p = d[i+1];
parameters.push_back(new_Node(Node::variable, "[PRIMITIVE FUNCTIONS]", 0, Token::make(p, p + std::strlen(p))));
}
}
// for (size_t i = 0; i < len; ++i) {
// const char* p = d[i+1];
// parameters.push_back(new_Node(Node::variable, "[PRIMITIVE FUNCTIONS]", 0, Token::make(p, p + std::strlen(p))));
// }
// }
Node operator()(map<Token, Node>& bindings, Node_Factory& new_Node) const
Node operator()(Environment& bindings, Node_Factory& new_Node) const
{
if (primitive) return primitive(parameters, bindings, new_Node);
else return Node();
......@@ -86,138 +83,118 @@ namespace Sass {
// RGB Functions ///////////////////////////////////////////////////////
extern Function_Descriptor rgb_descriptor;
Node rgb(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature rgb_sig;
Node rgb(const Node, Environment&, Node_Factory&);
extern Function_Descriptor rgba_4_descriptor;
Node rgba_4(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor rgba_2_descriptor;
Node rgba_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature rgba_4_sig;
Node rgba_4(const Node, Environment&, Node_Factory&);
extern Function_Descriptor red_descriptor;
Node red(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature rgba_2_sig;
Node rgba_2(const Node, Environment&, Node_Factory&);
extern Function_Descriptor green_descriptor;
Node green(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature red_sig;
Node red(const Node, Environment&, Node_Factory&);
extern Function_Descriptor blue_descriptor;
Node blue(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature green_sig;
Node green(const Node, Environment&, Node_Factory&);
extern Function_Descriptor mix_2_descriptor;
Node mix_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature blue_sig;
Node blue(const Node, Environment&, Node_Factory&);
extern Function_Descriptor mix_3_descriptor;
Node mix_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature mix_sig;
Node mix(const Node, Environment&, Node_Factory&);
// HSL Functions ///////////////////////////////////////////////////////
extern Function_Descriptor hsla_descriptor;
Node hsla(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature hsla_sig;
Node hsla(const Node, Environment&, Node_Factory&);
extern Function_Descriptor hsl_descriptor;
Node hsl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature hsl_sig;
Node hsl(const Node, Environment&, Node_Factory&);
extern Function_Descriptor adjust_hue_descriptor;
Node adjust_hue(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature adjust_hue_sig;
Node adjust_hue(const Node, Environment&, Node_Factory&);
extern Function_Descriptor invert_descriptor;
Node invert(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature invert_sig;
Node invert(const Node, Environment&, Node_Factory&);
// Opacity Functions ///////////////////////////////////////////////////
extern Function_Descriptor alpha_descriptor;
extern Function_Descriptor opacity_descriptor;
Node alpha(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature alpha_sig;
extern Signature opacity_sig;
Node alpha(const Node, Environment&, Node_Factory&);
extern Function_Descriptor opacify_descriptor;
extern Function_Descriptor fade_in_descriptor;
Node opacify(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature opacify_sig;
extern Signature fade_in_sig;
Node opacify(const Node, Environment&, Node_Factory&);
extern Function_Descriptor transparentize_descriptor;
extern Function_Descriptor fade_out_descriptor;
Node transparentize(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature transparentize_sig;
extern Signature fade_out_sig;
Node transparentize(const Node, Environment&, Node_Factory&);
// String Functions ////////////////////////////////////////////////////
extern Function_Descriptor unquote_descriptor;
Node unquote(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature unquote_sig;
Node unquote(const Node, Environment&, Node_Factory&);
extern Function_Descriptor quote_descriptor;
Node quote(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature quote_sig;
Node quote(const Node, Environment&, Node_Factory&);
// Number Functions ////////////////////////////////////////////////////
extern Function_Descriptor percentage_descriptor;
Node percentage(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature percentage_sig;
Node percentage(const Node, Environment&, Node_Factory&);
extern Function_Descriptor round_descriptor;
Node round(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature round_sig;
Node round(const Node, Environment&, Node_Factory&);
extern Function_Descriptor ceil_descriptor;
Node ceil(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature ceil_sig;
Node ceil(const Node, Environment&, Node_Factory&);
extern Function_Descriptor floor_descriptor;
Node floor(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature floor_sig;
Node floor(const Node, Environment&, Node_Factory&);
extern Function_Descriptor abs_descriptor;
Node abs(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature abs_sig;
Node abs(const Node, Environment&, Node_Factory&);
// List Functions //////////////////////////////////////////////////////
extern Function_Descriptor length_descriptor;
Node length(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature length_sig;
Node length(const Node, Environment&, Node_Factory&);
extern Function_Descriptor nth_descriptor;
Node nth(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor join_2_descriptor;
Node join_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor join_3_descriptor;
Node join_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature nth_sig;
Node nth(const Node, Environment&, Node_Factory&);
extern Function_Descriptor append_2_descriptor;
Node append_2(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature join_sig;
Node join(const Node, Environment&, Node_Factory&);
extern Function_Descriptor append_3_descriptor;
Node append_3(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature append_sig;
Node append(const Node, Environment&, Node_Factory&);
extern Function_Descriptor compact_1_descriptor;
extern Function_Descriptor compact_2_descriptor;
extern Function_Descriptor compact_3_descriptor;
extern Function_Descriptor compact_4_descriptor;
extern Function_Descriptor compact_5_descriptor;
extern Function_Descriptor compact_6_descriptor;
extern Function_Descriptor compact_7_descriptor;
extern Function_Descriptor compact_8_descriptor;
extern Function_Descriptor compact_9_descriptor;
extern Function_Descriptor compact_10_descriptor;
extern Function_Descriptor compact_11_descriptor;
extern Function_Descriptor compact_12_descriptor;
Node compact(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature compact_sig;
Node compact(const Node, Environment&, Node_Factory&);
// Introspection Functions /////////////////////////////////////////////
extern Function_Descriptor type_of_descriptor;
Node type_of(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature type_of_sig;
Node type_of(const Node, Environment&, Node_Factory&);
extern Function_Descriptor unit_descriptor;
Node unit(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature unit_sig;
Node unit(const Node, Environment&, Node_Factory&);
extern Function_Descriptor unitless_descriptor;
Node unitless(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature unitless_sig;
Node unitless(const Node, Environment&, Node_Factory&);
extern Function_Descriptor comparable_descriptor;
Node comparable(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature comparable_sig;
Node comparable(const Node, Environment&, Node_Factory&);
// Boolean Functions ///////////////////////////////////////////////////
extern Function_Descriptor not_descriptor;
Node not_impl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature not_sig;
Node not_impl(const Node, Environment&, Node_Factory&);
extern Function_Descriptor if_descriptor;
Node if_impl(const Node parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Signature if_sig;
Node if_impl(const Node, Environment&, 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