Commit 33c5ecdf by Aaron Leung

Bam! Variable substitution works!

parent 6ffd60ae
#include <cstdio>
#include "document.hpp"
#include <iostream>
namespace Sass {
using namespace Prelexer;
using std::cout; using std::endl;
Document::Document(char* _path, char* _source) {
path = _path;
......@@ -42,13 +44,24 @@ namespace Sass {
if (try_munching<block_comment>()) {
return Node(Node::comment, top);
}
else if (try_munching<variable>()) {
return parse_var_def();
}
else return parse_ruleset();
}
Node Document::parse_var_def() {
const Token key = top;
try_munching<exactly<':'> >();
environment[string(key)] = parse_values();
try_munching<exactly<';'> >();
return Node(Node::null);
}
Node Document::parse_ruleset() {
Node ruleset(Node::ruleset);
ruleset.push_child(parse_selector());
ruleset.push_child(parse_declarations());
ruleset.push_child(parse_clauses());
return ruleset;
}
......@@ -57,14 +70,18 @@ namespace Sass {
return Node(Node::selector, top);
}
Node Document::parse_declarations() {
Node Document::parse_clauses() {
try_munching<exactly<'{'> >();
Node decls(Node::declarations);
Node decls(Node::clauses);
while(!try_munching<exactly<'}'> >()) {
if (try_munching<block_comment>()) {
decls.push_child(Node(Node::comment, top));
continue;
}
else if (try_munching<variable>()) {
decls.push_child(parse_var_def());
continue;
}
try_munching<identifier>();
Token id = top;
if (try_munching<exactly<':'> >()) {
......@@ -77,7 +94,7 @@ namespace Sass {
else {
Node ruleset(Node::ruleset);
ruleset.push_child(Node(Node::selector, id));
ruleset.push_child(parse_declarations());
ruleset.push_child(parse_clauses());
decls.push_opt_child(ruleset);
}
}
......@@ -87,7 +104,15 @@ namespace Sass {
Node Document::parse_values() {
Node values(Node::values);
while(try_munching<identifier>() || try_munching<dimension>() ||
try_munching<percentage>() || try_munching<number>()) {
try_munching<percentage>() || try_munching<number>() ||
try_munching<hex>() || 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]);
}
}
else
values.push_child(Node(Node::value, top));
}
return values;
......
#include <map>
#include "node.hpp"
namespace Sass {
using std::vector;
using std::map;
using namespace Prelexer;
struct Document {
......@@ -9,6 +11,10 @@ namespace Sass {
char* source;
char* position;
unsigned int line_number;
// TO DO: move the environment up into the context class when it's ready
map<string, Node> environment;
vector<Node> statements;
Token top;
bool last_munch_succeeded;
......@@ -57,9 +63,10 @@ namespace Sass {
void parse_scss();
Node parse_statement();
Node parse_var_def();
Node parse_ruleset();
Node parse_selector();
Node parse_declarations();
Node parse_clauses();
Node parse_values();
};
......
......@@ -48,7 +48,7 @@ namespace Sass {
children[1].dump(depth);
cout << ";" << endl;
break;
case declarations:
case clauses:
cout << " {" << endl;
for (int i = 0; i < children.size(); ++i) {
children[i].dump(depth + 1);
......@@ -92,7 +92,7 @@ namespace Sass {
children[1].emit_expanded_css(buf, prefix);
buf << ";" << endl;
break;
case declarations:
case clauses:
buf << " {" << endl;
for (int i = 0; i < children.size(); ++i)
children[i].emit_expanded_css(buf, prefix);
......
......@@ -9,7 +9,7 @@ namespace Sass {
null,
comment,
ruleset,
declarations,
clauses,
selector_group,
selector,
simple_selector_sequence,
......
$blah: bloo;
/* top level comment -- should preserved */
div {
/* another comment that should be preserved */
color: red;
background: blue;
$blux: hux;
span {
font-weight: bold;
a {
text-decoration: none;
color: green;
border: 1px $blah red;
}
/* yet another comment that should be preserved */
display: inline-block;
}
p {
padding: 10px 8%;
-webkit-box-sizing: $blux;
}
margin: 10px 5px;
}
......
......@@ -16,6 +16,11 @@ namespace Sass {
unsigned int _line_number);
Token(const Token& t);
inline bool is_null() { return begin == 0 || end == 0; }
inline operator string() { return string(begin, end - begin); }
inline operator string() const { return string(begin, end - begin); }
inline bool operator<(const Token& rhs) const {
return (begin < rhs.begin) ||
(begin == rhs.begin && end < rhs.end);
}
};
}
\ 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