Commit 9e8b930e by Aaron Leung

Finished the node refactor. Required more debugging than I expected.

parent 42a50269
build: sassc.cpp document.cpp node.cpp token.cpp prelexer.cpp build: sassc.cpp document.cpp node.cpp values.cpp prelexer.cpp
g++ -o bin/sassc sassc.cpp document.cpp document_parser.cpp eval_apply.cpp node.cpp values.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
......
...@@ -39,8 +39,7 @@ namespace Sass { ...@@ -39,8 +39,7 @@ namespace Sass {
size_t ref_count; size_t ref_count;
Context() Context()
: pending(vector<Node>()), : source_refs(vector<char*>()),
source_refs(vector<char*>()),
ref_count(0) ref_count(0)
{ } { }
......
...@@ -9,8 +9,8 @@ namespace Sass { ...@@ -9,8 +9,8 @@ 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(1, Node::root)), root(Node(Node::root, 1)),
lexed(Token()) lexed(Token::make())
{ {
if (!source) { if (!source) {
std::FILE *f; std::FILE *f;
...@@ -35,8 +35,8 @@ namespace Sass { ...@@ -35,8 +35,8 @@ 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(1, Node::root)), root(Node(Node::root, 1)),
lexed(Token()) lexed(Token::make())
{ {
std::FILE *f; std::FILE *f;
// TO DO: CHECK f AGAINST NULL/0 // TO DO: CHECK f AGAINST NULL/0
...@@ -59,12 +59,12 @@ namespace Sass { ...@@ -59,12 +59,12 @@ namespace Sass {
if (context.ref_count == 0) delete &context; if (context.ref_count == 0) delete &context;
} }
void Document::eval_pending() // void Document::eval_pending()
{ // {
for (int i = 0; i < context.pending.size(); ++i) { // for (int i = 0; i < context.pending.size(); ++i) {
eval(context.pending[i], context.global_env); // eval(context.pending[i], context.global_env);
} // }
} // }
using std::string; using std::string;
using std::stringstream; using std::stringstream;
......
...@@ -85,7 +85,7 @@ namespace Sass { ...@@ -85,7 +85,7 @@ namespace Sass {
after_whitespace = spaces(position); after_whitespace = spaces(position);
if (after_whitespace) { if (after_whitespace) {
line_number += count_interval<'\n'>(position, after_whitespace); line_number += count_interval<'\n'>(position, after_whitespace);
lexed = Token(position, after_whitespace); lexed = Token::make(position, after_whitespace);
return position = after_whitespace; return position = after_whitespace;
} }
else { else {
...@@ -101,7 +101,7 @@ namespace Sass { ...@@ -101,7 +101,7 @@ namespace Sass {
const char* after_token = mx(after_whitespace); const char* after_token = mx(after_whitespace);
if (after_token) { if (after_token) {
line_number += count_interval<'\n'>(position, after_token); line_number += count_interval<'\n'>(position, after_token);
lexed = Token(after_whitespace, after_token); lexed = Token::make(after_whitespace, after_token);
return position = after_token; return position = after_token;
} }
else { else {
......
...@@ -26,8 +26,8 @@ namespace Sass { ...@@ -26,8 +26,8 @@ namespace Sass {
lex< exactly<';'> >(); lex< exactly<';'> >();
} }
else if (peek< variable >(position)) { else if (peek< variable >(position)) {
lex< exactly<';'> >();
root << parse_assignment(); root << parse_assignment();
lex< exactly<';'> >();
} }
else { else {
root << parse_ruleset(); root << parse_ruleset();
...@@ -152,7 +152,7 @@ namespace Sass { ...@@ -152,7 +152,7 @@ namespace Sass {
Node Document::parse_selector_group() Node Document::parse_selector_group()
{ {
Node group(line_number, Node::selector_group, 1); Node group(Node::selector_group, line_number, 1);
group << parse_selector(); group << parse_selector();
while (lex< exactly<','> >()) group << parse_selector(); while (lex< exactly<','> >()) group << parse_selector();
return group; return group;
...@@ -266,7 +266,7 @@ namespace Sass { ...@@ -266,7 +266,7 @@ namespace Sass {
Node Document::parse_attribute_selector() Node Document::parse_attribute_selector()
{ {
Node attr_sel(line_number, Node::attribute_selector, 3); Node attr_sel(Node::attribute_selector, line_number, 3);
lex< exactly<'['> >(); lex< exactly<'['> >();
lex< type_selector >(); lex< type_selector >();
attr_sel << Node(Node::value, line_number, lexed); attr_sel << Node(Node::value, line_number, lexed);
...@@ -316,8 +316,8 @@ namespace Sass { ...@@ -316,8 +316,8 @@ namespace Sass {
block[0].has_expansions = true; block[0].has_expansions = true;
} }
else if (lex< variable >()) { else if (lex< variable >()) {
semicolon = true;
block << parse_assignment(); block << parse_assignment();
semicolon = true;
} }
// else if (look_for_rule(position)) { // else if (look_for_rule(position)) {
// block << parse_rule(); // block << parse_rule();
...@@ -498,7 +498,7 @@ namespace Sass { ...@@ -498,7 +498,7 @@ namespace Sass {
if (lex< rgb_prefix >()) if (lex< rgb_prefix >())
{ {
Node result(Node::color, line_number, 3); Node result(Node::numeric_color, line_number, 3);
lex< number >(); lex< number >();
result << Node(line_number, std::atof(lexed.begin)); result << Node(line_number, std::atof(lexed.begin));
lex< exactly<','> >(); lex< exactly<','> >();
...@@ -644,7 +644,7 @@ namespace Sass { ...@@ -644,7 +644,7 @@ namespace Sass {
(q = peek< id_name >(p)) || (q = peek< class_name >(p)) || (q = peek< id_name >(p)) || (q = peek< class_name >(p)) ||
(q = look_for_pseudo(p)) || (q = look_for_attrib(p)); (q = look_for_pseudo(p)) || (q = look_for_attrib(p));
// cerr << "looking for simple selector; found:" << endl; // cerr << "looking for simple selector; found:" << endl;
// cerr << (q ? string(Token(q,q+8)) : "nothing") << endl; // cerr << (q ? string(Token::make(q,q+8)) : "nothing") << endl;
return q; return q;
} }
......
...@@ -40,7 +40,7 @@ namespace Sass { ...@@ -40,7 +40,7 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case selector: { case selector: {
string result; string result;
if (!has_backref && !prefix.empty()) { if (!has_backref && !prefix.empty()) {
...@@ -48,7 +48,7 @@ namespace Sass { ...@@ -48,7 +48,7 @@ namespace Sass {
result += ' '; result += ' ';
} }
if (at(0).type == selector_combinator) { if (at(0).type == selector_combinator) {
result += string(at(0).content.token); result += at(0).content.token.to_string();
result += ' '; result += ' ';
} }
else { else {
...@@ -59,12 +59,12 @@ namespace Sass { ...@@ -59,12 +59,12 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case selector_combinator: { case selector_combinator: {
if (std::isspace(content.token.begin[0])) return string(" "); if (std::isspace(content.token.begin[0])) return string(" ");
else return string(" ") += string(content.token) += string(" "); else return string(" ") += string(content.token) += string(" ");
} break; } break;
case simple_selector_sequence: { case simple_selector_sequence: {
string result; string result;
for (int i = 0; i < size(); ++i) { for (int i = 0; i < size(); ++i) {
...@@ -72,14 +72,14 @@ namespace Sass { ...@@ -72,14 +72,14 @@ namespace Sass {
} }
return result; return result;
} break; } break;
case pseudo_negation: { case pseudo_negation: {
string result(at(0).to_string(prefix)); string result(at(0).to_string(prefix));
result += at(1).to_string(prefix); result += at(1).to_string(prefix);
result += ')'; result += ')';
return result; return result;
} break; } break;
case functional_pseudo: { case functional_pseudo: {
string result(at(0).to_string(prefix)); string result(at(0).to_string(prefix));
for (int i = 1; i < size(); ++i) { for (int i = 1; i < size(); ++i) {
...@@ -88,7 +88,7 @@ namespace Sass { ...@@ -88,7 +88,7 @@ namespace Sass {
result += ')'; result += ')';
return result; return result;
} break; } break;
case attribute_selector: { case attribute_selector: {
string result("["); string result("[");
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
...@@ -96,7 +96,7 @@ namespace Sass { ...@@ -96,7 +96,7 @@ namespace Sass {
result += ']'; result += ']';
return result; return result;
} break; } break;
case backref: { case backref: {
return prefix; return prefix;
} break; } break;
...@@ -122,10 +122,6 @@ namespace Sass { ...@@ -122,10 +122,6 @@ namespace Sass {
case expression: case expression:
case term: { case term: {
string result(at(0).to_string(prefix)); string result(at(0).to_string(prefix));
// for (int i = 2; i < size(); i += 2) {
// // result += " ";
// result += at(i).to_string(prefix);
// }
for (int i = 1; i < size(); ++i) { for (int i = 1; i < size(); ++i) {
if (!(at(i).type == add || if (!(at(i).type == add ||
// at(i).type == sub || // another edge case -- consider uncommenting // at(i).type == sub || // another edge case -- consider uncommenting
...@@ -147,21 +143,16 @@ namespace Sass { ...@@ -147,21 +143,16 @@ namespace Sass {
case numeric_dimension: { case numeric_dimension: {
stringstream ss; stringstream ss;
// ss.setf(std::ios::fixed, std::ios::floatfield);
// ss.precision(3);
ss << content.dimension.numeric_value; ss << content.dimension.numeric_value;
Token unit; ss << string(content.dimension.unit, 2);
unit.begin = content.dimension.unit; // << string(content.dimension.unit, Prelexer::identifier(content.dimension.unit) - content.dimension.unit);
unit.end = Prelexer::identifier(content.dimension.unit); // cerr << Token::make(content.dimension.unit, content.dimension.unit + 2).to_string();
ss << string(unit); // << Token::make(content.dimension.unit, Prelexer::identifier(content.dimension.unit)).to_string();
// << string(Token(content.dimension.unit, Prelexer::identifier(content.dimension.unit)));
return ss.str(); return ss.str();
} break; } break;
case number: { case number: {
stringstream ss; stringstream ss;
// ss.setf(std::ios::fixed, std::ios::floatfield);
// ss.precision(3);
ss << content.numeric_value; ss << content.numeric_value;
return ss.str(); return ss.str();
} break; } break;
...@@ -213,7 +204,9 @@ namespace Sass { ...@@ -213,7 +204,9 @@ namespace Sass {
// } break; // } break;
default: { default: {
return string(content.token); // return content.token.to_string();
if (!has_children && type != flags) return content.token.to_string();
else return "";
} break; } break;
} }
} }
......
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include "values.hpp" #include "values.hpp"
#include <iostream>
namespace Sass { namespace Sass {
using std::string; using std::string;
using std::vector; using std::vector;
using std::stringstream; using std::stringstream;
using std::cerr; using std::endl;
struct Node { struct Node {
enum Type { enum Type {
...@@ -96,7 +98,7 @@ namespace Sass { ...@@ -96,7 +98,7 @@ namespace Sass {
void clear() void clear()
{ {
type = none; line_number = 0; type = none; line_number = 0; has_children = false;
has_statements = false; has_blocks = false; has_expansions = false; has_statements = false; has_blocks = false; has_expansions = false;
has_backref = false; from_variable = false; eval_me = false; has_backref = false; from_variable = false; eval_me = false;
} }
...@@ -174,6 +176,7 @@ namespace Sass { ...@@ -174,6 +176,7 @@ namespace Sass {
clear(); clear();
type = numeric_dimension; type = numeric_dimension;
line_number = ln; line_number = ln;
content.dimension = Dimension();
content.dimension.numeric_value = val; content.dimension.numeric_value = val;
content.dimension.unit = tok.begin; content.dimension.unit = tok.begin;
} }
...@@ -192,86 +195,4 @@ namespace Sass { ...@@ -192,86 +195,4 @@ namespace Sass {
++allocations; ++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;
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);
void flatten();
};
} }
\ No newline at end of file
...@@ -29,6 +29,7 @@ int main(int argc, char* argv[]) { ...@@ -29,6 +29,7 @@ int main(int argc, char* argv[]) {
} }
Document doc(path, 0); Document doc(path, 0);
cerr << "PREPARING TO PARSE DOCUMENT" << endl;
doc.parse_scss(); doc.parse_scss();
cerr << "SUCCESSFULLY PARSED DOCUMENT" << endl; cerr << "SUCCESSFULLY PARSED DOCUMENT" << endl;
// doc.eval_pending(); // doc.eval_pending();
...@@ -36,8 +37,8 @@ int main(int argc, char* argv[]) { ...@@ -36,8 +37,8 @@ int main(int argc, char* argv[]) {
cerr << "SUCCESSFULLY EVALED DOCUMENT" << endl; cerr << "SUCCESSFULLY EVALED DOCUMENT" << endl;
string output = doc.emit_css(style); string output = doc.emit_css(style);
cerr << "Fresh nodes:\t" << Node::fresh << endl; // cerr << "Fresh nodes:\t" << Node::fresh << endl;
cerr << "Copied nodes:\t" << Node::copied << endl; // cerr << "Copied nodes:\t" << Node::copied << endl;
cerr << "Allocations:\t" << Node::allocations << endl; cerr << "Allocations:\t" << Node::allocations << endl;
cout << output; cout << output;
......
...@@ -23,8 +23,8 @@ div { ...@@ -23,8 +23,8 @@ div {
l: 15 / 5 / $three; l: 15 / 5 / $three;
m: 1/2, $stuff url("www.foo.com/blah.png") blah blah; m: 1/2, $stuff url("www.foo.com/blah.png") blah blah;
n: 1 2 3, $stuff 4 5 (6, 7 8 9); n: 1 2 3, $stuff 4 5 (6, 7 8 9);
o: 3px + 3px; o: 3px + 3px + 3px;
p: 4 + 1em; p: 4 + 1px;
q: (20pt / 10pt); q: (20pt / 10pt);
r: 16em * 4; r: 16em * 4;
s: (5em / 2); s: (5em / 2);
......
...@@ -19,8 +19,8 @@ div { ...@@ -19,8 +19,8 @@ div {
l: 1; l: 1;
m: 1/2, 1 2 3 url("www.foo.com/blah.png") blah blah; m: 1/2, 1 2 3 url("www.foo.com/blah.png") blah blah;
n: 1 2 3, 1 2 3 4 5 6, 7 8 9; n: 1 2 3, 1 2 3 4 5 6, 7 8 9;
o: 6px; o: 9px;
p: 5em; p: 5px;
q: 2; q: 2;
r: 64em; r: 64em;
s: 2.5em; s: 2.5em;
......
#include "token.hpp" #include "values.hpp"
namespace Sass { namespace Sass {
Token::Token() : begin(0), end(0) { } // Token::Token() : begin(0), end(0) { }
Token::Token(const char* begin, const char* end) // Token::Token(const char* begin, const char* end)
: begin(begin), end(end) { } // : begin(begin), end(end) { }
string Token::unquote() const { string Token::unquote() const {
string result; string result;
......
...@@ -17,6 +17,9 @@ namespace Sass { ...@@ -17,6 +17,9 @@ namespace Sass {
inline operator string() const inline operator string() const
{ return string(begin, end - begin); } { return string(begin, end - begin); }
string to_string() const
{ return string(begin, end - begin); }
string unquote() const; string unquote() const;
void unquote_to_stream(std::stringstream& buf) const; void unquote_to_stream(std::stringstream& buf) const;
...@@ -25,7 +28,23 @@ namespace Sass { ...@@ -25,7 +28,23 @@ namespace Sass {
bool operator==(const Token& rhs) const; bool operator==(const Token& rhs) const;
operator bool() operator bool()
{ return begin && end && begin >= end; } { return begin && end && begin >= end; }
// static Token make()
// {
// Token t;
// t.begin = 0;
// t.end = 0;
// return t;
// }
//
static Token make(const char* b = 0, const char* e = 0)
{
Token t;
t.begin = b;
t.end = e;
return t;
}
}; };
struct Dimension { struct Dimension {
......
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