Commit 9d10d034 by Aaron Leung

Bam, all allocations are deallocated.

parent 104d269a
......@@ -42,6 +42,7 @@ namespace Sass {
: global_env(Environment()),
function_env(map<pair<string, size_t>, Function>()),
source_refs(vector<char*>()),
registry(vector<vector<Node>*>()),
include_paths(vector<string>()),
ref_count(0)
{
......@@ -51,9 +52,11 @@ namespace Sass {
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];
}
cerr << "Deallocated " << i << " source string(s)." << endl;
}
inline void Context::register_function(Function_Descriptor d, Implementation ip)
......
......@@ -45,6 +45,7 @@ namespace Sass {
Environment global_env;
map<pair<string, size_t>, Function> function_env;
vector<char*> source_refs; // all the source c-strings
vector<vector<Node>*> registry; // all the child vectors
size_t ref_count;
void collect_include_paths(const char* paths_str);
......
......@@ -12,7 +12,7 @@ namespace Sass {
source(source_str),
line_number(1),
context(ctx),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
if (source_str) {
......@@ -49,7 +49,7 @@ namespace Sass {
: path(path), source(source),
line_number(1), own_source(false),
context(*(new Context())),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
if (!source) {
......@@ -78,7 +78,7 @@ namespace Sass {
: path(path), source(0),
line_number(1), own_source(false),
context(context),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
std::FILE *f;
......@@ -108,7 +108,7 @@ namespace Sass {
line_number(line_number),
own_source(false),
context(context),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{ }
......
......@@ -26,7 +26,7 @@ namespace Sass {
root[0].has_expansions = true;
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();
if (!lex< exactly<';'> >()) syntax_error("top-level variable binding must be terminated by ';'");
}
......@@ -64,14 +64,14 @@ namespace Sass {
Node params(parse_mixin_parameters());
if (!peek< exactly<'{'> >()) syntax_error("body for mixin " + name.content.token.to_string() + " must begin with a '{'");
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;
return mixin;
}
Node Document::parse_mixin_parameters()
{
Node params(Node::parameters, line_number);
Node params(Node::parameters, context.registry, line_number);
Token name(lexed);
if (lex< exactly<'('> >()) {
if (peek< variable >()) {
......@@ -92,7 +92,7 @@ namespace Sass {
Node var(Node::variable, line_number, lexed);
if (lex< exactly<':'> >()) { // default value
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;
return par_and_val;
}
......@@ -107,7 +107,7 @@ namespace Sass {
if (!lex< identifier >()) syntax_error("invalid name in @include directive");
Node name(Node::identifier, line_number, lexed);
Node args(parse_arguments());
Node call(Node::expansion, line_number, 3);
Node call(Node::expansion, context.registry, line_number, 3);
call << name << args;
return call;
}
......@@ -115,7 +115,7 @@ namespace Sass {
Node Document::parse_arguments()
{
Token name(lexed);
Node args(Node::arguments, line_number);
Node args(Node::arguments, context.registry, line_number);
if (lex< exactly<'('> >()) {
if (!peek< exactly<')'> >(position)) {
args << parse_argument();
......@@ -137,7 +137,7 @@ namespace Sass {
Node var(Node::variable, line_number, lexed);
lex< exactly<':'> >();
Node val(parse_space_list());
Node assn(Node::assignment, line_number, 2);
Node assn(Node::assignment, context.registry, line_number, 2);
assn << var << val;
return assn;
}
......@@ -152,14 +152,14 @@ namespace Sass {
Node var(Node::variable, line_number, lexed);
if (!lex< exactly<':'> >()) syntax_error("expected ':' after " + lexed.to_string() + " in assignment statement");
Node val(parse_list());
Node assn(Node::assignment, line_number, 2);
Node assn(Node::assignment, context.registry, line_number, 2);
assn << var << val;
return assn;
}
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();
// 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;
......@@ -178,7 +178,7 @@ namespace Sass {
Node sel1(parse_selector());
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;
while (lex< exactly<','> >()) group << parse_selector();
return group;
......@@ -212,7 +212,7 @@ namespace Sass {
peek< exactly<')'> >() ||
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;
selector << seq1;
......@@ -255,7 +255,7 @@ namespace Sass {
{ return simp1; }
// 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.has_backref = saw_backref;
......@@ -323,14 +323,14 @@ namespace Sass {
Node Document::parse_pseudo() {
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 << parse_selector_group();
lex< exactly<')'> >();
return ps_not;
}
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);
pseudo << Node(Node::value, line_number, name);
if (lex< alternatives< even, odd > >()) {
......@@ -370,7 +370,7 @@ namespace Sass {
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<'['> >();
if (!lex< type_selector >()) syntax_error("invalid attribute name in attribute selector");
Token name(lexed);
......@@ -390,7 +390,7 @@ namespace Sass {
{
lex< exactly<'{'> >();
bool semicolon = false;
Node block(Node::block, line_number, 1);
Node block(Node::block, context.registry, line_number, 1);
block << Node(Node::flags);
while (!lex< exactly<'}'> >()) {
if (semicolon) {
......@@ -463,7 +463,7 @@ namespace Sass {
}
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");
rule << Node(Node::property, line_number, lexed);
if (!lex< exactly<':'> >()) syntax_error("property \"" + lexed.to_string() + "\" must be followed by a ':'");
......@@ -482,12 +482,12 @@ namespace Sass {
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());
// if it's a singleton, return it directly; don't wrap it
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.eval_me |= list1.eval_me;
......@@ -512,7 +512,7 @@ namespace Sass {
peek< exactly<','> >(position))
{ 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.eval_me |= disj1.eval_me;
......@@ -536,7 +536,7 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it
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;
while (lex< sequence< or_kwd, negate< identifier > > >()) disjunction << parse_conjunction();
disjunction.eval_me = true;
......@@ -550,7 +550,7 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it
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;
while (lex< sequence< and_kwd, negate< identifier > > >()) conjunction << parse_relation();
conjunction.eval_me = true;
......@@ -569,7 +569,7 @@ namespace Sass {
peek< lte_op >(position)))
{ return expr1; }
Node relation(Node::relation, line_number, 3);
Node relation(Node::relation, context.registry, line_number, 3);
expr1.eval_me = true;
relation << expr1;
......@@ -596,7 +596,7 @@ namespace Sass {
peek< sequence< negate< number >, exactly<'-'> > >(position)))
{ return term1; }
Node expression(Node::expression, line_number, 3);
Node expression(Node::expression, context.registry, line_number, 3);
term1.eval_me = true;
expression << term1;
......@@ -624,7 +624,7 @@ namespace Sass {
peek< exactly<'/'> >(position)))
{ return fact1; }
Node term(Node::term, line_number, 3);
Node term(Node::term, context.registry, line_number, 3);
term << fact1;
if (fact1.eval_me) term.eval_me = true;
......@@ -725,7 +725,7 @@ namespace Sass {
lex< identifier >();
Node name(Node::identifier, line_number, lexed);
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.eval_me = true;
return call;
......
......@@ -11,10 +11,10 @@
namespace Sass {
using std::map;
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node accumulate(Node::Type op, Node& acc, Node& rhs);
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, vector<vector<Node>*>& registry);
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_function(const Function& f, 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, vector<vector<Node>*>& registry);
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
namespace Sass {
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 str Function_Descriptor[];
......@@ -37,8 +37,8 @@ namespace Sass {
}
}
Node operator()(map<Token, Node>& bindings) const
{ return implementation(parameters, bindings); }
Node operator()(map<Token, Node>& bindings, vector<vector<Node>*>& registry) const
{ return implementation(parameters, bindings, registry); }
};
......@@ -47,111 +47,111 @@ namespace Sass {
// RGB Functions ///////////////////////////////////////////////////////
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;
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;
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;
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;
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;
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;
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;
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 ///////////////////////////////////////////////////////
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;
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;
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 ///////////////////////////////////////////////////
extern Function_Descriptor alpha_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 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 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 ////////////////////////////////////////////////////
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;
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 ////////////////////////////////////////////////////
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;
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;
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;
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;
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 //////////////////////////////////////////////////////
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;
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;
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;
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 /////////////////////////////////////////////
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;
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;
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;
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 ///////////////////////////////////////////////////
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 {
++allocations;
n.content.children->reserve(size());
for (int i = 0; i < size(); ++i) {
n << at(i).clone();
n << at(i).clone(registry);
}
registry.push_back(n.content.children);
}
......
......@@ -190,7 +190,7 @@ namespace Sass {
void emit_nested_css(stringstream& buf, size_t depth);
void emit_expanded_css(stringstream& buf, const string& prefix);
Node clone() const;
Node clone(vector<vector<Node>*>& registry) const;
void flatten();
Node()
......
......@@ -37,10 +37,21 @@ extern "C" {
static char* process_document(Sass::Document& doc, int style)
{
using namespace Sass;
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)));
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);
strcpy(c_output, output.c_str());
......@@ -87,6 +98,8 @@ extern "C" {
try {
Context cpp_ctx(c_ctx->options.include_paths);
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->error_message = 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