Commit 9180b5c4 by Dean Mao

add callback support and add newlines at end of files

parent c4ce49a4
...@@ -6,13 +6,12 @@ Node bindings to libsass ...@@ -6,13 +6,12 @@ Node bindings to libsass
## Install ## Install
cd libsass && make && cd .. npm install
node-waf configure && node-waf build
## Usage ## Usage
var sass = require('./sass'); var sass = require('./sass');
sass.render('body{background:blue; a{color:black;}}', function(css){ sass.render('body{background:blue; a{color:black;}}', function(err, css){
console.log(css) console.log(css)
}); });
...@@ -40,4 +39,4 @@ Heavily inspired by <https://github.com/LearnBoost/stylus> ...@@ -40,4 +39,4 @@ Heavily inspired by <https://github.com/LearnBoost/stylus>
* publish npm * publish npm
* use node-gyp for builds * use node-gyp for builds
* file context * file context
* folder context * folder context
\ No newline at end of file
#include <v8.h> #include <v8.h>
#include <node.h> #include <node.h>
#include <string>
#include <cstdlib>
#include "libsass/sass_interface.h" #include "libsass/sass_interface.h"
using namespace v8; using namespace v8;
void WorkOnContext(uv_work_t* req) {
sass_context* ctx = static_cast<sass_context*>(req->data);
sass_compile(ctx);
}
void MakeCallback(uv_work_t* req) {
HandleScope scope;
TryCatch try_catch;
sass_context* ctx = static_cast<sass_context*>(req->data);
if (ctx->error_status == 0) {
// if no error, do callback(null, result)
const unsigned argc = 2;
Local<Value> argv[argc] = {
Local<Value>::New(Null()),
Local<Value>::New(String::New(ctx->output_string))
};
ctx->callback->Call(Context::GetCurrent()->Global(), argc, argv);
} else {
// if error, do callback(error)
const unsigned argc = 1;
Local<Value> argv[argc] = {
Local<Value>::New(String::New(ctx->error_message))
};
ctx->callback->Call(Context::GetCurrent()->Global(), argc, argv);
}
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
}
Handle<Value> Render(const Arguments& args) { Handle<Value> Render(const Arguments& args) {
HandleScope scope; HandleScope scope;
struct sass_context* ctx = sass_new_context(); sass_context* ctx = sass_new_context();
String::AsciiValue astr(args[0]); String::AsciiValue astr(args[0]);
char * cs = *astr; Local<Function> callback = Local<Function>::Cast(args[1]);
ctx->source_string = cs; ctx->source_string = new char[strlen(*astr)+1];
strcpy(ctx->source_string, *astr);
ctx->options.include_paths = 0; ctx->options.include_paths = 0;
ctx->options.output_style = SASS_STYLE_NESTED; ctx->options.output_style = SASS_STYLE_NESTED;
ctx->callback = Persistent<Function>::New(callback);
ctx->request.data = ctx;
sass_compile(ctx); int status = uv_queue_work(uv_default_loop(), &ctx->request, WorkOnContext, MakeCallback);
assert(status == 0);
return scope.Close(String::New(ctx->output_string)); return Undefined();
} }
void RegisterModule(v8::Handle<v8::Object> target) { void RegisterModule(v8::Handle<v8::Object> target) {
......
...@@ -20,13 +20,13 @@ var imports = {}; ...@@ -20,13 +20,13 @@ var imports = {};
* when undefined defaults to `src`. * when undefined defaults to `src`.
* *
* Examples: * Examples:
* *
* Pass the middleware to Connect, grabbing .scss files from this directory * Pass the middleware to Connect, grabbing .scss files from this directory
* and saving .css files to _./public_. * and saving .css files to _./public_.
* *
* Following that we have a `staticProvider` layer setup to serve the .css * Following that we have a `staticProvider` layer setup to serve the .css
* files generated by Sass. * files generated by Sass.
* *
* var server = connect.createServer( * var server = connect.createServer(
* sass.middleware({ * sass.middleware({
* src: __dirname * src: __dirname
...@@ -34,7 +34,7 @@ var imports = {}; ...@@ -34,7 +34,7 @@ var imports = {};
* }) * })
* , connect.static(__dirname + '/public') * , connect.static(__dirname + '/public')
* ); * );
* *
* @param {Object} options * @param {Object} options
* @return {Function} * @return {Function}
* @api public * @api public
...@@ -99,8 +99,8 @@ module.exports = function(options){ ...@@ -99,8 +99,8 @@ module.exports = function(options){
var style = options.compile(); var style = options.compile();
var paths = []; var paths = [];
delete imports[sassPath]; delete imports[sassPath];
style.render(str, function(css){ style.render(str, function(err, css){
// if (err) return next(err); if (err) return next(err);
if (debug) log('render', sassPath); if (debug) log('render', sassPath);
imports[sassPath] = paths; imports[sassPath] = paths;
mkdirp(dirname(cssPath), 0700, function(err){ mkdirp(dirname(cssPath), 0700, function(err){
...@@ -187,4 +187,4 @@ function checkImports(path, fn) { ...@@ -187,4 +187,4 @@ function checkImports(path, fn) {
function log(key, val) { function log(key, val) {
console.error(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val); console.error(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val);
} }
\ No newline at end of file
...@@ -6,7 +6,7 @@ using std::cerr; using std::endl; ...@@ -6,7 +6,7 @@ using std::cerr; using std::endl;
namespace Sass { namespace Sass {
using std::pair; using std::pair;
void Context::collect_include_paths(const char* paths_str) void Context::collect_include_paths(const char* paths_str)
{ {
const size_t wd_len = 1024; const size_t wd_len = 1024;
...@@ -39,7 +39,7 @@ namespace Sass { ...@@ -39,7 +39,7 @@ namespace Sass {
// cerr << include_paths[i] << endl; // cerr << include_paths[i] << endl;
// } // }
} }
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<pair<string, size_t>, Function>()),
...@@ -54,7 +54,7 @@ namespace Sass { ...@@ -54,7 +54,7 @@ namespace Sass {
register_functions(); register_functions();
collect_include_paths(paths_str); collect_include_paths(paths_str);
} }
Context::~Context() Context::~Context()
{ {
for (size_t i = 0; i < source_refs.size(); ++i) { for (size_t i = 0; i < source_refs.size(); ++i) {
...@@ -64,19 +64,19 @@ namespace Sass { ...@@ -64,19 +64,19 @@ namespace Sass {
new_Node.free(); new_Node.free();
// 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, Implementation 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, Implementation 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;
} }
void Context::register_functions() void Context::register_functions()
{ {
using namespace Functions; using namespace Functions;
...@@ -122,5 +122,6 @@ namespace Sass { ...@@ -122,5 +122,6 @@ namespace Sass {
// Boolean Functions // Boolean Functions
register_function(not_descriptor, not_impl); register_function(not_descriptor, not_impl);
} }
} }
...@@ -9,29 +9,29 @@ ...@@ -9,29 +9,29 @@
namespace Sass { namespace Sass {
using std::pair; using std::pair;
using std::map; using std::map;
struct Environment { struct Environment {
map<Token, Node> current_frame; map<Token, Node> current_frame;
Environment* parent; Environment* parent;
Environment* global; Environment* global;
Environment() Environment()
: current_frame(map<Token, Node>()), parent(0), global(0) : current_frame(map<Token, Node>()), parent(0), global(0)
{ } { }
void link(Environment& env) void link(Environment& env)
{ {
parent = &env; parent = &env;
global = parent->global ? parent->global : parent; global = parent->global ? parent->global : parent;
} }
bool query(const Token& key) const bool query(const Token& key) const
{ {
if (current_frame.count(key)) return true; if (current_frame.count(key)) return true;
else if (parent) return parent->query(key); else if (parent) return parent->query(key);
else return false; else return false;
} }
Node& operator[](const Token& key) Node& operator[](const Token& key)
{ {
if (current_frame.count(key)) return current_frame[key]; if (current_frame.count(key)) return current_frame[key];
...@@ -56,10 +56,11 @@ namespace Sass { ...@@ -56,10 +56,11 @@ namespace Sass {
void collect_include_paths(const char* paths_str); void collect_include_paths(const char* paths_str);
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, Implementation ip);
void register_function(Function_Descriptor d, Implementation ip, size_t arity); void register_function(Function_Descriptor d, Implementation ip, size_t arity);
void register_functions(); void register_functions();
}; };
} }
...@@ -90,17 +90,17 @@ namespace Sass { ...@@ -90,17 +90,17 @@ namespace Sass {
return doc; return doc;
} }
void Document::throw_syntax_error(string message, size_t ln) void Document::throw_syntax_error(string message, size_t ln)
{ throw Error(Error::syntax, path, ln ? ln : line, message); } { throw Error(Error::syntax, path, ln ? ln : line, message); }
void Document::throw_read_error(string message, size_t ln) void Document::throw_read_error(string message, size_t ln)
{ throw Error(Error::read, path, ln ? ln : line, message); } { throw Error(Error::read, path, ln ? ln : line, message); }
using std::string; using std::string;
using std::stringstream; using std::stringstream;
using std::endl; using std::endl;
string Document::emit_css(CSS_Style style) { string Document::emit_css(CSS_Style style) {
stringstream output; stringstream output;
switch (style) { switch (style) {
...@@ -121,3 +121,4 @@ namespace Sass { ...@@ -121,3 +121,4 @@ namespace Sass {
return retval; return retval;
} }
} }
...@@ -25,7 +25,7 @@ namespace Sass { ...@@ -25,7 +25,7 @@ namespace Sass {
struct Document { struct Document {
enum CSS_Style { nested, expanded, compact, compressed, echo }; enum CSS_Style { nested, expanded, compact, compressed, echo };
string path; string path;
char* source; char* source;
const char* position; const char* position;
...@@ -34,7 +34,7 @@ namespace Sass { ...@@ -34,7 +34,7 @@ namespace Sass {
bool own_source; bool own_source;
Context& context; Context& context;
Node root; Node root;
Token lexed; Token lexed;
...@@ -84,7 +84,7 @@ namespace Sass { ...@@ -84,7 +84,7 @@ namespace Sass {
return 0; return 0;
} }
} }
template <prelexer mx> template <prelexer mx>
const char* lex() const char* lex()
{ {
...@@ -123,7 +123,7 @@ namespace Sass { ...@@ -123,7 +123,7 @@ namespace Sass {
return 0; return 0;
} }
} }
void parse_scss(); void parse_scss();
Node parse_import(); Node parse_import();
Node parse_include(); Node parse_include();
...@@ -163,13 +163,14 @@ namespace Sass { ...@@ -163,13 +163,14 @@ namespace Sass {
Node parse_if_directive(Node surrounding_ruleset); Node parse_if_directive(Node surrounding_ruleset);
Node parse_for_directive(Node surrounding_ruleset); Node parse_for_directive(Node surrounding_ruleset);
Selector_Lookahead lookahead_for_selector(const char* start = 0); Selector_Lookahead lookahead_for_selector(const char* start = 0);
void throw_syntax_error(string message, size_t ln = 0); void throw_syntax_error(string message, size_t ln = 0);
void throw_read_error(string message, size_t ln = 0); void throw_read_error(string message, size_t ln = 0);
string emit_css(CSS_Style style); string emit_css(CSS_Style style);
}; };
} }
\ No newline at end of file
namespace Sass { namespace Sass {
struct Error { struct Error {
enum Type { read, write, syntax, evaluation }; enum Type { read, write, syntax, evaluation };
Type type; Type type;
string path; string path;
size_t line; size_t line;
string message; string message;
Error(Type type, string path, size_t line, string message) Error(Type type, string path, size_t line, string message)
: type(type), path(path), line(line), message(message) : type(type), path(path), line(line), message(message)
{ } { }
}; };
} }
\ No newline at end of file
...@@ -27,7 +27,7 @@ namespace Sass { ...@@ -27,7 +27,7 @@ namespace Sass {
env[expr[0].token()] = expr; env[expr[0].token()] = expr;
return expr; return expr;
} break; } break;
case Node::expansion: { case Node::expansion: {
Token name(expr[0].token()); Token name(expr[0].token());
Node args(expr[1]); Node args(expr[1]);
...@@ -39,7 +39,7 @@ namespace Sass { ...@@ -39,7 +39,7 @@ namespace Sass {
expr += expansion; expr += expansion;
return expr; return expr;
} break; } break;
case Node::propset: { case Node::propset: {
eval(expr[1], prefix, env, f_env, new_Node, ctx); eval(expr[1], prefix, env, f_env, new_Node, ctx);
return expr; return expr;
...@@ -91,14 +91,14 @@ namespace Sass { ...@@ -91,14 +91,14 @@ namespace Sass {
Node sel(needs_reparsing.parse_selector_group()); Node sel(needs_reparsing.parse_selector_group());
return sel; return sel;
} break; } break;
case Node::root: { case Node::root: {
for (size_t i = 0, S = expr.size(); i < S; ++i) { for (size_t i = 0, S = expr.size(); i < S; ++i) {
expr[i] = eval(expr[i], prefix, env, f_env, new_Node, ctx); expr[i] = eval(expr[i], prefix, env, f_env, new_Node, ctx);
} }
return expr; return expr;
} break; } break;
case Node::block: { case Node::block: {
Environment new_frame; Environment new_frame;
new_frame.link(env); new_frame.link(env);
...@@ -107,7 +107,7 @@ namespace Sass { ...@@ -107,7 +107,7 @@ namespace Sass {
} }
return expr; return expr;
} break; } break;
case Node::assignment: { case Node::assignment: {
Node val(expr[1]); Node val(expr[1]);
if (val.type() == Node::comma_list || val.type() == Node::space_list) { if (val.type() == Node::comma_list || val.type() == Node::space_list) {
...@@ -149,7 +149,7 @@ namespace Sass { ...@@ -149,7 +149,7 @@ namespace Sass {
if (expr.should_eval()) expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx); if (expr.should_eval()) expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
return expr; return expr;
} break; } break;
case Node::disjunction: { case Node::disjunction: {
Node result; Node result;
for (size_t i = 0, S = expr.size(); i < S; ++i) { for (size_t i = 0, S = expr.size(); i < S; ++i) {
...@@ -159,7 +159,7 @@ namespace Sass { ...@@ -159,7 +159,7 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case Node::conjunction: { case Node::conjunction: {
Node result; Node result;
for (size_t i = 0, S = expr.size(); i < S; ++i) { for (size_t i = 0, S = expr.size(); i < S; ++i) {
...@@ -168,16 +168,16 @@ namespace Sass { ...@@ -168,16 +168,16 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case Node::relation: { case Node::relation: {
Node lhs(eval(expr[0], prefix, env, f_env, new_Node, ctx)); Node lhs(eval(expr[0], prefix, env, f_env, new_Node, ctx));
Node op(expr[1]); Node op(expr[1]);
Node rhs(eval(expr[2], prefix, env, f_env, new_Node, ctx)); Node rhs(eval(expr[2], prefix, env, f_env, new_Node, ctx));
// TO DO: don't allocate both T and F // TO DO: don't allocate both T and F
Node T(new_Node(Node::boolean, lhs.path(), lhs.line(), true)); Node T(new_Node(Node::boolean, lhs.path(), lhs.line(), true));
Node F(new_Node(Node::boolean, lhs.path(), lhs.line(), false)); Node F(new_Node(Node::boolean, lhs.path(), lhs.line(), false));
switch (op.type()) switch (op.type())
{ {
case Node::eq: return (lhs == rhs) ? T : F; case Node::eq: return (lhs == rhs) ? T : F;
...@@ -231,12 +231,12 @@ namespace Sass { ...@@ -231,12 +231,12 @@ namespace Sass {
Token::make(Prelexer::number(expr.token().begin), Token::make(Prelexer::number(expr.token().begin),
expr.token().end)); expr.token().end));
} break; } break;
case Node::textual_number: { case Node::textual_number: {
return new_Node(expr.path(), expr.line(), std::atof(expr.token().begin)); return new_Node(expr.path(), expr.line(), std::atof(expr.token().begin));
} break; } break;
case Node::textual_hex: { case Node::textual_hex: {
Node triple(new_Node(Node::numeric_color, expr.path(), expr.line(), 4)); Node triple(new_Node(Node::numeric_color, expr.path(), expr.line(), 4));
Token hext(Token::make(expr.token().begin+1, expr.token().end)); Token hext(Token::make(expr.token().begin+1, expr.token().end));
if (hext.length() == 6) { if (hext.length() == 6) {
...@@ -252,19 +252,19 @@ namespace Sass { ...@@ -252,19 +252,19 @@ namespace Sass {
triple << new_Node(expr.path(), expr.line(), 1.0); triple << new_Node(expr.path(), expr.line(), 1.0);
return triple; return triple;
} break; } break;
case Node::variable: { case Node::variable: {
if (!env.query(expr.token())) throw_eval_error("reference to unbound variable " + expr.token().to_string(), expr.path(), expr.line()); if (!env.query(expr.token())) throw_eval_error("reference to unbound variable " + expr.token().to_string(), expr.path(), expr.line());
return env[expr.token()]; return env[expr.token()];
} break; } break;
case Node::function_call: { case Node::function_call: {
// TO DO: default-constructed Function should be a generic callback (maybe) // TO DO: default-constructed Function should be a generic callback (maybe)
pair<string, size_t> sig(expr[0].token().to_string(), expr[1].size()); pair<string, size_t> sig(expr[0].token().to_string(), expr[1].size());
if (!f_env.count(sig)) return expr; if (!f_env.count(sig)) return expr;
return apply_function(f_env[sig], expr[1], prefix, env, f_env, new_Node, ctx); return apply_function(f_env[sig], expr[1], prefix, env, f_env, new_Node, ctx);
} break; } break;
case Node::unary_plus: { case Node::unary_plus: {
Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx)); Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx));
if (arg.is_numeric()) { if (arg.is_numeric()) {
...@@ -275,7 +275,7 @@ namespace Sass { ...@@ -275,7 +275,7 @@ namespace Sass {
return expr; return expr;
} }
} break; } break;
case Node::unary_minus: { case Node::unary_minus: {
Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx)); Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx));
if (arg.is_numeric()) { if (arg.is_numeric()) {
...@@ -286,7 +286,7 @@ namespace Sass { ...@@ -286,7 +286,7 @@ namespace Sass {
return expr; return expr;
} }
} break; } break;
case Node::string_schema: case Node::string_schema:
case Node::value_schema: { case Node::value_schema: {
for (size_t i = 0, S = expr.size(); i < S; ++i) { for (size_t i = 0, S = expr.size(); i < S; ++i) {
...@@ -294,7 +294,7 @@ namespace Sass { ...@@ -294,7 +294,7 @@ namespace Sass {
} }
return expr; return expr;
} break; } break;
case Node::css_import: { case Node::css_import: {
expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx); expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
return expr; return expr;
...@@ -359,7 +359,7 @@ namespace Sass { ...@@ -359,7 +359,7 @@ namespace Sass {
Node lhs(acc.back()); Node lhs(acc.back());
double lnum = lhs.numeric_value(); double lnum = lhs.numeric_value();
double rnum = rhs.numeric_value(); double rnum = rhs.numeric_value();
if (lhs.type() == Node::number && rhs.type() == Node::number) { if (lhs.type() == Node::number && rhs.type() == Node::number) {
Node result(new_Node(acc.path(), acc.line(), operate(op, lnum, rnum))); Node result(new_Node(acc.path(), acc.line(), operate(op, lnum, rnum)));
acc.pop_back(); acc.pop_back();
...@@ -451,7 +451,7 @@ namespace Sass { ...@@ -451,7 +451,7 @@ namespace Sass {
// Apply a mixin -- bind the arguments in a new environment, link the new // Apply a mixin -- bind the arguments in a new environment, link the new
// 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) 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)
{ {
Node params(mixin[1]); Node params(mixin[1]);
...@@ -510,7 +510,7 @@ namespace Sass { ...@@ -510,7 +510,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<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{ {
map<Token, Node> bindings; map<Token, Node> bindings;
...@@ -855,3 +855,4 @@ namespace Sass { ...@@ -855,3 +855,4 @@ namespace Sass {
{ return selector_but(sel, new_Node, 0, 1); } { return selector_but(sel, new_Node, 0, 1); }
} }
...@@ -10,11 +10,11 @@ ...@@ -10,11 +10,11 @@
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& src_refs); Node eval(Node expr, Node prefix, Environment& env, map<pair<string, size_t>, Function>& f_env, Node_Factory& new_Node, Context& src_refs);
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& src_refs); 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& src_refs);
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& src_refs); 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& src_refs);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node); Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
...@@ -28,4 +28,5 @@ namespace Sass { ...@@ -28,4 +28,5 @@ namespace Sass {
Node selector_butfirst(Node sel, Node_Factory& new_Node); Node selector_butfirst(Node sel, Node_Factory& new_Node);
Node selector_butlast(Node sel, Node_Factory& new_Node); Node selector_butlast(Node sel, Node_Factory& new_Node);
} }
\ No newline at end of file
...@@ -7,20 +7,20 @@ ...@@ -7,20 +7,20 @@
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 (*Implementation)(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[];
struct Function { struct Function {
string name; string name;
vector<Token> parameters; vector<Token> parameters;
Implementation implementation; Implementation implementation;
Function() Function()
{ /* TO DO: set up the generic callback here */ } { /* TO DO: set up the generic callback here */ }
Function(Function_Descriptor d, Implementation ip) Function(Function_Descriptor d, Implementation ip)
: name(d[0]), : name(d[0]),
parameters(vector<Token>()), parameters(vector<Token>()),
...@@ -28,7 +28,7 @@ namespace Sass { ...@@ -28,7 +28,7 @@ namespace Sass {
{ {
size_t len = 0; size_t len = 0;
while (d[len+1]) ++len; while (d[len+1]) ++len;
parameters.reserve(len); parameters.reserve(len);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
const char* p = d[i+1]; const char* p = d[i+1];
...@@ -36,12 +36,12 @@ namespace Sass { ...@@ -36,12 +36,12 @@ namespace Sass {
parameters.push_back(name); parameters.push_back(name);
} }
} }
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); } { return implementation(parameters, bindings, new_Node); }
}; };
namespace Functions { namespace Functions {
// RGB Functions /////////////////////////////////////////////////////// // RGB Functions ///////////////////////////////////////////////////////
...@@ -51,58 +51,58 @@ namespace Sass { ...@@ -51,58 +51,58 @@ namespace Sass {
extern Function_Descriptor rgba_4_descriptor; extern Function_Descriptor rgba_4_descriptor;
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor rgba_2_descriptor; extern Function_Descriptor rgba_2_descriptor;
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor red_descriptor; extern Function_Descriptor red_descriptor;
Node red(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node red(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor green_descriptor; extern Function_Descriptor green_descriptor;
Node green(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node green(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor blue_descriptor; extern Function_Descriptor blue_descriptor;
Node blue(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node blue(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor mix_2_descriptor; extern Function_Descriptor mix_2_descriptor;
Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor mix_3_descriptor; extern Function_Descriptor mix_3_descriptor;
Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// HSL Functions /////////////////////////////////////////////////////// // HSL Functions ///////////////////////////////////////////////////////
extern Function_Descriptor hsla_descriptor; extern Function_Descriptor hsla_descriptor;
Node hsla(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node hsla(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor hsl_descriptor; extern Function_Descriptor hsl_descriptor;
Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor invert_descriptor; extern Function_Descriptor invert_descriptor;
Node invert(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node invert(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// Opacity Functions /////////////////////////////////////////////////// // Opacity Functions ///////////////////////////////////////////////////
extern Function_Descriptor alpha_descriptor; extern Function_Descriptor alpha_descriptor;
extern Function_Descriptor opacity_descriptor; extern Function_Descriptor opacity_descriptor;
Node alpha(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node alpha(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor opacify_descriptor; extern Function_Descriptor opacify_descriptor;
extern Function_Descriptor fade_in_descriptor; extern Function_Descriptor fade_in_descriptor;
Node opacify(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node opacify(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor transparentize_descriptor; extern Function_Descriptor transparentize_descriptor;
extern Function_Descriptor fade_out_descriptor; extern Function_Descriptor fade_out_descriptor;
Node transparentize(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node transparentize(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// String Functions //////////////////////////////////////////////////// // String Functions ////////////////////////////////////////////////////
extern Function_Descriptor unquote_descriptor; extern Function_Descriptor unquote_descriptor;
Node unquote(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node unquote(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor quote_descriptor; extern Function_Descriptor quote_descriptor;
Node quote(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node quote(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// Number Functions //////////////////////////////////////////////////// // Number Functions ////////////////////////////////////////////////////
extern Function_Descriptor percentage_descriptor; extern Function_Descriptor percentage_descriptor;
...@@ -117,42 +117,43 @@ namespace Sass { ...@@ -117,42 +117,43 @@ namespace Sass {
extern Function_Descriptor floor_descriptor; extern Function_Descriptor floor_descriptor;
Node floor(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node floor(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor abs_descriptor; extern Function_Descriptor abs_descriptor;
Node abs(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node abs(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// List Functions ////////////////////////////////////////////////////// // List Functions //////////////////////////////////////////////////////
extern Function_Descriptor length_descriptor; extern Function_Descriptor length_descriptor;
Node length(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node length(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor nth_descriptor; extern Function_Descriptor nth_descriptor;
Node nth(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node nth(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor join_2_descriptor; extern Function_Descriptor join_2_descriptor;
Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor join_3_descriptor; extern Function_Descriptor join_3_descriptor;
Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// Introspection Functions ///////////////////////////////////////////// // Introspection Functions /////////////////////////////////////////////
extern Function_Descriptor type_of_descriptor; extern Function_Descriptor type_of_descriptor;
Node type_of(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node type_of(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor unit_descriptor; extern Function_Descriptor unit_descriptor;
Node unit(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node unit(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor unitless_descriptor; extern Function_Descriptor unitless_descriptor;
Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
extern Function_Descriptor comparable_descriptor; extern Function_Descriptor comparable_descriptor;
Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
// Boolean Functions /////////////////////////////////////////////////// // Boolean Functions ///////////////////////////////////////////////////
extern Function_Descriptor not_descriptor; extern Function_Descriptor not_descriptor;
Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node); Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node);
} }
} }
...@@ -51,7 +51,7 @@ namespace Sass { ...@@ -51,7 +51,7 @@ namespace Sass {
} }
return true; return true;
} break; } break;
case variable: case variable:
case identifier: case identifier:
case uri: case uri:
...@@ -62,12 +62,12 @@ namespace Sass { ...@@ -62,12 +62,12 @@ namespace Sass {
case string_constant: { case string_constant: {
return token().unquote() == rhs.token().unquote(); return token().unquote() == rhs.token().unquote();
} break; } break;
case number: case number:
case numeric_percentage: { case numeric_percentage: {
return numeric_value() == rhs.numeric_value(); return numeric_value() == rhs.numeric_value();
} break; } break;
case numeric_dimension: { case numeric_dimension: {
if (unit() == rhs.unit()) { if (unit() == rhs.unit()) {
return numeric_value() == rhs.numeric_value(); return numeric_value() == rhs.numeric_value();
...@@ -76,26 +76,26 @@ namespace Sass { ...@@ -76,26 +76,26 @@ namespace Sass {
return false; return false;
} }
} break; } break;
case boolean: { case boolean: {
return boolean_value() == rhs.boolean_value(); return boolean_value() == rhs.boolean_value();
} break; } break;
default: { default: {
return true; return true;
} break; } break;
} }
return false; return false;
} }
bool Node::operator!=(Node rhs) const bool Node::operator!=(Node rhs) const
{ return !(*this == rhs); } { return !(*this == rhs); }
bool Node::operator<(Node rhs) const bool Node::operator<(Node rhs) const
{ {
Type lhs_type = type(); Type lhs_type = type();
Type rhs_type = rhs.type(); Type rhs_type = rhs.type();
// comparing atomic numbers // comparing atomic numbers
if ((lhs_type == number && rhs_type == number) || if ((lhs_type == number && rhs_type == number) ||
(lhs_type == numeric_percentage && rhs_type == numeric_percentage)) { (lhs_type == numeric_percentage && rhs_type == numeric_percentage)) {
...@@ -158,13 +158,13 @@ namespace Sass { ...@@ -158,13 +158,13 @@ namespace Sass {
throw Error(Error::evaluation, path(), line(), "incomparable types"); throw Error(Error::evaluation, path(), line(), "incomparable types");
} }
} }
bool Node::operator<=(Node rhs) const bool Node::operator<=(Node rhs) const
{ return *this < rhs || *this == rhs; } { return *this < rhs || *this == rhs; }
bool Node::operator>(Node rhs) const bool Node::operator>(Node rhs) const
{ return !(*this <= rhs); } { return !(*this <= rhs); }
bool Node::operator>=(Node rhs) const bool Node::operator>=(Node rhs) const
{ return !(*this < rhs); } { return !(*this < rhs); }
...@@ -172,7 +172,7 @@ namespace Sass { ...@@ -172,7 +172,7 @@ namespace Sass {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Token method implementations // Token method implementations
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
string Token::unquote() const string Token::unquote() const
{ {
string result; string result;
...@@ -210,7 +210,7 @@ namespace Sass { ...@@ -210,7 +210,7 @@ namespace Sass {
return result; return result;
} }
} }
void Token::unquote_to_stream(std::stringstream& buf) const void Token::unquote_to_stream(std::stringstream& buf) const
{ {
const char* p = begin; const char* p = begin;
...@@ -247,7 +247,7 @@ namespace Sass { ...@@ -247,7 +247,7 @@ namespace Sass {
return; return;
} }
} }
bool Token::operator<(const Token& rhs) const bool Token::operator<(const Token& rhs) const
{ {
const char* first1 = begin; const char* first1 = begin;
...@@ -262,15 +262,15 @@ namespace Sass { ...@@ -262,15 +262,15 @@ namespace Sass {
} }
return (first2 != last2); return (first2 != last2);
} }
bool Token::operator==(const Token& rhs) const bool Token::operator==(const Token& rhs) const
{ {
if (length() != rhs.length()) return false; if (length() != rhs.length()) return false;
if ((begin[0] == '"' || begin[0] == '\'') && if ((begin[0] == '"' || begin[0] == '\'') &&
(rhs.begin[0] == '"' || rhs.begin[0] == '\'')) (rhs.begin[0] == '"' || rhs.begin[0] == '\''))
{ return unquote() == rhs.unquote(); } { return unquote() == rhs.unquote(); }
const char* p = begin; const char* p = begin;
const char* q = rhs.begin; const char* q = rhs.begin;
for (; p < end; ++p, ++q) if (*p != *q) return false; for (; p < end; ++p, ++q) if (*p != *q) return false;
...@@ -298,7 +298,7 @@ namespace Sass { ...@@ -298,7 +298,7 @@ namespace Sass {
// if you reach this point, you've got a logic error somewhere // if you reach this point, you've got a logic error somewhere
return 0; return 0;
} }
extern const char percent_str[] = "%"; extern const char percent_str[] = "%";
extern const char empty_str[] = ""; extern const char empty_str[] = "";
Token Node_Impl::unit() Token Node_Impl::unit()
...@@ -308,14 +308,15 @@ namespace Sass { ...@@ -308,14 +308,15 @@ namespace Sass {
case Node::numeric_percentage: { case Node::numeric_percentage: {
return Token::make(percent_str); return Token::make(percent_str);
} break; } break;
case Node::numeric_dimension: { case Node::numeric_dimension: {
return value.dimension.unit; return value.dimension.unit;
} break; } break;
default: break; default: break;
} }
return Token::make(empty_str); return Token::make(empty_str);
} }
} }
\ No newline at end of file
...@@ -46,7 +46,7 @@ namespace Sass { ...@@ -46,7 +46,7 @@ namespace Sass {
string unquote() const; string unquote() const;
void unquote_to_stream(std::stringstream& buf) const; void unquote_to_stream(std::stringstream& buf) const;
operator bool() operator bool()
{ return begin && end && begin >= end; } { return begin && end && begin >= end; }
...@@ -58,7 +58,7 @@ namespace Sass { ...@@ -58,7 +58,7 @@ namespace Sass {
double numeric; double numeric;
Token unit; Token unit;
}; };
struct Node_Impl; struct Node_Impl;
class Node { class Node {
...@@ -199,7 +199,7 @@ namespace Sass { ...@@ -199,7 +199,7 @@ namespace Sass {
bool is_null_ptr() const; bool is_null_ptr() const;
void flatten(); void flatten();
bool operator==(Node rhs) const; bool operator==(Node rhs) const;
bool operator!=(Node rhs) const; bool operator!=(Node rhs) const;
bool operator<(Node rhs) const; bool operator<(Node rhs) const;
...@@ -214,7 +214,7 @@ namespace Sass { ...@@ -214,7 +214,7 @@ namespace Sass {
void emit_expanded_css(stringstream& buf, const string& prefix); void emit_expanded_css(stringstream& buf, const string& prefix);
}; };
struct Node_Impl { struct Node_Impl {
union value_t { union value_t {
bool boolean; bool boolean;
...@@ -255,13 +255,13 @@ namespace Sass { ...@@ -255,13 +255,13 @@ namespace Sass {
should_eval(false), should_eval(false),
is_unquoted(false) is_unquoted(false)
{ } { }
bool is_numeric() bool is_numeric()
{ return type >= Node::number && type <= Node::numeric_dimension; } { return type >= Node::number && type <= Node::numeric_dimension; }
size_t size() size_t size()
{ return children.size(); } { return children.size(); }
bool empty() bool empty()
{ return children.empty(); } { return children.empty(); }
...@@ -321,7 +321,7 @@ namespace Sass { ...@@ -321,7 +321,7 @@ namespace Sass {
bool& boolean_value() bool& boolean_value()
{ return value.boolean; } { return value.boolean; }
double numeric_value(); double numeric_value();
Token unit(); Token unit();
}; };
...@@ -332,11 +332,11 @@ namespace Sass { ...@@ -332,11 +332,11 @@ namespace Sass {
// -- in the header file so they can easily be declared inline // -- in the header file so they can easily be declared inline
// -- outside of their class definition to get the right declaration order // -- outside of their class definition to get the right declaration order
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
inline Node::Node(Node_Impl* ip) : ip_(ip) { } inline Node::Node(Node_Impl* ip) : ip_(ip) { }
inline Node::Type Node::type() const { return ip_->type; } inline Node::Type Node::type() const { return ip_->type; }
inline bool Node::has_children() const { return ip_->has_children; } inline bool Node::has_children() const { return ip_->has_children; }
inline bool Node::has_statements() const { return ip_->has_statements; } inline bool Node::has_statements() const { return ip_->has_statements; }
inline bool Node::has_blocks() const { return ip_->has_blocks; } inline bool Node::has_blocks() const { return ip_->has_blocks; }
...@@ -346,12 +346,12 @@ namespace Sass { ...@@ -346,12 +346,12 @@ namespace Sass {
inline bool& Node::should_eval() const { return ip_->should_eval; } inline bool& Node::should_eval() const { return ip_->should_eval; }
inline bool& Node::is_unquoted() const { return ip_->is_unquoted; } inline bool& Node::is_unquoted() const { return ip_->is_unquoted; }
inline bool Node::is_numeric() const { return ip_->is_numeric(); } inline bool Node::is_numeric() const { return ip_->is_numeric(); }
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; }
inline size_t Node::size() const { return ip_->size(); } inline size_t Node::size() const { return ip_->size(); }
inline bool Node::empty() const { return ip_->empty(); } inline bool Node::empty() const { return ip_->empty(); }
inline Node& Node::at(size_t i) const { return ip_->at(i); } inline Node& Node::at(size_t i) const { return ip_->at(i); }
inline Node& Node::back() const { return ip_->back(); } inline Node& Node::back() const { return ip_->back(); }
inline Node& Node::operator[](size_t i) const { return at(i); } inline Node& Node::operator[](size_t i) const { return at(i); }
...@@ -390,3 +390,4 @@ namespace Sass { ...@@ -390,3 +390,4 @@ namespace Sass {
inline bool Node::is_null_ptr() const { return !ip_; } inline bool Node::is_null_ptr() const { return !ip_; }
} }
...@@ -27,10 +27,10 @@ namespace Sass { ...@@ -27,10 +27,10 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case selector: { case selector: {
string result; string result;
result += at(0).to_string(); result += at(0).to_string();
for (size_t i = 1, S = size(); i < S; ++i) { for (size_t i = 1, S = size(); i < S; ++i) {
result += " "; result += " ";
...@@ -38,11 +38,11 @@ namespace Sass { ...@@ -38,11 +38,11 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case selector_combinator: { case selector_combinator: {
return token().to_string(); return token().to_string();
} break; } break;
case simple_selector_sequence: { case simple_selector_sequence: {
string result; string result;
for (size_t i = 0, S = size(); i < S; ++i) { for (size_t i = 0, S = size(); i < S; ++i) {
...@@ -50,12 +50,12 @@ namespace Sass { ...@@ -50,12 +50,12 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case pseudo: case pseudo:
case simple_selector: { case simple_selector: {
return token().to_string(); return token().to_string();
} break; } break;
case pseudo_negation: { case pseudo_negation: {
string result; string result;
result += at(0).to_string(); result += at(0).to_string();
...@@ -63,7 +63,7 @@ namespace Sass { ...@@ -63,7 +63,7 @@ namespace Sass {
result += ')'; result += ')';
return result; return result;
} break; } break;
case functional_pseudo: { case functional_pseudo: {
string result; string result;
result += at(0).to_string(); result += at(0).to_string();
...@@ -73,7 +73,7 @@ namespace Sass { ...@@ -73,7 +73,7 @@ namespace Sass {
result += ')'; result += ')';
return result; return result;
} break; } break;
case attribute_selector: { case attribute_selector: {
string result; string result;
result += "["; result += "[";
...@@ -93,7 +93,7 @@ namespace Sass { ...@@ -93,7 +93,7 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case space_list: { case space_list: {
string result(at(0).to_string()); string result(at(0).to_string());
for (size_t i = 1, S = size(); i < S; ++i) { for (size_t i = 1, S = size(); i < S; ++i) {
...@@ -103,7 +103,7 @@ namespace Sass { ...@@ -103,7 +103,7 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case expression: case expression:
case term: { case term: {
string result(at(0).to_string()); string result(at(0).to_string());
...@@ -116,16 +116,16 @@ namespace Sass { ...@@ -116,16 +116,16 @@ namespace Sass {
} }
return result; return result;
} break; } break;
//edge case //edge case
case sub: { case sub: {
return "-"; return "-";
} break; } break;
case div: { case div: {
return "/"; return "/";
} break; } break;
case css_import: { case css_import: {
stringstream ss; stringstream ss;
ss << "@import url("; ss << "@import url(";
...@@ -134,7 +134,7 @@ namespace Sass { ...@@ -134,7 +134,7 @@ namespace Sass {
ss << ")"; ss << ")";
return ss.str(); return ss.str();
} }
case function_call: { case function_call: {
stringstream ss; stringstream ss;
ss << at(0).to_string(); ss << at(0).to_string();
...@@ -143,7 +143,7 @@ namespace Sass { ...@@ -143,7 +143,7 @@ namespace Sass {
ss << ")"; ss << ")";
return ss.str(); return ss.str();
} }
case arguments: { case arguments: {
stringstream ss; stringstream ss;
size_t S = size(); size_t S = size();
...@@ -156,40 +156,40 @@ namespace Sass { ...@@ -156,40 +156,40 @@ namespace Sass {
} }
return ss.str(); return ss.str();
} }
case unary_plus: { case unary_plus: {
stringstream ss; stringstream ss;
ss << "+"; ss << "+";
ss << at(0).to_string(); ss << at(0).to_string();
return ss.str(); return ss.str();
} }
case unary_minus: { case unary_minus: {
stringstream ss; stringstream ss;
ss << "-"; ss << "-";
ss << at(0).to_string(); ss << at(0).to_string();
return ss.str(); return ss.str();
} }
case numeric_percentage: { case numeric_percentage: {
stringstream ss; stringstream ss;
ss << numeric_value(); ss << numeric_value();
ss << '%'; ss << '%';
return ss.str(); return ss.str();
} }
case numeric_dimension: { case numeric_dimension: {
stringstream ss; stringstream ss;
ss << numeric_value() << unit().to_string(); ss << numeric_value() << unit().to_string();
return ss.str(); return ss.str();
} break; } break;
case number: { case number: {
stringstream ss; stringstream ss;
ss << numeric_value(); ss << numeric_value();
return ss.str(); return ss.str();
} break; } break;
case numeric_color: { case numeric_color: {
if (at(3).numeric_value() >= 1.0) if (at(3).numeric_value() >= 1.0)
{ {
...@@ -201,7 +201,7 @@ namespace Sass { ...@@ -201,7 +201,7 @@ namespace Sass {
else if (a >= 0xff && b >= 0xff && c == 0) else if (a >= 0xff && b >= 0xff && c == 0)
{ return "yellow"; } { return "yellow"; }
else if (a == 0 && b >= 0xff && c >= 0xff) else if (a == 0 && b >= 0xff && c >= 0xff)
{ return "aqua"; } { return "aqua"; }
else if (a >= 0xff && b == 0 && c >= 0xff) else if (a >= 0xff && b == 0 && c >= 0xff)
{ return "fuchsia"; } { return "fuchsia"; }
else if (a >= 0xff && b == 0 && c == 0) else if (a >= 0xff && b == 0 && c == 0)
...@@ -236,7 +236,7 @@ namespace Sass { ...@@ -236,7 +236,7 @@ namespace Sass {
return ss.str(); return ss.str();
} }
} break; } break;
case uri: { case uri: {
string result("url("); string result("url(");
result += token().to_string(); result += token().to_string();
...@@ -248,7 +248,7 @@ namespace Sass { ...@@ -248,7 +248,7 @@ namespace Sass {
// ignore it // ignore it
return ""; return "";
} break; } break;
case string_constant: { case string_constant: {
if (is_unquoted()) return token().unquote(); if (is_unquoted()) return token().unquote();
else { else {
...@@ -257,22 +257,22 @@ namespace Sass { ...@@ -257,22 +257,22 @@ namespace Sass {
else return result; else return result;
} }
} break; } break;
case boolean: { case boolean: {
if (boolean_value()) return "true"; if (boolean_value()) return "true";
else return "false"; else return "false";
} break; } break;
case important: { case important: {
return "!important"; return "!important";
} break; } break;
case value_schema: { case value_schema: {
string result; string result;
for (size_t i = 0, S = size(); i < S; ++i) result += at(i).to_string(); for (size_t i = 0, S = size(); i < S; ++i) result += at(i).to_string();
return result; return result;
} break; } break;
case string_schema: { case string_schema: {
string result; string result;
for (size_t i = 0, S = size(); i < S; ++i) { for (size_t i = 0, S = size(); i < S; ++i) {
...@@ -286,7 +286,7 @@ namespace Sass { ...@@ -286,7 +286,7 @@ namespace Sass {
} }
return result; return result;
} break; } break;
default: { default: {
// return content.token.to_string(); // return content.token.to_string();
if (!has_children()) return token().to_string(); if (!has_children()) return token().to_string();
...@@ -338,14 +338,14 @@ namespace Sass { ...@@ -338,14 +338,14 @@ namespace Sass {
case propset: { case propset: {
emit_propset(buf, depth, ""); emit_propset(buf, depth, "");
} break; } break;
case rule: { case rule: {
buf << endl << string(2*depth, ' '); buf << endl << string(2*depth, ' ');
at(0).emit_nested_css(buf, depth); // property at(0).emit_nested_css(buf, depth); // property
at(1).emit_nested_css(buf, depth); // values at(1).emit_nested_css(buf, depth); // values
buf << ";"; buf << ";";
} break; } break;
case css_import: { case css_import: {
buf << string(2*depth, ' '); buf << string(2*depth, ' ');
buf << to_string(); buf << to_string();
...@@ -373,7 +373,7 @@ namespace Sass { ...@@ -373,7 +373,7 @@ namespace Sass {
} break; } break;
} }
} }
void Node::emit_propset(stringstream& buf, size_t depth, const string& prefix) void Node::emit_propset(stringstream& buf, size_t depth, const string& prefix)
{ {
string new_prefix(prefix); string new_prefix(prefix);
...@@ -405,4 +405,5 @@ namespace Sass { ...@@ -405,4 +405,5 @@ namespace Sass {
void Node::echo(stringstream& buf, size_t depth) { } void Node::echo(stringstream& buf, size_t depth) { }
void Node::emit_expanded_css(stringstream& buf, const string& prefix) { } void Node::emit_expanded_css(stringstream& buf, const string& prefix) { }
} }
\ No newline at end of file
#include "node_factory.hpp" #include "node_factory.hpp"
namespace Sass { namespace Sass {
Node_Impl* Node_Factory::alloc_Node_Impl(Node::Type type, string path, size_t line) Node_Impl* Node_Factory::alloc_Node_Impl(Node::Type type, string path, size_t line)
{ {
Node_Impl* ip = new Node_Impl(); Node_Impl* ip = new Node_Impl();
...@@ -69,7 +69,7 @@ namespace Sass { ...@@ -69,7 +69,7 @@ namespace Sass {
ip->value.dimension.unit = t; ip->value.dimension.unit = t;
return Node(ip); return Node(ip);
} }
// for making nodes representing rgba color quads // for making nodes representing rgba color quads
Node Node_Factory::operator()(string path, size_t line, double r, double g, double b, double a) Node Node_Factory::operator()(string path, size_t line, double r, double g, double b, double a)
{ {
...@@ -84,4 +84,5 @@ namespace Sass { ...@@ -84,4 +84,5 @@ namespace Sass {
void Node_Factory::free() void Node_Factory::free()
{ for (size_t i = 0, S = pool_.size(); i < S; ++i) delete pool_[i]; } { for (size_t i = 0, S = pool_.size(); i < S; ++i) delete pool_[i]; }
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ namespace Sass { ...@@ -9,7 +9,7 @@ namespace Sass {
struct Token; struct Token;
struct Node_Impl; struct Node_Impl;
class Node_Factory { class Node_Factory {
vector<Node_Impl*> pool_; vector<Node_Impl*> pool_;
Node_Impl* alloc_Node_Impl(Node::Type type, string file, size_t line); Node_Impl* alloc_Node_Impl(Node::Type type, string file, size_t line);
...@@ -33,5 +33,6 @@ namespace Sass { ...@@ -33,5 +33,6 @@ namespace Sass {
void free(); void free();
}; };
} }
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Sass { namespace Sass {
namespace Prelexer { namespace Prelexer {
// Matches zero characters (always succeeds without consuming input). // Matches zero characters (always succeeds without consuming input).
const char* epsilon(char *src) { const char* epsilon(char *src) {
return src; return src;
...@@ -12,10 +12,10 @@ namespace Sass { ...@@ -12,10 +12,10 @@ namespace Sass {
const char* empty(char *src) { const char* empty(char *src) {
return *src ? 0 : src; return *src ? 0 : src;
} }
// Match any single character. // Match any single character.
const char* any_char(const char* src) { return *src ? src++ : src; } const char* any_char(const char* src) { return *src ? src++ : src; }
// Match a single character satisfying the ctype predicates. // Match a single character satisfying the ctype predicates.
const char* space(const char* src) { return std::isspace(*src) ? src+1 : 0; } const char* space(const char* src) { return std::isspace(*src) ? src+1 : 0; }
const char* alpha(const char* src) { return std::isalpha(*src) ? src+1 : 0; } const char* alpha(const char* src) { return std::isalpha(*src) ? src+1 : 0; }
...@@ -30,7 +30,7 @@ namespace Sass { ...@@ -30,7 +30,7 @@ namespace Sass {
const char* xdigits(const char* src) { return one_plus<xdigit>(src); } const char* xdigits(const char* src) { return one_plus<xdigit>(src); }
const char* alnums(const char* src) { return one_plus<alnum>(src); } const char* alnums(const char* src) { return one_plus<alnum>(src); }
const char* puncts(const char* src) { return one_plus<punct>(src); } const char* puncts(const char* src) { return one_plus<punct>(src); }
// Match a line comment. // Match a line comment.
extern const char slash_slash[] = "//"; extern const char slash_slash[] = "//";
const char* line_comment(const char* src) { return to_endl<slash_slash>(src); } const char* line_comment(const char* src) { return to_endl<slash_slash>(src); }
...@@ -60,7 +60,7 @@ namespace Sass { ...@@ -60,7 +60,7 @@ namespace Sass {
const char* interpolant(const char* src) { const char* interpolant(const char* src) {
return delimited_by<hash_lbrace, rbrace, false>(src); return delimited_by<hash_lbrace, rbrace, false>(src);
} }
// Whitespace handling. // Whitespace handling.
const char* optional_spaces(const char* src) { return optional<spaces>(src); } const char* optional_spaces(const char* src) { return optional<spaces>(src); }
const char* optional_comment(const char* src) { return optional<comment>(src); } const char* optional_comment(const char* src) { return optional<comment>(src); }
...@@ -70,7 +70,7 @@ namespace Sass { ...@@ -70,7 +70,7 @@ namespace Sass {
const char* no_spaces(const char* src) { const char* no_spaces(const char* src) {
return negate< spaces >(src); return negate< spaces >(src);
} }
// Match CSS identifiers. // Match CSS identifiers.
const char* identifier(const char* src) { const char* identifier(const char* src) {
return sequence< optional< exactly<'-'> >, return sequence< optional< exactly<'-'> >,
...@@ -79,8 +79,8 @@ namespace Sass { ...@@ -79,8 +79,8 @@ namespace Sass {
exactly<'-'>, exactly<'-'>,
exactly<'_'> > > >(src); exactly<'_'> > > >(src);
} }
// Match interpolant schemas // Match interpolant schemas
const char* identifier_schema(const char* src) { const char* identifier_schema(const char* src) {
// follows this pattern: (x*ix*)+ // follows this pattern: (x*ix*)+
...@@ -94,7 +94,7 @@ namespace Sass { ...@@ -94,7 +94,7 @@ namespace Sass {
interpolant, interpolant,
zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > > > >(src); zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > > > >(src);
} }
// Match CSS '@' keywords. // Match CSS '@' keywords.
const char* at_keyword(const char* src) { const char* at_keyword(const char* src) {
return sequence<exactly<'@'>, identifier>(src); return sequence<exactly<'@'>, identifier>(src);
...@@ -156,7 +156,7 @@ namespace Sass { ...@@ -156,7 +156,7 @@ namespace Sass {
const char* while_directive(const char* src) { const char* while_directive(const char* src) {
return exactly<while_kwd>(src); return exactly<while_kwd>(src);
} }
const char* name(const char* src) { const char* name(const char* src) {
return one_plus< alternatives< alnum, return one_plus< alternatives< alnum,
exactly<'-'>, exactly<'-'>,
...@@ -305,12 +305,12 @@ namespace Sass { ...@@ -305,12 +305,12 @@ namespace Sass {
const char* ancestor_of(const char* src) { const char* ancestor_of(const char* src) {
return sequence< spaces, negate< exactly<'{'> > >(src); return sequence< spaces, negate< exactly<'{'> > >(src);
} }
// Match SCSS variable names. // Match SCSS variable names.
const char* variable(const char* src) { const char* variable(const char* src) {
return sequence<exactly<'$'>, name>(src); return sequence<exactly<'$'>, name>(src);
} }
// Match Sass boolean keywords. // Match Sass boolean keywords.
extern const char and_chars[] = "and"; extern const char and_chars[] = "and";
extern const char or_chars[] = "or"; extern const char or_chars[] = "or";
...@@ -357,7 +357,7 @@ namespace Sass { ...@@ -357,7 +357,7 @@ namespace Sass {
const char* lte_op(const char* src) { const char* lte_op(const char* src) {
return exactly<lte_chars>(src); return exactly<lte_chars>(src);
} }
// Path matching functions. // Path matching functions.
const char* folder(const char* src) { const char* folder(const char* src) {
return sequence< zero_plus< any_char_except<'/'> >, return sequence< zero_plus< any_char_except<'/'> >,
...@@ -367,4 +367,5 @@ namespace Sass { ...@@ -367,4 +367,5 @@ namespace Sass {
return zero_plus< folder >(src); return zero_plus< folder >(src);
} }
} }
} }
\ No newline at end of file
...@@ -11,7 +11,7 @@ namespace Sass { ...@@ -11,7 +11,7 @@ namespace Sass {
const char* exactly(const char* src) { const char* exactly(const char* src) {
return *src == pre ? src + 1 : 0; return *src == pre ? src + 1 : 0;
} }
// Match a string constant. // Match a string constant.
template <const char* prefix> template <const char* prefix>
const char* exactly(const char* src) { const char* exactly(const char* src) {
...@@ -49,7 +49,7 @@ namespace Sass { ...@@ -49,7 +49,7 @@ namespace Sass {
while (class_char<char_class>(p)) ++p; while (class_char<char_class>(p)) ++p;
return p == src ? 0 : p; return p == src ? 0 : p;
} }
// Match a sequence of characters up to the next newline. // Match a sequence of characters up to the next newline.
template <const char* prefix> template <const char* prefix>
const char* to_endl(const char* src) { const char* to_endl(const char* src) {
...@@ -57,7 +57,7 @@ namespace Sass { ...@@ -57,7 +57,7 @@ namespace Sass {
while (*src && *src != '\n') ++src; while (*src && *src != '\n') ++src;
return src; return src;
} }
// Match a sequence of characters delimited by the supplied chars. // Match a sequence of characters delimited by the supplied chars.
template <char beg, char end, bool esc> template <char beg, char end, bool esc>
const char* delimited_by(const char* src) { const char* delimited_by(const char* src) {
...@@ -71,7 +71,7 @@ namespace Sass { ...@@ -71,7 +71,7 @@ namespace Sass {
src = stop ? stop : src + 1; src = stop ? stop : src + 1;
} }
} }
// Match a sequence of characters delimited by the supplied strings. // Match a sequence of characters delimited by the supplied strings.
template <const char* beg, const char* end, bool esc> template <const char* beg, const char* end, bool esc>
const char* delimited_by(const char* src) { const char* delimited_by(const char* src) {
...@@ -85,7 +85,7 @@ namespace Sass { ...@@ -85,7 +85,7 @@ namespace Sass {
src = stop ? stop : src + 1; src = stop ? stop : src + 1;
} }
} }
// Match any single character. // Match any single character.
const char* any_char(const char* src); const char* any_char(const char* src);
// Match any single character except the supplied one. // Match any single character except the supplied one.
...@@ -93,19 +93,19 @@ namespace Sass { ...@@ -93,19 +93,19 @@ namespace Sass {
const char* any_char_except(const char* src) { const char* any_char_except(const char* src) {
return (*src && *src != c) ? src+1 : 0; return (*src && *src != c) ? src+1 : 0;
} }
// Matches zero characters (always succeeds without consuming input). // Matches zero characters (always succeeds without consuming input).
const char* epsilon(const char*); const char* epsilon(const char*);
// Matches the empty string. // Matches the empty string.
const char* empty(const char*); const char* empty(const char*);
// Succeeds of the supplied matcher fails, and vice versa. // Succeeds of the supplied matcher fails, and vice versa.
template <prelexer mx> template <prelexer mx>
const char* negate(const char* src) { const char* negate(const char* src) {
return mx(src) ? 0 : src; return mx(src) ? 0 : src;
} }
// Tries the matchers in sequence and returns the first match (or none) // Tries the matchers in sequence and returns the first match (or none)
template <prelexer mx1, prelexer mx2> template <prelexer mx1, prelexer mx2>
const char* alternatives(const char* src) { const char* alternatives(const char* src) {
...@@ -113,7 +113,7 @@ namespace Sass { ...@@ -113,7 +113,7 @@ namespace Sass {
(rslt = mx1(src)) || (rslt = mx2(src)); (rslt = mx1(src)) || (rslt = mx2(src));
return rslt; return rslt;
} }
// Same as above, but with 3 arguments. // Same as above, but with 3 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3> template <prelexer mx1, prelexer mx2, prelexer mx3>
const char* alternatives(const char* src) { const char* alternatives(const char* src) {
...@@ -121,7 +121,7 @@ namespace Sass { ...@@ -121,7 +121,7 @@ namespace Sass {
(rslt = mx1(src)) || (rslt = mx2(src)) || (rslt = mx3(src)); (rslt = mx1(src)) || (rslt = mx2(src)) || (rslt = mx3(src));
return rslt; return rslt;
} }
// Same as above, but with 4 arguments. // Same as above, but with 4 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4> template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4>
const char* alternatives(const char* src) { const char* alternatives(const char* src) {
...@@ -130,7 +130,7 @@ namespace Sass { ...@@ -130,7 +130,7 @@ namespace Sass {
(rslt = mx3(src)) || (rslt = mx4(src)); (rslt = mx3(src)) || (rslt = mx4(src));
return rslt; return rslt;
} }
// Same as above, but with 5 arguments. // Same as above, but with 5 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, template <prelexer mx1, prelexer mx2, prelexer mx3,
prelexer mx4, prelexer mx5> prelexer mx4, prelexer mx5>
...@@ -140,7 +140,7 @@ namespace Sass { ...@@ -140,7 +140,7 @@ namespace Sass {
(rslt = mx4(src)) || (rslt = mx5(src)); (rslt = mx4(src)) || (rslt = mx5(src));
return rslt; return rslt;
} }
// Same as above, but with 6 arguments. // Same as above, but with 6 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, template <prelexer mx1, prelexer mx2, prelexer mx3,
prelexer mx4, prelexer mx5, prelexer mx6> prelexer mx4, prelexer mx5, prelexer mx6>
...@@ -150,7 +150,7 @@ namespace Sass { ...@@ -150,7 +150,7 @@ namespace Sass {
(rslt = mx4(src)) || (rslt = mx5(src)) || (rslt = mx6(src)); (rslt = mx4(src)) || (rslt = mx5(src)) || (rslt = mx6(src));
return rslt; return rslt;
} }
// Same as above, but with 7 arguments. // Same as above, but with 7 arguments.
template <prelexer mx1, prelexer mx2, template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4, prelexer mx3, prelexer mx4,
...@@ -164,7 +164,7 @@ namespace Sass { ...@@ -164,7 +164,7 @@ namespace Sass {
(rslt = mx7(rslt)); (rslt = mx7(rslt));
return rslt; return rslt;
} }
// Same as above, but with 8 arguments. // Same as above, but with 8 arguments.
template <prelexer mx1, prelexer mx2, template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4, prelexer mx3, prelexer mx4,
...@@ -178,7 +178,7 @@ namespace Sass { ...@@ -178,7 +178,7 @@ namespace Sass {
(rslt = mx7(rslt)) || (rslt = mx8(rslt)); (rslt = mx7(rslt)) || (rslt = mx8(rslt));
return rslt; return rslt;
} }
// Tries the matchers in sequence and succeeds if they all succeed. // Tries the matchers in sequence and succeeds if they all succeed.
template <prelexer mx1, prelexer mx2> template <prelexer mx1, prelexer mx2>
const char* sequence(const char* src) { const char* sequence(const char* src) {
...@@ -186,7 +186,7 @@ namespace Sass { ...@@ -186,7 +186,7 @@ namespace Sass {
(rslt = mx1(rslt)) && (rslt = mx2(rslt)); (rslt = mx1(rslt)) && (rslt = mx2(rslt));
return rslt; return rslt;
} }
// Same as above, but with 3 arguments. // Same as above, but with 3 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3> template <prelexer mx1, prelexer mx2, prelexer mx3>
const char* sequence(const char* src) { const char* sequence(const char* src) {
...@@ -194,7 +194,7 @@ namespace Sass { ...@@ -194,7 +194,7 @@ namespace Sass {
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) && (rslt = mx3(rslt)); (rslt = mx1(rslt)) && (rslt = mx2(rslt)) && (rslt = mx3(rslt));
return rslt; return rslt;
} }
// Same as above, but with 4 arguments. // Same as above, but with 4 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4> template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4>
const char* sequence(const char* src) { const char* sequence(const char* src) {
...@@ -203,7 +203,7 @@ namespace Sass { ...@@ -203,7 +203,7 @@ namespace Sass {
(rslt = mx3(rslt)) && (rslt = mx4(rslt)); (rslt = mx3(rslt)) && (rslt = mx4(rslt));
return rslt; return rslt;
} }
// Same as above, but with 5 arguments. // Same as above, but with 5 arguments.
template <prelexer mx1, prelexer mx2, template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4, prelexer mx3, prelexer mx4,
...@@ -215,7 +215,7 @@ namespace Sass { ...@@ -215,7 +215,7 @@ namespace Sass {
(rslt = mx5(rslt)); (rslt = mx5(rslt));
return rslt; return rslt;
} }
// Same as above, but with 6 arguments. // Same as above, but with 6 arguments.
template <prelexer mx1, prelexer mx2, template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4, prelexer mx3, prelexer mx4,
...@@ -227,7 +227,7 @@ namespace Sass { ...@@ -227,7 +227,7 @@ namespace Sass {
(rslt = mx5(rslt)) && (rslt = mx6(rslt)); (rslt = mx5(rslt)) && (rslt = mx6(rslt));
return rslt; return rslt;
} }
// Same as above, but with 7 arguments. // Same as above, but with 7 arguments.
template <prelexer mx1, prelexer mx2, template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4, prelexer mx3, prelexer mx4,
...@@ -241,14 +241,14 @@ namespace Sass { ...@@ -241,14 +241,14 @@ namespace Sass {
(rslt = mx7(rslt)); (rslt = mx7(rslt));
return rslt; return rslt;
} }
// Match a pattern or not. Always succeeds. // Match a pattern or not. Always succeeds.
template <prelexer mx> template <prelexer mx>
const char* optional(const char* src) { const char* optional(const char* src) {
const char* p = mx(src); const char* p = mx(src);
return p ? p : src; return p ? p : src;
} }
// Match zero or more of the supplied pattern // Match zero or more of the supplied pattern
template <prelexer mx> template <prelexer mx>
const char* zero_plus(const char* src) { const char* zero_plus(const char* src) {
...@@ -256,7 +256,7 @@ namespace Sass { ...@@ -256,7 +256,7 @@ namespace Sass {
while (p) src = p, p = mx(src); while (p) src = p, p = mx(src);
return src; return src;
} }
// Match one or more of the supplied pattern // Match one or more of the supplied pattern
template <prelexer mx> template <prelexer mx>
const char* one_plus(const char* src) { const char* one_plus(const char* src) {
...@@ -265,7 +265,7 @@ namespace Sass { ...@@ -265,7 +265,7 @@ namespace Sass {
while (p) src = p, p = mx(src); while (p) src = p, p = mx(src);
return src; return src;
} }
// Match a single character satisfying the ctype predicates. // Match a single character satisfying the ctype predicates.
const char* space(const char* src); const char* space(const char* src);
const char* alpha(const char* src); const char* alpha(const char* src);
...@@ -280,7 +280,7 @@ namespace Sass { ...@@ -280,7 +280,7 @@ namespace Sass {
const char* xdigits(const char* src); const char* xdigits(const char* src);
const char* alnums(const char* src); const char* alnums(const char* src);
const char* puncts(const char* src); const char* puncts(const char* src);
// Match a line comment. // Match a line comment.
const char* line_comment(const char* src); const char* line_comment(const char* src);
// Match a block comment. // Match a block comment.
...@@ -368,10 +368,10 @@ namespace Sass { ...@@ -368,10 +368,10 @@ namespace Sass {
const char* precedes(const char* src); const char* precedes(const char* src);
const char* parent_of(const char* src); const char* parent_of(const char* src);
const char* ancestor_of(const char* src); const char* ancestor_of(const char* src);
// Match SCSS variable names. // Match SCSS variable names.
const char* variable(const char* src); const char* variable(const char* src);
// Match Sass boolean keywords. // Match Sass boolean keywords.
const char* true_kwd(const char* src); const char* true_kwd(const char* src);
const char* false_kwd(const char* src); const char* false_kwd(const char* src);
...@@ -384,11 +384,11 @@ namespace Sass { ...@@ -384,11 +384,11 @@ namespace Sass {
const char* gte_op(const char* src); const char* gte_op(const char* src);
const char* lt_op(const char* src); const char* lt_op(const char* src);
const char* lte_op(const char* src); const char* lte_op(const char* src);
// Path matching functions. // Path matching functions.
const char* folder(const char* src); const char* folder(const char* src);
const char* folders(const char* src); const char* folders(const char* src);
// Utility functions for finding and counting characters in a string. // Utility functions for finding and counting characters in a string.
template<char c> template<char c>
const char* find_first(const char* src) { const char* find_first(const char* src) {
...@@ -433,6 +433,7 @@ namespace Sass { ...@@ -433,6 +433,7 @@ namespace Sass {
} }
return counter; return counter;
} }
} }
} }
...@@ -14,9 +14,9 @@ extern "C" { ...@@ -14,9 +14,9 @@ extern "C" {
sass_context* sass_new_context() sass_context* sass_new_context()
{ return (sass_context*) calloc(1, sizeof(sass_context)); } { return (sass_context*) calloc(1, sizeof(sass_context)); }
void sass_free_context(sass_context* ctx) void sass_free_context(sass_context* ctx)
{ {
if (ctx->output_string) if (ctx->output_string)
free(ctx->output_string); free(ctx->output_string);
free(ctx); free(ctx);
...@@ -24,14 +24,14 @@ extern "C" { ...@@ -24,14 +24,14 @@ extern "C" {
sass_file_context* sass_new_file_context() sass_file_context* sass_new_file_context()
{ return (sass_file_context*) calloc(1, sizeof(sass_file_context)); } { return (sass_file_context*) calloc(1, sizeof(sass_file_context)); }
void sass_free_file_context(sass_file_context* ctx) void sass_free_file_context(sass_file_context* ctx)
{ {
if (ctx->output_string) if (ctx->output_string)
free(ctx->output_string); free(ctx->output_string);
free(ctx); free(ctx);
} }
sass_folder_context* sass_new_folder_context() sass_folder_context* sass_new_folder_context()
{ return (sass_folder_context*) calloc(1, sizeof(sass_folder_context)); } { return (sass_folder_context*) calloc(1, sizeof(sass_folder_context)); }
...@@ -86,7 +86,7 @@ extern "C" { ...@@ -86,7 +86,7 @@ extern "C" {
// TO DO: CATCH EVERYTHING ELSE // TO DO: CATCH EVERYTHING ELSE
return 0; return 0;
} }
int sass_compile_file(sass_file_context* c_ctx) int sass_compile_file(sass_file_context* c_ctx)
{ {
using namespace Sass; using namespace Sass;
...@@ -123,10 +123,11 @@ extern "C" { ...@@ -123,10 +123,11 @@ extern "C" {
// TO DO: CATCH EVERYTHING ELSE // TO DO: CATCH EVERYTHING ELSE
return 0; return 0;
} }
int sass_compile_folder(sass_folder_context* c_ctx) int sass_compile_folder(sass_folder_context* c_ctx)
{ {
return 1; return 1;
} }
} }
#include <node.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -18,6 +20,8 @@ struct sass_context { ...@@ -18,6 +20,8 @@ struct sass_context {
struct sass_options options; struct sass_options options;
int error_status; int error_status;
char* error_message; char* error_message;
uv_work_t request;
v8::Persistent<v8::Function> callback;
}; };
struct sass_file_context { struct sass_file_context {
...@@ -50,4 +54,5 @@ int sass_compile_folder (struct sass_folder_context* ctx); ...@@ -50,4 +54,5 @@ int sass_compile_folder (struct sass_folder_context* ctx);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
\ No newline at end of file
...@@ -14,36 +14,36 @@ int main() ...@@ -14,36 +14,36 @@ int main()
{ {
using namespace Sass; using namespace Sass;
using namespace std; using namespace std;
cout << sizeof(Node_Impl*) << endl; cout << sizeof(Node_Impl*) << endl;
cout << sizeof(Node) << endl; cout << sizeof(Node) << endl;
cout << sizeof(Node_Impl) << endl << endl; cout << sizeof(Node_Impl) << endl << endl;
Node_Factory new_Node = Node_Factory(); Node_Factory new_Node = Node_Factory();
Node interior(new_Node(Node::block, "", 0, 3)); Node interior(new_Node(Node::block, "", 0, 3));
cout << interior.size() << endl; cout << interior.size() << endl;
cout << interior.has_children() << endl; cout << interior.has_children() << endl;
cout << interior.should_eval() << endl << endl; cout << interior.should_eval() << endl << endl;
Node num(new_Node("", 0, 255, 123, 32)); Node num(new_Node("", 0, 255, 123, 32));
Node num2(new_Node("", 0, 255, 123, 32)); Node num2(new_Node("", 0, 255, 123, 32));
Node num3(new_Node("", 0, 255, 122, 20, .75)); Node num3(new_Node("", 0, 255, 122, 20, .75));
cout << num.size() << endl; cout << num.size() << endl;
cout << num.has_children() << endl; cout << num.has_children() << endl;
cout << num.has_statements() << endl << endl; cout << num.has_statements() << endl << endl;
cout << num[1].is_numeric() << endl; cout << num[1].is_numeric() << endl;
cout << num[1].numeric_value() << endl << endl; cout << num[1].numeric_value() << endl << endl;
cout << (num == num2) << endl; cout << (num == num2) << endl;
cout << (num == num3) << endl << endl; cout << (num == num3) << endl << endl;
cout << (num3[2] < num2[2]) << endl; cout << (num3[2] < num2[2]) << endl;
cout << (num2[3] < num3[3]) << endl << endl; cout << (num2[3] < num3[3]) << endl << endl;
cout << (num2[2] >= num3[2]) << endl; cout << (num2[2] >= num3[2]) << endl;
cout << (num2[3] != num3[3]) << endl << endl; cout << (num2[3] != num3[3]) << endl << endl;
...@@ -92,4 +92,5 @@ int main() ...@@ -92,4 +92,5 @@ int main()
new_Node.free(); new_Node.free();
return 0; return 0;
} }
\ No newline at end of file
var binding = require('./build/Release/binding') var binding = require('./build/Release/binding')
var render = function(str, cb){ exports.render = binding.render
cb(binding.render(str)) exports.middleware = require('./lib/middleware');
}
exports.render = render
exports.middleware = require('./lib/middleware');
\ No newline at end of file
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