sassc 1.7.1 → 1.8.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/ext/libsass/.gitignore +10 -6
- data/ext/libsass/.travis.yml +4 -1
- data/ext/libsass/GNUmakefile.am +88 -0
- data/ext/libsass/Makefile +157 -76
- data/ext/libsass/Makefile.conf +47 -0
- data/ext/libsass/Readme.md +13 -14
- data/ext/libsass/appveyor.yml +25 -41
- data/ext/libsass/configure.ac +20 -7
- data/ext/libsass/contrib/plugin.cpp +1 -1
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
- data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
- data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
- data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
- data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
- data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
- data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
- data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
- data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
- data/ext/libsass/script/ci-build-libsass +67 -23
- data/ext/libsass/src/GNUmakefile.am +54 -0
- data/ext/libsass/src/ast.cpp +2029 -0
- data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
- data/ext/libsass/src/ast_def_macros.hpp +47 -0
- data/ext/libsass/src/ast_factory.hpp +93 -0
- data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
- data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
- data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
- data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
- data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
- data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
- data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
- data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
- data/ext/libsass/src/color_maps.cpp +643 -0
- data/ext/libsass/src/color_maps.hpp +333 -0
- data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
- data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
- data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
- data/ext/libsass/src/context.hpp +150 -0
- data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
- data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
- data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
- data/ext/libsass/src/debugger.hpp +683 -0
- data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
- data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
- data/ext/libsass/src/environment.cpp +184 -0
- data/ext/libsass/src/environment.hpp +92 -0
- data/ext/libsass/src/error_handling.cpp +46 -0
- data/ext/libsass/src/error_handling.hpp +34 -0
- data/ext/libsass/src/eval.cpp +1462 -0
- data/ext/libsass/src/eval.hpp +107 -0
- data/ext/libsass/src/expand.cpp +653 -0
- data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
- data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
- data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
- data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
- data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
- data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
- data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
- data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
- data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
- data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
- data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
- data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
- data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
- data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
- data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
- data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
- data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
- data/ext/libsass/src/memory_manager.cpp +76 -0
- data/ext/libsass/src/memory_manager.hpp +48 -0
- data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
- data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
- data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
- data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
- data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
- data/ext/libsass/src/parser.cpp +2529 -0
- data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
- data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
- data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
- data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
- data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
- data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
- data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
- data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
- data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
- data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
- data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
- data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
- data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
- data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
- data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
- data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
- data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
- data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
- data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
- data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
- data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
- data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
- data/ext/libsass/src/to_c.cpp +73 -0
- data/ext/libsass/src/to_c.hpp +41 -0
- data/ext/libsass/src/to_string.cpp +47 -0
- data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
- data/ext/libsass/src/to_value.cpp +109 -0
- data/ext/libsass/src/to_value.hpp +50 -0
- data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
- data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
- data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
- data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
- data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
- data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
- data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
- data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
- data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
- data/ext/libsass/src/util.hpp +59 -0
- data/ext/libsass/src/values.cpp +137 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/ext/libsass/test/test_node.cpp +33 -33
- data/ext/libsass/test/test_paths.cpp +5 -6
- data/ext/libsass/test/test_selector_difference.cpp +4 -5
- data/ext/libsass/test/test_specificity.cpp +4 -5
- data/ext/libsass/test/test_subset_map.cpp +91 -91
- data/ext/libsass/test/test_superselector.cpp +11 -11
- data/ext/libsass/test/test_unification.cpp +4 -4
- data/ext/libsass/win/libsass.targets +101 -0
- data/ext/libsass/win/libsass.vcxproj +45 -127
- data/ext/libsass/win/libsass.vcxproj.filters +303 -0
- data/lib/sassc/import_handler.rb +1 -1
- data/lib/sassc/native/native_functions_api.rb +3 -3
- data/lib/sassc/version.rb +1 -1
- data/test/custom_importer_test.rb +1 -4
- data/test/functions_test.rb +3 -2
- data/test/native_test.rb +4 -3
- metadata +117 -110
- data/ext/libsass/Makefile.am +0 -146
- data/ext/libsass/ast.cpp +0 -945
- data/ext/libsass/ast_def_macros.hpp +0 -21
- data/ext/libsass/ast_factory.hpp +0 -92
- data/ext/libsass/color_names.hpp +0 -327
- data/ext/libsass/context.hpp +0 -157
- data/ext/libsass/contextualize.cpp +0 -148
- data/ext/libsass/contextualize.hpp +0 -46
- data/ext/libsass/contextualize_eval.cpp +0 -93
- data/ext/libsass/contextualize_eval.hpp +0 -44
- data/ext/libsass/debugger.hpp +0 -558
- data/ext/libsass/environment.hpp +0 -163
- data/ext/libsass/error_handling.cpp +0 -35
- data/ext/libsass/error_handling.hpp +0 -32
- data/ext/libsass/eval.cpp +0 -1392
- data/ext/libsass/eval.hpp +0 -88
- data/ext/libsass/expand.cpp +0 -575
- data/ext/libsass/memory_manager.hpp +0 -57
- data/ext/libsass/parser.cpp +0 -2403
- data/ext/libsass/posix/getopt.c +0 -562
- data/ext/libsass/posix/getopt.h +0 -95
- data/ext/libsass/to_c.cpp +0 -61
- data/ext/libsass/to_c.hpp +0 -44
- data/ext/libsass/to_string.cpp +0 -34
- data/ext/libsass/util.hpp +0 -54
- data/ext/libsass/win/libsass.filters +0 -312
@@ -5,7 +5,6 @@
|
|
5
5
|
#include "utf8_string.hpp"
|
6
6
|
|
7
7
|
namespace Sass {
|
8
|
-
using namespace std;
|
9
8
|
|
10
9
|
Emitter::Emitter(Context* ctx)
|
11
10
|
: wbuf(),
|
@@ -23,7 +22,7 @@ namespace Sass {
|
|
23
22
|
{ }
|
24
23
|
|
25
24
|
// return buffer as string
|
26
|
-
string Emitter::get_buffer(void)
|
25
|
+
std::string Emitter::get_buffer(void)
|
27
26
|
{
|
28
27
|
return wbuf.buffer;
|
29
28
|
}
|
@@ -38,10 +37,10 @@ namespace Sass {
|
|
38
37
|
void Emitter::add_source_index(size_t idx)
|
39
38
|
{ wbuf.smap.source_index.push_back(idx); }
|
40
39
|
|
41
|
-
string Emitter::generate_source_map(Context &ctx)
|
40
|
+
std::string Emitter::generate_source_map(Context &ctx)
|
42
41
|
{ return wbuf.smap.generate_source_map(ctx); }
|
43
42
|
|
44
|
-
void Emitter::set_filename(const string& str)
|
43
|
+
void Emitter::set_filename(const std::string& str)
|
45
44
|
{ wbuf.smap.file = str; }
|
46
45
|
|
47
46
|
void Emitter::add_open_mapping(AST_Node* node)
|
@@ -67,7 +66,7 @@ namespace Sass {
|
|
67
66
|
{
|
68
67
|
// check the schedule
|
69
68
|
if (scheduled_linefeed) {
|
70
|
-
string linefeeds = "";
|
69
|
+
std::string linefeeds = "";
|
71
70
|
|
72
71
|
for (size_t i = 0; i < scheduled_linefeed; i++)
|
73
72
|
linefeeds += ctx ? ctx->linefeed : "\n";
|
@@ -76,7 +75,7 @@ namespace Sass {
|
|
76
75
|
append_string(linefeeds);
|
77
76
|
|
78
77
|
} else if (scheduled_space) {
|
79
|
-
string spaces(scheduled_space, ' ');
|
78
|
+
std::string spaces(scheduled_space, ' ');
|
80
79
|
scheduled_space = 0;
|
81
80
|
append_string(spaces);
|
82
81
|
}
|
@@ -94,21 +93,21 @@ namespace Sass {
|
|
94
93
|
}
|
95
94
|
|
96
95
|
// prepend some text or token to the buffer
|
97
|
-
void Emitter::prepend_string(const string& text)
|
96
|
+
void Emitter::prepend_string(const std::string& text)
|
98
97
|
{
|
99
98
|
wbuf.smap.prepend(Offset(text));
|
100
99
|
wbuf.buffer = text + wbuf.buffer;
|
101
100
|
}
|
102
101
|
|
103
102
|
// append some text or token to the buffer
|
104
|
-
void Emitter::append_string(const string& text)
|
103
|
+
void Emitter::append_string(const std::string& text)
|
105
104
|
{
|
106
105
|
// write space/lf
|
107
106
|
flush_schedules();
|
108
107
|
|
109
108
|
if (in_comment && output_style() == COMPACT) {
|
110
109
|
// unescape comment nodes
|
111
|
-
string out = comment_to_string(text);
|
110
|
+
std::string out = comment_to_string(text);
|
112
111
|
// add to buffer
|
113
112
|
wbuf.buffer += out;
|
114
113
|
// account for data in source-maps
|
@@ -122,7 +121,7 @@ namespace Sass {
|
|
122
121
|
}
|
123
122
|
|
124
123
|
// append some white-space only text
|
125
|
-
void Emitter::append_wspace(const string& text)
|
124
|
+
void Emitter::append_wspace(const std::string& text)
|
126
125
|
{
|
127
126
|
if (text.empty()) return;
|
128
127
|
if (peek_linefeed(text.c_str())) {
|
@@ -133,7 +132,7 @@ namespace Sass {
|
|
133
132
|
|
134
133
|
// append some text or token to the buffer
|
135
134
|
// this adds source-mappings for node start and end
|
136
|
-
void Emitter::append_token(const string& text, AST_Node* node)
|
135
|
+
void Emitter::append_token(const std::string& text, AST_Node* node)
|
137
136
|
{
|
138
137
|
flush_schedules();
|
139
138
|
add_open_mapping(node);
|
@@ -149,7 +148,7 @@ namespace Sass {
|
|
149
148
|
if (output_style() == COMPACT) return;
|
150
149
|
if (scheduled_linefeed && indentation)
|
151
150
|
scheduled_linefeed = 1;
|
152
|
-
string indent = "";
|
151
|
+
std::string indent = "";
|
153
152
|
for (size_t i = 0; i < indentation; i++)
|
154
153
|
indent += ctx ? ctx->indent : " ";
|
155
154
|
append_string(indent);
|
@@ -171,7 +170,7 @@ namespace Sass {
|
|
171
170
|
|
172
171
|
void Emitter::append_comma_separator()
|
173
172
|
{
|
174
|
-
scheduled_space = 0;
|
173
|
+
// scheduled_space = 0;
|
175
174
|
append_string(",");
|
176
175
|
append_optional_space();
|
177
176
|
}
|
@@ -227,6 +226,7 @@ namespace Sass {
|
|
227
226
|
|
228
227
|
void Emitter::append_scope_opener(AST_Node* node)
|
229
228
|
{
|
229
|
+
scheduled_linefeed = 0;
|
230
230
|
append_optional_space();
|
231
231
|
flush_schedules();
|
232
232
|
if (node) add_open_mapping(node);
|
@@ -7,26 +7,25 @@
|
|
7
7
|
|
8
8
|
namespace Sass {
|
9
9
|
class Context;
|
10
|
-
using namespace std;
|
11
10
|
|
12
11
|
class Emitter {
|
13
12
|
|
14
13
|
public:
|
15
14
|
Emitter(Context* ctx);
|
16
|
-
virtual ~Emitter() { }
|
15
|
+
virtual ~Emitter() { }
|
17
16
|
|
18
17
|
protected:
|
19
18
|
OutputBuffer wbuf;
|
20
19
|
public:
|
21
|
-
const string buffer(void) { return wbuf.buffer; }
|
20
|
+
const std::string& buffer(void) { return wbuf.buffer; }
|
22
21
|
const SourceMap smap(void) { return wbuf.smap; }
|
23
22
|
const OutputBuffer output(void) { return wbuf; }
|
24
23
|
// proxy methods for source maps
|
25
24
|
void add_source_index(size_t idx);
|
26
|
-
void set_filename(const string& str);
|
25
|
+
void set_filename(const std::string& str);
|
27
26
|
void add_open_mapping(AST_Node* node);
|
28
27
|
void add_close_mapping(AST_Node* node);
|
29
|
-
string generate_source_map(Context &ctx);
|
28
|
+
std::string generate_source_map(Context &ctx);
|
30
29
|
ParserState remap(const ParserState& pstate);
|
31
30
|
|
32
31
|
public:
|
@@ -50,8 +49,8 @@ namespace Sass {
|
|
50
49
|
bool in_comma_array;
|
51
50
|
|
52
51
|
public:
|
53
|
-
// return buffer as string
|
54
|
-
string get_buffer(void);
|
52
|
+
// return buffer as std::string
|
53
|
+
std::string get_buffer(void);
|
55
54
|
// flush scheduled space/linefeed
|
56
55
|
Output_Style output_style(void);
|
57
56
|
// add outstanding linefeed
|
@@ -59,15 +58,15 @@ namespace Sass {
|
|
59
58
|
// flush scheduled space/linefeed
|
60
59
|
void flush_schedules(void);
|
61
60
|
// prepend some text or token to the buffer
|
62
|
-
void prepend_string(const string& text);
|
61
|
+
void prepend_string(const std::string& text);
|
63
62
|
void prepend_output(const OutputBuffer& out);
|
64
63
|
// append some text or token to the buffer
|
65
|
-
void append_string(const string& text);
|
64
|
+
void append_string(const std::string& text);
|
66
65
|
// append some white-space only text
|
67
|
-
void append_wspace(const string& text);
|
66
|
+
void append_wspace(const std::string& text);
|
68
67
|
// append some text or token to the buffer
|
69
68
|
// this adds source-mappings for node start and end
|
70
|
-
void append_token(const string& text, AST_Node* node);
|
69
|
+
void append_token(const std::string& text, AST_Node* node);
|
71
70
|
|
72
71
|
public: // syntax sugar
|
73
72
|
void append_indentation();
|
@@ -0,0 +1,184 @@
|
|
1
|
+
#include "ast.hpp"
|
2
|
+
#include "environment.hpp"
|
3
|
+
|
4
|
+
namespace Sass {
|
5
|
+
|
6
|
+
template <typename T>
|
7
|
+
Environment<T>::Environment() : local_frame_(std::map<std::string, T>()), parent_(0) { }
|
8
|
+
template <typename T>
|
9
|
+
Environment<T>::Environment(Environment<T>* env) : local_frame_(std::map<std::string, T>()), parent_(env) { }
|
10
|
+
template <typename T>
|
11
|
+
Environment<T>::Environment(Environment<T>& env) : local_frame_(std::map<std::string, T>()), parent_(&env) { }
|
12
|
+
|
13
|
+
// link parent to create a stack
|
14
|
+
template <typename T>
|
15
|
+
void Environment<T>::link(Environment& env) { parent_ = &env; }
|
16
|
+
template <typename T>
|
17
|
+
void Environment<T>::link(Environment* env) { parent_ = env; }
|
18
|
+
|
19
|
+
// this is used to find the global frame
|
20
|
+
// which is the second last on the stack
|
21
|
+
template <typename T>
|
22
|
+
bool Environment<T>::is_lexical() const
|
23
|
+
{
|
24
|
+
return !! parent_ && parent_->parent_;
|
25
|
+
}
|
26
|
+
|
27
|
+
// only match the real root scope
|
28
|
+
// there is still a parent around
|
29
|
+
// not sure what it is actually use for
|
30
|
+
// I guess we store functions etc. there
|
31
|
+
template <typename T>
|
32
|
+
bool Environment<T>::is_global() const
|
33
|
+
{
|
34
|
+
return parent_ && ! parent_->parent_;
|
35
|
+
}
|
36
|
+
|
37
|
+
template <typename T>
|
38
|
+
std::map<std::string, T>& Environment<T>::local_frame() {
|
39
|
+
return local_frame_;
|
40
|
+
}
|
41
|
+
|
42
|
+
template <typename T>
|
43
|
+
bool Environment<T>::has_local(const std::string& key) const
|
44
|
+
{ return local_frame_.find(key) != local_frame_.end(); }
|
45
|
+
|
46
|
+
template <typename T>
|
47
|
+
T& Environment<T>::get_local(const std::string& key)
|
48
|
+
{ return local_frame_[key]; }
|
49
|
+
|
50
|
+
template <typename T>
|
51
|
+
void Environment<T>::set_local(const std::string& key, T val)
|
52
|
+
{
|
53
|
+
local_frame_[key] = val;
|
54
|
+
}
|
55
|
+
|
56
|
+
template <typename T>
|
57
|
+
void Environment<T>::del_local(const std::string& key)
|
58
|
+
{ local_frame_.erase(key); }
|
59
|
+
|
60
|
+
template <typename T>
|
61
|
+
Environment<T>* Environment<T>::global_env()
|
62
|
+
{
|
63
|
+
Environment* cur = this;
|
64
|
+
while (cur->is_lexical()) {
|
65
|
+
cur = cur->parent_;
|
66
|
+
}
|
67
|
+
return cur;
|
68
|
+
}
|
69
|
+
|
70
|
+
template <typename T>
|
71
|
+
bool Environment<T>::has_global(const std::string& key)
|
72
|
+
{ return global_env()->has(key); }
|
73
|
+
|
74
|
+
template <typename T>
|
75
|
+
T& Environment<T>::get_global(const std::string& key)
|
76
|
+
{ return (*global_env())[key]; }
|
77
|
+
|
78
|
+
template <typename T>
|
79
|
+
void Environment<T>::set_global(const std::string& key, T val)
|
80
|
+
{
|
81
|
+
global_env()->local_frame_[key] = val;
|
82
|
+
}
|
83
|
+
|
84
|
+
template <typename T>
|
85
|
+
void Environment<T>::del_global(const std::string& key)
|
86
|
+
{ global_env()->local_frame_.erase(key); }
|
87
|
+
|
88
|
+
template <typename T>
|
89
|
+
Environment<T>* Environment<T>::lexical_env(const std::string& key)
|
90
|
+
{
|
91
|
+
Environment* cur = this;
|
92
|
+
while (cur) {
|
93
|
+
if (cur->has_local(key)) {
|
94
|
+
return cur;
|
95
|
+
}
|
96
|
+
cur = cur->parent_;
|
97
|
+
}
|
98
|
+
return this;
|
99
|
+
}
|
100
|
+
|
101
|
+
// see if we have a lexical variable
|
102
|
+
// move down the stack but stop before we
|
103
|
+
// reach the global frame (is not included)
|
104
|
+
template <typename T>
|
105
|
+
bool Environment<T>::has_lexical(const std::string& key) const
|
106
|
+
{
|
107
|
+
auto cur = this;
|
108
|
+
while (cur->is_lexical()) {
|
109
|
+
if (cur->has_local(key)) return true;
|
110
|
+
cur = cur->parent_;
|
111
|
+
}
|
112
|
+
return false;
|
113
|
+
}
|
114
|
+
|
115
|
+
// see if we have a lexical we could update
|
116
|
+
// either update already existing lexical value
|
117
|
+
// or if flag is set, we create one if no lexical found
|
118
|
+
template <typename T>
|
119
|
+
void Environment<T>::set_lexical(const std::string& key, T val)
|
120
|
+
{
|
121
|
+
auto cur = this;
|
122
|
+
while (cur->is_lexical()) {
|
123
|
+
if (cur->has_local(key)) {
|
124
|
+
cur->set_local(key, val);
|
125
|
+
return;
|
126
|
+
}
|
127
|
+
cur = cur->parent_;
|
128
|
+
}
|
129
|
+
set_local(key, val);
|
130
|
+
}
|
131
|
+
|
132
|
+
// look on the full stack for key
|
133
|
+
// include all scopes available
|
134
|
+
template <typename T>
|
135
|
+
bool Environment<T>::has(const std::string& key) const
|
136
|
+
{
|
137
|
+
auto cur = this;
|
138
|
+
while (cur) {
|
139
|
+
if (cur->has_local(key)) {
|
140
|
+
return true;
|
141
|
+
}
|
142
|
+
cur = cur->parent_;
|
143
|
+
}
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
|
147
|
+
// use array access for getter and setter functions
|
148
|
+
template <typename T>
|
149
|
+
T& Environment<T>::operator[](const std::string& key)
|
150
|
+
{
|
151
|
+
auto cur = this;
|
152
|
+
while (cur) {
|
153
|
+
if (cur->has_local(key)) {
|
154
|
+
return cur->get_local(key);
|
155
|
+
}
|
156
|
+
cur = cur->parent_;
|
157
|
+
}
|
158
|
+
return get_local(key);
|
159
|
+
}
|
160
|
+
|
161
|
+
#ifdef DEBUG
|
162
|
+
template <typename T>
|
163
|
+
size_t Environment<T>::print(std::string prefix)
|
164
|
+
{
|
165
|
+
size_t indent = 0;
|
166
|
+
if (parent_) indent = parent_->print(prefix) + 1;
|
167
|
+
std::cerr << prefix << std::string(indent, ' ') << "== " << this << std::endl;
|
168
|
+
for (typename std::map<std::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
|
169
|
+
if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
|
170
|
+
std::cerr << prefix << std::string(indent, ' ') << i->first << " " << i->second;
|
171
|
+
if (Value* val = dynamic_cast<Value*>(i->second))
|
172
|
+
{ std::cerr << " : " << val->to_string(true, 5); }
|
173
|
+
std::cerr << std::endl;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
return indent ;
|
177
|
+
}
|
178
|
+
#endif
|
179
|
+
|
180
|
+
// compile implementation for AST_Node
|
181
|
+
template class Environment<AST_Node*>;
|
182
|
+
|
183
|
+
}
|
184
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#ifndef SASS_ENVIRONMENT_H
|
2
|
+
#define SASS_ENVIRONMENT_H
|
3
|
+
|
4
|
+
#include <string>
|
5
|
+
#include <map>
|
6
|
+
|
7
|
+
#include "ast_fwd_decl.hpp"
|
8
|
+
#include "ast_def_macros.hpp"
|
9
|
+
#include "memory_manager.hpp"
|
10
|
+
|
11
|
+
namespace Sass {
|
12
|
+
|
13
|
+
template <typename T>
|
14
|
+
class Environment {
|
15
|
+
// TODO: test with map
|
16
|
+
std::map<std::string, T> local_frame_;
|
17
|
+
ADD_PROPERTY(Environment*, parent)
|
18
|
+
|
19
|
+
public:
|
20
|
+
Memory_Manager mem;
|
21
|
+
Environment();
|
22
|
+
Environment(Environment* env);
|
23
|
+
Environment(Environment& env);
|
24
|
+
|
25
|
+
// link parent to create a stack
|
26
|
+
void link(Environment& env);
|
27
|
+
void link(Environment* env);
|
28
|
+
|
29
|
+
// this is used to find the global frame
|
30
|
+
// which is the second last on the stack
|
31
|
+
bool is_lexical() const;
|
32
|
+
|
33
|
+
// only match the real root scope
|
34
|
+
// there is still a parent around
|
35
|
+
// not sure what it is actually use for
|
36
|
+
// I guess we store functions etc. there
|
37
|
+
bool is_global() const;
|
38
|
+
|
39
|
+
// scope operates on the current frame
|
40
|
+
|
41
|
+
std::map<std::string, T>& local_frame();
|
42
|
+
|
43
|
+
bool has_local(const std::string& key) const;
|
44
|
+
|
45
|
+
T& get_local(const std::string& key);
|
46
|
+
|
47
|
+
// set variable on the current frame
|
48
|
+
void set_local(const std::string& key, T val);
|
49
|
+
|
50
|
+
void del_local(const std::string& key);
|
51
|
+
|
52
|
+
// global operates on the global frame
|
53
|
+
// which is the second last on the stack
|
54
|
+
Environment* global_env();
|
55
|
+
// get the env where the variable already exists
|
56
|
+
// if it does not yet exist, we return current env
|
57
|
+
Environment* lexical_env(const std::string& key);
|
58
|
+
|
59
|
+
bool has_global(const std::string& key);
|
60
|
+
|
61
|
+
T& get_global(const std::string& key);
|
62
|
+
|
63
|
+
// set a variable on the global frame
|
64
|
+
void set_global(const std::string& key, T val);
|
65
|
+
|
66
|
+
void del_global(const std::string& key);
|
67
|
+
|
68
|
+
// see if we have a lexical variable
|
69
|
+
// move down the stack but stop before we
|
70
|
+
// reach the global frame (is not included)
|
71
|
+
bool has_lexical(const std::string& key) const;
|
72
|
+
|
73
|
+
// see if we have a lexical we could update
|
74
|
+
// either update already existing lexical value
|
75
|
+
// or we create a new one on the current frame
|
76
|
+
void set_lexical(const std::string& key, T val);
|
77
|
+
|
78
|
+
// look on the full stack for key
|
79
|
+
// include all scopes available
|
80
|
+
bool has(const std::string& key) const;
|
81
|
+
|
82
|
+
// use array access for getter and setter functions
|
83
|
+
T& operator[](const std::string& key);
|
84
|
+
|
85
|
+
#ifdef DEBUG
|
86
|
+
size_t print(std::string prefix = "");
|
87
|
+
#endif
|
88
|
+
|
89
|
+
};
|
90
|
+
}
|
91
|
+
|
92
|
+
#endif
|