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.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.gitignore +10 -6
  4. data/ext/libsass/.travis.yml +4 -1
  5. data/ext/libsass/GNUmakefile.am +88 -0
  6. data/ext/libsass/Makefile +157 -76
  7. data/ext/libsass/Makefile.conf +47 -0
  8. data/ext/libsass/Readme.md +13 -14
  9. data/ext/libsass/appveyor.yml +25 -41
  10. data/ext/libsass/configure.ac +20 -7
  11. data/ext/libsass/contrib/plugin.cpp +1 -1
  12. data/ext/libsass/include/sass.h +15 -0
  13. data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
  14. data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
  15. data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
  16. data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
  17. data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
  18. data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
  19. data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
  20. data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
  21. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
  22. data/ext/libsass/script/ci-build-libsass +67 -23
  23. data/ext/libsass/src/GNUmakefile.am +54 -0
  24. data/ext/libsass/src/ast.cpp +2029 -0
  25. data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
  26. data/ext/libsass/src/ast_def_macros.hpp +47 -0
  27. data/ext/libsass/src/ast_factory.hpp +93 -0
  28. data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
  29. data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
  30. data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
  31. data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
  32. data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
  33. data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
  34. data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
  35. data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
  36. data/ext/libsass/src/c99func.c +54 -0
  37. data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
  38. data/ext/libsass/src/color_maps.cpp +643 -0
  39. data/ext/libsass/src/color_maps.hpp +333 -0
  40. data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
  41. data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
  42. data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
  43. data/ext/libsass/src/context.hpp +150 -0
  44. data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
  45. data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
  46. data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
  47. data/ext/libsass/src/debugger.hpp +683 -0
  48. data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
  49. data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
  50. data/ext/libsass/src/environment.cpp +184 -0
  51. data/ext/libsass/src/environment.hpp +92 -0
  52. data/ext/libsass/src/error_handling.cpp +46 -0
  53. data/ext/libsass/src/error_handling.hpp +34 -0
  54. data/ext/libsass/src/eval.cpp +1462 -0
  55. data/ext/libsass/src/eval.hpp +107 -0
  56. data/ext/libsass/src/expand.cpp +653 -0
  57. data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
  58. data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
  59. data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
  60. data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
  61. data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
  62. data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
  63. data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
  64. data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
  65. data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
  66. data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
  67. data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
  68. data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
  69. data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
  70. data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
  71. data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
  72. data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
  73. data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
  74. data/ext/libsass/src/memory_manager.cpp +76 -0
  75. data/ext/libsass/src/memory_manager.hpp +48 -0
  76. data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
  77. data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
  78. data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
  79. data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
  80. data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
  81. data/ext/libsass/src/parser.cpp +2529 -0
  82. data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
  83. data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
  84. data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
  85. data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
  86. data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
  87. data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
  88. data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
  89. data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
  90. data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
  91. data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
  92. data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
  93. data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
  94. data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
  95. data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
  96. data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
  97. data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
  98. data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
  99. data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
  100. data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
  101. data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
  102. data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
  103. data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
  104. data/ext/libsass/src/to_c.cpp +73 -0
  105. data/ext/libsass/src/to_c.hpp +41 -0
  106. data/ext/libsass/src/to_string.cpp +47 -0
  107. data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
  108. data/ext/libsass/src/to_value.cpp +109 -0
  109. data/ext/libsass/src/to_value.hpp +50 -0
  110. data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
  111. data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
  112. data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
  113. data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
  114. data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
  115. data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
  116. data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
  117. data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
  118. data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
  119. data/ext/libsass/src/util.hpp +59 -0
  120. data/ext/libsass/src/values.cpp +137 -0
  121. data/ext/libsass/src/values.hpp +12 -0
  122. data/ext/libsass/test/test_node.cpp +33 -33
  123. data/ext/libsass/test/test_paths.cpp +5 -6
  124. data/ext/libsass/test/test_selector_difference.cpp +4 -5
  125. data/ext/libsass/test/test_specificity.cpp +4 -5
  126. data/ext/libsass/test/test_subset_map.cpp +91 -91
  127. data/ext/libsass/test/test_superselector.cpp +11 -11
  128. data/ext/libsass/test/test_unification.cpp +4 -4
  129. data/ext/libsass/win/libsass.targets +101 -0
  130. data/ext/libsass/win/libsass.vcxproj +45 -127
  131. data/ext/libsass/win/libsass.vcxproj.filters +303 -0
  132. data/lib/sassc/import_handler.rb +1 -1
  133. data/lib/sassc/native/native_functions_api.rb +3 -3
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/custom_importer_test.rb +1 -4
  136. data/test/functions_test.rb +3 -2
  137. data/test/native_test.rb +4 -3
  138. metadata +117 -110
  139. data/ext/libsass/Makefile.am +0 -146
  140. data/ext/libsass/ast.cpp +0 -945
  141. data/ext/libsass/ast_def_macros.hpp +0 -21
  142. data/ext/libsass/ast_factory.hpp +0 -92
  143. data/ext/libsass/color_names.hpp +0 -327
  144. data/ext/libsass/context.hpp +0 -157
  145. data/ext/libsass/contextualize.cpp +0 -148
  146. data/ext/libsass/contextualize.hpp +0 -46
  147. data/ext/libsass/contextualize_eval.cpp +0 -93
  148. data/ext/libsass/contextualize_eval.hpp +0 -44
  149. data/ext/libsass/debugger.hpp +0 -558
  150. data/ext/libsass/environment.hpp +0 -163
  151. data/ext/libsass/error_handling.cpp +0 -35
  152. data/ext/libsass/error_handling.hpp +0 -32
  153. data/ext/libsass/eval.cpp +0 -1392
  154. data/ext/libsass/eval.hpp +0 -88
  155. data/ext/libsass/expand.cpp +0 -575
  156. data/ext/libsass/memory_manager.hpp +0 -57
  157. data/ext/libsass/parser.cpp +0 -2403
  158. data/ext/libsass/posix/getopt.c +0 -562
  159. data/ext/libsass/posix/getopt.h +0 -95
  160. data/ext/libsass/to_c.cpp +0 -61
  161. data/ext/libsass/to_c.hpp +0 -44
  162. data/ext/libsass/to_string.cpp +0 -34
  163. data/ext/libsass/util.hpp +0 -54
  164. 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