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 {
struct Context {
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 "document.hpp"
#include <iostream>
namespace Sass {
Document::Document(string path, char* source)
: path(path), source(source),
: path(path), source(source), source_refs(vector<char*>()),
line_number(1), own_source(false),
context(*(new Context())),
root(Node(1, Node::root)),
......@@ -30,7 +31,7 @@ namespace Sass {
}
Document::Document(string path, Context& context)
: path(path), source(source),
: path(path), source(0), source_refs(vector<char*>()),
line_number(1), own_source(false),
context(context),
root(Node(1, Node::root)),
......@@ -48,13 +49,17 @@ namespace Sass {
std::fread(source, sizeof(char), len, f);
source[len] = '\0';
std::fclose(f);
own_source = true;
position = source;
++context.ref_count;
}
Document::~Document() {
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 {
string path;
char* source;
char* position;
vector<char*> source_refs;
const char* position;
size_t line_number;
bool own_source;
......@@ -31,10 +32,10 @@ namespace Sass {
~Document();
template <prelexer mx>
char* peek(char* start = 0)
const char* peek(const char* start = 0)
{
if (!start) start = position;
char* after_whitespace;
const char* after_whitespace;
if (mx == block_comment) {
after_whitespace =
zero_plus< alternatives<spaces, line_comment> >(start);
......@@ -57,7 +58,7 @@ namespace Sass {
else {
after_whitespace = spaces_and_comments(start);
}
char* after_token = mx(after_whitespace);
const char* after_token = mx(after_whitespace);
if (after_token) {
return after_token;
}
......@@ -67,9 +68,9 @@ namespace Sass {
}
template <prelexer mx>
char* lex()
const char* lex()
{
char* after_whitespace;
const char* after_whitespace;
if (mx == block_comment) {
after_whitespace =
zero_plus< alternatives<spaces, line_comment> >(position);
......@@ -94,7 +95,7 @@ namespace Sass {
else {
after_whitespace = spaces_and_comments(position);
}
char* after_token = mx(after_whitespace);
const char* after_token = mx(after_whitespace);
if (after_token) {
line_number += count_interval<'\n'>(position, after_token);
lexed = Token(after_whitespace, after_token);
......@@ -106,6 +107,7 @@ namespace Sass {
}
void parse_scss();
Node parse_import();
void parse_var_def();
Node parse_ruleset();
Node parse_selector_group();
......@@ -118,8 +120,8 @@ namespace Sass {
Node parse_rule();
Node parse_values();
char* look_for_rule(char* start = 0);
char* look_for_values(char* start = 0);
const char* look_for_rule(const char* start = 0);
const char* look_for_values(const char* start = 0);
string emit_css(CSS_Style style);
......
......@@ -7,19 +7,6 @@ namespace Sass {
string Document::emit_css(CSS_Style style) {
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) {
case echo:
root.echo(output);
......
......@@ -7,24 +7,14 @@ namespace Sass {
void Document::parse_scss()
{
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) {
if (lex< block_comment >()) {
root << Node(line_number, Node::comment, lexed);
}
else if (peek< import >(position)) {
root += parse_import();
lex< exactly<';'> >();
}
else if (peek< variable >(position)) {
parse_var_def();
lex< exactly<';'> >();
......@@ -35,6 +25,21 @@ namespace Sass {
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()
{
......@@ -189,6 +194,20 @@ namespace Sass {
block.has_rules_or_comments = 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 >()) {
parse_var_def();
semicolon = true;
......@@ -224,6 +243,7 @@ namespace Sass {
lex< hex >() || lex < string_constant >() ||
lex< variable >()) {
if (lexed.begin[0] == '$') {
cerr << "about to fetch variable: " << string(lexed) << endl;
Node fetched(context.environment[lexed]);
for (int i = 0; i < fetched.children->size(); ++i) {
values << fetched.children->at(i);
......@@ -236,9 +256,9 @@ namespace Sass {
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< exactly<':'> >(p)) &&
(p = look_for_values(p)) &&
......@@ -246,10 +266,10 @@ namespace Sass {
return p;
}
char* Document::look_for_values(char* start)
const char* Document::look_for_values(const char* start)
{
char* p = start ? start : position;
char* q;
const char* p = start ? start : position;
const char* q;
while ((q = peek< identifier >(p)) || (q = peek< dimension >(p)) ||
(q = peek< percentage >(p)) || (q = peek< number >(p)) ||
(q = peek< hex >(p)) || (q = peek< string_constant >(p)) ||
......
......@@ -137,6 +137,14 @@ namespace Sass {
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)
{
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