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