Commit 0a324343 by Aaron Leung

Sharing vectors instead of copying them. This program now leaks memory, BTW.

parent 0e72aa2c
...@@ -25,7 +25,7 @@ namespace Sass { ...@@ -25,7 +25,7 @@ namespace Sass {
try_munching<exactly<':'> >(); try_munching<exactly<':'> >();
environment[string(key)] = parse_values(); environment[string(key)] = parse_values();
try_munching<exactly<';'> >(); try_munching<exactly<';'> >();
return Node(Node::null); return Node(Node::nil);
} }
Node Document::parse_ruleset() { Node Document::parse_ruleset() {
...@@ -79,8 +79,8 @@ namespace Sass { ...@@ -79,8 +79,8 @@ namespace Sass {
try_munching<variable>()) { try_munching<variable>()) {
if (top.begin[0] == '$') { if (top.begin[0] == '$') {
Node stuff(environment[string(top)]); Node stuff(environment[string(top)]);
for (int i = 0; i < stuff.children.size(); ++i) { for (int i = 0; i < stuff.children->size(); ++i) {
values.push_child(stuff.children[i]); values.push_child((*(stuff.children))[i]);
} }
} }
else else
......
...@@ -8,64 +8,82 @@ using std::cout; ...@@ -8,64 +8,82 @@ using std::cout;
using std::endl; using std::endl;
namespace Sass { namespace Sass {
Node::Node() { } unsigned int Node::fresh = 0;
unsigned int Node::copied = 0;
Node::Node() { ++fresh; children = 0; opt_children = 0; }
Node::Node(Node_Type _type) { Node::Node(Node_Type _type) {
type = _type; type = _type;
children = new vector<Node>;
opt_children = new vector<Node>;
++fresh;
} }
Node::Node(Node_Type _type, Token& _token) { Node::Node(Node_Type _type, Token& _token) {
type = _type; type = _type;
token = _token; token = _token;
children = 0;
opt_children = 0;
++fresh;
} }
Node::Node(const Node& n) {
type = n.type;
token = n.token;
children = n.children;
opt_children = n.opt_children;
++copied;
}
void Node::push_child(const Node& node) { void Node::push_child(const Node& node) {
children.push_back(node); if (!children) children = new vector<Node>;
children->push_back(node);
} }
void Node::push_opt_child(const Node& node) { void Node::push_opt_child(const Node& node) {
opt_children.push_back(node); if (!opt_children) opt_children = new vector<Node>;
opt_children->push_back(node);
} }
void Node::dump(unsigned int depth) { void Node::dump(unsigned int depth) {
switch (type) { // switch (type) {
case comment: // case comment:
for (int i = depth; i > 0; --i) cout << " "; // for (int i = depth; i > 0; --i) cout << " ";
cout << string(token) << endl; // cout << string(token) << endl;
break; // break;
case selector: // case selector:
cout << string(token); // cout << string(token);
break; // break;
case value: // case value:
cout << string(token); // cout << string(token);
break; // break;
case property: // case property:
cout << string(token) << ":"; // cout << string(token) << ":";
break; // break;
case values: // case values:
for (int i = 0; i < children.size(); ++i) // for (int i = 0; i < children.size(); ++i)
cout << " " << string(children[i].token); // cout << " " << string(children[i].token);
break; // break;
case rule: // case rule:
for (int i = depth; i > 0; --i) cout << " "; // for (int i = depth; i > 0; --i) cout << " ";
children[0].dump(depth); // children[0].dump(depth);
children[1].dump(depth); // children[1].dump(depth);
cout << ";" << endl; // cout << ";" << endl;
break; // break;
case clauses: // case clauses:
cout << " {" << endl; // cout << " {" << endl;
for (int i = 0; i < children.size(); ++i) { // for (int i = 0; i < children.size(); ++i) {
children[i].dump(depth + 1); // children[i].dump(depth + 1);
} // }
for (int i = 0; i < opt_children.size(); ++i) { // for (int i = 0; i < opt_children.size(); ++i) {
opt_children[i].dump(depth + 1); // opt_children[i].dump(depth + 1);
} // }
for (int i = depth; i > 0; --i) cout << " "; // for (int i = depth; i > 0; --i) cout << " ";
cout << "}" << endl; // cout << "}" << endl;
break; // break;
case ruleset: // case ruleset:
for (int i = depth; i > 0; --i) cout << " "; // for (int i = depth; i > 0; --i) cout << " ";
children[0].dump(depth); // children[0].dump(depth);
children[1].dump(depth); // children[1].dump(depth);
break; // break;
default: cout << "HUH?"; break; // default: cout << "HUH?"; break;
} // }
} }
void Node::emit_nested_css(stringstream& buf, void Node::emit_nested_css(stringstream& buf,
...@@ -74,39 +92,39 @@ namespace Sass { ...@@ -74,39 +92,39 @@ namespace Sass {
string indentation(2 * depth, ' '); string indentation(2 * depth, ' ');
bool has_rules, has_nested_rulesets; bool has_rules, has_nested_rulesets;
if (type == ruleset) { if (type == ruleset) {
has_rules = !(children[1].children.empty()); has_rules = !((*children)[1].children->empty());
has_nested_rulesets = !(children[1].opt_children.empty()); has_nested_rulesets = !((*children)[1].opt_children->empty());
} }
switch (type) { switch (type) {
case ruleset: case ruleset:
if (has_rules) { if (has_rules) {
buf << indentation; buf << indentation;
children[0].emit_nested_css(buf, prefix, depth); // selector (*children)[0].emit_nested_css(buf, prefix, depth); // selector
buf << " {"; buf << " {";
for (int i = 0; i < children[1].children.size(); ++i) { for (int i = 0; i < (*children)[1].children->size(); ++i) {
children[1].children[i].emit_nested_css(buf, "", depth + 1); // rules (*(*children)[1].children)[i].emit_nested_css(buf, "", depth + 1); // rules
} }
buf << " }" << endl; buf << " }" << endl;
} }
if (has_nested_rulesets) { if (has_nested_rulesets) {
for (int i = 0; i < children[1].opt_children.size(); ++i) { // do each nested ruleset for (int i = 0; i < (*children)[1].opt_children->size(); ++i) { // do each nested ruleset
children[1].opt_children[i].emit_nested_css(buf, prefix + (prefix.empty() ? "" : " ") + string(children[0].token), depth + (has_rules ? 1 : 0)); (*(*children)[1].opt_children)[i].emit_nested_css(buf, prefix + (prefix.empty() ? "" : " ") + string((*children)[0].token), depth + (has_rules ? 1 : 0));
} }
} }
if (depth == 0 && prefix.empty()) buf << endl; if (depth == 0 && prefix.empty()) buf << endl;
break; break;
case rule: case rule:
buf << endl << indentation; buf << endl << indentation;
children[0].emit_nested_css(buf, "", depth); // property (*children)[0].emit_nested_css(buf, "", depth); // property
children[1].emit_nested_css(buf, "", depth); // values (*children)[1].emit_nested_css(buf, "", depth); // values
buf << ";"; buf << ";";
break; break;
case property: case property:
buf << string(token) << ":"; buf << string(token) << ":";
break; break;
case values: case values:
for (int i = 0; i < children.size(); ++i) { for (int i = 0; i < children->size(); ++i) {
buf << " " << string(children[i].token); buf << " " << string((*children)[i].token);
} }
break; break;
case selector: case selector:
...@@ -121,50 +139,51 @@ namespace Sass { ...@@ -121,50 +139,51 @@ namespace Sass {
} }
void Node::emit_expanded_css(stringstream& buf, const string& prefix) { void Node::emit_expanded_css(stringstream& buf, const string& prefix) {
switch (type) { // switch (type) {
case selector: // case selector:
if (!prefix.empty()) buf << " "; // if (!prefix.empty()) buf << " ";
buf << string(token); // buf << string(token);
break; // break;
case comment: // case comment:
if (!prefix.empty()) buf << " "; // if (!prefix.empty()) buf << " ";
buf << string(token) << endl; // buf << string(token) << endl;
break; // break;
case property: // case property:
buf << string(token) << ":"; // buf << string(token) << ":";
break; // break;
case values: // case values:
for (int i = 0; i < children.size(); ++i) { // for (int i = 0; i < children.size(); ++i) {
buf << " " << string(children[i].token); // buf << " " << string(children[i].token);
} // }
break; // break;
case rule: // case rule:
buf << " "; // buf << " ";
children[0].emit_expanded_css(buf, prefix); // children[0].emit_expanded_css(buf, prefix);
children[1].emit_expanded_css(buf, prefix); // children[1].emit_expanded_css(buf, prefix);
buf << ";" << endl; // buf << ";" << endl;
break; // break;
case clauses: // case clauses:
if (children.size() > 0) { // if (children.size() > 0) {
buf << " {" << endl; // buf << " {" << endl;
for (int i = 0; i < children.size(); ++i) // for (int i = 0; i < children.size(); ++i)
children[i].emit_expanded_css(buf, prefix); // children[i].emit_expanded_css(buf, prefix);
buf << "}" << endl; // buf << "}" << endl;
} // }
for (int i = 0; i < opt_children.size(); ++i) // for (int i = 0; i < opt_children.size(); ++i)
opt_children[i].emit_expanded_css(buf, prefix); // opt_children[i].emit_expanded_css(buf, prefix);
break; // break;
case ruleset: // case ruleset:
// buf << prefix; // // buf << prefix;
if (children[1].children.size() > 0) { // if (children[1].children.size() > 0) {
buf << prefix << (prefix.empty() ? "" : " "); // buf << prefix << (prefix.empty() ? "" : " ");
children[0].emit_expanded_css(buf, ""); // children[0].emit_expanded_css(buf, "");
} // }
string newprefix(prefix.empty() ? prefix : prefix + " "); // string newprefix(prefix.empty() ? prefix : prefix + " ");
children[1].emit_expanded_css(buf, newprefix + string(children[0].token)); // children[1].emit_expanded_css(buf, newprefix + string(children[0].token));
if (prefix.empty()) buf << endl; // if (prefix.empty()) buf << endl;
break; // break;
} // }
} }
} }
\ No newline at end of file
...@@ -8,7 +8,7 @@ namespace Sass { ...@@ -8,7 +8,7 @@ namespace Sass {
struct Node { struct Node {
enum Node_Type { enum Node_Type {
null, nil,
comment, comment,
ruleset, ruleset,
clauses, clauses,
...@@ -19,23 +19,67 @@ namespace Sass { ...@@ -19,23 +19,67 @@ namespace Sass {
rule, rule,
property, property,
values, values,
value, value
lookahead_sequence,
lookahead_token
}; };
static unsigned int fresh;
static unsigned int copied;
Node_Type type; Node_Type type;
Token token; Token token;
vector<Node> children; vector<Node>* children;
vector<Node> opt_children; vector<Node>* opt_children;
Node(); Node();
Node(Node_Type _type); Node(Node_Type _type);
Node(Node_Type _type, Token& _token); Node(Node_Type _type, Token& _token);
Node(const Node& n);
void push_child(const Node& node); void push_child(const Node& node);
void push_opt_child(const Node& node); void push_opt_child(const Node& node);
void dump(unsigned int depth = 0); void dump(unsigned int depth = 0);
void emit_nested_css(stringstream& buf, const string& prefix, size_t depth); void emit_nested_css(stringstream& buf, const string& prefix, size_t depth);
void emit_expanded_css(stringstream& buf, const string& prefix); void emit_expanded_css(stringstream& buf, const string& prefix);
}; };
// struct Node {
// enum Type {
// nil,
// comment,
// ruleset,
// selector_group,
// selector,
// simple_selector_sequence,
// type_selector,
// class_selector,
// id_selector,
// attribute_selector,
// clauses,
// rule,
// property,
// values,
// value
// };
//
// bool has_rules;
// bool has_rulesets;
// Type type;
// Token token;
// vector<Node>* children;
//
// Node(const Node& n)
// : has_rules(n.has_rules), has_rulesets(n.has_rulesets),
// type(n.type), token(n.token), children(n.children)
// { n.children = 0; } // No joint custody.
// Node(Type type_)
// : has_rules(false), has_rulesets(false),
// type(type_), token(Token()), children(0)
// { }
// Node(Type type_, size_t size);
// Node(Type type_, Token& token_);
//
// Node& operator=(const Node& node);
// Node& operator+=(const Node& node);
// Node& operator<<(const Node& node);
// };
} }
\ No newline at end of file
...@@ -30,6 +30,9 @@ int main(int argc, char* argv[]) { ...@@ -30,6 +30,9 @@ int main(int argc, char* argv[]) {
doc.parse_scss(); doc.parse_scss();
string output = doc.emit_css(style); string output = doc.emit_css(style);
cout << output; cout << output;
cerr << "Fresh nodes:\t" << Node::fresh << endl;
cerr << "Copied nodes:\t" << Node::copied << endl;
return 0; return 0;
} }
\ 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