Commit c15503ae by Aaron Leung

Trying to get imports to work correctly. Cross-file variables not working for some reason.

parent 7eb9753c
...@@ -3,6 +3,7 @@ namespace Sass { ...@@ -3,6 +3,7 @@ namespace Sass {
struct Context { struct Context {
map<Token, Node> environment; map<Token, Node> environment;
Context() : environment(map<Token, Node>()) { } size_t ref_count;
Context() : environment(map<Token, Node>()), ref_count(0) { }
}; };
} }
\ No newline at end of file
#include <cstdio> #include <cstdio>
#include "document.hpp" #include "document.hpp"
#include <iostream>
namespace Sass { namespace Sass {
Document::Document(string path, char* source) Document::Document(string path, char* source)
: path(path), source(source), : path(path), source(source), source_refs(vector<char*>()),
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(1, Node::root)),
...@@ -30,7 +31,7 @@ namespace Sass { ...@@ -30,7 +31,7 @@ namespace Sass {
} }
Document::Document(string path, Context& context) Document::Document(string path, Context& context)
: path(path), source(source), : path(path), source(0), source_refs(vector<char*>()),
line_number(1), own_source(false), line_number(1), own_source(false),
context(context), context(context),
root(Node(1, Node::root)), root(Node(1, Node::root)),
...@@ -48,13 +49,17 @@ namespace Sass { ...@@ -48,13 +49,17 @@ namespace Sass {
std::fread(source, sizeof(char), len, f); std::fread(source, sizeof(char), len, f);
source[len] = '\0'; source[len] = '\0';
std::fclose(f); std::fclose(f);
own_source = true;
position = source; position = source;
++context.ref_count;
} }
Document::~Document() { Document::~Document() {
if (own_source) delete [] source; if (own_source) delete [] source;
delete &context; --context.ref_count;
if (context.ref_count == 0) delete &context;
for (int i = 0; i < source_refs.size(); ++i) {
delete [] source_refs[i];
}
} }
} }
\ No newline at end of file
...@@ -13,7 +13,8 @@ namespace Sass { ...@@ -13,7 +13,8 @@ namespace Sass {
string path; string path;
char* source; char* source;
char* position; vector<char*> source_refs;
const char* position;
size_t line_number; size_t line_number;
bool own_source; bool own_source;
...@@ -31,10 +32,10 @@ namespace Sass { ...@@ -31,10 +32,10 @@ namespace Sass {
~Document(); ~Document();
template <prelexer mx> template <prelexer mx>
char* peek(char* start = 0) const char* peek(const char* start = 0)
{ {
if (!start) start = position; if (!start) start = position;
char* after_whitespace; const char* after_whitespace;
if (mx == block_comment) { if (mx == block_comment) {
after_whitespace = after_whitespace =
zero_plus< alternatives<spaces, line_comment> >(start); zero_plus< alternatives<spaces, line_comment> >(start);
...@@ -57,7 +58,7 @@ namespace Sass { ...@@ -57,7 +58,7 @@ namespace Sass {
else { else {
after_whitespace = spaces_and_comments(start); after_whitespace = spaces_and_comments(start);
} }
char* after_token = mx(after_whitespace); const char* after_token = mx(after_whitespace);
if (after_token) { if (after_token) {
return after_token; return after_token;
} }
...@@ -67,9 +68,9 @@ namespace Sass { ...@@ -67,9 +68,9 @@ namespace Sass {
} }
template <prelexer mx> template <prelexer mx>
char* lex() const char* lex()
{ {
char* after_whitespace; const char* after_whitespace;
if (mx == block_comment) { if (mx == block_comment) {
after_whitespace = after_whitespace =
zero_plus< alternatives<spaces, line_comment> >(position); zero_plus< alternatives<spaces, line_comment> >(position);
...@@ -94,7 +95,7 @@ namespace Sass { ...@@ -94,7 +95,7 @@ namespace Sass {
else { else {
after_whitespace = spaces_and_comments(position); after_whitespace = spaces_and_comments(position);
} }
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(after_whitespace, after_token);
...@@ -106,6 +107,7 @@ namespace Sass { ...@@ -106,6 +107,7 @@ namespace Sass {
} }
void parse_scss(); void parse_scss();
Node parse_import();
void parse_var_def(); void parse_var_def();
Node parse_ruleset(); Node parse_ruleset();
Node parse_selector_group(); Node parse_selector_group();
...@@ -118,8 +120,8 @@ namespace Sass { ...@@ -118,8 +120,8 @@ namespace Sass {
Node parse_rule(); Node parse_rule();
Node parse_values(); Node parse_values();
char* look_for_rule(char* start = 0); const char* look_for_rule(const char* start = 0);
char* look_for_values(char* start = 0); const char* look_for_values(const char* start = 0);
string emit_css(CSS_Style style); string emit_css(CSS_Style style);
......
...@@ -7,19 +7,6 @@ namespace Sass { ...@@ -7,19 +7,6 @@ namespace Sass {
string Document::emit_css(CSS_Style style) { string Document::emit_css(CSS_Style style) {
stringstream output; stringstream output;
// for (int i = 0; i < statements.size(); ++i) {
// switch (style) {
// case echo:
// statements[i].echo(output);
// break;
// case nested:
// statements[i].emit_nested_css(output, 0, vector<string>());
// break;
// case expanded:
// statements[i].emit_expanded_css(output, "");
// break;
// }
// }
switch (style) { switch (style) {
case echo: case echo:
root.echo(output); root.echo(output);
......
...@@ -7,24 +7,14 @@ namespace Sass { ...@@ -7,24 +7,14 @@ namespace Sass {
void Document::parse_scss() void Document::parse_scss()
{ {
lex<optional_spaces>(); lex<optional_spaces>();
// while(*position) {
// if (lex< block_comment >()) {
// statements.push_back(Node(line_number, Node::comment, lexed));
// }
// else if (peek< variable >(position)) {
// parse_var_def();
// lex< exactly<';'> >();
// }
// else {
// statements.push_back(parse_ruleset());
// }
// lex<optional_spaces>();
// }
while(*position) { while(*position) {
if (lex< block_comment >()) { if (lex< block_comment >()) {
root << Node(line_number, Node::comment, lexed); root << Node(line_number, Node::comment, lexed);
} }
else if (peek< import >(position)) {
root += parse_import();
lex< exactly<';'> >();
}
else if (peek< variable >(position)) { else if (peek< variable >(position)) {
parse_var_def(); parse_var_def();
lex< exactly<';'> >(); lex< exactly<';'> >();
...@@ -35,6 +25,21 @@ namespace Sass { ...@@ -35,6 +25,21 @@ namespace Sass {
lex<optional_spaces>(); lex<optional_spaces>();
} }
} }
Node Document::parse_import()
{
lex< import >();
lex< string_constant >();
string import_path(lexed.unquote());
const char* curr_path_start = path.c_str();
const char* curr_path_end = folders(curr_path_start);
string current_path(curr_path_start, curr_path_end - curr_path_start);
cerr << "importing " << current_path + import_path << endl;
Document importee(current_path + import_path, context);
importee.parse_scss();
source_refs.push_back(importee.source);
return importee.root;
}
void Document::parse_var_def() void Document::parse_var_def()
{ {
...@@ -189,6 +194,20 @@ namespace Sass { ...@@ -189,6 +194,20 @@ namespace Sass {
block.has_rules_or_comments = true; block.has_rules_or_comments = true;
semicolon = true; semicolon = true;
} }
else if (peek< import >(position)) {
Node imported_tree(parse_import());
for (int i = 0; i < imported_tree.children->size(); ++i) {
if (imported_tree.children->at(i).type == Node::comment ||
imported_tree.children->at(i).type == Node::rule) {
block.has_rules_or_comments = true;
}
else if (imported_tree.children->at(i).type == Node::ruleset) {
block.has_rulesets = true;
}
block << imported_tree.children->at(i);
}
semicolon = true;
}
else if (lex< variable >()) { else if (lex< variable >()) {
parse_var_def(); parse_var_def();
semicolon = true; semicolon = true;
...@@ -224,6 +243,7 @@ namespace Sass { ...@@ -224,6 +243,7 @@ namespace Sass {
lex< hex >() || lex < string_constant >() || lex< hex >() || lex < string_constant >() ||
lex< variable >()) { lex< variable >()) {
if (lexed.begin[0] == '$') { if (lexed.begin[0] == '$') {
cerr << "about to fetch variable: " << string(lexed) << endl;
Node fetched(context.environment[lexed]); Node fetched(context.environment[lexed]);
for (int i = 0; i < fetched.children->size(); ++i) { for (int i = 0; i < fetched.children->size(); ++i) {
values << fetched.children->at(i); values << fetched.children->at(i);
...@@ -236,9 +256,9 @@ namespace Sass { ...@@ -236,9 +256,9 @@ namespace Sass {
return values; return values;
} }
char* Document::look_for_rule(char* start) const char* Document::look_for_rule(const char* start)
{ {
char* p = start ? start : position; const char* p = start ? start : position;
(p = peek< identifier >(p)) && (p = peek< identifier >(p)) &&
(p = peek< exactly<':'> >(p)) && (p = peek< exactly<':'> >(p)) &&
(p = look_for_values(p)) && (p = look_for_values(p)) &&
...@@ -246,10 +266,10 @@ namespace Sass { ...@@ -246,10 +266,10 @@ namespace Sass {
return p; return p;
} }
char* Document::look_for_values(char* start) const char* Document::look_for_values(const char* start)
{ {
char* p = start ? start : position; const char* p = start ? start : position;
char* q; const char* q;
while ((q = peek< identifier >(p)) || (q = peek< dimension >(p)) || while ((q = peek< identifier >(p)) || (q = peek< dimension >(p)) ||
(q = peek< percentage >(p)) || (q = peek< number >(p)) || (q = peek< percentage >(p)) || (q = peek< number >(p)) ||
(q = peek< hex >(p)) || (q = peek< string_constant >(p)) || (q = peek< hex >(p)) || (q = peek< string_constant >(p)) ||
......
...@@ -137,6 +137,14 @@ namespace Sass { ...@@ -137,6 +137,14 @@ namespace Sass {
return *this; return *this;
} }
Node& operator+=(const Node& n)
{
for (int i = 0; i < n.children->size(); ++i) {
children->push_back(n.children->at(i));
}
return *this;
}
string to_string(const string& prefix) string to_string(const string& prefix)
{ {
if (type == selector) { if (type == selector) {
......
div {
span {
moo: goo;
}
}
$x: boo;
\ No newline at end of file
hoo {
mux: scooba-dee-doo;
flux: gooboo $x;
}
\ No newline at end of file
@import "a.scss";
foo {
blah: blah;
goo {
blee: blee;
@import "../14_imports/b.scss";
hello: world;
}
@import "sub/c.scss";
}
\ No newline at end of file
blux {
hey: another thing;
ho: will this work;
}
\ 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