Commit 414e8f5f by Aaron Leung

Refactoring the node data structure. Should reduce the size from 56 bytes down to 32 bytes.

parent bd7f9014
build: sassc.cpp document.cpp node.cpp token.cpp prelexer.cpp build: sassc.cpp document.cpp node.cpp token.cpp prelexer.cpp
g++ -o bin/sassc sassc.cpp document.cpp document_parser.cpp eval_apply.cpp node.cpp token.cpp prelexer.cpp g++ -o bin/sassc sassc.cpp document.cpp document_parser.cpp eval_apply.cpp node.cpp values.cpp prelexer.cpp
test: build test: build
ruby spec.rb spec/basic/ ruby spec.rb spec/basic/
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include "token.hpp" #include "values.hpp"
namespace Sass { namespace Sass {
using std::string; using std::string;
...@@ -54,11 +54,12 @@ namespace Sass { ...@@ -54,11 +54,12 @@ namespace Sass {
textual_dimension, textual_dimension,
textual_number, textual_number,
textual_hex, textual_hex,
color_name;
string_constant, string_constant,
numeric_percentage, numeric_percentage,
numeric_dimension, numeric_dimension,
number, number,
hex_triple, numeric_color,
mixin, mixin,
parameters, parameters,
...@@ -73,212 +74,194 @@ namespace Sass { ...@@ -73,212 +74,194 @@ namespace Sass {
flags flags
}; };
static size_t fresh;
static size_t copied;
static size_t allocations;
size_t line_number;
mutable vector<Node>* children;
Token token;
double numeric_value;
Type type; Type type;
bool has_rules_or_comments; unsigned int line_number;
bool has_rulesets;
bool has_propsets; bool has_children;
bool has_statements;
bool has_blocks;
bool has_expansions; bool has_expansions;
bool has_backref; bool has_backref;
bool from_variable; bool from_variable;
bool eval_me; bool eval_me;
Node() : type(none), children(0) { ++fresh; } union {
Token token;
Node(Node::Type type) mutable vector<Node>* children;
: type(type), Dimension dimension;
children(0), double numeric_value;
has_rules_or_comments(false), } content;
has_rulesets(false),
has_propsets(false), static size_t allocations;
has_expansions(false)
{ ++fresh; }
Node(const Node& n)
: line_number(n.line_number),
children(n.children),
token(n.token),
numeric_value(n.numeric_value),
type(n.type),
has_rules_or_comments(n.has_rules_or_comments),
has_rulesets(n.has_rulesets),
has_propsets(n.has_propsets),
has_expansions(n.has_expansions),
has_backref(n.has_backref),
from_variable(n.from_variable),
eval_me(n.eval_me)
{ ++copied; }
Node(size_t line_number, Type type, size_t length = 0)
: line_number(line_number),
children(new vector<Node>),
token(Token()),
numeric_value(0),
type(type),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ children->reserve(length); ++fresh; ++allocations; }
Node(size_t line_number, Type type, const Node& n)
: line_number(line_number),
children(new vector<Node>(1, n)),
token(Token()),
numeric_value(0),
type(type),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ ++fresh; ++allocations; }
Node(size_t line_number, Type type, const Node& n, const Node& m)
: line_number(line_number),
children(new vector<Node>),
token(Token()),
numeric_value(0),
type(type),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{
children->reserve(2);
children->push_back(n);
children->push_back(m);
++fresh;
++allocations;
}
Node(size_t line_number, Type type, Token& token) void clear()
: line_number(line_number),
children(0),
token(token),
numeric_value(0),
type(type),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ ++fresh; }
Node(size_t line_number, double d)
: line_number(line_number),
children(0),
token(Token()),
numeric_value(d),
type(number),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ ++fresh; }
Node(size_t line_number, double d, Token& token)
: line_number(line_number),
children(0),
token(token),
numeric_value(d),
type(numeric_dimension),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ ++fresh; }
Node(size_t line_number, double a, double b, double c)
: line_number(line_number),
children(new vector<Node>()),
token(Token()),
numeric_value(0),
type(hex_triple),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_expansions(false),
has_backref(false),
from_variable(false),
eval_me(false)
{ {
children->reserve(3); type = none; line_number = 0;
children->push_back(Node(line_number, a)); has_statements = false; has_blocks = false; has_expansions = false;
children->push_back(Node(line_number, b)); has_backref = false; from_variable = false; eval_me = false;
children->push_back(Node(line_number, c));
++fresh;
++allocations;
} }
//~Node() { delete children; }
size_t size() const size_t size() const
{ return children->size(); } { return content.children->size(); }
Node& operator[](const size_t i) const Node& operator[](const size_t i) const
{ return children->at(i); } { return content.children->at(i); }
Node& at(const size_t i) const Node& at(const size_t i) const
{ return children->at(i); } { return content.children->at(i); }
Node& operator=(const Node& n)
{
line_number = n.line_number;
children = n.children;
token = n.token;
numeric_value = n.numeric_value;
type = n.type;
has_rules_or_comments = n.has_rules_or_comments;
has_rulesets = n.has_rulesets;
has_propsets = n.has_propsets;
has_backref = n.has_backref;
from_variable = n.from_variable;
eval_me = n.eval_me;
++copied;
return *this;
}
Node& operator<<(const Node& n) Node& operator<<(const Node& n)
{ {
children->push_back(n); content.children->push_back(n);
return *this; return *this;
} }
Node& operator+=(const Node& n) Node& operator+=(const Node& n)
{ {
for (int i = 0; i < n.children->size(); ++i) { for (int i = 0; i < n.size(); ++i) {
children->push_back(n.children->at(i)); content.children->push_back(n[i]);
} }
return *this; return *this;
} }
string to_string(const string& prefix) const; string to_string(const string& prefix) const;
void release() const { children = 0; } void echo(stringstream& buf, size_t depth = 0);
void emit_nested_css(stringstream& buf,
size_t depth,
const vector<string>& prefixes);
void emit_nested_css(stringstream& buf, size_t depth);
void emit_expanded_css(stringstream& buf, const string& prefix);
Node clone() const;
void flatten();
Node()
{ clear(); }
Node(Type t) // flags
{ clear(); type = t; }
Node(Type t, unsigned int ln, size_t s = 0) // nodes with children
{
clear();
type = t;
line_number = ln;
content.children = new vector<Node>;
content.children->reserve(s);
has_children = true;
++allocations;
}
Node(Type t, unsigned int ln, const Token& tok) // nodes with a single token
{
clear();
type = t;
line_number = ln;
content.token = tok;
}
Node(unsigned int ln, double val) // numeric values
{
clear();
type = number;
line_number = ln;
content.numeric_value = val;
}
Node(unsigned int ln, double val, const Token& tok) // dimensions
{
clear();
type = numeric_dimension;
line_number = ln;
content.dimension.numeric_value = val;
content.dimension.unit = tok.begin;
}
Node(unsigned int ln, double r, double g, double b) // colors
{
clear();
type = numeric_color;
line_number = ln;
content.children = new vector<Node>;
content.children->reserve(3);
content.children->push_back(Node(ln, r));
content.children->push_back(Node(ln, g));
content.children->push_back(Node(ln, b));
has_children = true;
++allocations;
}
};
struct Orig_Node {
enum Type {
root,
ruleset,
propset,
selector_group,
selector,
selector_combinator,
simple_selector_sequence,
backref,
simple_selector,
type_selector,
class_selector,
id_selector,
pseudo,
pseudo_negation,
functional_pseudo,
attribute_selector,
block,
rule,
property,
nil,
comma_list,
space_list,
expression,
add,
sub,
term,
mul,
div,
factor,
values,
value,
identifier,
uri,
textual_percentage,
textual_dimension,
textual_number,
textual_hex,
string_constant,
numeric_percentage,
numeric_dimension,
number,
hex_triple,
mixin,
parameters,
expansion,
arguments,
variable,
assignment,
comment,
none,
flags
};
string to_string(const string& prefix) const;
Node clone() const; Node clone() const;
......
...@@ -26,6 +26,10 @@ namespace Sass { ...@@ -26,6 +26,10 @@ namespace Sass {
operator bool() operator bool()
{ return begin && end && begin >= end; } { return begin && end && begin >= end; }
};
struct Dimension {
const double numeric_value;
const char* unit;
}; };
} }
\ 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