Commit c28965db by Aaron Leung

Merge branch 'func_resolver'

parents d6ae70ed 74e8c9f1
#include "context.hpp" #include "context.hpp"
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <sstream>
#include <unistd.h> #include <unistd.h>
#include "prelexer.hpp" #include "prelexer.hpp"
#include "color_names.hpp" #include "color_names.hpp"
...@@ -73,21 +74,20 @@ namespace Sass { ...@@ -73,21 +74,20 @@ namespace Sass {
} }
delete[] image_path; delete[] image_path;
new_Node.free(); 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 f(const_cast<char*>(sig), ip, *this);
// function_env[pair<string, size_t>(f.name, f.parameters.size())] = f;
function_env[f.name] = f; function_env[f.name] = f;
} }
inline void Context::register_function(Function_Descriptor d, Primitive ip, size_t arity) inline void Context::register_function(Signature sig, Primitive ip, size_t arity)
{ {
Function f(d, ip, new_Node); Function f(const_cast<char*>(sig), ip, *this);
// function_env[pair<string, size_t>(f.name, arity)] = f; std::stringstream stub;
function_env[f.name] = f; stub << f.name << " " << arity;
function_env[stub.str()] = f;
} }
inline void Context::register_overload_stub(string name) inline void Context::register_overload_stub(string name)
...@@ -98,68 +98,53 @@ namespace Sass { ...@@ -98,68 +98,53 @@ namespace Sass {
void Context::register_functions() void Context::register_functions()
{ {
using namespace Functions; using namespace Functions;
// RGB Functions // RGB Functions
register_function(rgb_descriptor, rgb); register_function(rgb_sig, rgb);
register_overload_stub("rgba"); register_overload_stub("rgba");
register_function(rgba_4_descriptor, rgba_4); register_function(rgba_4_sig, rgba_4, 4);
register_function(rgba_2_descriptor, rgba_2); register_function(rgba_2_sig, rgba_2, 2);
register_function(red_descriptor, red); register_function(red_sig, red);
register_function(green_descriptor, green); register_function(green_sig, green);
register_function(blue_descriptor, blue); register_function(blue_sig, blue);
register_overload_stub("mix"); register_function(mix_sig, mix);
register_function(mix_2_descriptor, mix_2);
register_function(mix_3_descriptor, mix_3);
// HSL Functions // HSL Functions
register_function(hsla_descriptor, hsla); register_function(hsla_sig, hsla);
register_function(hsl_descriptor, hsl); register_function(hsl_sig, hsl);
register_function(adjust_hue_descriptor, adjust_hue); register_function(adjust_hue_sig, adjust_hue);
register_function(invert_descriptor, invert); register_function(adjust_color_sig, adjust_color);
register_function(change_color_sig, change_color);
register_function(invert_sig, invert);
// Opacity Functions // Opacity Functions
register_function(alpha_descriptor, alpha); register_function(alpha_sig, alpha);
register_function(opacity_descriptor, alpha); register_function(opacity_sig, alpha);
register_function(opacify_descriptor, opacify); register_function(opacify_sig, opacify);
register_function(fade_in_descriptor, opacify); register_function(fade_in_sig, opacify);
register_function(transparentize_descriptor, transparentize); register_function(transparentize_sig, transparentize);
register_function(fade_out_descriptor, transparentize); register_function(fade_out_sig, transparentize);
// String Functions // String Functions
register_function(unquote_descriptor, unquote); register_function(unquote_sig, unquote);
register_function(quote_descriptor, quote); register_function(quote_sig, quote);
// Number Functions // Number Functions
register_function(percentage_descriptor, percentage); register_function(percentage_sig, percentage);
register_function(round_descriptor, round); register_function(round_sig, round);
register_function(ceil_descriptor, ceil); register_function(ceil_sig, ceil);
register_function(floor_descriptor, floor); register_function(floor_sig, floor);
register_function(abs_descriptor, abs); register_function(abs_sig, abs);
// List Functions // List Functions
register_function(length_descriptor, length); register_function(length_sig, length);
register_function(nth_descriptor, nth); register_function(nth_sig, nth);
register_overload_stub("join"); register_function(join_sig, join);
register_function(join_2_descriptor, join_2); register_function(append_sig, append);
register_function(join_3_descriptor, join_3); register_function(compact_sig, compact);
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);
// Introspection Functions // Introspection Functions
register_function(type_of_descriptor, type_of); register_function(type_of_sig, type_of);
register_function(unit_descriptor, unit); register_function(unit_sig, unit);
register_function(unitless_descriptor, unitless); register_function(unitless_sig, unitless);
register_function(comparable_descriptor, comparable); register_function(comparable_sig, comparable);
// Boolean Functions // Boolean Functions
register_function(not_descriptor, not_impl); register_function(not_sig, not_impl);
register_function(if_descriptor, if_impl); register_function(if_sig, if_impl);
} }
void Context::setup_color_map() void Context::setup_color_map()
......
#define SASS_CONTEXT #define SASS_CONTEXT
#ifndef SASS_ENVIRONMENT //#ifndef SASS_ENVIRONMENT
#include "environment.hpp" #include "environment.hpp"
#endif //#endif
#include <utility> #include <utility>
#ifndef SASS_NODE_FACTORY
#include "node_factory.hpp" #include "node_factory.hpp"
#endif
#ifndef SASS_FUNCTIONS
#include "functions.hpp" #include "functions.hpp"
#endif
namespace Sass { namespace Sass {
using std::pair; using std::pair;
using std::map; using std::map;
// struct Environment {
// map<Token, Node> current_frame;
// Environment* parent;
// Environment* global;
// Environment()
// : current_frame(map<Token, Node>()), parent(0), global(0)
// { }
// void link(Environment& env)
// {
// parent = &env;
// global = parent->global ? parent->global : parent;
// }
// bool query(const Token& key) const
// {
// if (current_frame.count(key)) return true;
// else if (parent) return parent->query(key);
// else return false;
// }
// Node& operator[](const Token& key)
// {
// if (current_frame.count(key)) return current_frame[key];
// else if (parent) return (*parent)[key];
// else return current_frame[key];
// }
// };
struct Context { struct Context {
Environment global_env; Environment global_env;
map<string, Function> function_env; map<string, Function> function_env;
...@@ -61,9 +37,9 @@ namespace Sass { ...@@ -61,9 +37,9 @@ namespace Sass {
void collect_include_paths(const char* paths_str); void collect_include_paths(const char* paths_str);
Context(const char* paths_str = 0, const char* img_path_str = 0); Context(const char* paths_str = 0, const char* img_path_str = 0);
~Context(); ~Context();
void register_function(Function_Descriptor d, Primitive ip); void register_function(Signature sig, Primitive ip);
void register_function(Function_Descriptor d, Primitive ip, size_t arity); void register_function(Signature sig, Primitive ip, size_t arity);
void register_overload_stub(string name); void register_overload_stub(string name);
void register_functions(); void register_functions();
void setup_color_map(); void setup_color_map();
......
#define SASS_DOCUMENT
#include <map> #include <map>
#ifndef SASS_PRELEXER #ifndef SASS_PRELEXER
......
#define SASS_ERROR
namespace Sass { namespace Sass {
struct Error { struct Error {
......
...@@ -707,21 +707,20 @@ namespace Sass { ...@@ -707,21 +707,20 @@ namespace Sass {
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 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; // evaluate arguments in the current environment
// bind arguments for (size_t i = 0, S = args.size(); i < S; ++i) {
for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) { if (args[i].type() != Node::assignment) {
if (args[i].type() == Node::assignment) { args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
Node arg(args[i]);
Token name(arg[0].token());
bindings[name] = eval(arg[1], prefix, env, f_env, new_Node, ctx);
} }
else { else {
// TO DO: ensure (j < f.parameters.size()) args[i][1] = eval(args[i][1], prefix, env, f_env, new_Node, ctx);
bindings[f.parameters[j].token()] = eval(args[i], prefix, env, f_env, new_Node, ctx);
++j;
} }
} }
return f(bindings, new_Node); // bind arguments
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(f.parameter_names, bindings, new_Node);
} }
else { else {
Node params(f.definition[1]); Node params(f.definition[1]);
......
#define SASS_EVAL_APPLY
#include <map> #include <map>
#ifndef SASS_NODE #ifndef SASS_NODE
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Sass { namespace Sass {
using namespace std; using namespace std;
// Token type for representing lexed chunks of text
struct Token { struct Token {
const char* begin; const char* begin;
const char* end; const char* end;
...@@ -61,6 +62,7 @@ namespace Sass { ...@@ -61,6 +62,7 @@ namespace Sass {
struct Node_Impl; struct Node_Impl;
// Node type for representing SCSS expression nodes. Really just a handle.
class Node { class Node {
private: private:
friend class Node_Factory; friend class Node_Factory;
...@@ -189,6 +191,7 @@ namespace Sass { ...@@ -189,6 +191,7 @@ namespace Sass {
bool is_numeric() const; bool is_numeric() const;
bool is_guarded() const; bool is_guarded() const;
bool& has_been_extended() const; bool& has_been_extended() const;
bool is_false() const;
string& path() const; string& path() const;
size_t line() const; size_t line() const;
...@@ -237,6 +240,7 @@ namespace Sass { ...@@ -237,6 +240,7 @@ namespace Sass {
}; };
// The actual implementation object for Nodes; Node handles point at these.
struct Node_Impl { struct Node_Impl {
union value_t { union value_t {
bool boolean; bool boolean;
...@@ -399,6 +403,7 @@ namespace Sass { ...@@ -399,6 +403,7 @@ namespace Sass {
inline bool Node::is_numeric() const { return ip_->is_numeric(); } inline bool Node::is_numeric() const { return ip_->is_numeric(); }
inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); } inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); }
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; } inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
inline bool Node::is_false() const { return (type() == boolean) && (boolean_value() == false); }
inline string& Node::path() const { return ip_->path; } inline string& Node::path() const { return ip_->path; }
inline size_t Node::line() const { return ip_->line; } inline size_t Node::line() const { return ip_->line; }
......
#define SASS_NODE_FACTORY
#include <vector> #include <vector>
#ifndef SASS_NODE #ifndef SASS_NODE
......
#define SASS_INTERFACE
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
......
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