sassc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +24 -0
  8. data/Rakefile +21 -0
  9. data/ext/libsass/.editorconfig +15 -0
  10. data/ext/libsass/.gitattributes +2 -0
  11. data/ext/libsass/.gitignore +61 -0
  12. data/ext/libsass/.travis.yml +38 -0
  13. data/ext/libsass/COPYING +25 -0
  14. data/ext/libsass/INSTALL +1 -0
  15. data/ext/libsass/LICENSE +25 -0
  16. data/ext/libsass/Makefile +223 -0
  17. data/ext/libsass/Makefile.am +145 -0
  18. data/ext/libsass/Readme.md +93 -0
  19. data/ext/libsass/appveyor.yml +76 -0
  20. data/ext/libsass/ast.cpp +581 -0
  21. data/ext/libsass/ast.hpp +1949 -0
  22. data/ext/libsass/ast_def_macros.hpp +16 -0
  23. data/ext/libsass/ast_factory.hpp +87 -0
  24. data/ext/libsass/ast_fwd_decl.hpp +72 -0
  25. data/ext/libsass/b64/cencode.h +32 -0
  26. data/ext/libsass/b64/encode.h +77 -0
  27. data/ext/libsass/backtrace.hpp +81 -0
  28. data/ext/libsass/base64vlq.cpp +43 -0
  29. data/ext/libsass/base64vlq.hpp +28 -0
  30. data/ext/libsass/bind.cpp +187 -0
  31. data/ext/libsass/bind.hpp +18 -0
  32. data/ext/libsass/cencode.c +102 -0
  33. data/ext/libsass/color_names.hpp +324 -0
  34. data/ext/libsass/configure.ac +130 -0
  35. data/ext/libsass/constants.cpp +144 -0
  36. data/ext/libsass/constants.hpp +145 -0
  37. data/ext/libsass/context.cpp +507 -0
  38. data/ext/libsass/context.hpp +150 -0
  39. data/ext/libsass/contextualize.cpp +157 -0
  40. data/ext/libsass/contextualize.hpp +65 -0
  41. data/ext/libsass/copy_c_str.cpp +13 -0
  42. data/ext/libsass/copy_c_str.hpp +5 -0
  43. data/ext/libsass/debug.hpp +39 -0
  44. data/ext/libsass/environment.hpp +75 -0
  45. data/ext/libsass/error_handling.cpp +28 -0
  46. data/ext/libsass/error_handling.hpp +28 -0
  47. data/ext/libsass/eval.cpp +1149 -0
  48. data/ext/libsass/eval.hpp +80 -0
  49. data/ext/libsass/expand.cpp +430 -0
  50. data/ext/libsass/expand.hpp +77 -0
  51. data/ext/libsass/extconf.rb +6 -0
  52. data/ext/libsass/extend.cpp +1962 -0
  53. data/ext/libsass/extend.hpp +50 -0
  54. data/ext/libsass/file.cpp +291 -0
  55. data/ext/libsass/file.hpp +18 -0
  56. data/ext/libsass/functions.cpp +1565 -0
  57. data/ext/libsass/functions.hpp +187 -0
  58. data/ext/libsass/inspect.cpp +727 -0
  59. data/ext/libsass/inspect.hpp +108 -0
  60. data/ext/libsass/json.cpp +1411 -0
  61. data/ext/libsass/json.hpp +117 -0
  62. data/ext/libsass/kwd_arg_macros.hpp +23 -0
  63. data/ext/libsass/m4/.gitkeep +0 -0
  64. data/ext/libsass/mapping.hpp +17 -0
  65. data/ext/libsass/memory_manager.hpp +54 -0
  66. data/ext/libsass/node.cpp +251 -0
  67. data/ext/libsass/node.hpp +122 -0
  68. data/ext/libsass/operation.hpp +153 -0
  69. data/ext/libsass/output_compressed.cpp +401 -0
  70. data/ext/libsass/output_compressed.hpp +95 -0
  71. data/ext/libsass/output_nested.cpp +364 -0
  72. data/ext/libsass/output_nested.hpp +108 -0
  73. data/ext/libsass/parser.cpp +2016 -0
  74. data/ext/libsass/parser.hpp +264 -0
  75. data/ext/libsass/paths.hpp +69 -0
  76. data/ext/libsass/position.hpp +22 -0
  77. data/ext/libsass/posix/getopt.c +562 -0
  78. data/ext/libsass/posix/getopt.h +95 -0
  79. data/ext/libsass/prelexer.cpp +688 -0
  80. data/ext/libsass/prelexer.hpp +513 -0
  81. data/ext/libsass/remove_placeholders.cpp +59 -0
  82. data/ext/libsass/remove_placeholders.hpp +43 -0
  83. data/ext/libsass/res/resource.rc +35 -0
  84. data/ext/libsass/sass.cpp +33 -0
  85. data/ext/libsass/sass.h +60 -0
  86. data/ext/libsass/sass2scss.cpp +834 -0
  87. data/ext/libsass/sass2scss.h +110 -0
  88. data/ext/libsass/sass_context.cpp +709 -0
  89. data/ext/libsass/sass_context.h +120 -0
  90. data/ext/libsass/sass_functions.cpp +137 -0
  91. data/ext/libsass/sass_functions.h +90 -0
  92. data/ext/libsass/sass_interface.cpp +277 -0
  93. data/ext/libsass/sass_interface.h +97 -0
  94. data/ext/libsass/sass_util.cpp +136 -0
  95. data/ext/libsass/sass_util.hpp +259 -0
  96. data/ext/libsass/sass_values.cpp +337 -0
  97. data/ext/libsass/sass_values.h +124 -0
  98. data/ext/libsass/script/bootstrap +10 -0
  99. data/ext/libsass/script/branding +10 -0
  100. data/ext/libsass/script/ci-build-libsass +72 -0
  101. data/ext/libsass/script/ci-install-compiler +4 -0
  102. data/ext/libsass/script/ci-install-deps +19 -0
  103. data/ext/libsass/script/ci-report-coverage +25 -0
  104. data/ext/libsass/script/coveralls-debug +32 -0
  105. data/ext/libsass/script/spec +5 -0
  106. data/ext/libsass/script/tap-driver +652 -0
  107. data/ext/libsass/script/tap-runner +1 -0
  108. data/ext/libsass/source_map.cpp +133 -0
  109. data/ext/libsass/source_map.hpp +46 -0
  110. data/ext/libsass/subset_map.hpp +145 -0
  111. data/ext/libsass/support/libsass.pc.in +11 -0
  112. data/ext/libsass/test-driver +127 -0
  113. data/ext/libsass/test/test_node.cpp +98 -0
  114. data/ext/libsass/test/test_paths.cpp +29 -0
  115. data/ext/libsass/test/test_selector_difference.cpp +28 -0
  116. data/ext/libsass/test/test_specificity.cpp +28 -0
  117. data/ext/libsass/test/test_subset_map.cpp +472 -0
  118. data/ext/libsass/test/test_superselector.cpp +71 -0
  119. data/ext/libsass/test/test_unification.cpp +33 -0
  120. data/ext/libsass/to_c.cpp +61 -0
  121. data/ext/libsass/to_c.hpp +44 -0
  122. data/ext/libsass/to_string.cpp +29 -0
  123. data/ext/libsass/to_string.hpp +32 -0
  124. data/ext/libsass/token.hpp +32 -0
  125. data/ext/libsass/units.cpp +54 -0
  126. data/ext/libsass/units.hpp +10 -0
  127. data/ext/libsass/utf8.h +34 -0
  128. data/ext/libsass/utf8/checked.h +327 -0
  129. data/ext/libsass/utf8/core.h +329 -0
  130. data/ext/libsass/utf8/unchecked.h +228 -0
  131. data/ext/libsass/utf8_string.cpp +102 -0
  132. data/ext/libsass/utf8_string.hpp +36 -0
  133. data/ext/libsass/util.cpp +189 -0
  134. data/ext/libsass/util.hpp +26 -0
  135. data/ext/libsass/win/libsass.filters +291 -0
  136. data/ext/libsass/win/libsass.sln +28 -0
  137. data/ext/libsass/win/libsass.vcxproj +255 -0
  138. data/lib/sassc.rb +6 -0
  139. data/lib/sassc/engine.rb +13 -0
  140. data/lib/sassc/native.rb +44 -0
  141. data/lib/sassc/native/native_context_api.rb +140 -0
  142. data/lib/sassc/native/native_functions_api.rb +41 -0
  143. data/lib/sassc/native/sass_input_style.rb +11 -0
  144. data/lib/sassc/native/sass_output_style.rb +10 -0
  145. data/lib/sassc/native/sass_value.rb +95 -0
  146. data/lib/sassc/native/string_list.rb +8 -0
  147. data/lib/sassc/version.rb +3 -0
  148. data/sassc.gemspec +43 -0
  149. data/test/smoke_test.rb +171 -0
  150. data/test/test_helper.rb +4 -0
  151. metadata +281 -0
@@ -0,0 +1,150 @@
1
+ #define SASS_CONTEXT
2
+
3
+ #include <string>
4
+ #include <vector>
5
+ #include <map>
6
+ #include "kwd_arg_macros.hpp"
7
+
8
+ #ifndef SASS_MEMORY_MANAGER
9
+ #include "memory_manager.hpp"
10
+ #endif
11
+
12
+ #ifndef SASS_ENVIRONMENT
13
+ #include "environment.hpp"
14
+ #endif
15
+
16
+ #ifndef SASS_SOURCE_MAP
17
+ #include "source_map.hpp"
18
+ #endif
19
+
20
+ #ifndef SASS_SUBSET_MAP
21
+ #include "subset_map.hpp"
22
+ #endif
23
+
24
+ #define BUFFERSIZE 255
25
+ #include "b64/encode.h"
26
+
27
+ #include "sass_functions.h"
28
+
29
+ struct Sass_C_Function_Descriptor;
30
+
31
+ namespace Sass {
32
+ using namespace std;
33
+ class AST_Node;
34
+ class Block;
35
+ class Expression;
36
+ class Color;
37
+ struct Backtrace;
38
+ // typedef const char* Signature;
39
+ // struct Context;
40
+ // typedef Environment<AST_Node*> Env;
41
+ // typedef Expression* (*Native_Function)(Env&, Context&, Signature, string, size_t);
42
+
43
+ enum Output_Style { NESTED, EXPANDED, COMPACT, COMPRESSED, FORMATTED };
44
+
45
+ struct Sass_Queued {
46
+ string abs_path;
47
+ string load_path;
48
+ const char* source;
49
+ public:
50
+ Sass_Queued(const string& load_path, const string& abs_path, const char* source);
51
+ };
52
+
53
+ struct Context {
54
+ Memory_Manager<AST_Node> mem;
55
+
56
+ const char* source_c_str;
57
+
58
+ // c-strs containing Sass file contents
59
+ // we will overtake ownership of memory
60
+ vector<const char*> sources;
61
+ // absolute paths to includes
62
+ vector<string> included_files;
63
+ // relative links to includes
64
+ vector<string> include_links;
65
+ // vectors above have same size
66
+
67
+ vector<string> include_paths; // lookup paths for includes
68
+ vector<Sass_Queued> queue; // queue of files to be parsed
69
+ map<string, Block*> style_sheets; // map of paths to ASTs
70
+ SourceMap source_map;
71
+ vector<Sass_C_Function_Callback> c_functions;
72
+
73
+ string image_path; // for the image-url Sass function
74
+ string input_path; // for relative paths in src-map
75
+ string output_path; // for relative paths to the output
76
+ bool source_comments; // for inline debug comments in css output
77
+ Output_Style output_style; // output style for the generated css code
78
+ string source_map_file; // path to source map file (enables feature)
79
+ bool source_map_embed; // embed in sourceMappingUrl (as data-url)
80
+ bool source_map_contents; // insert included contents into source map
81
+ bool omit_source_map_url; // disable source map comment in css output
82
+ bool is_indented_syntax_src; // treat source string as sass
83
+
84
+ // overload import calls
85
+ Sass_C_Import_Callback importer;
86
+ vector<struct Sass_Import*> import_stack;
87
+
88
+ map<string, Color*> names_to_colors;
89
+ map<int, string> colors_to_names;
90
+
91
+ size_t precision; // precision for outputting fractional numbers
92
+ bool _skip_source_map_update; // status flag to skip source map updates
93
+
94
+ KWD_ARG_SET(Data) {
95
+ KWD_ARG(Data, const char*, source_c_str);
96
+ KWD_ARG(Data, string, entry_point);
97
+ KWD_ARG(Data, string, input_path);
98
+ KWD_ARG(Data, string, output_path);
99
+ KWD_ARG(Data, string, image_path);
100
+ KWD_ARG(Data, const char*, include_paths_c_str);
101
+ KWD_ARG(Data, const char**, include_paths_array);
102
+ KWD_ARG(Data, vector<string>, include_paths);
103
+ KWD_ARG(Data, bool, source_comments);
104
+ KWD_ARG(Data, Output_Style, output_style);
105
+ KWD_ARG(Data, string, source_map_file);
106
+ KWD_ARG(Data, bool, omit_source_map_url);
107
+ KWD_ARG(Data, bool, is_indented_syntax_src);
108
+ KWD_ARG(Data, size_t, precision);
109
+ KWD_ARG(Data, bool, _skip_source_map_update);
110
+ KWD_ARG(Data, bool, source_map_embed);
111
+ KWD_ARG(Data, bool, source_map_contents);
112
+ KWD_ARG(Data, Sass_C_Import_Callback, importer);
113
+ };
114
+
115
+ Context(Data);
116
+ ~Context();
117
+ static string get_cwd();
118
+ void setup_color_map();
119
+ string add_file(string);
120
+ Block* parse_file();
121
+ string add_file(string, string);
122
+ Block* parse_string();
123
+ void add_source(string, string, const char*);
124
+ // allow to optionally overwrite the input path
125
+ // default argument for input_path is string("stdin")
126
+ // usefull to influence the source-map generating etc.
127
+ char* compile_file();
128
+ char* compile_string();
129
+ char* compile_block(Block* root);
130
+ char* generate_source_map();
131
+
132
+ vector<string> get_included_files(size_t skip = 0);
133
+
134
+ private:
135
+ void collect_include_paths(const char* paths_str);
136
+ void collect_include_paths(const char** paths_array);
137
+ string format_source_mapping_url(const string& file);
138
+
139
+ string cwd;
140
+
141
+ // void register_built_in_functions(Env* env);
142
+ // void register_function(Signature sig, Native_Function f, Env* env);
143
+ // void register_function(Signature sig, Native_Function f, size_t arity, Env* env);
144
+ // void register_overload_stub(string name, Env* env);
145
+
146
+ public:
147
+ Subset_Map<string, pair<Complex_Selector*, Compound_Selector*> > subset_map;
148
+ };
149
+
150
+ }
@@ -0,0 +1,157 @@
1
+ #include "contextualize.hpp"
2
+ #include "ast.hpp"
3
+ #include "eval.hpp"
4
+ #include "backtrace.hpp"
5
+ #include "to_string.hpp"
6
+ #include "parser.hpp"
7
+
8
+ namespace Sass {
9
+
10
+ Contextualize::Contextualize(Context& ctx, Eval* eval, Env* env, Backtrace* bt, Selector* placeholder, Selector* extender)
11
+ : ctx(ctx), eval(eval), env(env), parent(0), backtrace(bt), placeholder(placeholder), extender(extender)
12
+ { }
13
+
14
+ Contextualize::~Contextualize() { }
15
+
16
+ Selector* Contextualize::fallback_impl(AST_Node* n)
17
+ { return parent; }
18
+
19
+ Contextualize* Contextualize::with(Selector* s, Env* e, Backtrace* bt, Selector* p, Selector* ex)
20
+ {
21
+ parent = s;
22
+ env = e;
23
+ backtrace = bt;
24
+ placeholder = p;
25
+ extender = ex;
26
+ return this;
27
+ }
28
+
29
+ Selector* Contextualize::operator()(Selector_Schema* s)
30
+ {
31
+ To_String to_string;
32
+ string result_str(s->contents()->perform(eval->with(env, backtrace))->perform(&to_string));
33
+ result_str += '{'; // the parser looks for a brace to end the selector
34
+ Selector* result_sel = Parser::from_c_str(result_str.c_str(), ctx, s->path(), s->position()).parse_selector_group();
35
+ return result_sel->perform(this);
36
+ }
37
+
38
+ Selector* Contextualize::operator()(Selector_List* s)
39
+ {
40
+ Selector_List* p = static_cast<Selector_List*>(parent);
41
+ Selector_List* ss = 0;
42
+ if (p) {
43
+ ss = new (ctx.mem) Selector_List(s->path(), s->position(), p->length() * s->length());
44
+ for (size_t i = 0, L = p->length(); i < L; ++i) {
45
+ for (size_t j = 0, L = s->length(); j < L; ++j) {
46
+ parent = (*p)[i];
47
+ Complex_Selector* comb = static_cast<Complex_Selector*>((*s)[j]->perform(this));
48
+ if (comb) *ss << comb;
49
+ }
50
+ }
51
+ }
52
+ else {
53
+ ss = new (ctx.mem) Selector_List(s->path(), s->position(), s->length());
54
+ for (size_t j = 0, L = s->length(); j < L; ++j) {
55
+ Complex_Selector* comb = static_cast<Complex_Selector*>((*s)[j]->perform(this));
56
+ if (comb) *ss << comb;
57
+ }
58
+ }
59
+ return ss->length() ? ss : 0;
60
+ }
61
+
62
+ Selector* Contextualize::operator()(Complex_Selector* s)
63
+ {
64
+ To_String to_string;
65
+ Complex_Selector* ss = new (ctx.mem) Complex_Selector(*s);
66
+ Compound_Selector* new_head = 0;
67
+ Complex_Selector* new_tail = 0;
68
+ if (ss->head()) {
69
+ new_head = static_cast<Compound_Selector*>(s->head()->perform(this));
70
+ ss->head(new_head);
71
+ }
72
+ if (ss->tail()) {
73
+ new_tail = static_cast<Complex_Selector*>(s->tail()->perform(this));
74
+ ss->tail(new_tail);
75
+ }
76
+ if ((new_head && new_head->has_placeholder()) || (new_tail && new_tail->has_placeholder())) {
77
+ ss->has_placeholder(true);
78
+ }
79
+ else {
80
+ ss->has_placeholder(false);
81
+ }
82
+ if (!ss->head() && ss->combinator() == Complex_Selector::ANCESTOR_OF) {
83
+ return ss->tail();
84
+ }
85
+ else {
86
+ return ss;
87
+ }
88
+ }
89
+
90
+ Selector* Contextualize::operator()(Compound_Selector* s)
91
+ {
92
+ To_String to_string;
93
+ if (placeholder && extender && s->perform(&to_string) == placeholder->perform(&to_string)) {
94
+ return extender;
95
+ }
96
+ Compound_Selector* ss = new (ctx.mem) Compound_Selector(s->path(), s->position(), s->length());
97
+ for (size_t i = 0, L = s->length(); i < L; ++i) {
98
+ Simple_Selector* simp = static_cast<Simple_Selector*>((*s)[i]->perform(this));
99
+ if (simp) *ss << simp;
100
+ }
101
+ return ss->length() ? ss : 0;
102
+ }
103
+
104
+ Selector* Contextualize::operator()(Wrapped_Selector* s)
105
+ {
106
+ Selector* old_parent = parent;
107
+ parent = 0;
108
+ Wrapped_Selector* neg = new (ctx.mem) Wrapped_Selector(s->path(),
109
+ s->position(),
110
+ s->name(),
111
+ s->selector()->perform(this));
112
+ parent = old_parent;
113
+ return neg;
114
+ }
115
+
116
+ Selector* Contextualize::operator()(Pseudo_Selector* s)
117
+ { return s; }
118
+
119
+ Selector* Contextualize::operator()(Attribute_Selector* s)
120
+ {
121
+ // the value might be interpolated; evaluate it
122
+ String* v = s->value();
123
+ if (v && eval) {
124
+ v = static_cast<String*>(v->perform(eval->with(env, backtrace)));
125
+ }
126
+ Attribute_Selector* ss = new (ctx.mem) Attribute_Selector(*s);
127
+ ss->value(v);
128
+ return ss;
129
+ }
130
+
131
+ Selector* Contextualize::operator()(Selector_Qualifier* s)
132
+ { return s; }
133
+
134
+ Selector* Contextualize::operator()(Type_Selector* s)
135
+ { return s; }
136
+
137
+ Selector* Contextualize::operator()(Selector_Placeholder* p)
138
+ {
139
+ To_String to_string;
140
+ if (placeholder && extender && p->perform(&to_string) == placeholder->perform(&to_string)) {
141
+ return extender;
142
+ }
143
+ else {
144
+ return p;
145
+ }
146
+ }
147
+
148
+ Selector* Contextualize::operator()(Selector_Reference* s)
149
+ {
150
+ if (!parent) return 0;
151
+ Selector_Reference* ss = new (ctx.mem) Selector_Reference(*s);
152
+ ss->selector(parent);
153
+ return ss;
154
+ }
155
+
156
+
157
+ }
@@ -0,0 +1,65 @@
1
+ #define SASS_CONTEXTUALIZE
2
+
3
+ #ifndef SASS_ENVIRONMENT
4
+ #include "environment.hpp"
5
+ #endif
6
+
7
+ #ifndef SASS_OPERATION
8
+ #include "operation.hpp"
9
+ #endif
10
+
11
+ namespace Sass {
12
+ class AST_Node;
13
+ class Selector;
14
+ class Selector_Schema;
15
+ class Selector_List;
16
+ class Complex_Selector;
17
+ class Compound_Selector;
18
+ class Wrapped_Selector;
19
+ class Pseudo_Selector;
20
+ class Attribute_Selector;
21
+ class Selector_Qualifier;
22
+ class Type_Selector;
23
+ class Selector_Placeholder;
24
+ class Selector_Reference;
25
+ class Simple_Selector;
26
+ struct Context;
27
+ class Eval;
28
+ struct Backtrace;
29
+
30
+ typedef Environment<AST_Node*> Env;
31
+
32
+ class Contextualize : public Operation_CRTP<Selector*, Contextualize> {
33
+
34
+ Context& ctx;
35
+ Eval* eval;
36
+ Env* env;
37
+ Selector* parent;
38
+ Backtrace* backtrace;
39
+
40
+ Selector* fallback_impl(AST_Node* n);
41
+
42
+ public:
43
+ Selector* placeholder;
44
+ Selector* extender;
45
+ Contextualize(Context&, Eval*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
46
+ virtual ~Contextualize();
47
+ Contextualize* with(Selector*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
48
+ using Operation<Selector*>::operator();
49
+
50
+ Selector* operator()(Selector_Schema*);
51
+ Selector* operator()(Selector_List*);
52
+ Selector* operator()(Complex_Selector*);
53
+ Selector* operator()(Compound_Selector*);
54
+ Selector* operator()(Wrapped_Selector*);
55
+ Selector* operator()(Pseudo_Selector*);
56
+ Selector* operator()(Attribute_Selector*);
57
+ Selector* operator()(Selector_Qualifier*);
58
+ Selector* operator()(Type_Selector*);
59
+ Selector* operator()(Selector_Placeholder*);
60
+ Selector* operator()(Selector_Reference*);
61
+
62
+ template <typename U>
63
+ Selector* fallback(U x) { return fallback_impl(x); }
64
+ };
65
+ }
@@ -0,0 +1,13 @@
1
+ #include <cstdlib>
2
+ #include <cstring>
3
+
4
+ namespace Sass {
5
+ using namespace std;
6
+
7
+ char* copy_c_str(const char* orig)
8
+ {
9
+ char* copy = (char*) malloc(sizeof(char) * strlen(orig) + 1);
10
+ strcpy(copy, orig);
11
+ return copy;
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ namespace Sass {
2
+
3
+ char* copy_c_str(const char*);
4
+
5
+ }
@@ -0,0 +1,39 @@
1
+ #ifndef DEBUG_H
2
+ #define DEBUG_H
3
+
4
+ #include <stdint.h>
5
+
6
+ enum dbg_lvl_t : uint32_t {
7
+ NONE = 0,
8
+ TRIM = 1,
9
+ CHUNKS = 2,
10
+ SUBWEAVE = 4,
11
+ WEAVE = 8,
12
+ EXTEND_COMPOUND = 16,
13
+ EXTEND_COMPLEX = 32,
14
+ LCS = 64,
15
+ EXTEND_OBJECT = 128,
16
+ ALL = UINT32_MAX
17
+ };
18
+
19
+ #ifdef DEBUG
20
+
21
+ #ifndef DEBUG_LVL
22
+ const uint32_t debug_lvl = UINT32_MAX;
23
+ #else
24
+ const uint32_t debug_lvl = (DEBUG_LVL);
25
+ #endif // DEBUG_LVL
26
+
27
+ #define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; }
28
+ #define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; }
29
+ #define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; }
30
+
31
+ #else // DEBUG
32
+
33
+ #define DEBUG_PRINT(lvl, x)
34
+ #define DEBUG_PRINTLN(lvl, x)
35
+ #define DEBUG_EXEC(lvl, x)
36
+
37
+ #endif // DEBUG
38
+
39
+ #endif // DEBUG_H
@@ -0,0 +1,75 @@
1
+ #define SASS_ENVIRONMENT
2
+
3
+ #include <string>
4
+ #include <map>
5
+ #include "ast_def_macros.hpp"
6
+ #include <iostream>
7
+
8
+ namespace Sass {
9
+ using std::string;
10
+ using std::map;
11
+ using std::cerr;
12
+ using std::endl;
13
+
14
+ template <typename T>
15
+ class Environment {
16
+ // TODO: test with unordered_map
17
+ map<string, T> current_frame_;
18
+ ADD_PROPERTY(Environment*, parent);
19
+
20
+ public:
21
+ Environment() : current_frame_(map<string, T>()), parent_(0) { }
22
+
23
+ map<string, T>& current_frame() { return current_frame_; }
24
+
25
+ void link(Environment& env) { parent_ = &env; }
26
+ void link(Environment* env) { parent_ = env; }
27
+
28
+ bool has(const string key) const
29
+ {
30
+ if (current_frame_.count(key)) return true;
31
+ else if (parent_) return parent_->has(key);
32
+ else return false;
33
+ }
34
+
35
+ bool current_frame_has(const string key) const
36
+ { return !!current_frame_.count(key); }
37
+
38
+ Environment* grandparent() const
39
+ {
40
+ if(parent_ && parent_->parent_) return parent_->parent_;
41
+ else return 0;
42
+ }
43
+
44
+ bool global_frame_has(const string key) const
45
+ {
46
+ if(parent_ && !grandparent()) {
47
+ return has(key);
48
+ }
49
+ else if(parent_) {
50
+ return parent_->global_frame_has(key);
51
+ }
52
+ else {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ T& operator[](const string key)
58
+ {
59
+ if (current_frame_.count(key)) return current_frame_[key];
60
+ else if (parent_) return (*parent_)[key];
61
+ else return current_frame_[key];
62
+ }
63
+
64
+ void print()
65
+ {
66
+ for (typename map<string, T>::iterator i = current_frame_.begin(); i != current_frame_.end(); ++i) {
67
+ cerr << i->first << endl;
68
+ }
69
+ if (parent_) {
70
+ cerr << "---" << endl;
71
+ parent_->print();
72
+ }
73
+ }
74
+ };
75
+ }