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