sassc 2.0.1 → 2.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -1,4 +1,7 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
4
+
2
5
  #include <cstdlib>
3
6
  #include <cmath>
4
7
  #include <iostream>
@@ -17,7 +20,8 @@
17
20
  #include "position.hpp"
18
21
  #include "sass/values.h"
19
22
  #include "to_value.hpp"
20
- #include "to_c.hpp"
23
+ #include "ast2c.hpp"
24
+ #include "c2ast.hpp"
21
25
  #include "context.hpp"
22
26
  #include "backtrace.hpp"
23
27
  #include "lexer.hpp"
@@ -26,6 +30,7 @@
26
30
  #include "expand.hpp"
27
31
  #include "color_maps.hpp"
28
32
  #include "sass_functions.hpp"
33
+ #include "util_string.hpp"
29
34
 
30
35
  namespace Sass {
31
36
 
@@ -47,14 +52,51 @@ namespace Sass {
47
52
  return exp.environment();
48
53
  }
49
54
 
55
+ const std::string Eval::cwd()
56
+ {
57
+ return ctx.cwd();
58
+ }
59
+
60
+ struct Sass_Inspect_Options& Eval::options()
61
+ {
62
+ return ctx.c_options;
63
+ }
64
+
65
+ struct Sass_Compiler* Eval::compiler()
66
+ {
67
+ return ctx.c_compiler;
68
+ }
69
+
70
+ EnvStack& Eval::env_stack()
71
+ {
72
+ return exp.env_stack;
73
+ }
74
+
50
75
  Selector_List_Obj Eval::selector()
51
76
  {
52
77
  return exp.selector();
53
78
  }
54
79
 
55
- Expression_Ptr Eval::operator()(Block_Ptr b)
80
+ std::vector<Sass_Callee>& Eval::callee_stack()
81
+ {
82
+ return ctx.callee_stack;
83
+ }
84
+
85
+
86
+ SelectorStack& Eval::selector_stack()
87
+ {
88
+ return exp.selector_stack;
89
+ }
90
+
91
+ bool& Eval::old_at_root_without_rule()
92
+ {
93
+ return exp.old_at_root_without_rule;
94
+ }
95
+
96
+
97
+ Expression* Eval::operator()(Block* b)
56
98
  {
57
- Expression_Ptr val = 0;
99
+ Expression* val = 0;
58
100
  for (size_t i = 0, L = b->length(); i < L; ++i) {
59
101
  val = b->at(i)->perform(this);
60
102
  if (val) return val;
@@ -62,14 +104,14 @@ namespace Sass {
62
104
  return val;
63
105
  }
64
106
 
65
- Expression_Ptr Eval::operator()(Assignment_Ptr a)
107
+ Expression* Eval::operator()(Assignment* a)
66
108
  {
67
- Env* env = exp.environment();
109
+ Env* env = environment();
68
110
  std::string var(a->variable());
69
111
  if (a->is_global()) {
70
112
  if (a->is_default()) {
71
113
  if (env->has_global(var)) {
72
- Expression_Ptr e = Cast<Expression>(env->get_global(var));
114
+ Expression* e = Cast<Expression>(env->get_global(var));
73
115
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
74
116
  env->set_global(var, a->value()->perform(this));
75
117
  }
@@ -88,7 +130,7 @@ namespace Sass {
88
130
  while (cur && cur->is_lexical()) {
89
131
  if (cur->has_local(var)) {
90
132
  if (AST_Node_Obj node = cur->get_local(var)) {
91
- Expression_Ptr e = Cast<Expression>(node);
133
+ Expression* e = Cast<Expression>(node);
92
134
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
93
135
  cur->set_local(var, a->value()->perform(this));
94
136
  }
@@ -104,7 +146,7 @@ namespace Sass {
104
146
  }
105
147
  else if (env->has_global(var)) {
106
148
  if (AST_Node_Obj node = env->get_global(var)) {
107
- Expression_Ptr e = Cast<Expression>(node);
149
+ Expression* e = Cast<Expression>(node);
108
150
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
109
151
  env->set_global(var, a->value()->perform(this));
110
152
  }
@@ -123,11 +165,11 @@ namespace Sass {
123
165
  return 0;
124
166
  }
125
167
 
126
- Expression_Ptr Eval::operator()(If_Ptr i)
168
+ Expression* Eval::operator()(If* i)
127
169
  {
128
- Expression_Obj rv = 0;
129
- Env env(exp.environment());
130
- exp.env_stack.push_back(&env);
170
+ Expression_Obj rv;
171
+ Env env(environment());
172
+ env_stack().push_back(&env);
131
173
  Expression_Obj cond = i->predicate()->perform(this);
132
174
  if (!cond->is_false()) {
133
175
  rv = i->block()->perform(this);
@@ -136,13 +178,13 @@ namespace Sass {
136
178
  Block_Obj alt = i->alternative();
137
179
  if (alt) rv = alt->perform(this);
138
180
  }
139
- exp.env_stack.pop_back();
181
+ env_stack().pop_back();
140
182
  return rv.detach();
141
183
  }
142
184
 
143
185
  // For does not create a new env scope
144
186
  // But iteration vars are reset afterwards
145
- Expression_Ptr Eval::operator()(For_Ptr f)
187
+ Expression* Eval::operator()(For* f)
146
188
  {
147
189
  std::string variable(f->variable());
148
190
  Expression_Obj low = f->lower_bound()->perform(this);
@@ -168,9 +210,9 @@ namespace Sass {
168
210
  double end = sass_end->value();
169
211
  // only create iterator once in this environment
170
212
  Env env(environment(), true);
171
- exp.env_stack.push_back(&env);
213
+ env_stack().push_back(&env);
172
214
  Block_Obj body = f->block();
173
- Expression_Ptr val = 0;
215
+ Expression* val = 0;
174
216
  if (start < end) {
175
217
  if (f->is_inclusive()) ++end;
176
218
  for (double i = start;
@@ -192,24 +234,24 @@ namespace Sass {
192
234
  if (val) break;
193
235
  }
194
236
  }
195
- exp.env_stack.pop_back();
237
+ env_stack().pop_back();
196
238
  return val;
197
239
  }
198
240
 
199
241
  // Eval does not create a new env scope
200
242
  // But iteration vars are reset afterwards
201
- Expression_Ptr Eval::operator()(Each_Ptr e)
243
+ Expression* Eval::operator()(Each* e)
202
244
  {
203
245
  std::vector<std::string> variables(e->variables());
204
246
  Expression_Obj expr = e->list()->perform(this);
205
247
  Env env(environment(), true);
206
- exp.env_stack.push_back(&env);
207
- List_Obj list = 0;
208
- Map_Ptr map = 0;
248
+ env_stack().push_back(&env);
249
+ List_Obj list;
250
+ Map* map = nullptr;
209
251
  if (expr->concrete_type() == Expression::MAP) {
210
252
  map = Cast<Map>(expr);
211
253
  }
212
- else if (Selector_List_Ptr ls = Cast<Selector_List>(expr)) {
254
+ else if (Selector_List* ls = Cast<Selector_List>(expr)) {
213
255
  Listize listize;
214
256
  Expression_Obj rv = ls->perform(&listize);
215
257
  list = Cast<List>(rv);
@@ -223,14 +265,14 @@ namespace Sass {
223
265
  }
224
266
 
225
267
  Block_Obj body = e->block();
226
- Expression_Obj val = 0;
268
+ Expression_Obj val;
227
269
 
228
270
  if (map) {
229
271
  for (Expression_Obj key : map->keys()) {
230
272
  Expression_Obj value = map->at(key);
231
273
 
232
274
  if (variables.size() == 1) {
233
- List_Ptr variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
275
+ List* variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
234
276
  variable->append(key);
235
277
  variable->append(value);
236
278
  env.set_local(variables[0], variable);
@@ -248,18 +290,18 @@ namespace Sass {
248
290
  list = Cast<List>(list);
249
291
  }
250
292
  for (size_t i = 0, L = list->length(); i < L; ++i) {
251
- Expression_Ptr item = list->at(i);
293
+ Expression* item = list->at(i);
252
294
  // unwrap value if the expression is an argument
253
- if (Argument_Ptr arg = Cast<Argument>(item)) item = arg->value();
295
+ if (Argument* arg = Cast<Argument>(item)) item = arg->value();
254
296
  // check if we got passed a list of args (investigate)
255
- if (List_Ptr scalars = Cast<List>(item)) {
297
+ if (List* scalars = Cast<List>(item)) {
256
298
  if (variables.size() == 1) {
257
- Expression_Ptr var = scalars;
299
+ Expression* var = scalars;
258
300
  env.set_local(variables[0], var);
259
301
  } else {
260
302
  // XXX: this is never hit via spec tests
261
303
  for (size_t j = 0, K = variables.size(); j < K; ++j) {
262
- Expression_Ptr res = j >= scalars->length()
304
+ Expression* res = j >= scalars->length()
263
305
  ? SASS_MEMORY_NEW(Null, expr->pstate())
264
306
  : scalars->at(j);
265
307
  env.set_local(variables[j], res);
@@ -270,7 +312,7 @@ namespace Sass {
270
312
  env.set_local(variables.at(0), item);
271
313
  for (size_t j = 1, K = variables.size(); j < K; ++j) {
272
314
  // XXX: this is never hit via spec tests
273
- Expression_Ptr res = SASS_MEMORY_NEW(Null, expr->pstate());
315
+ Expression* res = SASS_MEMORY_NEW(Null, expr->pstate());
274
316
  env.set_local(variables[j], res);
275
317
  }
276
318
  }
@@ -279,46 +321,46 @@ namespace Sass {
279
321
  if (val) break;
280
322
  }
281
323
  }
282
- exp.env_stack.pop_back();
324
+ env_stack().pop_back();
283
325
  return val.detach();
284
326
  }
285
327
 
286
- Expression_Ptr Eval::operator()(While_Ptr w)
328
+ Expression* Eval::operator()(While* w)
287
329
  {
288
330
  Expression_Obj pred = w->predicate();
289
331
  Block_Obj body = w->block();
290
332
  Env env(environment(), true);
291
- exp.env_stack.push_back(&env);
333
+ env_stack().push_back(&env);
292
334
  Expression_Obj cond = pred->perform(this);
293
335
  while (!cond->is_false()) {
294
336
  Expression_Obj val = body->perform(this);
295
337
  if (val) {
296
- exp.env_stack.pop_back();
338
+ env_stack().pop_back();
297
339
  return val.detach();
298
340
  }
299
341
  cond = pred->perform(this);
300
342
  }
301
- exp.env_stack.pop_back();
343
+ env_stack().pop_back();
302
344
  return 0;
303
345
  }
304
346
 
305
- Expression_Ptr Eval::operator()(Return_Ptr r)
347
+ Expression* Eval::operator()(Return* r)
306
348
  {
307
349
  return r->value()->perform(this);
308
350
  }
309
351
 
310
- Expression_Ptr Eval::operator()(Warning_Ptr w)
352
+ Expression* Eval::operator()(Warning* w)
311
353
  {
312
- Sass_Output_Style outstyle = ctx.c_options.output_style;
313
- ctx.c_options.output_style = NESTED;
354
+ Sass_Output_Style outstyle = options().output_style;
355
+ options().output_style = NESTED;
314
356
  Expression_Obj message = w->message()->perform(this);
315
- Env* env = exp.environment();
357
+ Env* env = environment();
316
358
 
317
359
  // try to use generic function
318
360
  if (env->has("@warn[f]")) {
319
361
 
320
362
  // add call stack entry
321
- ctx.callee_stack.push_back({
363
+ callee_stack().push_back({
322
364
  "@warn",
323
365
  w->pstate().path,
324
366
  w->pstate().line + 1,
@@ -327,18 +369,18 @@ namespace Sass {
327
369
  { env }
328
370
  });
329
371
 
330
- Definition_Ptr def = Cast<Definition>((*env)["@warn[f]"]);
372
+ Definition* def = Cast<Definition>((*env)["@warn[f]"]);
331
373
  // Block_Obj body = def->block();
332
374
  // Native_Function func = def->native_function();
333
375
  Sass_Function_Entry c_function = def->c_function();
334
376
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
335
377
 
336
- To_C to_c;
378
+ AST2C ast2c;
337
379
  union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
338
- sass_list_set_value(c_args, 0, message->perform(&to_c));
339
- union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
340
- ctx.c_options.output_style = outstyle;
341
- ctx.callee_stack.pop_back();
380
+ sass_list_set_value(c_args, 0, message->perform(&ast2c));
381
+ union Sass_Value* c_val = c_func(c_args, c_function, compiler());
382
+ options().output_style = outstyle;
383
+ callee_stack().pop_back();
342
384
  sass_delete_value(c_args);
343
385
  sass_delete_value(c_val);
344
386
  return 0;
@@ -350,23 +392,23 @@ namespace Sass {
350
392
  traces.push_back(Backtrace(w->pstate()));
351
393
  std::cerr << traces_to_string(traces, " ");
352
394
  std::cerr << std::endl;
353
- ctx.c_options.output_style = outstyle;
395
+ options().output_style = outstyle;
354
396
  traces.pop_back();
355
397
  return 0;
356
398
  }
357
399
 
358
- Expression_Ptr Eval::operator()(Error_Ptr e)
400
+ Expression* Eval::operator()(Error* e)
359
401
  {
360
- Sass_Output_Style outstyle = ctx.c_options.output_style;
361
- ctx.c_options.output_style = NESTED;
402
+ Sass_Output_Style outstyle = options().output_style;
403
+ options().output_style = NESTED;
362
404
  Expression_Obj message = e->message()->perform(this);
363
- Env* env = exp.environment();
405
+ Env* env = environment();
364
406
 
365
407
  // try to use generic function
366
408
  if (env->has("@error[f]")) {
367
409
 
368
410
  // add call stack entry
369
- ctx.callee_stack.push_back({
411
+ callee_stack().push_back({
370
412
  "@error",
371
413
  e->pstate().path,
372
414
  e->pstate().line + 1,
@@ -375,18 +417,18 @@ namespace Sass {
375
417
  { env }
376
418
  });
377
419
 
378
- Definition_Ptr def = Cast<Definition>((*env)["@error[f]"]);
420
+ Definition* def = Cast<Definition>((*env)["@error[f]"]);
379
421
  // Block_Obj body = def->block();
380
422
  // Native_Function func = def->native_function();
381
423
  Sass_Function_Entry c_function = def->c_function();
382
424
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
383
425
 
384
- To_C to_c;
426
+ AST2C ast2c;
385
427
  union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
386
- sass_list_set_value(c_args, 0, message->perform(&to_c));
387
- union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
388
- ctx.c_options.output_style = outstyle;
389
- ctx.callee_stack.pop_back();
428
+ sass_list_set_value(c_args, 0, message->perform(&ast2c));
429
+ union Sass_Value* c_val = c_func(c_args, c_function, compiler());
430
+ options().output_style = outstyle;
431
+ callee_stack().pop_back();
390
432
  sass_delete_value(c_args);
391
433
  sass_delete_value(c_val);
392
434
  return 0;
@@ -394,23 +436,23 @@ namespace Sass {
394
436
  }
395
437
 
396
438
  std::string result(unquote(message->to_sass()));
397
- ctx.c_options.output_style = outstyle;
439
+ options().output_style = outstyle;
398
440
  error(result, e->pstate(), traces);
399
441
  return 0;
400
442
  }
401
443
 
402
- Expression_Ptr Eval::operator()(Debug_Ptr d)
444
+ Expression* Eval::operator()(Debug* d)
403
445
  {
404
- Sass_Output_Style outstyle = ctx.c_options.output_style;
405
- ctx.c_options.output_style = NESTED;
446
+ Sass_Output_Style outstyle = options().output_style;
447
+ options().output_style = NESTED;
406
448
  Expression_Obj message = d->value()->perform(this);
407
- Env* env = exp.environment();
449
+ Env* env = environment();
408
450
 
409
451
  // try to use generic function
410
452
  if (env->has("@debug[f]")) {
411
453
 
412
454
  // add call stack entry
413
- ctx.callee_stack.push_back({
455
+ callee_stack().push_back({
414
456
  "@debug",
415
457
  d->pstate().path,
416
458
  d->pstate().line + 1,
@@ -419,37 +461,36 @@ namespace Sass {
419
461
  { env }
420
462
  });
421
463
 
422
- Definition_Ptr def = Cast<Definition>((*env)["@debug[f]"]);
464
+ Definition* def = Cast<Definition>((*env)["@debug[f]"]);
423
465
  // Block_Obj body = def->block();
424
466
  // Native_Function func = def->native_function();
425
467
  Sass_Function_Entry c_function = def->c_function();
426
468
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
427
469
 
428
- To_C to_c;
470
+ AST2C ast2c;
429
471
  union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);
430
- sass_list_set_value(c_args, 0, message->perform(&to_c));
431
- union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
432
- ctx.c_options.output_style = outstyle;
433
- ctx.callee_stack.pop_back();
472
+ sass_list_set_value(c_args, 0, message->perform(&ast2c));
473
+ union Sass_Value* c_val = c_func(c_args, c_function, compiler());
474
+ options().output_style = outstyle;
475
+ callee_stack().pop_back();
434
476
  sass_delete_value(c_args);
435
477
  sass_delete_value(c_val);
436
478
  return 0;
437
479
 
438
480
  }
439
481
 
440
- std::string cwd(ctx.cwd());
441
482
  std::string result(unquote(message->to_sass()));
442
- std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd));
443
- std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd));
483
+ std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd(), cwd()));
484
+ std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd(), cwd()));
444
485
  std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path));
445
- ctx.c_options.output_style = outstyle;
486
+ options().output_style = outstyle;
446
487
 
447
488
  std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
448
489
  std::cerr << std::endl;
449
490
  return 0;
450
491
  }
451
492
 
452
- Expression_Ptr Eval::operator()(List_Ptr l)
493
+ Expression* Eval::operator()(List* l)
453
494
  {
454
495
  // special case for unevaluated map
455
496
  if (l->separator() == SASS_HASH) {
@@ -490,7 +531,7 @@ namespace Sass {
490
531
  return ll.detach();
491
532
  }
492
533
 
493
- Expression_Ptr Eval::operator()(Map_Ptr m)
534
+ Expression* Eval::operator()(Map* m)
494
535
  {
495
536
  if (m->is_expanded()) return m;
496
537
 
@@ -505,8 +546,8 @@ namespace Sass {
505
546
  m->pstate(),
506
547
  m->length());
507
548
  for (auto key : m->keys()) {
508
- Expression_Ptr ex_key = key->perform(this);
509
- Expression_Ptr ex_val = m->at(key);
549
+ Expression* ex_key = key->perform(this);
550
+ Expression* ex_val = m->at(key);
510
551
  if (ex_val == NULL) continue;
511
552
  ex_val = ex_val->perform(this);
512
553
  *mm << std::make_pair(ex_key, ex_val);
@@ -522,7 +563,7 @@ namespace Sass {
522
563
  return mm.detach();
523
564
  }
524
565
 
525
- Expression_Ptr Eval::operator()(Binary_Expression_Ptr b_in)
566
+ Expression* Eval::operator()(Binary_Expression* b_in)
526
567
  {
527
568
 
528
569
  Expression_Obj lhs = b_in->left();
@@ -543,21 +584,21 @@ namespace Sass {
543
584
  }
544
585
 
545
586
  // Evaluate variables as early o
546
- while (Variable_Ptr l_v = Cast<Variable>(lhs)) {
587
+ while (Variable* l_v = Cast<Variable>(lhs)) {
547
588
  lhs = operator()(l_v);
548
589
  }
549
- while (Variable_Ptr r_v = Cast<Variable>(rhs)) {
590
+ while (Variable* r_v = Cast<Variable>(rhs)) {
550
591
  rhs = operator()(r_v);
551
592
  }
552
593
 
553
594
  Binary_Expression_Obj b = b_in;
554
595
 
555
596
  // Evaluate sub-expressions early on
556
- while (Binary_Expression_Ptr l_b = Cast<Binary_Expression>(lhs)) {
597
+ while (Binary_Expression* l_b = Cast<Binary_Expression>(lhs)) {
557
598
  if (!force && l_b->is_delayed()) break;
558
599
  lhs = operator()(l_b);
559
600
  }
560
- while (Binary_Expression_Ptr r_b = Cast<Binary_Expression>(rhs)) {
601
+ while (Binary_Expression* r_b = Cast<Binary_Expression>(rhs)) {
561
602
  if (!force && r_b->is_delayed()) break;
562
603
  rhs = operator()(r_b);
563
604
  }
@@ -571,9 +612,9 @@ namespace Sass {
571
612
 
572
613
  // specific types we know are final
573
614
  // handle them early to avoid overhead
574
- if (Number_Ptr l_n = Cast<Number>(lhs)) {
615
+ if (Number* l_n = Cast<Number>(lhs)) {
575
616
  // lhs is number and rhs is number
576
- if (Number_Ptr r_n = Cast<Number>(rhs)) {
617
+ if (Number* r_n = Cast<Number>(rhs)) {
577
618
  try {
578
619
  switch (op_type) {
579
620
  case Sass_OP::EQ: return *l_n == *r_n ? bool_true : bool_false;
@@ -583,7 +624,7 @@ namespace Sass {
583
624
  case Sass_OP::LTE: return *l_n < *r_n || *l_n == *r_n ? bool_true : bool_false;
584
625
  case Sass_OP::GT: return *l_n < *r_n || *l_n == *r_n ? bool_false : bool_true;
585
626
  case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
586
- return Operators::op_numbers(op_type, *l_n, *r_n, ctx.c_options, b_in->pstate());
627
+ return Operators::op_numbers(op_type, *l_n, *r_n, options(), b_in->pstate());
587
628
  default: break;
588
629
  }
589
630
  }
@@ -594,17 +635,15 @@ namespace Sass {
594
635
  }
595
636
  }
596
637
  // lhs is number and rhs is color
597
- else if (Color_Ptr r_c = Cast<Color>(rhs)) {
638
+ // Todo: allow to work with HSLA colors
639
+ else if (Color* r_col = Cast<Color>(rhs)) {
640
+ Color_RGBA_Obj r_c = r_col->toRGBA();
598
641
  try {
599
642
  switch (op_type) {
600
643
  case Sass_OP::EQ: return *l_n == *r_c ? bool_true : bool_false;
601
644
  case Sass_OP::NEQ: return *l_n == *r_c ? bool_false : bool_true;
602
- case Sass_OP::LT: return *l_n < *r_c ? bool_true : bool_false;
603
- case Sass_OP::GTE: return *l_n < *r_c ? bool_false : bool_true;
604
- case Sass_OP::LTE: return *l_n < *r_c || *l_n == *r_c ? bool_true : bool_false;
605
- case Sass_OP::GT: return *l_n < *r_c || *l_n == *r_c ? bool_false : bool_true;
606
645
  case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
607
- return Operators::op_number_color(op_type, *l_n, *r_c, ctx.c_options, b_in->pstate());
646
+ return Operators::op_number_color(op_type, *l_n, *r_c, options(), b_in->pstate());
608
647
  default: break;
609
648
  }
610
649
  }
@@ -615,9 +654,11 @@ namespace Sass {
615
654
  }
616
655
  }
617
656
  }
618
- else if (Color_Ptr l_c = Cast<Color>(lhs)) {
657
+ else if (Color* l_col = Cast<Color>(lhs)) {
658
+ Color_RGBA_Obj l_c = l_col->toRGBA();
619
659
  // lhs is color and rhs is color
620
- if (Color_Ptr r_c = Cast<Color>(rhs)) {
660
+ if (Color* r_col = Cast<Color>(rhs)) {
661
+ Color_RGBA_Obj r_c = r_col->toRGBA();
621
662
  try {
622
663
  switch (op_type) {
623
664
  case Sass_OP::EQ: return *l_c == *r_c ? bool_true : bool_false;
@@ -627,7 +668,7 @@ namespace Sass {
627
668
  case Sass_OP::LTE: return *l_c < *r_c || *l_c == *r_c ? bool_true : bool_false;
628
669
  case Sass_OP::GT: return *l_c < *r_c || *l_c == *r_c ? bool_false : bool_true;
629
670
  case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
630
- return Operators::op_colors(op_type, *l_c, *r_c, ctx.c_options, b_in->pstate());
671
+ return Operators::op_colors(op_type, *l_c, *r_c, options(), b_in->pstate());
631
672
  default: break;
632
673
  }
633
674
  }
@@ -638,17 +679,13 @@ namespace Sass {
638
679
  }
639
680
  }
640
681
  // lhs is color and rhs is number
641
- else if (Number_Ptr r_n = Cast<Number>(rhs)) {
682
+ else if (Number* r_n = Cast<Number>(rhs)) {
642
683
  try {
643
684
  switch (op_type) {
644
685
  case Sass_OP::EQ: return *l_c == *r_n ? bool_true : bool_false;
645
686
  case Sass_OP::NEQ: return *l_c == *r_n ? bool_false : bool_true;
646
- case Sass_OP::LT: return *l_c < *r_n ? bool_true : bool_false;
647
- case Sass_OP::GTE: return *l_c < *r_n ? bool_false : bool_true;
648
- case Sass_OP::LTE: return *l_c < *r_n || *l_c == *r_n ? bool_true : bool_false;
649
- case Sass_OP::GT: return *l_c < *r_n || *l_c == *r_n ? bool_false : bool_true;
650
687
  case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
651
- return Operators::op_color_number(op_type, *l_c, *r_n, ctx.c_options, b_in->pstate());
688
+ return Operators::op_color_number(op_type, *l_c, *r_n, options(), b_in->pstate());
652
689
  default: break;
653
690
  }
654
691
  }
@@ -663,29 +700,29 @@ namespace Sass {
663
700
  String_Schema_Obj ret_schema;
664
701
 
665
702
  // only the last item will be used to eval the binary expression
666
- if (String_Schema_Ptr s_l = Cast<String_Schema>(b->left())) {
703
+ if (String_Schema* s_l = Cast<String_Schema>(b->left())) {
667
704
  if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) {
668
705
  ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
669
706
  Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
670
707
  b->op(), s_l->last(), b->right());
671
708
  bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified
672
709
  for (size_t i = 0; i < s_l->length() - 1; ++i) {
673
- ret_schema->append(s_l->at(i)->perform(this));
710
+ ret_schema->append(Cast<PreValue>(s_l->at(i)->perform(this)));
674
711
  }
675
- ret_schema->append(bin_ex->perform(this));
712
+ ret_schema->append(Cast<PreValue>(bin_ex->perform(this)));
676
713
  return ret_schema->perform(this);
677
714
  }
678
715
  }
679
- if (String_Schema_Ptr s_r = Cast<String_Schema>(b->right())) {
716
+ if (String_Schema* s_r = Cast<String_Schema>(b->right())) {
680
717
 
681
718
  if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) {
682
719
  ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
683
720
  Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
684
721
  b->op(), b->left(), s_r->first());
685
722
  bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified
686
- ret_schema->append(bin_ex->perform(this));
723
+ ret_schema->append(Cast<PreValue>(bin_ex->perform(this)));
687
724
  for (size_t i = 1; i < s_r->length(); ++i) {
688
- ret_schema->append(s_r->at(i)->perform(this));
725
+ ret_schema->append(Cast<PreValue>(s_r->at(i)->perform(this)));
689
726
  }
690
727
  return ret_schema->perform(this);
691
728
  }
@@ -716,8 +753,8 @@ namespace Sass {
716
753
  AST_Node_Obj lu = lhs;
717
754
  AST_Node_Obj ru = rhs;
718
755
 
719
- Expression::Concrete_Type l_type;
720
- Expression::Concrete_Type r_type;
756
+ Expression::Type l_type;
757
+ Expression::Type r_type;
721
758
 
722
759
  // Is one of the operands an interpolant?
723
760
  String_Schema_Obj s1 = Cast<String_Schema>(b->left());
@@ -737,7 +774,7 @@ namespace Sass {
737
774
  if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::MOD || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB ||
738
775
  op_type == Sass_OP::EQ) {
739
776
  // If possible upgrade LHS to a number (for number to string compare)
740
- if (String_Constant_Ptr str = Cast<String_Constant>(lhs)) {
777
+ if (String_Constant* str = Cast<String_Constant>(lhs)) {
741
778
  std::string value(str->value());
742
779
  const char* start = value.c_str();
743
780
  if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) {
@@ -745,7 +782,7 @@ namespace Sass {
745
782
  }
746
783
  }
747
784
  // If possible upgrade RHS to a number (for string to number compare)
748
- if (String_Constant_Ptr str = Cast<String_Constant>(rhs)) {
785
+ if (String_Constant* str = Cast<String_Constant>(rhs)) {
749
786
  std::string value(str->value());
750
787
  const char* start = value.c_str();
751
788
  if (Prelexer::sequence < Prelexer::dimension, Prelexer::number >(start) != 0) {
@@ -760,12 +797,12 @@ namespace Sass {
760
797
 
761
798
  if (force_delay) {
762
799
  std::string str("");
763
- str += v_l->to_string(ctx.c_options);
800
+ str += v_l->to_string(options());
764
801
  if (b->op().ws_before) str += " ";
765
802
  str += b->separator();
766
803
  if (b->op().ws_after) str += " ";
767
- str += v_r->to_string(ctx.c_options);
768
- String_Constant_Ptr val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str);
804
+ str += v_r->to_string(options());
805
+ String_Constant* val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str);
769
806
  val->is_interpolant(b->left()->has_interpolant());
770
807
  return val;
771
808
  }
@@ -785,7 +822,6 @@ namespace Sass {
785
822
  }
786
823
  catch (Exception::OperationError& err)
787
824
  {
788
- // throw Exception::Base(b->pstate(), err.what());
789
825
  traces.push_back(Backtrace(b->pstate()));
790
826
  throw Exception::SassValueError(traces, b->pstate(), err);
791
827
  }
@@ -799,25 +835,25 @@ namespace Sass {
799
835
  try {
800
836
  ParserState pstate(b->pstate());
801
837
  if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
802
- Number_Ptr l_n = Cast<Number>(lhs);
803
- Number_Ptr r_n = Cast<Number>(rhs);
838
+ Number* l_n = Cast<Number>(lhs);
839
+ Number* r_n = Cast<Number>(rhs);
804
840
  l_n->reduce(); r_n->reduce();
805
- rv = Operators::op_numbers(op_type, *l_n, *r_n, ctx.c_options, pstate);
841
+ rv = Operators::op_numbers(op_type, *l_n, *r_n, options(), pstate);
806
842
  }
807
843
  else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
808
- Number_Ptr l_n = Cast<Number>(lhs);
809
- Color_Ptr r_c = Cast<Color>(rhs);
810
- rv = Operators::op_number_color(op_type, *l_n, *r_c, ctx.c_options, pstate);
844
+ Number* l_n = Cast<Number>(lhs);
845
+ Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();
846
+ rv = Operators::op_number_color(op_type, *l_n, *r_c, options(), pstate);
811
847
  }
812
848
  else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
813
- Color_Ptr l_c = Cast<Color>(lhs);
814
- Number_Ptr r_n = Cast<Number>(rhs);
815
- rv = Operators::op_color_number(op_type, *l_c, *r_n, ctx.c_options, pstate);
849
+ Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();
850
+ Number* r_n = Cast<Number>(rhs);
851
+ rv = Operators::op_color_number(op_type, *l_c, *r_n, options(), pstate);
816
852
  }
817
853
  else if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
818
- Color_Ptr l_c = Cast<Color>(lhs);
819
- Color_Ptr r_c = Cast<Color>(rhs);
820
- rv = Operators::op_colors(op_type, *l_c, *r_c, ctx.c_options, pstate);
854
+ Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();
855
+ Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();
856
+ rv = Operators::op_colors(op_type, *l_c, *r_c, options(), pstate);
821
857
  }
822
858
  else {
823
859
  To_Value to_value(ctx);
@@ -838,15 +874,15 @@ namespace Sass {
838
874
  traces.push_back(Backtrace(v_r->pstate()));
839
875
  throw Exception::InvalidValue(traces, *v_r);
840
876
  }
841
- Value_Ptr ex = Operators::op_strings(b->op(), *v_l, *v_r, ctx.c_options, pstate, !interpolant); // pass true to compress
842
- if (String_Constant_Ptr str = Cast<String_Constant>(ex))
877
+ Value* ex = Operators::op_strings(b->op(), *v_l, *v_r, options(), pstate, !interpolant); // pass true to compress
878
+ if (String_Constant* str = Cast<String_Constant>(ex))
843
879
  {
844
880
  if (str->concrete_type() == Expression::STRING)
845
881
  {
846
- String_Constant_Ptr lstr = Cast<String_Constant>(lhs);
847
- String_Constant_Ptr rstr = Cast<String_Constant>(rhs);
882
+ String_Constant* lstr = Cast<String_Constant>(lhs);
883
+ String_Constant* rstr = Cast<String_Constant>(rhs);
848
884
  if (op_type != Sass_OP::SUB) {
849
- if (String_Constant_Ptr org = lstr ? lstr : rstr)
885
+ if (String_Constant* org = lstr ? lstr : rstr)
850
886
  { str->quote_mark(org->quote_mark()); }
851
887
  }
852
888
  }
@@ -874,11 +910,11 @@ namespace Sass {
874
910
 
875
911
  }
876
912
 
877
- Expression_Ptr Eval::operator()(Unary_Expression_Ptr u)
913
+ Expression* Eval::operator()(Unary_Expression* u)
878
914
  {
879
915
  Expression_Obj operand = u->operand()->perform(this);
880
916
  if (u->optype() == Unary_Expression::NOT) {
881
- Boolean_Ptr result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand);
917
+ Boolean* result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand);
882
918
  result->value(!result->value());
883
919
  return result;
884
920
  }
@@ -890,7 +926,7 @@ namespace Sass {
890
926
  return cpy.detach(); // return the copy
891
927
  }
892
928
  else if (u->optype() == Unary_Expression::SLASH) {
893
- std::string str = '/' + nr->to_string(ctx.c_options);
929
+ std::string str = '/' + nr->to_string(options());
894
930
  return SASS_MEMORY_NEW(String_Constant, u->pstate(), str);
895
931
  }
896
932
  // nothing for positive
@@ -903,7 +939,7 @@ namespace Sass {
903
939
  u->operand(SASS_MEMORY_NEW(String_Quoted, u->pstate(), ""));
904
940
  }
905
941
  // Never apply unary opertions on colors @see #2140
906
- else if (Color_Ptr color = Cast<Color>(operand)) {
942
+ else if (Color* color = Cast<Color>(operand)) {
907
943
  // Use the color name if this was eval with one
908
944
  if (color->disp().length() > 0) {
909
945
  operand = SASS_MEMORY_NEW(String_Constant, operand->pstate(), color->disp());
@@ -922,7 +958,7 @@ namespace Sass {
922
958
  return u;
923
959
  }
924
960
 
925
- Expression_Ptr Eval::operator()(Function_Call_Ptr c)
961
+ Expression* Eval::operator()(Function_Call* c)
926
962
  {
927
963
  if (traces.size() > Constants::MaxCallStack) {
928
964
  // XXX: this is never hit via spec tests
@@ -930,8 +966,18 @@ namespace Sass {
930
966
  stm << "Stack depth exceeded max of " << Constants::MaxCallStack;
931
967
  error(stm.str(), c->pstate(), traces);
932
968
  }
969
+
970
+ if (Cast<String_Schema>(c->sname())) {
971
+ Expression_Obj evaluated_name = c->sname()->perform(this);
972
+ Expression_Obj evaluated_args = c->arguments()->perform(this);
973
+ std::string str(evaluated_name->to_string());
974
+ str += evaluated_args->to_string();
975
+ return SASS_MEMORY_NEW(String_Constant, c->pstate(), str);
976
+ }
977
+
933
978
  std::string name(Util::normalize_underscores(c->name()));
934
979
  std::string full_name(name + "[f]");
980
+
935
981
  // we make a clone here, need to implement that further
936
982
  Arguments_Obj args = c->arguments();
937
983
 
@@ -951,9 +997,9 @@ namespace Sass {
951
997
  if (args->has_named_arguments()) {
952
998
  error("Function " + c->name() + " doesn't support keyword arguments", c->pstate(), traces);
953
999
  }
954
- String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted,
1000
+ String_Quoted* str = SASS_MEMORY_NEW(String_Quoted,
955
1001
  c->pstate(),
956
- lit->to_string(ctx.c_options));
1002
+ lit->to_string(options()));
957
1003
  str->is_interpolant(c->is_interpolant());
958
1004
  return str;
959
1005
  } else {
@@ -969,7 +1015,7 @@ namespace Sass {
969
1015
  if (full_name != "if[f]") {
970
1016
  args = Cast<Arguments>(args->perform(this));
971
1017
  }
972
- Definition_Ptr def = Cast<Definition>((*env)[full_name]);
1018
+ Definition* def = Cast<Definition>((*env)[full_name]);
973
1019
 
974
1020
  if (c->func()) def = c->func()->definition();
975
1021
 
@@ -979,7 +1025,7 @@ namespace Sass {
979
1025
  // account for rest arguments
980
1026
  if (args->has_rest_argument() && args->length() > 0) {
981
1027
  // get the rest arguments list
982
- List_Ptr rest = Cast<List>(args->last()->value());
1028
+ List* rest = Cast<List>(args->last()->value());
983
1029
  // arguments before rest argument plus rest
984
1030
  if (rest) L += rest->length() - 1;
985
1031
  }
@@ -999,13 +1045,13 @@ namespace Sass {
999
1045
 
1000
1046
  Parameters_Obj params = def->parameters();
1001
1047
  Env fn_env(def->environment());
1002
- exp.env_stack.push_back(&fn_env);
1048
+ env_stack().push_back(&fn_env);
1003
1049
 
1004
1050
  if (func || body) {
1005
- bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
1051
+ bind(std::string("Function"), c->name(), params, args, &fn_env, this, traces);
1006
1052
  std::string msg(", in function `" + c->name() + "`");
1007
1053
  traces.push_back(Backtrace(c->pstate(), msg));
1008
- ctx.callee_stack.push_back({
1054
+ callee_stack().push_back({
1009
1055
  c->name().c_str(),
1010
1056
  c->pstate().path,
1011
1057
  c->pstate().line + 1,
@@ -1024,7 +1070,7 @@ namespace Sass {
1024
1070
  if (!result) {
1025
1071
  error(std::string("Function ") + c->name() + " finished without @return", c->pstate(), traces);
1026
1072
  }
1027
- ctx.callee_stack.pop_back();
1073
+ callee_stack().pop_back();
1028
1074
  traces.pop_back();
1029
1075
  }
1030
1076
 
@@ -1042,10 +1088,10 @@ namespace Sass {
1042
1088
 
1043
1089
  // populates env with default values for params
1044
1090
  std::string ff(c->name());
1045
- bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
1091
+ bind(std::string("Function"), c->name(), params, args, &fn_env, this, traces);
1046
1092
  std::string msg(", in function `" + c->name() + "`");
1047
1093
  traces.push_back(Backtrace(c->pstate(), msg));
1048
- ctx.callee_stack.push_back({
1094
+ callee_stack().push_back({
1049
1095
  c->name().c_str(),
1050
1096
  c->pstate().path,
1051
1097
  c->pstate().line + 1,
@@ -1054,24 +1100,30 @@ namespace Sass {
1054
1100
  { env }
1055
1101
  });
1056
1102
 
1057
- To_C to_c;
1103
+ AST2C ast2c;
1058
1104
  union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false);
1059
1105
  for(size_t i = 0; i < params->length(); i++) {
1060
1106
  Parameter_Obj param = params->at(i);
1061
1107
  std::string key = param->name();
1062
1108
  AST_Node_Obj node = fn_env.get_local(key);
1063
1109
  Expression_Obj arg = Cast<Expression>(node);
1064
- sass_list_set_value(c_args, i, arg->perform(&to_c));
1110
+ sass_list_set_value(c_args, i, arg->perform(&ast2c));
1065
1111
  }
1066
- union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
1112
+ union Sass_Value* c_val = c_func(c_args, c_function, compiler());
1067
1113
  if (sass_value_get_tag(c_val) == SASS_ERROR) {
1068
- error("error in C function " + c->name() + ": " + sass_error_get_message(c_val), c->pstate(), traces);
1114
+ std::string message("error in C function " + c->name() + ": " + sass_error_get_message(c_val));
1115
+ sass_delete_value(c_val);
1116
+ sass_delete_value(c_args);
1117
+ error(message, c->pstate(), traces);
1069
1118
  } else if (sass_value_get_tag(c_val) == SASS_WARNING) {
1070
- error("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val), c->pstate(), traces);
1119
+ std::string message("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val));
1120
+ sass_delete_value(c_val);
1121
+ sass_delete_value(c_args);
1122
+ error(message, c->pstate(), traces);
1071
1123
  }
1072
- result = cval_to_astnode(c_val, traces, c->pstate());
1124
+ result = c2ast(c_val, traces, c->pstate());
1073
1125
 
1074
- ctx.callee_stack.pop_back();
1126
+ callee_stack().pop_back();
1075
1127
  traces.pop_back();
1076
1128
  sass_delete_value(c_args);
1077
1129
  if (c_val != c_args)
@@ -1085,30 +1137,20 @@ namespace Sass {
1085
1137
 
1086
1138
  result = result->perform(this);
1087
1139
  result->is_interpolant(c->is_interpolant());
1088
- exp.env_stack.pop_back();
1140
+ env_stack().pop_back();
1089
1141
  return result.detach();
1090
1142
  }
1091
1143
 
1092
- Expression_Ptr Eval::operator()(Function_Call_Schema_Ptr s)
1144
+ Expression* Eval::operator()(Variable* v)
1093
1145
  {
1094
- Expression_Ptr evaluated_name = s->name()->perform(this);
1095
- Expression_Ptr evaluated_args = s->arguments()->perform(this);
1096
- String_Schema_Obj ss = SASS_MEMORY_NEW(String_Schema, s->pstate(), 2);
1097
- ss->append(evaluated_name);
1098
- ss->append(evaluated_args);
1099
- return ss->perform(this);
1100
- }
1101
-
1102
- Expression_Ptr Eval::operator()(Variable_Ptr v)
1103
- {
1104
- Expression_Obj value = 0;
1146
+ Expression_Obj value;
1105
1147
  Env* env = environment();
1106
1148
  const std::string& name(v->name());
1107
1149
  EnvResult rv(env->find(name));
1108
1150
  if (rv.found) value = static_cast<Expression*>(rv.it->second.ptr());
1109
1151
  else error("Undefined variable: \"" + v->name() + "\".", v->pstate(), traces);
1110
- if (Argument_Ptr arg = Cast<Argument>(value)) value = arg->value();
1111
- if (Number_Ptr nr = Cast<Number>(value)) nr->zero(true); // force flag
1152
+ if (Argument* arg = Cast<Argument>(value)) value = arg->value();
1153
+ if (Number* nr = Cast<Number>(value)) nr->zero(true); // force flag
1112
1154
  value->is_interpolant(v->is_interpolant());
1113
1155
  if (force) value->is_expanded(false);
1114
1156
  value->set_delayed(false); // verified
@@ -1117,17 +1159,22 @@ namespace Sass {
1117
1159
  return value.detach();
1118
1160
  }
1119
1161
 
1120
- Expression_Ptr Eval::operator()(Color_Ptr c)
1162
+ Expression* Eval::operator()(Color_RGBA* c)
1163
+ {
1164
+ return c;
1165
+ }
1166
+
1167
+ Expression* Eval::operator()(Color_HSLA* c)
1121
1168
  {
1122
1169
  return c;
1123
1170
  }
1124
1171
 
1125
- Expression_Ptr Eval::operator()(Number_Ptr n)
1172
+ Expression* Eval::operator()(Number* n)
1126
1173
  {
1127
1174
  return n;
1128
1175
  }
1129
1176
 
1130
- Expression_Ptr Eval::operator()(Boolean_Ptr b)
1177
+ Expression* Eval::operator()(Boolean* b)
1131
1178
  {
1132
1179
  return b;
1133
1180
  }
@@ -1136,8 +1183,8 @@ namespace Sass {
1136
1183
 
1137
1184
  bool needs_closing_brace = false;
1138
1185
 
1139
- if (Arguments_Ptr args = Cast<Arguments>(ex)) {
1140
- List_Ptr ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA);
1186
+ if (Arguments* args = Cast<Arguments>(ex)) {
1187
+ List* ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA);
1141
1188
  for(auto arg : args->elements()) {
1142
1189
  ll->append(arg->value());
1143
1190
  }
@@ -1146,7 +1193,7 @@ namespace Sass {
1146
1193
  res += "(";
1147
1194
  ex = ll;
1148
1195
  }
1149
- if (Number_Ptr nr = Cast<Number>(ex)) {
1196
+ if (Number* nr = Cast<Number>(ex)) {
1150
1197
  Number reduced(nr);
1151
1198
  reduced.reduce();
1152
1199
  if (!reduced.is_valid_css_unit()) {
@@ -1154,10 +1201,10 @@ namespace Sass {
1154
1201
  throw Exception::InvalidValue(traces, *nr);
1155
1202
  }
1156
1203
  }
1157
- if (Argument_Ptr arg = Cast<Argument>(ex)) {
1204
+ if (Argument* arg = Cast<Argument>(ex)) {
1158
1205
  ex = arg->value();
1159
1206
  }
1160
- if (String_Quoted_Ptr sq = Cast<String_Quoted>(ex)) {
1207
+ if (String_Quoted* sq = Cast<String_Quoted>(ex)) {
1161
1208
  if (was_itpl) {
1162
1209
  bool was_interpolant = ex->is_interpolant();
1163
1210
  ex = SASS_MEMORY_NEW(String_Constant, sq->pstate(), sq->value());
@@ -1172,8 +1219,13 @@ namespace Sass {
1172
1219
  // XXX: this is never hit via spec tests
1173
1220
  ex = ex->perform(this);
1174
1221
  }
1222
+ // parent selector needs another go
1223
+ if (Cast<Parent_Reference>(ex)) {
1224
+ // XXX: this is never hit via spec tests
1225
+ ex = ex->perform(this);
1226
+ }
1175
1227
 
1176
- if (List_Ptr l = Cast<List>(ex)) {
1228
+ if (List* l = Cast<List>(ex)) {
1177
1229
  List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());
1178
1230
  // this fixes an issue with bourbon sample, not really sure why
1179
1231
  // if (l->size() && Cast<Null>((*l)[0])) { res += ""; }
@@ -1187,12 +1239,12 @@ namespace Sass {
1187
1239
  // here. Normally single list items are already unwrapped.
1188
1240
  if (l->size() > 1) {
1189
1241
  // string_to_output would fail "#{'_\a' '_\a'}";
1190
- std::string str(ll->to_string(ctx.c_options));
1242
+ std::string str(ll->to_string(options()));
1191
1243
  str = read_hex_escapes(str); // read escapes
1192
1244
  newline_to_space(str); // replace directly
1193
1245
  res += str; // append to result string
1194
1246
  } else {
1195
- res += (ll->to_string(ctx.c_options));
1247
+ res += (ll->to_string(options()));
1196
1248
  }
1197
1249
  ll->is_interpolant(l->is_interpolant());
1198
1250
  }
@@ -1207,9 +1259,9 @@ namespace Sass {
1207
1259
  else {
1208
1260
  // ex = ex->perform(this);
1209
1261
  if (into_quotes && ex->is_interpolant()) {
1210
- res += evacuate_escapes(ex ? ex->to_string(ctx.c_options) : "");
1262
+ res += evacuate_escapes(ex ? ex->to_string(options()) : "");
1211
1263
  } else {
1212
- std::string str(ex ? ex->to_string(ctx.c_options) : "");
1264
+ std::string str(ex ? ex->to_string(options()) : "");
1213
1265
  if (into_quotes) str = read_hex_escapes(str);
1214
1266
  res += str; // append to result string
1215
1267
  }
@@ -1219,14 +1271,14 @@ namespace Sass {
1219
1271
 
1220
1272
  }
1221
1273
 
1222
- Expression_Ptr Eval::operator()(String_Schema_Ptr s)
1274
+ Expression* Eval::operator()(String_Schema* s)
1223
1275
  {
1224
1276
  size_t L = s->length();
1225
1277
  bool into_quotes = false;
1226
1278
  if (L > 1) {
1227
1279
  if (!Cast<String_Quoted>((*s)[0]) && !Cast<String_Quoted>((*s)[L - 1])) {
1228
- if (String_Constant_Ptr l = Cast<String_Constant>((*s)[0])) {
1229
- if (String_Constant_Ptr r = Cast<String_Constant>((*s)[L - 1])) {
1280
+ if (String_Constant* l = Cast<String_Constant>((*s)[0])) {
1281
+ if (String_Constant* r = Cast<String_Constant>((*s)[L - 1])) {
1230
1282
  if (r->value().size() > 0) {
1231
1283
  if (l->value()[0] == '"' && r->value()[r->value().size() - 1] == '"') into_quotes = true;
1232
1284
  if (l->value()[0] == '\'' && r->value()[r->value().size() - 1] == '\'') into_quotes = true;
@@ -1255,7 +1307,7 @@ namespace Sass {
1255
1307
  // string schema seems to have a special unquoting behavior (also handles "nested" quotes)
1256
1308
  String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false, s->css());
1257
1309
  // if (s->is_interpolant()) str->quote_mark(0);
1258
- // String_Constant_Ptr str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
1310
+ // String_Constant* str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
1259
1311
  if (str->quote_mark()) str->quote_mark('*');
1260
1312
  else if (!is_in_comment) str->value(string_to_output(str->value()));
1261
1313
  str->is_interpolant(s->is_interpolant());
@@ -1263,32 +1315,25 @@ namespace Sass {
1263
1315
  }
1264
1316
 
1265
1317
 
1266
- Expression_Ptr Eval::operator()(String_Constant_Ptr s)
1318
+ Expression* Eval::operator()(String_Constant* s)
1267
1319
  {
1268
- if (!s->is_delayed() && name_to_color(s->value())) {
1269
- Color_Ptr c = SASS_MEMORY_COPY(name_to_color(s->value())); // copy
1270
- c->pstate(s->pstate());
1271
- c->disp(s->value());
1272
- c->is_delayed(true);
1273
- return c;
1274
- }
1275
1320
  return s;
1276
1321
  }
1277
1322
 
1278
- Expression_Ptr Eval::operator()(String_Quoted_Ptr s)
1323
+ Expression* Eval::operator()(String_Quoted* s)
1279
1324
  {
1280
- String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), "");
1325
+ String_Quoted* str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), "");
1281
1326
  str->value(s->value());
1282
1327
  str->quote_mark(s->quote_mark());
1283
1328
  str->is_interpolant(s->is_interpolant());
1284
1329
  return str;
1285
1330
  }
1286
1331
 
1287
- Expression_Ptr Eval::operator()(Supports_Operator_Ptr c)
1332
+ Expression* Eval::operator()(Supports_Operator* c)
1288
1333
  {
1289
- Expression_Ptr left = c->left()->perform(this);
1290
- Expression_Ptr right = c->right()->perform(this);
1291
- Supports_Operator_Ptr cc = SASS_MEMORY_NEW(Supports_Operator,
1334
+ Expression* left = c->left()->perform(this);
1335
+ Expression* right = c->right()->perform(this);
1336
+ Supports_Operator* cc = SASS_MEMORY_NEW(Supports_Operator,
1292
1337
  c->pstate(),
1293
1338
  Cast<Supports_Condition>(left),
1294
1339
  Cast<Supports_Condition>(right),
@@ -1296,52 +1341,52 @@ namespace Sass {
1296
1341
  return cc;
1297
1342
  }
1298
1343
 
1299
- Expression_Ptr Eval::operator()(Supports_Negation_Ptr c)
1344
+ Expression* Eval::operator()(Supports_Negation* c)
1300
1345
  {
1301
- Expression_Ptr condition = c->condition()->perform(this);
1302
- Supports_Negation_Ptr cc = SASS_MEMORY_NEW(Supports_Negation,
1346
+ Expression* condition = c->condition()->perform(this);
1347
+ Supports_Negation* cc = SASS_MEMORY_NEW(Supports_Negation,
1303
1348
  c->pstate(),
1304
1349
  Cast<Supports_Condition>(condition));
1305
1350
  return cc;
1306
1351
  }
1307
1352
 
1308
- Expression_Ptr Eval::operator()(Supports_Declaration_Ptr c)
1353
+ Expression* Eval::operator()(Supports_Declaration* c)
1309
1354
  {
1310
- Expression_Ptr feature = c->feature()->perform(this);
1311
- Expression_Ptr value = c->value()->perform(this);
1312
- Supports_Declaration_Ptr cc = SASS_MEMORY_NEW(Supports_Declaration,
1355
+ Expression* feature = c->feature()->perform(this);
1356
+ Expression* value = c->value()->perform(this);
1357
+ Supports_Declaration* cc = SASS_MEMORY_NEW(Supports_Declaration,
1313
1358
  c->pstate(),
1314
1359
  feature,
1315
1360
  value);
1316
1361
  return cc;
1317
1362
  }
1318
1363
 
1319
- Expression_Ptr Eval::operator()(Supports_Interpolation_Ptr c)
1364
+ Expression* Eval::operator()(Supports_Interpolation* c)
1320
1365
  {
1321
- Expression_Ptr value = c->value()->perform(this);
1322
- Supports_Interpolation_Ptr cc = SASS_MEMORY_NEW(Supports_Interpolation,
1366
+ Expression* value = c->value()->perform(this);
1367
+ Supports_Interpolation* cc = SASS_MEMORY_NEW(Supports_Interpolation,
1323
1368
  c->pstate(),
1324
1369
  value);
1325
1370
  return cc;
1326
1371
  }
1327
1372
 
1328
- Expression_Ptr Eval::operator()(At_Root_Query_Ptr e)
1373
+ Expression* Eval::operator()(At_Root_Query* e)
1329
1374
  {
1330
1375
  Expression_Obj feature = e->feature();
1331
1376
  feature = (feature ? feature->perform(this) : 0);
1332
1377
  Expression_Obj value = e->value();
1333
1378
  value = (value ? value->perform(this) : 0);
1334
- Expression_Ptr ee = SASS_MEMORY_NEW(At_Root_Query,
1379
+ Expression* ee = SASS_MEMORY_NEW(At_Root_Query,
1335
1380
  e->pstate(),
1336
1381
  Cast<String>(feature),
1337
1382
  value);
1338
1383
  return ee;
1339
1384
  }
1340
1385
 
1341
- Media_Query_Ptr Eval::operator()(Media_Query_Ptr q)
1386
+ Media_Query* Eval::operator()(Media_Query* q)
1342
1387
  {
1343
1388
  String_Obj t = q->media_type();
1344
- t = static_cast<String_Ptr>(t.isNull() ? 0 : t->perform(this));
1389
+ t = static_cast<String*>(t.isNull() ? 0 : t->perform(this));
1345
1390
  Media_Query_Obj qq = SASS_MEMORY_NEW(Media_Query,
1346
1391
  q->pstate(),
1347
1392
  t,
@@ -1349,12 +1394,12 @@ namespace Sass {
1349
1394
  q->is_negated(),
1350
1395
  q->is_restricted());
1351
1396
  for (size_t i = 0, L = q->length(); i < L; ++i) {
1352
- qq->append(static_cast<Media_Query_Expression_Ptr>((*q)[i]->perform(this)));
1397
+ qq->append(static_cast<Media_Query_Expression*>((*q)[i]->perform(this)));
1353
1398
  }
1354
1399
  return qq.detach();
1355
1400
  }
1356
1401
 
1357
- Expression_Ptr Eval::operator()(Media_Query_Expression_Ptr e)
1402
+ Expression* Eval::operator()(Media_Query_Expression* e)
1358
1403
  {
1359
1404
  Expression_Obj feature = e->feature();
1360
1405
  feature = (feature ? feature->perform(this) : 0);
@@ -1378,12 +1423,12 @@ namespace Sass {
1378
1423
  e->is_interpolated());
1379
1424
  }
1380
1425
 
1381
- Expression_Ptr Eval::operator()(Null_Ptr n)
1426
+ Expression* Eval::operator()(Null* n)
1382
1427
  {
1383
1428
  return n;
1384
1429
  }
1385
1430
 
1386
- Expression_Ptr Eval::operator()(Argument_Ptr a)
1431
+ Expression* Eval::operator()(Argument* a)
1387
1432
  {
1388
1433
  Expression_Obj val = a->value()->perform(this);
1389
1434
  bool is_rest_argument = a->is_rest_argument();
@@ -1412,13 +1457,13 @@ namespace Sass {
1412
1457
  is_keyword_argument);
1413
1458
  }
1414
1459
 
1415
- Expression_Ptr Eval::operator()(Arguments_Ptr a)
1460
+ Expression* Eval::operator()(Arguments* a)
1416
1461
  {
1417
1462
  Arguments_Obj aa = SASS_MEMORY_NEW(Arguments, a->pstate());
1418
1463
  if (a->length() == 0) return aa.detach();
1419
1464
  for (size_t i = 0, L = a->length(); i < L; ++i) {
1420
1465
  Expression_Obj rv = (*a)[i]->perform(this);
1421
- Argument_Ptr arg = Cast<Argument>(rv);
1466
+ Argument* arg = Cast<Argument>(rv);
1422
1467
  if (!(arg->is_rest_argument() || arg->is_keyword_argument())) {
1423
1468
  aa->append(arg);
1424
1469
  }
@@ -1429,8 +1474,8 @@ namespace Sass {
1429
1474
  Expression_Obj splat = Cast<Argument>(rest)->value()->perform(this);
1430
1475
 
1431
1476
  Sass_Separator separator = SASS_COMMA;
1432
- List_Ptr ls = Cast<List>(splat);
1433
- Map_Ptr ms = Cast<Map>(splat);
1477
+ List* ls = Cast<List>(splat);
1478
+ Map* ms = Cast<Map>(splat);
1434
1479
 
1435
1480
  List_Obj arglist = SASS_MEMORY_NEW(List,
1436
1481
  splat->pstate(),
@@ -1454,7 +1499,7 @@ namespace Sass {
1454
1499
 
1455
1500
  if (a->has_keyword_argument()) {
1456
1501
  Expression_Obj rv = a->get_keyword_argument()->perform(this);
1457
- Argument_Ptr rvarg = Cast<Argument>(rv);
1502
+ Argument* rvarg = Cast<Argument>(rv);
1458
1503
  Expression_Obj kwarg = rvarg->value()->perform(this);
1459
1504
 
1460
1505
  aa->append(SASS_MEMORY_NEW(Argument, kwarg->pstate(), kwarg, "", false, true));
@@ -1462,74 +1507,14 @@ namespace Sass {
1462
1507
  return aa.detach();
1463
1508
  }
1464
1509
 
1465
- Expression_Ptr Eval::operator()(Comment_Ptr c)
1510
+ Expression* Eval::operator()(Comment* c)
1466
1511
  {
1467
1512
  return 0;
1468
1513
  }
1469
1514
 
1470
- inline Expression_Ptr Eval::fallback_impl(AST_Node_Ptr n)
1515
+ Selector_List* Eval::operator()(Selector_List* s)
1471
1516
  {
1472
- return static_cast<Expression_Ptr>(n);
1473
- }
1474
-
1475
- // All the binary helpers.
1476
-
1477
- Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate)
1478
- {
1479
- using std::strlen;
1480
- using std::strcpy;
1481
- Expression_Ptr e = NULL;
1482
- switch (sass_value_get_tag(v)) {
1483
- case SASS_BOOLEAN: {
1484
- e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v));
1485
- } break;
1486
- case SASS_NUMBER: {
1487
- e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));
1488
- } break;
1489
- case SASS_COLOR: {
1490
- e = SASS_MEMORY_NEW(Color, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v));
1491
- } break;
1492
- case SASS_STRING: {
1493
- if (sass_string_is_quoted(v))
1494
- e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v));
1495
- else {
1496
- e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v));
1497
- }
1498
- } break;
1499
- case SASS_LIST: {
1500
- List_Ptr l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v));
1501
- for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) {
1502
- l->append(cval_to_astnode(sass_list_get_value(v, i), traces, pstate));
1503
- }
1504
- l->is_bracketed(sass_list_get_is_bracketed(v));
1505
- e = l;
1506
- } break;
1507
- case SASS_MAP: {
1508
- Map_Ptr m = SASS_MEMORY_NEW(Map, pstate);
1509
- for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) {
1510
- *m << std::make_pair(
1511
- cval_to_astnode(sass_map_get_key(v, i), traces, pstate),
1512
- cval_to_astnode(sass_map_get_value(v, i), traces, pstate));
1513
- }
1514
- e = m;
1515
- } break;
1516
- case SASS_NULL: {
1517
- e = SASS_MEMORY_NEW(Null, pstate);
1518
- } break;
1519
- case SASS_ERROR: {
1520
- error("Error in C function: " + std::string(sass_error_get_message(v)), pstate, traces);
1521
- } break;
1522
- case SASS_WARNING: {
1523
- error("Warning in C function: " + std::string(sass_warning_get_message(v)), pstate, traces);
1524
- } break;
1525
- default: break;
1526
- }
1527
- return e;
1528
- }
1529
-
1530
- Selector_List_Ptr Eval::operator()(Selector_List_Ptr s)
1531
- {
1532
- std::vector<Selector_List_Obj> rv;
1517
+ SelectorStack rv;
1533
1518
  Selector_List_Obj sl = SASS_MEMORY_NEW(Selector_List, s->pstate());
1534
1519
  sl->is_optional(s->is_optional());
1535
1520
  sl->media_block(s->media_block());
@@ -1560,14 +1545,14 @@ namespace Sass {
1560
1545
  }
1561
1546
 
1562
1547
 
1563
- Selector_List_Ptr Eval::operator()(Complex_Selector_Ptr s)
1548
+ Selector_List* Eval::operator()(Complex_Selector* s)
1564
1549
  {
1565
1550
  bool implicit_parent = !exp.old_at_root_without_rule;
1566
- if (is_in_selector_schema) exp.selector_stack.push_back(0);
1551
+ if (is_in_selector_schema) exp.selector_stack.push_back({});
1567
1552
  Selector_List_Obj resolved = s->resolve_parent_refs(exp.selector_stack, traces, implicit_parent);
1568
1553
  if (is_in_selector_schema) exp.selector_stack.pop_back();
1569
1554
  for (size_t i = 0; i < resolved->length(); i++) {
1570
- Complex_Selector_Ptr is = resolved->at(i)->first();
1555
+ Complex_Selector* is = resolved->at(i)->mutable_first();
1571
1556
  while (is) {
1572
1557
  if (is->head()) {
1573
1558
  is->head(operator()(is->head()));
@@ -1578,10 +1563,10 @@ namespace Sass {
1578
1563
  return resolved.detach();
1579
1564
  }
1580
1565
 
1581
- Compound_Selector_Ptr Eval::operator()(Compound_Selector_Ptr s)
1566
+ Compound_Selector* Eval::operator()(Compound_Selector* s)
1582
1567
  {
1583
1568
  for (size_t i = 0; i < s->length(); i++) {
1584
- Simple_Selector_Ptr ss = s->at(i);
1569
+ Simple_Selector* ss = s->at(i);
1585
1570
  // skip parents here (called via resolve_parent_refs)
1586
1571
  if (ss == NULL || Cast<Parent_Selector>(ss)) continue;
1587
1572
  s->at(i) = Cast<Simple_Selector>(ss->perform(this));
@@ -1589,14 +1574,12 @@ namespace Sass {
1589
1574
  return s;
1590
1575
  }
1591
1576
 
1592
- Selector_List_Ptr Eval::operator()(Selector_Schema_Ptr s)
1577
+ Selector_List* Eval::operator()(Selector_Schema* s)
1593
1578
  {
1594
1579
  LOCAL_FLAG(is_in_selector_schema, true);
1595
1580
  // the parser will look for a brace to end the selector
1596
- ctx.c_options.in_selector = true; // do not compress colors
1597
1581
  Expression_Obj sel = s->contents()->perform(this);
1598
- std::string result_str(sel->to_string(ctx.c_options));
1599
- ctx.c_options.in_selector = false; // flag temporary only
1582
+ std::string result_str(sel->to_string(options()));
1600
1583
  result_str = unquote(Util::rtrim(result_str));
1601
1584
  char* temp_cstr = sass_copy_c_string(result_str.c_str());
1602
1585
  ctx.strings.push_back(temp_cstr); // attach to context
@@ -1605,26 +1588,23 @@ namespace Sass {
1605
1588
  // a selector schema may or may not connect to parent?
1606
1589
  bool chroot = s->connect_parent() == false;
1607
1590
  Selector_List_Obj sl = p.parse_selector_list(chroot);
1608
- auto vec_str_rend = ctx.strings.rend();
1609
- auto vec_str_rbegin = ctx.strings.rbegin();
1610
- // remove the first item searching from the back
1611
- // we cannot assume our item is still the last one
1612
- // order is not important, so we can optimize this
1613
- auto it = std::find(vec_str_rbegin, vec_str_rend, temp_cstr);
1614
- // undefined behavior if not found!
1615
- if (it != vec_str_rend) {
1616
- // overwrite with last item
1617
- *it = ctx.strings.back();
1618
- // remove last one from vector
1619
- ctx.strings.pop_back();
1620
- // free temporary copy
1621
- free(temp_cstr);
1622
- }
1623
1591
  flag_is_in_selector_schema.reset();
1624
1592
  return operator()(sl);
1625
1593
  }
1626
1594
 
1627
- Expression_Ptr Eval::operator()(Parent_Selector_Ptr p)
1595
+ Expression* Eval::operator()(Parent_Selector* p)
1596
+ {
1597
+ if (Selector_List_Obj pr = selector()) {
1598
+ exp.selector_stack.pop_back();
1599
+ Selector_List_Obj rv = operator()(pr);
1600
+ exp.selector_stack.push_back(rv);
1601
+ return rv.detach();
1602
+ } else {
1603
+ return SASS_MEMORY_NEW(Null, p->pstate());
1604
+ }
1605
+ }
1606
+
1607
+ Expression* Eval::operator()(Parent_Reference* p)
1628
1608
  {
1629
1609
  if (Selector_List_Obj pr = selector()) {
1630
1610
  exp.selector_stack.pop_back();
@@ -1636,7 +1616,7 @@ namespace Sass {
1636
1616
  }
1637
1617
  }
1638
1618
 
1639
- Simple_Selector_Ptr Eval::operator()(Simple_Selector_Ptr s)
1619
+ Simple_Selector* Eval::operator()(Simple_Selector* s)
1640
1620
  {
1641
1621
  return s;
1642
1622
  }
@@ -1646,13 +1626,13 @@ namespace Sass {
1646
1626
  // be fixed by implement superselector correctly for `:not`
1647
1627
  // first use of "find" (ATM only implemented for selectors)
1648
1628
  bool hasNotSelector(AST_Node_Obj obj) {
1649
- if (Wrapped_Selector_Ptr w = Cast<Wrapped_Selector>(obj)) {
1629
+ if (Wrapped_Selector* w = Cast<Wrapped_Selector>(obj)) {
1650
1630
  return w->name() == ":not";
1651
1631
  }
1652
1632
  return false;
1653
1633
  }
1654
1634
 
1655
- Wrapped_Selector_Ptr Eval::operator()(Wrapped_Selector_Ptr s)
1635
+ Wrapped_Selector* Eval::operator()(Wrapped_Selector* s)
1656
1636
  {
1657
1637
 
1658
1638
  if (s->name() == ":not") {
@@ -1660,15 +1640,14 @@ namespace Sass {
1660
1640
  if (s->selector()->find(hasNotSelector)) {
1661
1641
  s->selector()->clear();
1662
1642
  s->name(" ");
1663
- } else if (s->selector()->length() == 1) {
1664
- Complex_Selector_Ptr cs = s->selector()->at(0);
1665
- if (cs->tail()) {
1666
- s->selector()->clear();
1667
- s->name(" ");
1643
+ } else {
1644
+ for (size_t i = 0; i < s->selector()->length(); ++i) {
1645
+ Complex_Selector* cs = s->selector()->at(i);
1646
+ if (cs->tail()) {
1647
+ s->selector()->clear();
1648
+ s->name(" ");
1649
+ }
1668
1650
  }
1669
- } else if (s->selector()->length() > 1) {
1670
- s->selector()->clear();
1671
- s->name(" ");
1672
1651
  }
1673
1652
  }
1674
1653
  }