Commit 9d10d034 by Aaron Leung

Bam, all allocations are deallocated.

parent 104d269a
...@@ -42,6 +42,7 @@ namespace Sass { ...@@ -42,6 +42,7 @@ namespace Sass {
: global_env(Environment()), : global_env(Environment()),
function_env(map<pair<string, size_t>, Function>()), function_env(map<pair<string, size_t>, Function>()),
source_refs(vector<char*>()), source_refs(vector<char*>()),
registry(vector<vector<Node>*>()),
include_paths(vector<string>()), include_paths(vector<string>()),
ref_count(0) ref_count(0)
{ {
...@@ -51,9 +52,11 @@ namespace Sass { ...@@ -51,9 +52,11 @@ namespace Sass {
Context::~Context() Context::~Context()
{ {
for (int i = 0; i < source_refs.size(); ++i) { int i;
for (i = 0; i < source_refs.size(); ++i) {
delete[] source_refs[i]; delete[] source_refs[i];
} }
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)
......
...@@ -45,6 +45,7 @@ namespace Sass { ...@@ -45,6 +45,7 @@ namespace Sass {
Environment global_env; Environment global_env;
map<pair<string, size_t>, Function> function_env; map<pair<string, size_t>, Function> function_env;
vector<char*> source_refs; // all the source c-strings vector<char*> source_refs; // all the source c-strings
vector<vector<Node>*> registry; // all the child vectors
size_t ref_count; size_t ref_count;
void collect_include_paths(const char* paths_str); void collect_include_paths(const char* paths_str);
......
...@@ -12,7 +12,7 @@ namespace Sass { ...@@ -12,7 +12,7 @@ namespace Sass {
source(source_str), source(source_str),
line_number(1), line_number(1),
context(ctx), context(ctx),
root(Node(Node::root, 1)), root(Node(Node::root, context.registry, 1)),
lexed(Token::make()) lexed(Token::make())
{ {
if (source_str) { if (source_str) {
...@@ -49,7 +49,7 @@ namespace Sass { ...@@ -49,7 +49,7 @@ namespace Sass {
: path(path), source(source), : path(path), source(source),
line_number(1), own_source(false), line_number(1), own_source(false),
context(*(new Context())), context(*(new Context())),
root(Node(Node::root, 1)), root(Node(Node::root, context.registry, 1)),
lexed(Token::make()) lexed(Token::make())
{ {
if (!source) { if (!source) {
...@@ -78,7 +78,7 @@ namespace Sass { ...@@ -78,7 +78,7 @@ namespace Sass {
: path(path), source(0), : path(path), source(0),
line_number(1), own_source(false), line_number(1), own_source(false),
context(context), context(context),
root(Node(Node::root, 1)), root(Node(Node::root, context.registry, 1)),
lexed(Token::make()) lexed(Token::make())
{ {
std::FILE *f; std::FILE *f;
...@@ -108,7 +108,7 @@ namespace Sass { ...@@ -108,7 +108,7 @@ namespace Sass {
line_number(line_number), line_number(line_number),
own_source(false), own_source(false),
context(context), context(context),
root(Node(Node::root, 1)), root(Node(Node::root, context.registry, 1)),
lexed(Token::make()) lexed(Token::make())
{ } { }
......
...@@ -26,7 +26,7 @@ namespace Sass { ...@@ -26,7 +26,7 @@ namespace Sass {
root[0].has_expansions = true; root[0].has_expansions = true;
if (!lex< exactly<';'> >()) syntax_error("top-level @include directive must be terminated by ';'"); if (!lex< exactly<';'> >()) syntax_error("top-level @include directive must be terminated by ';'");
} }
else if (peek< variable >(position)) { else if (peek< variable >(position)) {
root << parse_assignment(); root << parse_assignment();
if (!lex< exactly<';'> >()) syntax_error("top-level variable binding must be terminated by ';'"); if (!lex< exactly<';'> >()) syntax_error("top-level variable binding must be terminated by ';'");
} }
...@@ -64,14 +64,14 @@ namespace Sass { ...@@ -64,14 +64,14 @@ namespace Sass {
Node params(parse_mixin_parameters()); Node params(parse_mixin_parameters());
if (!peek< exactly<'{'> >()) syntax_error("body for mixin " + name.content.token.to_string() + " must begin with a '{'"); if (!peek< exactly<'{'> >()) syntax_error("body for mixin " + name.content.token.to_string() + " must begin with a '{'");
Node body(parse_block(true)); Node body(parse_block(true));
Node mixin(Node::mixin, line_number, 3); Node mixin(Node::mixin, context.registry, line_number, 3);
mixin << name << params << body; mixin << name << params << body;
return mixin; return mixin;
} }
Node Document::parse_mixin_parameters() Node Document::parse_mixin_parameters()
{ {
Node params(Node::parameters, line_number); Node params(Node::parameters, context.registry, line_number);
Token name(lexed); Token name(lexed);
if (lex< exactly<'('> >()) { if (lex< exactly<'('> >()) {
if (peek< variable >()) { if (peek< variable >()) {
...@@ -92,7 +92,7 @@ namespace Sass { ...@@ -92,7 +92,7 @@ namespace Sass {
Node var(Node::variable, line_number, lexed); Node var(Node::variable, line_number, lexed);
if (lex< exactly<':'> >()) { // default value if (lex< exactly<':'> >()) { // default value
Node val(parse_space_list()); Node val(parse_space_list());
Node par_and_val(Node::assignment, line_number, 2); Node par_and_val(Node::assignment, context.registry, line_number, 2);
par_and_val << var << val; par_and_val << var << val;
return par_and_val; return par_and_val;
} }
...@@ -107,7 +107,7 @@ namespace Sass { ...@@ -107,7 +107,7 @@ namespace Sass {
if (!lex< identifier >()) syntax_error("invalid name in @include directive"); if (!lex< identifier >()) syntax_error("invalid name in @include directive");
Node name(Node::identifier, line_number, lexed); Node name(Node::identifier, line_number, lexed);
Node args(parse_arguments()); Node args(parse_arguments());
Node call(Node::expansion, line_number, 3); Node call(Node::expansion, context.registry, line_number, 3);
call << name << args; call << name << args;
return call; return call;
} }
...@@ -115,7 +115,7 @@ namespace Sass { ...@@ -115,7 +115,7 @@ namespace Sass {
Node Document::parse_arguments() Node Document::parse_arguments()
{ {
Token name(lexed); Token name(lexed);
Node args(Node::arguments, line_number); Node args(Node::arguments, context.registry, line_number);
if (lex< exactly<'('> >()) { if (lex< exactly<'('> >()) {
if (!peek< exactly<')'> >(position)) { if (!peek< exactly<')'> >(position)) {
args << parse_argument(); args << parse_argument();
...@@ -137,7 +137,7 @@ namespace Sass { ...@@ -137,7 +137,7 @@ namespace Sass {
Node var(Node::variable, line_number, lexed); Node var(Node::variable, line_number, lexed);
lex< exactly<':'> >(); lex< exactly<':'> >();
Node val(parse_space_list()); Node val(parse_space_list());
Node assn(Node::assignment, line_number, 2); Node assn(Node::assignment, context.registry, line_number, 2);
assn << var << val; assn << var << val;
return assn; return assn;
} }
...@@ -152,14 +152,14 @@ namespace Sass { ...@@ -152,14 +152,14 @@ namespace Sass {
Node var(Node::variable, line_number, lexed); Node var(Node::variable, line_number, lexed);
if (!lex< exactly<':'> >()) syntax_error("expected ':' after " + lexed.to_string() + " in assignment statement"); if (!lex< exactly<':'> >()) syntax_error("expected ':' after " + lexed.to_string() + " in assignment statement");
Node val(parse_list()); Node val(parse_list());
Node assn(Node::assignment, line_number, 2); Node assn(Node::assignment, context.registry, line_number, 2);
assn << var << val; assn << var << val;
return assn; return assn;
} }
Node Document::parse_ruleset(bool definition) Node Document::parse_ruleset(bool definition)
{ {
Node ruleset(Node::ruleset, line_number, 2); Node ruleset(Node::ruleset, context.registry, line_number, 2);
ruleset << parse_selector_group(); ruleset << parse_selector_group();
// if (ruleset[0].type == Node::selector) cerr << "ruleset starts with selector" << endl; // if (ruleset[0].type == Node::selector) cerr << "ruleset starts with selector" << endl;
// if (ruleset[0].type == Node::selector_group) cerr << "ruleset starts with selector_group" << endl; // if (ruleset[0].type == Node::selector_group) cerr << "ruleset starts with selector_group" << endl;
...@@ -178,7 +178,7 @@ namespace Sass { ...@@ -178,7 +178,7 @@ namespace Sass {
Node sel1(parse_selector()); Node sel1(parse_selector());
if (!peek< exactly<','> >()) return sel1; if (!peek< exactly<','> >()) return sel1;
Node group(Node::selector_group, line_number, 2); Node group(Node::selector_group, context.registry, line_number, 2);
group << sel1; group << sel1;
while (lex< exactly<','> >()) group << parse_selector(); while (lex< exactly<','> >()) group << parse_selector();
return group; return group;
...@@ -212,7 +212,7 @@ namespace Sass { ...@@ -212,7 +212,7 @@ namespace Sass {
peek< exactly<')'> >() || peek< exactly<')'> >() ||
peek< exactly<'{'> >()) return seq1; peek< exactly<'{'> >()) return seq1;
Node selector(Node::selector, line_number, 2); Node selector(Node::selector, context.registry, line_number, 2);
if (seq1.has_backref) selector.has_backref = true; if (seq1.has_backref) selector.has_backref = true;
selector << seq1; selector << seq1;
...@@ -255,7 +255,7 @@ namespace Sass { ...@@ -255,7 +255,7 @@ namespace Sass {
{ return simp1; } { return simp1; }
// now we know we have a sequence of simple selectors // now we know we have a sequence of simple selectors
Node seq(Node::simple_selector_sequence, line_number, 2); Node seq(Node::simple_selector_sequence, context.registry, line_number, 2);
seq << simp1; seq << simp1;
seq.has_backref = saw_backref; seq.has_backref = saw_backref;
...@@ -323,14 +323,14 @@ namespace Sass { ...@@ -323,14 +323,14 @@ namespace Sass {
Node Document::parse_pseudo() { Node Document::parse_pseudo() {
if (lex< pseudo_not >()) { if (lex< pseudo_not >()) {
Node ps_not(Node::pseudo_negation, line_number, 2); Node ps_not(Node::pseudo_negation, context.registry, line_number, 2);
ps_not << Node(Node::value, line_number, lexed); ps_not << Node(Node::value, line_number, lexed);
ps_not << parse_selector_group(); ps_not << parse_selector_group();
lex< exactly<')'> >(); lex< exactly<')'> >();
return ps_not; return ps_not;
} }
else if (lex< sequence< pseudo_prefix, functional > >()) { else if (lex< sequence< pseudo_prefix, functional > >()) {
Node pseudo(Node::functional_pseudo, line_number, 2); Node pseudo(Node::functional_pseudo, context.registry, line_number, 2);
Token name(lexed); Token name(lexed);
pseudo << Node(Node::value, line_number, name); pseudo << Node(Node::value, line_number, name);
if (lex< alternatives< even, odd > >()) { if (lex< alternatives< even, odd > >()) {
...@@ -370,7 +370,7 @@ namespace Sass { ...@@ -370,7 +370,7 @@ namespace Sass {
Node Document::parse_attribute_selector() Node Document::parse_attribute_selector()
{ {
Node attr_sel(Node::attribute_selector, line_number, 3); Node attr_sel(Node::attribute_selector, context.registry, line_number, 3);
lex< exactly<'['> >(); lex< exactly<'['> >();
if (!lex< type_selector >()) syntax_error("invalid attribute name in attribute selector"); if (!lex< type_selector >()) syntax_error("invalid attribute name in attribute selector");
Token name(lexed); Token name(lexed);
...@@ -390,7 +390,7 @@ namespace Sass { ...@@ -390,7 +390,7 @@ namespace Sass {
{ {
lex< exactly<'{'> >(); lex< exactly<'{'> >();
bool semicolon = false; bool semicolon = false;
Node block(Node::block, line_number, 1); Node block(Node::block, context.registry, line_number, 1);
block << Node(Node::flags); block << Node(Node::flags);
while (!lex< exactly<'}'> >()) { while (!lex< exactly<'}'> >()) {
if (semicolon) { if (semicolon) {
...@@ -463,7 +463,7 @@ namespace Sass { ...@@ -463,7 +463,7 @@ namespace Sass {
} }
Node Document::parse_rule() { Node Document::parse_rule() {
Node rule(Node::rule, line_number, 2); Node rule(Node::rule, context.registry, line_number, 2);
if (!lex< identifier >()) syntax_error("invalid property name"); if (!lex< identifier >()) syntax_error("invalid property name");
rule << Node(Node::property, line_number, lexed); rule << Node(Node::property, line_number, lexed);
if (!lex< exactly<':'> >()) syntax_error("property \"" + lexed.to_string() + "\" must be followed by a ':'"); if (!lex< exactly<':'> >()) syntax_error("property \"" + lexed.to_string() + "\" must be followed by a ':'");
...@@ -482,12 +482,12 @@ namespace Sass { ...@@ -482,12 +482,12 @@ namespace Sass {
peek< exactly<'}'> >(position) || peek< exactly<'}'> >(position) ||
peek< exactly<'{'> >(position) || peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position)) peek< exactly<')'> >(position))
{ return Node(Node::nil, line_number); } { return Node(Node::nil, context.registry, line_number); }
Node list1(parse_space_list()); Node list1(parse_space_list());
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (!peek< exactly<','> >(position)) return list1; if (!peek< exactly<','> >(position)) return list1;
Node comma_list(Node::comma_list, line_number, 2); Node comma_list(Node::comma_list, context.registry, line_number, 2);
comma_list << list1; comma_list << list1;
comma_list.eval_me |= list1.eval_me; comma_list.eval_me |= list1.eval_me;
...@@ -512,7 +512,7 @@ namespace Sass { ...@@ -512,7 +512,7 @@ namespace Sass {
peek< exactly<','> >(position)) peek< exactly<','> >(position))
{ return disj1; } { return disj1; }
Node space_list(Node::space_list, line_number, 2); Node space_list(Node::space_list, context.registry, line_number, 2);
space_list << disj1; space_list << disj1;
space_list.eval_me |= disj1.eval_me; space_list.eval_me |= disj1.eval_me;
...@@ -536,7 +536,7 @@ namespace Sass { ...@@ -536,7 +536,7 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< or_kwd, negate< identifier > > >()) return conj1; if (!peek< sequence< or_kwd, negate< identifier > > >()) return conj1;
Node disjunction(Node::disjunction, line_number, 2); Node disjunction(Node::disjunction, context.registry, line_number, 2);
disjunction << conj1; disjunction << conj1;
while (lex< sequence< or_kwd, negate< identifier > > >()) disjunction << parse_conjunction(); while (lex< sequence< or_kwd, negate< identifier > > >()) disjunction << parse_conjunction();
disjunction.eval_me = true; disjunction.eval_me = true;
...@@ -550,7 +550,7 @@ namespace Sass { ...@@ -550,7 +550,7 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< and_kwd, negate< identifier > > >()) return rel1; if (!peek< sequence< and_kwd, negate< identifier > > >()) return rel1;
Node conjunction(Node::conjunction, line_number, 2); Node conjunction(Node::conjunction, context.registry, line_number, 2);
conjunction << rel1; conjunction << rel1;
while (lex< sequence< and_kwd, negate< identifier > > >()) conjunction << parse_relation(); while (lex< sequence< and_kwd, negate< identifier > > >()) conjunction << parse_relation();
conjunction.eval_me = true; conjunction.eval_me = true;
...@@ -569,7 +569,7 @@ namespace Sass { ...@@ -569,7 +569,7 @@ namespace Sass {
peek< lte_op >(position))) peek< lte_op >(position)))
{ return expr1; } { return expr1; }
Node relation(Node::relation, line_number, 3); Node relation(Node::relation, context.registry, line_number, 3);
expr1.eval_me = true; expr1.eval_me = true;
relation << expr1; relation << expr1;
...@@ -596,7 +596,7 @@ namespace Sass { ...@@ -596,7 +596,7 @@ namespace Sass {
peek< sequence< negate< number >, exactly<'-'> > >(position))) peek< sequence< negate< number >, exactly<'-'> > >(position)))
{ return term1; } { return term1; }
Node expression(Node::expression, line_number, 3); Node expression(Node::expression, context.registry, line_number, 3);
term1.eval_me = true; term1.eval_me = true;
expression << term1; expression << term1;
...@@ -624,7 +624,7 @@ namespace Sass { ...@@ -624,7 +624,7 @@ namespace Sass {
peek< exactly<'/'> >(position))) peek< exactly<'/'> >(position)))
{ return fact1; } { return fact1; }
Node term(Node::term, line_number, 3); Node term(Node::term, context.registry, line_number, 3);
term << fact1; term << fact1;
if (fact1.eval_me) term.eval_me = true; if (fact1.eval_me) term.eval_me = true;
...@@ -725,7 +725,7 @@ namespace Sass { ...@@ -725,7 +725,7 @@ namespace Sass {
lex< identifier >(); lex< identifier >();
Node name(Node::identifier, line_number, lexed); Node name(Node::identifier, line_number, lexed);
Node args(parse_arguments()); Node args(parse_arguments());
Node call(Node::function_call, line_number, 2); Node call(Node::function_call, context.registry, line_number, 2);
call << name << args; call << name << args;
call.eval_me = true; call.eval_me = true;
return call; return call;
......
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
namespace Sass { namespace Sass {
using std::map; using std::map;
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env); Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
Node accumulate(Node::Type op, Node& acc, Node& rhs); Node accumulate(Node::Type op, Node& acc, Node& rhs, vector<vector<Node>*>& registry);
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, Environment& env, map<pair<string, size_t>, Function>& f_env); Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env); Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
} }
\ No newline at end of file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace Sass { namespace Sass {
using std::map; using std::map;
typedef Node (*Implementation)(const vector<Token>&, map<Token, Node>&); typedef Node (*Implementation)(const vector<Token>&, map<Token, Node>&, vector<vector<Node>*>& registry);
typedef const char* str; typedef const char* str;
typedef str Function_Descriptor[]; typedef str Function_Descriptor[];
...@@ -37,8 +37,8 @@ namespace Sass { ...@@ -37,8 +37,8 @@ namespace Sass {
} }
} }
Node operator()(map<Token, Node>& bindings) const Node operator()(map<Token, Node>& bindings, vector<vector<Node>*>& registry) const
{ return implementation(parameters, bindings); } { return implementation(parameters, bindings, registry); }
}; };
...@@ -47,111 +47,111 @@ namespace Sass { ...@@ -47,111 +47,111 @@ namespace Sass {
// RGB Functions /////////////////////////////////////////////////////// // RGB Functions ///////////////////////////////////////////////////////
extern Function_Descriptor rgb_descriptor; extern Function_Descriptor rgb_descriptor;
Node rgb(const vector<Token>& parameters, map<Token, Node>& bindings); Node rgb(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor rgba_4_descriptor; extern Function_Descriptor rgba_4_descriptor;
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings); Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor rgba_2_descriptor; extern Function_Descriptor rgba_2_descriptor;
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings); Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor red_descriptor; extern Function_Descriptor red_descriptor;
Node red(const vector<Token>& parameters, map<Token, Node>& bindings); Node red(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor green_descriptor; extern Function_Descriptor green_descriptor;
Node green(const vector<Token>& parameters, map<Token, Node>& bindings); Node green(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor blue_descriptor; extern Function_Descriptor blue_descriptor;
Node blue(const vector<Token>& parameters, map<Token, Node>& bindings); Node blue(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor mix_2_descriptor; extern Function_Descriptor mix_2_descriptor;
Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings); Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor mix_3_descriptor; extern Function_Descriptor mix_3_descriptor;
Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings); Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 hsla(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor hsl_descriptor; extern Function_Descriptor hsl_descriptor;
Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings); Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor invert_descriptor; extern Function_Descriptor invert_descriptor;
Node invert(const vector<Token>& parameters, map<Token, Node>& bindings); Node invert(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 alpha(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
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 opacify(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
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 transparentize(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 unquote(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor quote_descriptor; extern Function_Descriptor quote_descriptor;
Node quote(const vector<Token>& parameters, map<Token, Node>& bindings); Node quote(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// Number Functions //////////////////////////////////////////////////// // Number Functions ////////////////////////////////////////////////////
extern Function_Descriptor percentage_descriptor; extern Function_Descriptor percentage_descriptor;
Node percentage(const vector<Token>& parameters, map<Token, Node>& bindings); Node percentage(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor round_descriptor; extern Function_Descriptor round_descriptor;
Node round(const vector<Token>& parameters, map<Token, Node>& bindings); Node round(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor ceil_descriptor; extern Function_Descriptor ceil_descriptor;
Node ceil(const vector<Token>& parameters, map<Token, Node>& bindings); Node ceil(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor floor_descriptor; extern Function_Descriptor floor_descriptor;
Node floor(const vector<Token>& parameters, map<Token, Node>& bindings); Node floor(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor abs_descriptor; extern Function_Descriptor abs_descriptor;
Node abs(const vector<Token>& parameters, map<Token, Node>& bindings); Node abs(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 length(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor nth_descriptor; extern Function_Descriptor nth_descriptor;
Node nth(const vector<Token>& parameters, map<Token, Node>& bindings); Node nth(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor join_2_descriptor; extern Function_Descriptor join_2_descriptor;
Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings); Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor join_3_descriptor; extern Function_Descriptor join_3_descriptor;
Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings); Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 type_of(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor unit_descriptor; extern Function_Descriptor unit_descriptor;
Node unit(const vector<Token>& parameters, map<Token, Node>& bindings); Node unit(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor unitless_descriptor; extern Function_Descriptor unitless_descriptor;
Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings); Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor comparable_descriptor; extern Function_Descriptor comparable_descriptor;
Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings); Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// 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 not_impl(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
} }
......
...@@ -23,7 +23,7 @@ namespace Sass { ...@@ -23,7 +23,7 @@ namespace Sass {
++allocations; ++allocations;
n.content.children->reserve(size()); n.content.children->reserve(size());
for (int i = 0; i < size(); ++i) { for (int i = 0; i < size(); ++i) {
n << at(i).clone(); n << at(i).clone(registry);
} }
registry.push_back(n.content.children); registry.push_back(n.content.children);
} }
......
...@@ -190,7 +190,7 @@ namespace Sass { ...@@ -190,7 +190,7 @@ namespace Sass {
void emit_nested_css(stringstream& buf, size_t depth); void emit_nested_css(stringstream& buf, size_t depth);
void emit_expanded_css(stringstream& buf, const string& prefix); void emit_expanded_css(stringstream& buf, const string& prefix);
Node clone() const; Node clone(vector<vector<Node>*>& registry) const;
void flatten(); void flatten();
Node() Node()
......
...@@ -37,10 +37,21 @@ extern "C" { ...@@ -37,10 +37,21 @@ extern "C" {
static char* process_document(Sass::Document& doc, int style) static char* process_document(Sass::Document& doc, int style)
{ {
using namespace Sass; using namespace Sass;
doc.parse_scss(); doc.parse_scss();
eval(doc.root, doc.context.global_env, doc.context.function_env); cerr << "PARSED" << endl;
eval(doc.root, doc.context.global_env, doc.context.function_env, doc.context.registry);
cerr << "EVALUATED" << endl;
string output(doc.emit_css(static_cast<Document::CSS_Style>(style))); string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
cerr << "EMITTED" << endl;
cerr << "Allocations:\t" << Node::allocations << endl;
cerr << "Registry size:\t" << doc.context.registry.size() << endl;
int i;
for (i = 0; i < doc.context.registry.size(); ++i) {
delete doc.context.registry[i];
}
cerr << "Deallocations:\t" << i << endl;
char* c_output = (char*) malloc(output.size() + 1); char* c_output = (char*) malloc(output.size() + 1);
strcpy(c_output, output.c_str()); strcpy(c_output, output.c_str());
...@@ -87,6 +98,8 @@ extern "C" { ...@@ -87,6 +98,8 @@ extern "C" {
try { try {
Context cpp_ctx(c_ctx->options.include_paths); Context cpp_ctx(c_ctx->options.include_paths);
Document doc(c_ctx->input_path, 0, cpp_ctx); Document doc(c_ctx->input_path, 0, cpp_ctx);
cerr << "MADE A DOC AND CONTEXT OBJ" << endl;
cerr << "REGISTRY: " << doc.context.registry.size() << endl;
c_ctx->output_string = process_document(doc, c_ctx->options.output_style); c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
c_ctx->error_message = 0; c_ctx->error_message = 0;
c_ctx->error_status = 0; c_ctx->error_status = 0;
......
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