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
@@ -6,8 +6,10 @@
6
6
  #include "constants.hpp"
7
7
  #include "to_string.hpp"
8
8
  #include "inspect.hpp"
9
+ #include "extend.hpp"
9
10
  #include "eval.hpp"
10
11
  #include "util.hpp"
12
+ #include "expand.hpp"
11
13
  #include "utf8_string.hpp"
12
14
  #include "utf8.h"
13
15
 
@@ -39,19 +41,21 @@ namespace Sass {
39
41
  {
40
42
  Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[built-in function]"));
41
43
  sig_parser.lex<Prelexer::identifier>();
42
- string name(Util::normalize_underscores(sig_parser.lexed));
44
+ std::string name(Util::normalize_underscores(sig_parser.lexed));
43
45
  Parameters* params = sig_parser.parse_parameters();
44
- return new (ctx.mem) Definition(ParserState("[built-in function]"),
45
- sig,
46
- name,
47
- params,
48
- func,
49
- &ctx,
50
- false);
46
+ return SASS_MEMORY_NEW(ctx.mem, Definition,
47
+ ParserState("[built-in function]"),
48
+ sig,
49
+ name,
50
+ params,
51
+ func,
52
+ false);
51
53
  }
52
54
 
53
55
  Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx)
54
56
  {
57
+ using namespace Prelexer;
58
+
55
59
  const char* sig = sass_function_get_signature(c_func);
56
60
  Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[c function]"));
57
61
  // allow to overload generic callback plus @warn, @error and @debug with custom functions
@@ -60,26 +64,52 @@ namespace Sass {
60
64
  exactly < Constants::error_kwd >,
61
65
  exactly < Constants::debug_kwd >
62
66
  > >();
63
- string name(Util::normalize_underscores(sig_parser.lexed));
67
+ std::string name(Util::normalize_underscores(sig_parser.lexed));
64
68
  Parameters* params = sig_parser.parse_parameters();
65
- return new (ctx.mem) Definition(ParserState("[c function]"),
66
- sig,
67
- name,
68
- params,
69
- c_func,
70
- &ctx,
71
- false, true);
69
+ return SASS_MEMORY_NEW(ctx.mem, Definition,
70
+ ParserState("[c function]"),
71
+ sig,
72
+ name,
73
+ params,
74
+ c_func,
75
+ false, true);
76
+ }
77
+
78
+ std::string function_name(Signature sig)
79
+ {
80
+ std::string str(sig);
81
+ return str.substr(0, str.find('('));
72
82
  }
73
83
 
74
84
  namespace Functions {
75
85
 
86
+ inline void handle_utf8_error (const ParserState& pstate, Backtrace* backtrace)
87
+ {
88
+ try {
89
+ throw;
90
+ }
91
+ catch (utf8::invalid_code_point) {
92
+ std::string msg("utf8::invalid_code_point");
93
+ error(msg, pstate, backtrace);
94
+ }
95
+ catch (utf8::not_enough_room) {
96
+ std::string msg("utf8::not_enough_room");
97
+ error(msg, pstate, backtrace);
98
+ }
99
+ catch (utf8::invalid_utf8) {
100
+ std::string msg("utf8::invalid_utf8");
101
+ error(msg, pstate, backtrace);
102
+ }
103
+ catch (...) { throw; }
104
+ }
105
+
76
106
  template <typename T>
77
- T* get_arg(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace)
107
+ T* get_arg(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace)
78
108
  {
79
109
  // Minimal error handling -- the expectation is that built-ins will be written correctly!
80
110
  T* val = dynamic_cast<T*>(env[argname]);
81
111
  if (!val) {
82
- string msg("argument `");
112
+ std::string msg("argument `");
83
113
  msg += argname;
84
114
  msg += "` of `";
85
115
  msg += sig;
@@ -90,27 +120,27 @@ namespace Sass {
90
120
  return val;
91
121
  }
92
122
 
93
- Map* get_arg_m(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx)
123
+ Map* get_arg_m(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx)
94
124
  {
95
125
  // Minimal error handling -- the expectation is that built-ins will be written correctly!
96
126
  Map* val = dynamic_cast<Map*>(env[argname]);
97
127
  if (val) return val;
98
128
 
99
129
  List* lval = dynamic_cast<List*>(env[argname]);
100
- if (lval && lval->length() == 0) return new (ctx.mem) Map(pstate, 0);
130
+ if (lval && lval->length() == 0) return SASS_MEMORY_NEW(ctx.mem, Map, pstate, 0);
101
131
 
102
132
  // fallback on get_arg for error handling
103
133
  val = get_arg<Map>(argname, env, sig, pstate, backtrace);
104
134
  return val;
105
135
  }
106
136
 
107
- Number* get_arg_r(const string& argname, Env& env, Signature sig, ParserState pstate, double lo, double hi, Backtrace* backtrace)
137
+ Number* get_arg_r(const std::string& argname, Env& env, Signature sig, ParserState pstate, double lo, double hi, Backtrace* backtrace)
108
138
  {
109
139
  // Minimal error handling -- the expectation is that built-ins will be written correctly!
110
140
  Number* val = get_arg<Number>(argname, env, sig, pstate, backtrace);
111
141
  double v = val->value();
112
142
  if (!(lo <= v && v <= hi)) {
113
- stringstream msg;
143
+ std::stringstream msg;
114
144
  msg << "argument `" << argname << "` of `" << sig << "` must be between ";
115
145
  msg << lo << " and " << hi;
116
146
  error(msg.str(), pstate, backtrace);
@@ -118,7 +148,55 @@ namespace Sass {
118
148
  return val;
119
149
  }
120
150
 
121
- #ifdef __MINGW32__
151
+ #define ARGSEL(argname, seltype, contextualize) get_arg_sel<seltype>(argname, env, sig, pstate, backtrace, ctx)
152
+
153
+ template <typename T>
154
+ T* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx);
155
+
156
+ template <>
157
+ Selector_List* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
158
+ To_String to_string(&ctx, false);
159
+ Expression* exp = ARG(argname, Expression);
160
+ if (exp->concrete_type() == Expression::NULL_VAL) {
161
+ std::stringstream msg;
162
+ msg << argname << ": null is not a valid selector: it must be a string,\n";
163
+ msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
164
+ error(msg.str(), pstate);
165
+ }
166
+ std::string exp_src = exp->perform(&to_string) + "{";
167
+ return Parser::parse_selector(exp_src.c_str(), ctx);
168
+ }
169
+
170
+ template <>
171
+ Complex_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
172
+ To_String to_string(&ctx, false);
173
+ Expression* exp = ARG(argname, Expression);
174
+ if (exp->concrete_type() == Expression::NULL_VAL) {
175
+ std::stringstream msg;
176
+ msg << argname << ": null is not a valid selector: it must be a string,\n";
177
+ msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
178
+ error(msg.str(), pstate);
179
+ }
180
+ std::string exp_src = exp->perform(&to_string) + "{";
181
+ Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
182
+ return (sel_list->length() > 0) ? sel_list->first() : 0;
183
+ }
184
+
185
+ template <>
186
+ Compound_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) {
187
+ To_String to_string(&ctx, false);
188
+ Expression* exp = ARG(argname, Expression);
189
+ if (exp->concrete_type() == Expression::NULL_VAL) {
190
+ std::stringstream msg;
191
+ msg << argname << ": null is not a string for `" << function_name(sig) << "'";
192
+ error(msg.str(), pstate);
193
+ }
194
+ std::string exp_src = exp->perform(&to_string) + "{";
195
+ Selector_List* sel_list = Parser::parse_selector(exp_src.c_str(), ctx);
196
+ return (sel_list->length() > 0) ? sel_list->first()->tail()->head() : 0;
197
+ }
198
+
199
+ #ifdef __MINGW32__
122
200
  uint64_t GetSeed()
123
201
  {
124
202
  HCRYPTPROV hp = 0;
@@ -132,23 +210,24 @@ namespace Sass {
132
210
 
133
211
  return seed;
134
212
  }
135
- #else
136
- static random_device rd;
213
+ #else
214
+ static std::random_device rd;
137
215
  uint64_t GetSeed()
138
216
  {
139
- return rd();
140
- }
141
- #endif
217
+ return rd();
218
+ }
219
+ #endif
142
220
 
143
221
  // note: the performance of many implementations of
144
222
  // random_device degrades sharply once the entropy pool
145
223
  // is exhausted. For practical use, random_device is
146
224
  // generally only used to seed a PRNG such as mt19937.
147
- static mt19937 rand(static_cast<unsigned int>(GetSeed()));
225
+ static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));
148
226
 
149
227
  // features
150
- static set<string> features {
228
+ static std::set<std::string> features {
151
229
  "global-variable-shadowing",
230
+ "extend-selector-pseudoclass",
152
231
  "at-error",
153
232
  "units-level-3"
154
233
  };
@@ -159,52 +238,62 @@ namespace Sass {
159
238
 
160
239
  inline double color_num(Number* n) {
161
240
  if (n->unit() == "%") {
162
- return std::min(std::max(n->value(), 0.0), 1.0) * 255;
241
+ return std::min(std::max(n->value() * 255 / 100.0, 0.0), 255.0);
163
242
  } else {
164
243
  return std::min(std::max(n->value(), 0.0), 255.0);
165
244
  }
166
245
  }
167
246
 
247
+ inline double alpha_num(Number* n) {
248
+ if (n->unit() == "%") {
249
+ return std::min(std::max(n->value(), 0.0), 100.0);
250
+ } else {
251
+ return std::min(std::max(n->value(), 0.0), 1.0);
252
+ }
253
+ }
254
+
168
255
  Signature rgb_sig = "rgb($red, $green, $blue)";
169
256
  BUILT_IN(rgb)
170
257
  {
171
- return new (ctx.mem) Color(pstate,
172
- color_num(ARGR("$red", Number, 0, 255)),
173
- color_num(ARGR("$green", Number, 0, 255)),
174
- color_num(ARGR("$blue", Number, 0, 255)));
258
+ return SASS_MEMORY_NEW(ctx.mem, Color,
259
+ pstate,
260
+ color_num(ARG("$red", Number)),
261
+ color_num(ARG("$green", Number)),
262
+ color_num(ARG("$blue", Number)));
175
263
  }
176
264
 
177
265
  Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
178
266
  BUILT_IN(rgba_4)
179
267
  {
180
- return new (ctx.mem) Color(pstate,
181
- color_num(ARGR("$red", Number, 0, 255)),
182
- color_num(ARGR("$green", Number, 0, 255)),
183
- color_num(ARGR("$blue", Number, 0, 255)),
184
- ARGR("$alpha", Number, 0, 1)->value());
268
+ return SASS_MEMORY_NEW(ctx.mem, Color,
269
+ pstate,
270
+ color_num(ARG("$red", Number)),
271
+ color_num(ARG("$green", Number)),
272
+ color_num(ARG("$blue", Number)),
273
+ alpha_num(ARG("$alpha", Number)));
185
274
  }
186
275
 
187
276
  Signature rgba_2_sig = "rgba($color, $alpha)";
188
277
  BUILT_IN(rgba_2)
189
278
  {
190
279
  Color* c_arg = ARG("$color", Color);
191
- Color* new_c = new (ctx.mem) Color(*c_arg);
192
- new_c->a(ARGR("$alpha", Number, 0, 1)->value());
280
+ Color* new_c = SASS_MEMORY_NEW(ctx.mem, Color, *c_arg);
281
+ new_c->a(alpha_num(ARG("$alpha", Number)));
193
282
  new_c->disp("");
194
283
  return new_c;
195
284
  }
196
285
 
197
286
  Signature red_sig = "red($color)";
198
287
  BUILT_IN(red)
199
- { return new (ctx.mem) Number(pstate, ARG("$color", Color)->r()); }
288
+ { return SASS_MEMORY_NEW(ctx.mem, Number, pstate, ARG("$color", Color)->r()); }
200
289
 
201
290
  Signature green_sig = "green($color)";
202
291
  BUILT_IN(green)
203
- { return new (ctx.mem) Number(pstate, ARG("$color", Color)->g()); }
292
+ { return SASS_MEMORY_NEW(ctx.mem, Number, pstate, ARG("$color", Color)->g()); }
204
293
 
205
294
  Signature blue_sig = "blue($color)";
206
295
  BUILT_IN(blue)
207
- { return new (ctx.mem) Number(pstate, ARG("$color", Color)->b()); }
296
+ { return SASS_MEMORY_NEW(ctx.mem, Number, pstate, ARG("$color", Color)->b()); }
208
297
 
209
298
  Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)";
210
299
  BUILT_IN(mix)
@@ -220,11 +309,12 @@ namespace Sass {
220
309
  double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
221
310
  double w2 = 1 - w1;
222
311
 
223
- return new (ctx.mem) Color(pstate,
224
- std::round(w1*color1->r() + w2*color2->r()),
225
- std::round(w1*color1->g() + w2*color2->g()),
226
- std::round(w1*color1->b() + w2*color2->b()),
227
- color1->a()*p + color2->a()*(1-p));
312
+ return SASS_MEMORY_NEW(ctx.mem, Color,
313
+ pstate,
314
+ std::round(w1*color1->r() + w2*color2->r()),
315
+ std::round(w1*color1->g() + w2*color2->g()),
316
+ std::round(w1*color1->b() + w2*color2->b()),
317
+ color1->a()*p + color2->a()*(1-p));
228
318
  }
229
319
 
230
320
  ////////////////
@@ -298,15 +388,15 @@ namespace Sass {
298
388
  double g = (h_to_rgb(m1, m2, h) * 255.0);
299
389
  double b = (h_to_rgb(m1, m2, h-1.0/3.0) * 255.0);
300
390
 
301
- return new (ctx.mem) Color(pstate, r, g, b, a);
391
+ return SASS_MEMORY_NEW(ctx.mem, Color, pstate, r, g, b, a);
302
392
  }
303
393
 
304
394
  Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
305
395
  BUILT_IN(hsl)
306
396
  {
307
397
  return hsla_impl(ARG("$hue", Number)->value(),
308
- ARGR("$saturation", Number, 0, 100)->value(),
309
- ARGR("$lightness", Number, 0, 100)->value(),
398
+ ARG("$saturation", Number)->value(),
399
+ ARG("$lightness", Number)->value(),
310
400
  1.0,
311
401
  ctx,
312
402
  pstate);
@@ -316,9 +406,9 @@ namespace Sass {
316
406
  BUILT_IN(hsla)
317
407
  {
318
408
  return hsla_impl(ARG("$hue", Number)->value(),
319
- ARGR("$saturation", Number, 0, 100)->value(),
320
- ARGR("$lightness", Number, 0, 100)->value(),
321
- ARGR("$alpha", Number, 0, 1)->value(),
409
+ ARG("$saturation", Number)->value(),
410
+ ARG("$lightness", Number)->value(),
411
+ ARG("$alpha", Number)->value(),
322
412
  ctx,
323
413
  pstate);
324
414
  }
@@ -330,7 +420,7 @@ namespace Sass {
330
420
  HSL hsl_color = rgb_to_hsl(rgb_color->r(),
331
421
  rgb_color->g(),
332
422
  rgb_color->b());
333
- return new (ctx.mem) Number(pstate, hsl_color.h, "deg");
423
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, hsl_color.h, "deg");
334
424
  }
335
425
 
336
426
  Signature saturation_sig = "saturation($color)";
@@ -340,7 +430,7 @@ namespace Sass {
340
430
  HSL hsl_color = rgb_to_hsl(rgb_color->r(),
341
431
  rgb_color->g(),
342
432
  rgb_color->b());
343
- return new (ctx.mem) Number(pstate, hsl_color.s, "%");
433
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, hsl_color.s, "%");
344
434
  }
345
435
 
346
436
  Signature lightness_sig = "lightness($color)";
@@ -350,7 +440,7 @@ namespace Sass {
350
440
  HSL hsl_color = rgb_to_hsl(rgb_color->r(),
351
441
  rgb_color->g(),
352
442
  rgb_color->b());
353
- return new (ctx.mem) Number(pstate, hsl_color.l, "%");
443
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, hsl_color.l, "%");
354
444
  }
355
445
 
356
446
  Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
@@ -421,7 +511,7 @@ namespace Sass {
421
511
  Number* amount = dynamic_cast<Number*>(env["$amount"]);
422
512
  if (!amount) {
423
513
  To_String to_string(&ctx);
424
- return new (ctx.mem) String_Constant(pstate, "saturate(" + env["$color"]->perform(&to_string) + ")");
514
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "saturate(" + env["$color"]->perform(&to_string) + ")");
425
515
  }
426
516
 
427
517
  ARGR("$amount", Number, 0, 100);
@@ -482,7 +572,7 @@ namespace Sass {
482
572
  Number* amount = dynamic_cast<Number*>(env["$color"]);
483
573
  if (amount) {
484
574
  To_String to_string(&ctx);
485
- return new (ctx.mem) String_Constant(pstate, "grayscale(" + amount->perform(&to_string) + ")");
575
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "grayscale(" + amount->perform(&to_string) + ")");
486
576
  }
487
577
 
488
578
  Color* rgb_color = ARG("$color", Color);
@@ -519,15 +609,16 @@ namespace Sass {
519
609
  Number* amount = dynamic_cast<Number*>(env["$color"]);
520
610
  if (amount) {
521
611
  To_String to_string(&ctx);
522
- return new (ctx.mem) String_Constant(pstate, "invert(" + amount->perform(&to_string) + ")");
612
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "invert(" + amount->perform(&to_string) + ")");
523
613
  }
524
614
 
525
615
  Color* rgb_color = ARG("$color", Color);
526
- return new (ctx.mem) Color(pstate,
527
- 255 - rgb_color->r(),
528
- 255 - rgb_color->g(),
529
- 255 - rgb_color->b(),
530
- rgb_color->a());
616
+ return SASS_MEMORY_NEW(ctx.mem, Color,
617
+ pstate,
618
+ 255 - rgb_color->r(),
619
+ 255 - rgb_color->g(),
620
+ 255 - rgb_color->b(),
621
+ rgb_color->a());
531
622
  }
532
623
 
533
624
  ////////////////////
@@ -539,17 +630,17 @@ namespace Sass {
539
630
  {
540
631
  String_Constant* ie_kwd = dynamic_cast<String_Constant*>(env["$color"]);
541
632
  if (ie_kwd) {
542
- return new (ctx.mem) String_Constant(pstate, "alpha(" + ie_kwd->value() + ")");
633
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "alpha(" + ie_kwd->value() + ")");
543
634
  }
544
635
 
545
636
  // CSS3 filter function overload: pass literal through directly
546
637
  Number* amount = dynamic_cast<Number*>(env["$color"]);
547
638
  if (amount) {
548
639
  To_String to_string(&ctx);
549
- return new (ctx.mem) String_Constant(pstate, "opacity(" + amount->perform(&to_string) + ")");
640
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "opacity(" + amount->perform(&to_string) + ")");
550
641
  }
551
642
 
552
- return new (ctx.mem) Number(pstate, ARG("$color", Color)->a());
643
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, ARG("$color", Color)->a());
553
644
  }
554
645
 
555
646
  Signature opacify_sig = "opacify($color, $amount)";
@@ -559,11 +650,12 @@ namespace Sass {
559
650
  Color* color = ARG("$color", Color);
560
651
  double amount = ARGR("$amount", Number, 0, 1)->value();
561
652
  double alpha = std::min(color->a() + amount, 1.0);
562
- return new (ctx.mem) Color(pstate,
563
- color->r(),
564
- color->g(),
565
- color->b(),
566
- alpha);
653
+ return SASS_MEMORY_NEW(ctx.mem, Color,
654
+ pstate,
655
+ color->r(),
656
+ color->g(),
657
+ color->b(),
658
+ alpha);
567
659
  }
568
660
 
569
661
  Signature transparentize_sig = "transparentize($color, $amount)";
@@ -573,11 +665,12 @@ namespace Sass {
573
665
  Color* color = ARG("$color", Color);
574
666
  double amount = ARGR("$amount", Number, 0, 1)->value();
575
667
  double alpha = std::max(color->a() - amount, 0.0);
576
- return new (ctx.mem) Color(pstate,
577
- color->r(),
578
- color->g(),
579
- color->b(),
580
- alpha);
668
+ return SASS_MEMORY_NEW(ctx.mem, Color,
669
+ pstate,
670
+ color->r(),
671
+ color->g(),
672
+ color->b(),
673
+ alpha);
581
674
  }
582
675
 
583
676
  ////////////////////////
@@ -603,27 +696,36 @@ namespace Sass {
603
696
  error("cannot specify both RGB and HSL values for `adjust-color`", pstate);
604
697
  }
605
698
  if (rgb) {
606
- return new (ctx.mem) Color(pstate,
607
- color->r() + (r ? r->value() : 0),
608
- color->g() + (g ? g->value() : 0),
609
- color->b() + (b ? b->value() : 0),
610
- color->a() + (a ? a->value() : 0));
699
+ double rr = r ? ARGR("$red", Number, -255, 255)->value() : 0;
700
+ double gg = g ? ARGR("$green", Number, -255, 255)->value() : 0;
701
+ double bb = b ? ARGR("$blue", Number, -255, 255)->value() : 0;
702
+ double aa = a ? ARGR("$alpha", Number, -1, 1)->value() : 0;
703
+ return SASS_MEMORY_NEW(ctx.mem, Color,
704
+ pstate,
705
+ color->r() + rr,
706
+ color->g() + gg,
707
+ color->b() + bb,
708
+ color->a() + aa);
611
709
  }
612
710
  if (hsl) {
613
711
  HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b());
712
+ double ss = s ? ARGR("$saturation", Number, -100, 100)->value() : 0;
713
+ double ll = l ? ARGR("$lightness", Number, -100, 100)->value() : 0;
714
+ double aa = a ? ARGR("$alpha", Number, -1, 1)->value() : 0;
614
715
  return hsla_impl(hsl_struct.h + (h ? h->value() : 0),
615
- hsl_struct.s + (s ? s->value() : 0),
616
- hsl_struct.l + (l ? l->value() : 0),
617
- color->a() + (a ? a->value() : 0),
716
+ hsl_struct.s + ss,
717
+ hsl_struct.l + ll,
718
+ color->a() + aa,
618
719
  ctx,
619
720
  pstate);
620
721
  }
621
722
  if (a) {
622
- return new (ctx.mem) Color(pstate,
623
- color->r(),
624
- color->g(),
625
- color->b(),
626
- color->a() + (a ? a->value() : 0));
723
+ return SASS_MEMORY_NEW(ctx.mem, Color,
724
+ pstate,
725
+ color->r(),
726
+ color->g(),
727
+ color->b(),
728
+ color->a() + (a ? a->value() : 0));
627
729
  }
628
730
  error("not enough arguments for `adjust-color`", pstate);
629
731
  // unreachable
@@ -653,11 +755,12 @@ namespace Sass {
653
755
  double gscale = (g ? ARGR("$green", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
654
756
  double bscale = (b ? ARGR("$blue", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
655
757
  double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
656
- return new (ctx.mem) Color(pstate,
657
- color->r() + rscale * (rscale > 0.0 ? 255 - color->r() : color->r()),
658
- color->g() + gscale * (gscale > 0.0 ? 255 - color->g() : color->g()),
659
- color->b() + bscale * (bscale > 0.0 ? 255 - color->b() : color->b()),
660
- color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()));
758
+ return SASS_MEMORY_NEW(ctx.mem, Color,
759
+ pstate,
760
+ color->r() + rscale * (rscale > 0.0 ? 255 - color->r() : color->r()),
761
+ color->g() + gscale * (gscale > 0.0 ? 255 - color->g() : color->g()),
762
+ color->b() + bscale * (bscale > 0.0 ? 255 - color->b() : color->b()),
763
+ color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()));
661
764
  }
662
765
  if (hsl) {
663
766
  double hscale = (h ? ARGR("$hue", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
@@ -673,11 +776,12 @@ namespace Sass {
673
776
  }
674
777
  if (a) {
675
778
  double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
676
- return new (ctx.mem) Color(pstate,
677
- color->r(),
678
- color->g(),
679
- color->b(),
680
- color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()));
779
+ return SASS_MEMORY_NEW(ctx.mem, Color,
780
+ pstate,
781
+ color->r(),
782
+ color->g(),
783
+ color->b(),
784
+ color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()));
681
785
  }
682
786
  error("not enough arguments for `scale-color`", pstate);
683
787
  // unreachable
@@ -703,11 +807,12 @@ namespace Sass {
703
807
  error("cannot specify both RGB and HSL values for `change-color`", pstate);
704
808
  }
705
809
  if (rgb) {
706
- return new (ctx.mem) Color(pstate,
707
- r ? ARGR("$red", Number, 0, 255)->value() : color->r(),
708
- g ? ARGR("$green", Number, 0, 255)->value() : color->g(),
709
- b ? ARGR("$blue", Number, 0, 255)->value() : color->b(),
710
- a ? ARGR("$alpha", Number, 0, 255)->value() : color->a());
810
+ return SASS_MEMORY_NEW(ctx.mem, Color,
811
+ pstate,
812
+ r ? ARGR("$red", Number, 0, 255)->value() : color->r(),
813
+ g ? ARGR("$green", Number, 0, 255)->value() : color->g(),
814
+ b ? ARGR("$blue", Number, 0, 255)->value() : color->b(),
815
+ a ? ARGR("$alpha", Number, 0, 255)->value() : color->a());
711
816
  }
712
817
  if (hsl) {
713
818
  HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b());
@@ -719,11 +824,12 @@ namespace Sass {
719
824
  }
720
825
  if (a) {
721
826
  double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a();
722
- return new (ctx.mem) Color(pstate,
723
- color->r(),
724
- color->g(),
725
- color->b(),
726
- alpha);
827
+ return SASS_MEMORY_NEW(ctx.mem, Color,
828
+ pstate,
829
+ color->r(),
830
+ color->g(),
831
+ color->b(),
832
+ alpha);
727
833
  }
728
834
  error("not enough arguments for `change-color`", pstate);
729
835
  // unreachable
@@ -746,18 +852,18 @@ namespace Sass {
746
852
  double b = cap_channel<0xff>(c->b());
747
853
  double a = cap_channel<1> (c->a()) * 255;
748
854
 
749
- stringstream ss;
855
+ std::stringstream ss;
750
856
  ss << '#' << std::setw(2) << std::setfill('0');
751
857
  ss << std::hex << std::setw(2) << static_cast<unsigned long>(std::floor(a+0.5));
752
858
  ss << std::hex << std::setw(2) << static_cast<unsigned long>(std::floor(r+0.5));
753
859
  ss << std::hex << std::setw(2) << static_cast<unsigned long>(std::floor(g+0.5));
754
860
  ss << std::hex << std::setw(2) << static_cast<unsigned long>(std::floor(b+0.5));
755
861
 
756
- string result(ss.str());
862
+ std::string result(ss.str());
757
863
  for (size_t i = 0, L = result.length(); i < L; ++i) {
758
864
  result[i] = std::toupper(result[i]);
759
865
  }
760
- return new (ctx.mem) String_Constant(pstate, result);
866
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, result);
761
867
  }
762
868
 
763
869
  ///////////////////
@@ -769,16 +875,23 @@ namespace Sass {
769
875
  {
770
876
  AST_Node* arg = env["$string"];
771
877
  if (dynamic_cast<Null*>(arg)) {
772
- return new (ctx.mem) Null(pstate);
878
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
773
879
  }
774
880
  else if (String_Quoted* string_quoted = dynamic_cast<String_Quoted*>(arg)) {
775
- String_Constant* result = new (ctx.mem) String_Constant(pstate, string_quoted->value());
881
+ String_Constant* result = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, string_quoted->value());
776
882
  // remember if the string was quoted (color tokens)
777
883
  result->sass_fix_1291(string_quoted->quote_mark() != 0);
778
884
  return result;
779
885
  }
780
- To_String to_string(&ctx);
781
- return new (ctx.mem) String_Constant(pstate, unquote(string(arg->perform(&to_string))));
886
+ else if (dynamic_cast<String_Constant*>(arg)) {
887
+ return (Expression*) arg;
888
+ }
889
+ else {
890
+ To_String to_string(&ctx);
891
+ std::string val(arg->perform(&to_string));
892
+ deprecated("Passing " + val + ", a non-string value, to unquote()", pstate);
893
+ return (Expression*) arg;
894
+ }
782
895
  }
783
896
 
784
897
  Signature quote_sig = "quote($string)";
@@ -786,8 +899,8 @@ namespace Sass {
786
899
  {
787
900
  To_String to_string(&ctx);
788
901
  AST_Node* arg = env["$string"];
789
- string str(quote(arg->perform(&to_string), String_Constant::double_quote()));
790
- String_Constant* result = new (ctx.mem) String_Constant(pstate, str);
902
+ std::string str(quote(arg->perform(&to_string), String_Constant::double_quote()));
903
+ String_Quoted* result = SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str);
791
904
  result->is_delayed(true);
792
905
  return result;
793
906
  }
@@ -796,39 +909,29 @@ namespace Sass {
796
909
  Signature str_length_sig = "str-length($string)";
797
910
  BUILT_IN(str_length)
798
911
  {
799
- size_t len = string::npos;
912
+ size_t len = std::string::npos;
800
913
  try {
801
914
  String_Constant* s = ARG("$string", String_Constant);
802
915
  len = UTF_8::code_point_count(s->value(), 0, s->value().size());
803
916
 
804
917
  }
805
- catch (utf8::invalid_code_point) {
806
- string msg("utf8::invalid_code_point");
807
- error(msg, pstate, backtrace);
808
- }
809
- catch (utf8::not_enough_room) {
810
- string msg("utf8::not_enough_room");
811
- error(msg, pstate, backtrace);
812
- }
813
- catch (utf8::invalid_utf8) {
814
- string msg("utf8::invalid_utf8");
815
- error(msg, pstate, backtrace);
816
- }
817
- catch (...) { throw; }
918
+ // handle any invalid utf8 errors
919
+ // other errors will be re-thrown
920
+ catch (...) { handle_utf8_error(pstate, backtrace); }
818
921
  // return something even if we had an error (-1)
819
- return new (ctx.mem) Number(pstate, len);
922
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)len);
820
923
  }
821
924
 
822
925
  Signature str_insert_sig = "str-insert($string, $insert, $index)";
823
926
  BUILT_IN(str_insert)
824
927
  {
825
- string str;
928
+ std::string str;
826
929
  try {
827
930
  String_Constant* s = ARG("$string", String_Constant);
828
931
  str = s->value();
829
932
  str = unquote(str);
830
933
  String_Constant* i = ARG("$insert", String_Constant);
831
- string ins = i->value();
934
+ std::string ins = i->value();
832
935
  ins = unquote(ins);
833
936
  Number* ind = ARG("$index", Number);
834
937
  double index = ind->value();
@@ -859,108 +962,78 @@ namespace Sass {
859
962
  if (ss->quote_mark()) str = quote(str);
860
963
  }
861
964
  }
862
- catch (utf8::invalid_code_point) {
863
- string msg("utf8::invalid_code_point");
864
- error(msg, pstate, backtrace);
865
- }
866
- catch (utf8::not_enough_room) {
867
- string msg("utf8::not_enough_room");
868
- error(msg, pstate, backtrace);
869
- }
870
- catch (utf8::invalid_utf8) {
871
- string msg("utf8::invalid_utf8");
872
- error(msg, pstate, backtrace);
873
- }
874
- catch (...) { throw; }
875
- return new (ctx.mem) String_Constant(pstate, str);
965
+ // handle any invalid utf8 errors
966
+ // other errors will be re-thrown
967
+ catch (...) { handle_utf8_error(pstate, backtrace); }
968
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str);
876
969
  }
877
970
 
878
971
  Signature str_index_sig = "str-index($string, $substring)";
879
972
  BUILT_IN(str_index)
880
973
  {
881
- size_t index = string::npos;
974
+ size_t index = std::string::npos;
882
975
  try {
883
976
  String_Constant* s = ARG("$string", String_Constant);
884
977
  String_Constant* t = ARG("$substring", String_Constant);
885
- string str = s->value();
978
+ std::string str = s->value();
886
979
  str = unquote(str);
887
- string substr = t->value();
980
+ std::string substr = t->value();
888
981
  substr = unquote(substr);
889
982
 
890
983
  size_t c_index = str.find(substr);
891
- if(c_index == string::npos) {
892
- return new (ctx.mem) Null(pstate);
984
+ if(c_index == std::string::npos) {
985
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
893
986
  }
894
987
  index = UTF_8::code_point_count(str, 0, c_index) + 1;
895
988
  }
896
- catch (utf8::invalid_code_point) {
897
- string msg("utf8::invalid_code_point");
898
- error(msg, pstate, backtrace);
899
- }
900
- catch (utf8::not_enough_room) {
901
- string msg("utf8::not_enough_room");
902
- error(msg, pstate, backtrace);
903
- }
904
- catch (utf8::invalid_utf8) {
905
- string msg("utf8::invalid_utf8");
906
- error(msg, pstate, backtrace);
907
- }
908
- catch (...) { throw; }
989
+ // handle any invalid utf8 errors
990
+ // other errors will be re-thrown
991
+ catch (...) { handle_utf8_error(pstate, backtrace); }
909
992
  // return something even if we had an error (-1)
910
- return new (ctx.mem) Number(pstate, index);
993
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)index);
911
994
  }
912
995
 
913
996
  Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
914
997
  BUILT_IN(str_slice)
915
998
  {
916
- string newstr;
999
+ std::string newstr;
917
1000
  try {
918
1001
  String_Constant* s = ARG("$string", String_Constant);
919
1002
  double start_at = ARG("$start-at", Number)->value();
920
1003
  double end_at = ARG("$end-at", Number)->value();
921
1004
 
922
- string str = unquote(s->value());
1005
+ std::string str = unquote(s->value());
923
1006
 
924
1007
  size_t size = utf8::distance(str.begin(), str.end());
925
1008
  if (end_at <= size * -1.0) { end_at += size; }
926
1009
  if (end_at < 0) { end_at += size + 1; }
927
- if (end_at > size) { end_at = size; }
1010
+ if (end_at > size) { end_at = (double)size; }
928
1011
  if (start_at < 0) { start_at += size + 1; }
929
1012
  else if (start_at == 0) { ++ start_at; }
930
1013
 
931
1014
  if (start_at <= end_at)
932
1015
  {
933
- string::iterator start = str.begin();
1016
+ std::string::iterator start = str.begin();
934
1017
  utf8::advance(start, start_at - 1, str.end());
935
- string::iterator end = start;
1018
+ std::string::iterator end = start;
936
1019
  utf8::advance(end, end_at - start_at + 1, str.end());
937
- newstr = string(start, end);
1020
+ newstr = std::string(start, end);
938
1021
  }
939
1022
  if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
940
1023
  if(ss->quote_mark()) newstr = quote(newstr);
941
1024
  }
942
1025
  }
943
- catch (utf8::invalid_code_point) {
944
- string msg("utf8::invalid_code_point");
945
- error(msg, pstate, backtrace);
946
- }
947
- catch (utf8::not_enough_room) {
948
- string msg("utf8::not_enough_room");
949
- error(msg, pstate, backtrace);
950
- }
951
- catch (utf8::invalid_utf8) {
952
- string msg("utf8::invalid_utf8");
953
- error(msg, pstate, backtrace);
954
- }
955
- catch (...) { throw; }
956
- return new (ctx.mem) String_Quoted(pstate, newstr);
1026
+ // handle any invalid utf8 errors
1027
+ // other errors will be re-thrown
1028
+ catch (...) { handle_utf8_error(pstate, backtrace); }
1029
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, newstr);
957
1030
  }
958
1031
 
959
1032
  Signature to_upper_case_sig = "to-upper-case($string)";
960
1033
  BUILT_IN(to_upper_case)
961
1034
  {
962
1035
  String_Constant* s = ARG("$string", String_Constant);
963
- string str = s->value();
1036
+ std::string str = s->value();
964
1037
 
965
1038
  for (size_t i = 0, L = str.length(); i < L; ++i) {
966
1039
  if (Sass::Util::isAscii(str[i])) {
@@ -969,16 +1042,19 @@ namespace Sass {
969
1042
  }
970
1043
 
971
1044
  if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
972
- str = ss->quote_mark() ? quote(str) : str;
1045
+ String_Quoted* cpy = SASS_MEMORY_NEW(ctx.mem, String_Quoted, *ss);
1046
+ cpy->value(str);
1047
+ return cpy;
1048
+ } else {
1049
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str);
973
1050
  }
974
- return new (ctx.mem) String_Constant(pstate, str);
975
1051
  }
976
1052
 
977
1053
  Signature to_lower_case_sig = "to-lower-case($string)";
978
1054
  BUILT_IN(to_lower_case)
979
1055
  {
980
1056
  String_Constant* s = ARG("$string", String_Constant);
981
- string str = s->value();
1057
+ std::string str = s->value();
982
1058
 
983
1059
  for (size_t i = 0, L = str.length(); i < L; ++i) {
984
1060
  if (Sass::Util::isAscii(str[i])) {
@@ -987,9 +1063,12 @@ namespace Sass {
987
1063
  }
988
1064
 
989
1065
  if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
990
- str = ss->quote_mark() ? quote(str, '"') : str;
1066
+ String_Quoted* cpy = SASS_MEMORY_NEW(ctx.mem, String_Quoted, *ss);
1067
+ cpy->value(str);
1068
+ return cpy;
1069
+ } else {
1070
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str);
991
1071
  }
992
- return new (ctx.mem) String_Constant(pstate, str);
993
1072
  }
994
1073
 
995
1074
  ///////////////////
@@ -1000,15 +1079,15 @@ namespace Sass {
1000
1079
  BUILT_IN(percentage)
1001
1080
  {
1002
1081
  Number* n = ARG("$number", Number);
1003
- if (!n->is_unitless()) error("argument $number of `" + string(sig) + "` must be unitless", pstate);
1004
- return new (ctx.mem) Number(pstate, n->value() * 100, "%");
1082
+ if (!n->is_unitless()) error("argument $number of `" + std::string(sig) + "` must be unitless", pstate);
1083
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, n->value() * 100, "%");
1005
1084
  }
1006
1085
 
1007
1086
  Signature round_sig = "round($number)";
1008
1087
  BUILT_IN(round)
1009
1088
  {
1010
1089
  Number* n = ARG("$number", Number);
1011
- Number* r = new (ctx.mem) Number(*n);
1090
+ Number* r = SASS_MEMORY_NEW(ctx.mem, Number, *n);
1012
1091
  r->pstate(pstate);
1013
1092
  r->value(std::floor(r->value() + 0.5));
1014
1093
  return r;
@@ -1018,7 +1097,7 @@ namespace Sass {
1018
1097
  BUILT_IN(ceil)
1019
1098
  {
1020
1099
  Number* n = ARG("$number", Number);
1021
- Number* r = new (ctx.mem) Number(*n);
1100
+ Number* r = SASS_MEMORY_NEW(ctx.mem, Number, *n);
1022
1101
  r->pstate(pstate);
1023
1102
  r->value(std::ceil(r->value()));
1024
1103
  return r;
@@ -1028,7 +1107,7 @@ namespace Sass {
1028
1107
  BUILT_IN(floor)
1029
1108
  {
1030
1109
  Number* n = ARG("$number", Number);
1031
- Number* r = new (ctx.mem) Number(*n);
1110
+ Number* r = SASS_MEMORY_NEW(ctx.mem, Number, *n);
1032
1111
  r->pstate(pstate);
1033
1112
  r->value(std::floor(r->value()));
1034
1113
  return r;
@@ -1038,7 +1117,7 @@ namespace Sass {
1038
1117
  BUILT_IN(abs)
1039
1118
  {
1040
1119
  Number* n = ARG("$number", Number);
1041
- Number* r = new (ctx.mem) Number(*n);
1120
+ Number* r = SASS_MEMORY_NEW(ctx.mem, Number, *n);
1042
1121
  r->pstate(pstate);
1043
1122
  r->value(std::abs(r->value()));
1044
1123
  return r;
@@ -1051,9 +1130,9 @@ namespace Sass {
1051
1130
  Number* least = 0;
1052
1131
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1053
1132
  Number* xi = dynamic_cast<Number*>(arglist->value_at_index(i));
1054
- if (!xi) error("`" + string(sig) + "` only takes numeric arguments", pstate);
1133
+ if (!xi) error("`" + std::string(sig) + "` only takes numeric arguments", pstate);
1055
1134
  if (least) {
1056
- if (lt(xi, least, ctx)) least = xi;
1135
+ if (Eval::lt(xi, least)) least = xi;
1057
1136
  } else least = xi;
1058
1137
  }
1059
1138
  return least;
@@ -1066,9 +1145,9 @@ namespace Sass {
1066
1145
  Number* greatest = 0;
1067
1146
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1068
1147
  Number* xi = dynamic_cast<Number*>(arglist->value_at_index(i));
1069
- if (!xi) error("`" + string(sig) + "` only takes numeric arguments", pstate);
1148
+ if (!xi) error("`" + std::string(sig) + "` only takes numeric arguments", pstate);
1070
1149
  if (greatest) {
1071
- if (lt(greatest, xi, ctx)) greatest = xi;
1150
+ if (Eval::lt(greatest, xi)) greatest = xi;
1072
1151
  } else greatest = xi;
1073
1152
  }
1074
1153
  return greatest;
@@ -1079,15 +1158,26 @@ namespace Sass {
1079
1158
  {
1080
1159
  Number* l = dynamic_cast<Number*>(env["$limit"]);
1081
1160
  if (l) {
1082
- if (trunc(l->value()) != l->value() || l->value() == 0) error("argument $limit of `" + string(sig) + "` must be a positive integer", pstate);
1083
- uniform_real_distribution<> distributor(1, l->value() + 1);
1161
+ double v = l->value();
1162
+ if (v < 1) {
1163
+ stringstream err;
1164
+ err << "$limit " << v << " must be greater than or equal to 1 for `random`";
1165
+ error(err.str(), pstate);
1166
+ }
1167
+ bool eq_int = std::fabs(trunc(v) - v) < NUMBER_EPSILON;
1168
+ if (!eq_int) {
1169
+ stringstream err;
1170
+ err << "Expected $limit to be an integer but got `" << v << "` for `random`";
1171
+ error(err.str(), pstate);
1172
+ }
1173
+ std::uniform_real_distribution<> distributor(1, v + 1);
1084
1174
  uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
1085
- return new (ctx.mem) Number(pstate, (double)distributed);
1175
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)distributed);
1086
1176
  }
1087
1177
  else {
1088
- uniform_real_distribution<> distributor(0, 1);
1178
+ std::uniform_real_distribution<> distributor(0, 1);
1089
1179
  double distributed = static_cast<double>(distributor(rand));
1090
- return new (ctx.mem) Number(pstate, distributed);
1180
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, distributed);
1091
1181
  }
1092
1182
  }
1093
1183
 
@@ -1101,13 +1191,24 @@ namespace Sass {
1101
1191
  Expression* v = ARG("$list", Expression);
1102
1192
  if (v->concrete_type() == Expression::MAP) {
1103
1193
  Map* map = dynamic_cast<Map*>(env["$list"]);
1104
- return new (ctx.mem) Number(pstate,
1105
- map ? map->length() : 1);
1194
+ return SASS_MEMORY_NEW(ctx.mem, Number,
1195
+ pstate,
1196
+ (double)(map ? map->length() : 1));
1197
+ }
1198
+ if (v->concrete_type() == Expression::SELECTOR) {
1199
+ if (Compound_Selector* h = dynamic_cast<Compound_Selector*>(v)) {
1200
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)h->length());
1201
+ } else if (Selector_List* ls = dynamic_cast<Selector_List*>(v)) {
1202
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)ls->length());
1203
+ } else {
1204
+ return SASS_MEMORY_NEW(ctx.mem, Number, pstate, 1);
1205
+ }
1106
1206
  }
1107
1207
 
1108
1208
  List* list = dynamic_cast<List*>(env["$list"]);
1109
- return new (ctx.mem) Number(pstate,
1110
- list ? list->size() : 1);
1209
+ return SASS_MEMORY_NEW(ctx.mem, Number,
1210
+ pstate,
1211
+ (double)(list ? list->size() : 1));
1111
1212
  }
1112
1213
 
1113
1214
  Signature nth_sig = "nth($list, $n)";
@@ -1116,20 +1217,20 @@ namespace Sass {
1116
1217
  Map* m = dynamic_cast<Map*>(env["$list"]);
1117
1218
  List* l = dynamic_cast<List*>(env["$list"]);
1118
1219
  Number* n = ARG("$n", Number);
1119
- if (n->value() == 0) error("argument `$n` of `" + string(sig) + "` must be non-zero", pstate);
1220
+ if (n->value() == 0) error("argument `$n` of `" + std::string(sig) + "` must be non-zero", pstate);
1120
1221
  // if the argument isn't a list, then wrap it in a singleton list
1121
1222
  if (!m && !l) {
1122
- l = new (ctx.mem) List(pstate, 1);
1223
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1123
1224
  *l << ARG("$list", Expression);
1124
1225
  }
1125
1226
  size_t len = m ? m->length() : l->length();
1126
1227
  bool empty = m ? m->empty() : l->empty();
1127
- if (empty) error("argument `$list` of `" + string(sig) + "` must not be empty", pstate);
1228
+ if (empty) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate);
1128
1229
  double index = std::floor(n->value() < 0 ? len + n->value() : n->value() - 1);
1129
- if (index < 0 || index > len - 1) error("index out of bounds for `" + string(sig) + "`", pstate);
1230
+ if (index < 0 || index > len - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate);
1130
1231
 
1131
1232
  if (m) {
1132
- l = new (ctx.mem) List(pstate, 1);
1233
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1133
1234
  *l << m->keys()[static_cast<unsigned int>(index)];
1134
1235
  *l << m->at(m->keys()[static_cast<unsigned int>(index)]);
1135
1236
  return l;
@@ -1146,13 +1247,13 @@ namespace Sass {
1146
1247
  Number* n = ARG("$n", Number);
1147
1248
  Expression* v = ARG("$value", Expression);
1148
1249
  if (!l) {
1149
- l = new (ctx.mem) List(pstate, 1);
1250
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1150
1251
  *l << ARG("$list", Expression);
1151
1252
  }
1152
- if (l->empty()) error("argument `$list` of `" + string(sig) + "` must not be empty", pstate);
1253
+ if (l->empty()) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate);
1153
1254
  double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1);
1154
- if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + string(sig) + "`", pstate);
1155
- List* result = new (ctx.mem) List(pstate, l->length(), l->separator());
1255
+ if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate);
1256
+ List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, l->length(), l->separator());
1156
1257
  for (size_t i = 0, L = l->length(); i < L; ++i) {
1157
1258
  *result << ((i == index) ? v : (*l)[i]);
1158
1259
  }
@@ -1165,13 +1266,13 @@ namespace Sass {
1165
1266
  List* l = dynamic_cast<List*>(env["$list"]);
1166
1267
  Expression* v = ARG("$value", Expression);
1167
1268
  if (!l) {
1168
- l = new (ctx.mem) List(pstate, 1);
1269
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1169
1270
  *l << ARG("$list", Expression);
1170
1271
  }
1171
1272
  for (size_t i = 0, L = l->length(); i < L; ++i) {
1172
- if (eq(l->value_at_index(i), v, ctx)) return new (ctx.mem) Number(pstate, i+1);
1273
+ if (Eval::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)(i+1));
1173
1274
  }
1174
- return new (ctx.mem) Null(pstate);
1275
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
1175
1276
  }
1176
1277
 
1177
1278
  Signature join_sig = "join($list1, $list2, $separator: auto)";
@@ -1180,22 +1281,22 @@ namespace Sass {
1180
1281
  List* l1 = dynamic_cast<List*>(env["$list1"]);
1181
1282
  List* l2 = dynamic_cast<List*>(env["$list2"]);
1182
1283
  String_Constant* sep = ARG("$separator", String_Constant);
1183
- List::Separator sep_val = (l1 ? l1->separator() : List::SPACE);
1284
+ enum Sass_Separator sep_val = (l1 ? l1->separator() : SASS_SPACE);
1184
1285
  if (!l1) {
1185
- l1 = new (ctx.mem) List(pstate, 1);
1286
+ l1 = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1186
1287
  *l1 << ARG("$list1", Expression);
1187
- sep_val = (l2 ? l2->separator() : List::SPACE);
1288
+ sep_val = (l2 ? l2->separator() : SASS_SPACE);
1188
1289
  }
1189
1290
  if (!l2) {
1190
- l2 = new (ctx.mem) List(pstate, 1);
1291
+ l2 = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1191
1292
  *l2 << ARG("$list2", Expression);
1192
1293
  }
1193
1294
  size_t len = l1->length() + l2->length();
1194
- string sep_str = unquote(sep->value());
1195
- if (sep_str == "space") sep_val = List::SPACE;
1196
- else if (sep_str == "comma") sep_val = List::COMMA;
1197
- else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
1198
- List* result = new (ctx.mem) List(pstate, len, sep_val);
1295
+ std::string sep_str = unquote(sep->value());
1296
+ if (sep_str == "space") sep_val = SASS_SPACE;
1297
+ else if (sep_str == "comma") sep_val = SASS_COMMA;
1298
+ else if (sep_str != "auto") error("argument `$separator` of `" + std::string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
1299
+ List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, len, sep_val);
1199
1300
  *result += l1;
1200
1301
  *result += l2;
1201
1302
  return result;
@@ -1208,23 +1309,24 @@ namespace Sass {
1208
1309
  Expression* v = ARG("$val", Expression);
1209
1310
  String_Constant* sep = ARG("$separator", String_Constant);
1210
1311
  if (!l) {
1211
- l = new (ctx.mem) List(pstate, 1);
1312
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1212
1313
  *l << ARG("$list", Expression);
1213
1314
  }
1214
- List* result = new (ctx.mem) List(pstate, l->length() + 1, l->separator());
1215
- string sep_str(unquote(sep->value()));
1216
- if (sep_str == "space") result->separator(List::SPACE);
1217
- else if (sep_str == "comma") result->separator(List::COMMA);
1218
- else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
1315
+ List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, l->length() + 1, l->separator());
1316
+ std::string sep_str(unquote(sep->value()));
1317
+ if (sep_str == "space") result->separator(SASS_SPACE);
1318
+ else if (sep_str == "comma") result->separator(SASS_COMMA);
1319
+ else if (sep_str != "auto") error("argument `$separator` of `" + std::string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
1219
1320
  *result += l;
1220
1321
  bool is_arglist = l->is_arglist();
1221
1322
  result->is_arglist(is_arglist);
1222
1323
  if (is_arglist) {
1223
- *result << new (ctx.mem) Argument(v->pstate(),
1224
- v,
1225
- "",
1226
- false,
1227
- false);
1324
+ *result << SASS_MEMORY_NEW(ctx.mem, Argument,
1325
+ v->pstate(),
1326
+ v,
1327
+ "",
1328
+ false,
1329
+ false);
1228
1330
 
1229
1331
  } else {
1230
1332
  *result << v;
@@ -1235,12 +1337,12 @@ namespace Sass {
1235
1337
  Signature zip_sig = "zip($lists...)";
1236
1338
  BUILT_IN(zip)
1237
1339
  {
1238
- List* arglist = new (ctx.mem) List(*ARG("$lists", List));
1340
+ List* arglist = SASS_MEMORY_NEW(ctx.mem, List, *ARG("$lists", List));
1239
1341
  size_t shortest = 0;
1240
1342
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1241
1343
  List* ith = dynamic_cast<List*>(arglist->value_at_index(i));
1242
1344
  if (!ith) {
1243
- ith = new (ctx.mem) List(pstate, 1);
1345
+ ith = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1244
1346
  *ith << arglist->value_at_index(i);
1245
1347
  if (arglist->is_arglist()) {
1246
1348
  ((Argument*)(*arglist)[i])->value(ith);
@@ -1250,10 +1352,10 @@ namespace Sass {
1250
1352
  }
1251
1353
  shortest = (i ? std::min(shortest, ith->length()) : ith->length());
1252
1354
  }
1253
- List* zippers = new (ctx.mem) List(pstate, shortest, List::COMMA);
1355
+ List* zippers = SASS_MEMORY_NEW(ctx.mem, List, pstate, shortest, SASS_COMMA);
1254
1356
  size_t L = arglist->length();
1255
1357
  for (size_t i = 0; i < shortest; ++i) {
1256
- List* zipper = new (ctx.mem) List(pstate, L);
1358
+ List* zipper = SASS_MEMORY_NEW(ctx.mem, List, pstate, L);
1257
1359
  for (size_t j = 0; j < L; ++j) {
1258
1360
  *zipper << (*static_cast<List*>(arglist->value_at_index(j)))[i];
1259
1361
  }
@@ -1267,11 +1369,12 @@ namespace Sass {
1267
1369
  {
1268
1370
  List* l = dynamic_cast<List*>(env["$list"]);
1269
1371
  if (!l) {
1270
- l = new (ctx.mem) List(pstate, 1);
1372
+ l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1);
1271
1373
  *l << ARG("$list", Expression);
1272
1374
  }
1273
- return new (ctx.mem) String_Constant(pstate,
1274
- l->separator() == List::COMMA ? "comma" : "space");
1375
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted,
1376
+ pstate,
1377
+ l->separator() == SASS_COMMA ? "comma" : "space");
1275
1378
  }
1276
1379
 
1277
1380
  /////////////////
@@ -1286,7 +1389,7 @@ namespace Sass {
1286
1389
  try {
1287
1390
  return m->at(v);
1288
1391
  } catch (const std::out_of_range&) {
1289
- return new (ctx.mem) Null(pstate);
1392
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
1290
1393
  }
1291
1394
  catch (...) { throw; }
1292
1395
  }
@@ -1296,14 +1399,14 @@ namespace Sass {
1296
1399
  {
1297
1400
  Map* m = ARGM("$map", Map, ctx);
1298
1401
  Expression* v = ARG("$key", Expression);
1299
- return new (ctx.mem) Boolean(pstate, m->has(v));
1402
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, m->has(v));
1300
1403
  }
1301
1404
 
1302
1405
  Signature map_keys_sig = "map-keys($map)";
1303
1406
  BUILT_IN(map_keys)
1304
1407
  {
1305
1408
  Map* m = ARGM("$map", Map, ctx);
1306
- List* result = new (ctx.mem) List(pstate, m->length(), List::COMMA);
1409
+ List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, m->length(), SASS_COMMA);
1307
1410
  for ( auto key : m->keys()) {
1308
1411
  *result << key;
1309
1412
  }
@@ -1314,7 +1417,7 @@ namespace Sass {
1314
1417
  BUILT_IN(map_values)
1315
1418
  {
1316
1419
  Map* m = ARGM("$map", Map, ctx);
1317
- List* result = new (ctx.mem) List(pstate, m->length(), List::COMMA);
1420
+ List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, m->length(), SASS_COMMA);
1318
1421
  for ( auto key : m->keys()) {
1319
1422
  *result << m->at(key);
1320
1423
  }
@@ -1328,7 +1431,7 @@ namespace Sass {
1328
1431
  Map* m2 = ARGM("$map2", Map, ctx);
1329
1432
 
1330
1433
  size_t len = m1->length() + m2->length();
1331
- Map* result = new (ctx.mem) Map(pstate, len);
1434
+ Map* result = SASS_MEMORY_NEW(ctx.mem, Map, pstate, len);
1332
1435
  *result += m1;
1333
1436
  *result += m2;
1334
1437
  return result;
@@ -1340,13 +1443,13 @@ namespace Sass {
1340
1443
  bool remove;
1341
1444
  Map* m = ARGM("$map", Map, ctx);
1342
1445
  List* arglist = ARG("$keys", List);
1343
- Map* result = new (ctx.mem) Map(pstate, 1);
1446
+ Map* result = SASS_MEMORY_NEW(ctx.mem, Map, pstate, 1);
1344
1447
  for (auto key : m->keys()) {
1345
1448
  remove = false;
1346
1449
  for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) {
1347
- remove = eq(key, arglist->value_at_index(j), ctx);
1450
+ remove = Eval::eq(key, arglist->value_at_index(j));
1348
1451
  }
1349
- if (!remove) *result << make_pair(key, m->at(key));
1452
+ if (!remove) *result << std::make_pair(key, m->at(key));
1350
1453
  }
1351
1454
  return result;
1352
1455
  }
@@ -1354,13 +1457,14 @@ namespace Sass {
1354
1457
  Signature keywords_sig = "keywords($args)";
1355
1458
  BUILT_IN(keywords)
1356
1459
  {
1357
- List* arglist = new (ctx.mem) List(*ARG("$args", List));
1358
- Map* result = new (ctx.mem) Map(pstate, 1);
1460
+ List* arglist = SASS_MEMORY_NEW(ctx.mem, List, *ARG("$args", List));
1461
+ Map* result = SASS_MEMORY_NEW(ctx.mem, Map, pstate, 1);
1359
1462
  for (size_t i = arglist->size(), L = arglist->length(); i < L; ++i) {
1360
- string name = string(((Argument*)(*arglist)[i])->name());
1463
+ std::string name = std::string(((Argument*)(*arglist)[i])->name());
1361
1464
  name = name.erase(0, 1); // sanitize name (remove dollar sign)
1362
- *result << make_pair(new (ctx.mem) String_Constant(pstate, name),
1363
- ((Argument*)(*arglist)[i])->value());
1465
+ *result << std::make_pair(SASS_MEMORY_NEW(ctx.mem, String_Quoted,
1466
+ pstate, name),
1467
+ ((Argument*)(*arglist)[i])->value());
1364
1468
  }
1365
1469
  return result;
1366
1470
  }
@@ -1373,23 +1477,16 @@ namespace Sass {
1373
1477
  BUILT_IN(type_of)
1374
1478
  {
1375
1479
  Expression* v = ARG("$value", Expression);
1376
- if (v->concrete_type() == Expression::STRING) {
1377
- To_String to_string(&ctx);
1378
- string str(v->perform(&to_string));
1379
- if (ctx.names_to_colors.count(str)) {
1380
- return new (ctx.mem) String_Constant(pstate, "color");
1381
- }
1382
- }
1383
- return new (ctx.mem) String_Constant(pstate, ARG("$value", Expression)->type());
1480
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, v->type());
1384
1481
  }
1385
1482
 
1386
1483
  Signature unit_sig = "unit($number)";
1387
1484
  BUILT_IN(unit)
1388
- { return new (ctx.mem) String_Quoted(pstate, quote(ARG("$number", Number)->unit(), '"')); }
1485
+ { return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, quote(ARG("$number", Number)->unit(), '"')); }
1389
1486
 
1390
1487
  Signature unitless_sig = "unitless($number)";
1391
1488
  BUILT_IN(unitless)
1392
- { return new (ctx.mem) Boolean(pstate, ARG("$number", Number)->is_unitless()); }
1489
+ { return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, ARG("$number", Number)->is_unitless()); }
1393
1490
 
1394
1491
  Signature comparable_sig = "comparable($number-1, $number-2)";
1395
1492
  BUILT_IN(comparable)
@@ -1397,103 +1494,111 @@ namespace Sass {
1397
1494
  Number* n1 = ARG("$number-1", Number);
1398
1495
  Number* n2 = ARG("$number-2", Number);
1399
1496
  if (n1->is_unitless() || n2->is_unitless()) {
1400
- return new (ctx.mem) Boolean(pstate, true);
1497
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1401
1498
  }
1402
1499
  Number tmp_n2(*n2);
1403
1500
  tmp_n2.normalize(n1->find_convertible_unit());
1404
- return new (ctx.mem) Boolean(pstate, n1->unit() == tmp_n2.unit());
1501
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, n1->unit() == tmp_n2.unit());
1405
1502
  }
1406
1503
 
1407
1504
  Signature variable_exists_sig = "variable-exists($name)";
1408
1505
  BUILT_IN(variable_exists)
1409
1506
  {
1410
- string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1507
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1411
1508
 
1412
1509
  if(d_env.has("$"+s)) {
1413
- return new (ctx.mem) Boolean(pstate, true);
1510
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1414
1511
  }
1415
1512
  else {
1416
- return new (ctx.mem) Boolean(pstate, false);
1513
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false);
1417
1514
  }
1418
1515
  }
1419
1516
 
1420
1517
  Signature global_variable_exists_sig = "global-variable-exists($name)";
1421
1518
  BUILT_IN(global_variable_exists)
1422
1519
  {
1423
- string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1520
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1424
1521
 
1425
1522
  if(d_env.has_global("$"+s)) {
1426
- return new (ctx.mem) Boolean(pstate, true);
1523
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1427
1524
  }
1428
1525
  else {
1429
- return new (ctx.mem) Boolean(pstate, false);
1526
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false);
1430
1527
  }
1431
1528
  }
1432
1529
 
1433
1530
  Signature function_exists_sig = "function-exists($name)";
1434
1531
  BUILT_IN(function_exists)
1435
1532
  {
1436
- string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1533
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1437
1534
 
1438
1535
  if(d_env.has_global(s+"[f]")) {
1439
- return new (ctx.mem) Boolean(pstate, true);
1536
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1440
1537
  }
1441
1538
  else {
1442
- return new (ctx.mem) Boolean(pstate, false);
1539
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false);
1443
1540
  }
1444
1541
  }
1445
1542
 
1446
1543
  Signature mixin_exists_sig = "mixin-exists($name)";
1447
1544
  BUILT_IN(mixin_exists)
1448
1545
  {
1449
- string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1546
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1450
1547
 
1451
1548
  if(d_env.has_global(s+"[m]")) {
1452
- return new (ctx.mem) Boolean(pstate, true);
1549
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1453
1550
  }
1454
1551
  else {
1455
- return new (ctx.mem) Boolean(pstate, false);
1552
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false);
1456
1553
  }
1457
1554
  }
1458
1555
 
1459
1556
  Signature feature_exists_sig = "feature-exists($name)";
1460
1557
  BUILT_IN(feature_exists)
1461
1558
  {
1462
- string s = unquote(ARG("$name", String_Constant)->value());
1559
+ std::string s = unquote(ARG("$name", String_Constant)->value());
1463
1560
 
1464
1561
  if(features.find(s) == features.end()) {
1465
- return new (ctx.mem) Boolean(pstate, false);
1562
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false);
1466
1563
  }
1467
1564
  else {
1468
- return new (ctx.mem) Boolean(pstate, true);
1565
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true);
1469
1566
  }
1470
1567
  }
1471
1568
 
1472
1569
  Signature call_sig = "call($name, $args...)";
1473
1570
  BUILT_IN(call)
1474
1571
  {
1475
- string name = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1476
- List* arglist = new (ctx.mem) List(*ARG("$args", List));
1572
+ std::string name = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
1573
+ List* arglist = SASS_MEMORY_NEW(ctx.mem, List, *ARG("$args", List));
1477
1574
 
1478
- Arguments* args = new (ctx.mem) Arguments(pstate);
1575
+ Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, pstate);
1576
+ std::string full_name(name + "[f]");
1577
+ Definition* def = d_env.has(full_name) ? static_cast<Definition*>((d_env)[full_name]) : 0;
1578
+ Parameters* params = def ? def->parameters() : 0;
1579
+ size_t param_size = params ? params->length() : 0;
1479
1580
  for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1480
1581
  Expression* expr = arglist->value_at_index(i);
1582
+ if (params && params->has_rest_parameter()) {
1583
+ Parameter* p = param_size > i ? (*params)[i] : 0;
1584
+ List* list = dynamic_cast<List*>(expr);
1585
+ if (list && p && !p->is_rest_parameter()) expr = (*list)[0];
1586
+ }
1481
1587
  if (arglist->is_arglist()) {
1482
- Argument* arg = static_cast<Argument*>((*arglist)[i]);
1483
- *args << new (ctx.mem) Argument(pstate,
1484
- expr,
1485
- "",
1486
- arg->is_rest_argument(),
1487
- arg->is_keyword_argument());
1588
+ Argument* arg = dynamic_cast<Argument*>((*arglist)[i]);
1589
+ *args << SASS_MEMORY_NEW(ctx.mem, Argument,
1590
+ pstate,
1591
+ expr,
1592
+ arg ? arg->name() : "",
1593
+ arg ? arg->is_rest_argument() : false,
1594
+ arg ? arg->is_keyword_argument() : false);
1488
1595
  } else {
1489
- *args << new (ctx.mem) Argument(pstate, expr);
1596
+ *args << SASS_MEMORY_NEW(ctx.mem, Argument, pstate, expr);
1490
1597
  }
1491
1598
  }
1492
- Function_Call* func = new (ctx.mem) Function_Call(pstate, name, args);
1493
- Contextualize contextualize(ctx, &d_env, backtrace);
1494
- Listize listize(ctx);
1495
- Eval eval(ctx, &contextualize, &listize, &d_env, backtrace);
1496
- return func->perform(&eval);
1599
+ Function_Call* func = SASS_MEMORY_NEW(ctx.mem, Function_Call, pstate, name, args);
1600
+ Expand expand(ctx, &d_env, backtrace);
1601
+ return func->perform(&expand.eval);
1497
1602
 
1498
1603
  }
1499
1604
 
@@ -1503,22 +1608,20 @@ namespace Sass {
1503
1608
 
1504
1609
  Signature not_sig = "not($value)";
1505
1610
  BUILT_IN(sass_not)
1506
- { return new (ctx.mem) Boolean(pstate, ARG("$value", Expression)->is_false()); }
1611
+ { return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, ARG("$value", Expression)->is_false()); }
1507
1612
 
1508
1613
  Signature if_sig = "if($condition, $if-true, $if-false)";
1509
1614
  // BUILT_IN(sass_if)
1510
1615
  // { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); }
1511
1616
  BUILT_IN(sass_if)
1512
1617
  {
1513
- Contextualize contextualize(ctx, &d_env, backtrace);
1514
- Listize listize(ctx);
1515
- Eval eval(ctx, &contextualize, &listize, &d_env, backtrace);
1516
- bool is_true = !ARG("$condition", Expression)->perform(&eval)->is_false();
1618
+ Expand expand(ctx, &d_env, backtrace);
1619
+ bool is_true = !ARG("$condition", Expression)->perform(&expand.eval)->is_false();
1517
1620
  if (is_true) {
1518
- return ARG("$if-true", Expression)->perform(&eval);
1621
+ return ARG("$if-true", Expression)->perform(&expand.eval);
1519
1622
  }
1520
1623
  else {
1521
- return ARG("$if-false", Expression)->perform(&eval);
1624
+ return ARG("$if-false", Expression)->perform(&expand.eval);
1522
1625
  }
1523
1626
  }
1524
1627
 
@@ -1542,9 +1645,9 @@ namespace Sass {
1542
1645
  {
1543
1646
  Expression* v = ARG("$value", Expression);
1544
1647
  if (v->concrete_type() == Expression::NULL_VAL) {
1545
- return new (ctx.mem) String_Constant(pstate, "null");
1648
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "null");
1546
1649
  } else if (v->concrete_type() == Expression::BOOLEAN && *v == 0) {
1547
- return new (ctx.mem) String_Constant(pstate, "false");
1650
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "false");
1548
1651
  } else if (v->concrete_type() == Expression::STRING) {
1549
1652
  return v;
1550
1653
  } else {
@@ -1554,38 +1657,244 @@ namespace Sass {
1554
1657
  old_style = ctx.output_style;
1555
1658
  ctx.output_style = NESTED;
1556
1659
  To_String to_string(&ctx, false);
1557
- string inspect = v->perform(&to_string);
1660
+ std::string inspect = v->perform(&to_string);
1558
1661
  if (inspect.empty() && parentheses) inspect = "()";
1559
1662
  ctx.output_style = old_style;
1560
- return new (ctx.mem) String_Constant(pstate, inspect);
1663
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, inspect);
1664
+ }
1665
+ // return v;
1666
+ }
1667
+ Signature selector_nest_sig = "selector-nest($selectors...)";
1668
+ BUILT_IN(selector_nest)
1669
+ {
1670
+ To_String to_string(&ctx, false);
1671
+ List* arglist = ARG("$selectors", List);
1672
+
1673
+ // Not enough parameters
1674
+ if( arglist->length() == 0 )
1675
+ error("$selectors: At least one selector must be passed", pstate);
1561
1676
 
1677
+ // Parse args into vector of selectors
1678
+ std::vector<Selector_List*> parsedSelectors;
1679
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1680
+ Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1681
+ if (exp->concrete_type() == Expression::NULL_VAL) {
1682
+ std::stringstream msg;
1683
+ msg << "$selectors: null is not a valid selector: it must be a string,\n";
1684
+ msg << "a list of strings, or a list of lists of strings for 'selector-nest'";
1685
+ error(msg.str(), pstate);
1686
+ }
1687
+ std::string exp_src = exp->perform(&to_string) + "{";
1688
+ Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1689
+ parsedSelectors.push_back(sel);
1690
+ }
1562
1691
 
1692
+ // Nothing to do
1693
+ if( parsedSelectors.empty() ) {
1694
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
1563
1695
  }
1564
- // return v;
1696
+
1697
+ // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector.
1698
+ std::vector<Selector_List*>::iterator itr = parsedSelectors.begin();
1699
+ Selector_List* result = *itr;
1700
+ ++itr;
1701
+
1702
+ for(;itr != parsedSelectors.end(); ++itr) {
1703
+ Selector_List* child = *itr;
1704
+ std::vector<Complex_Selector*> exploded;
1705
+ Selector_List* rv = child->parentize(result, ctx);
1706
+ for (size_t m = 0, mLen = rv->length(); m < mLen; ++m) {
1707
+ exploded.push_back((*rv)[m]);
1708
+ }
1709
+ result->elements(exploded);
1710
+ }
1711
+
1712
+ Listize listize(ctx);
1713
+ return result->perform(&listize);
1714
+ }
1715
+
1716
+ Signature selector_append_sig = "selector-append($selectors...)";
1717
+ BUILT_IN(selector_append)
1718
+ {
1719
+ To_String to_string;
1720
+ List* arglist = ARG("$selectors", List);
1721
+
1722
+ // Not enough parameters
1723
+ if( arglist->length() == 0 )
1724
+ error("$selectors: At least one selector must be passed", pstate);
1725
+
1726
+ // Parse args into vector of selectors
1727
+ std::vector<Selector_List*> parsedSelectors;
1728
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
1729
+ Expression* exp = dynamic_cast<Expression*>(arglist->value_at_index(i));
1730
+ if (exp->concrete_type() == Expression::NULL_VAL) {
1731
+ std::stringstream msg;
1732
+ msg << "$selectors: null is not a valid selector: it must be a string,\n";
1733
+ msg << "a list of strings, or a list of lists of strings for 'selector-append'";
1734
+ error(msg.str(), pstate);
1735
+ }
1736
+ std::string exp_src = exp->perform(&to_string) + "{";
1737
+ Selector_List* sel = Parser::parse_selector(exp_src.c_str(), ctx);
1738
+ parsedSelectors.push_back(sel);
1739
+ }
1740
+
1741
+ // Nothing to do
1742
+ if( parsedSelectors.empty() ) {
1743
+ return SASS_MEMORY_NEW(ctx.mem, Null, pstate);
1744
+ }
1745
+
1746
+ // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector.
1747
+ std::vector<Selector_List*>::iterator itr = parsedSelectors.begin();
1748
+ Selector_List* result = *itr;
1749
+ ++itr;
1750
+
1751
+ for(;itr != parsedSelectors.end(); ++itr) {
1752
+ Selector_List* child = *itr;
1753
+ std::vector<Complex_Selector*> newElements;
1754
+
1755
+ // For every COMPLEX_SELECTOR in `result`
1756
+ // For every COMPLEX_SELECTOR in `child`
1757
+ // let parentSeqClone equal a copy of result->elements[i]
1758
+ // let childSeq equal child->elements[j]
1759
+ // Append all of childSeq head elements into parentSeqClone
1760
+ // Set the innermost tail of parentSeqClone, to childSeq's tail
1761
+ // Replace result->elements with newElements
1762
+ for (size_t i = 0, resultLen = result->length(); i < resultLen; ++i) {
1763
+ for (size_t j = 0, childLen = child->length(); j < childLen; ++j) {
1764
+ Complex_Selector* parentSeqClone = (*result)[i]->cloneFully(ctx);
1765
+ Complex_Selector* childSeq = (*child)[j];
1766
+ Complex_Selector* base = childSeq->tail();
1767
+
1768
+ // Must be a simple sequence
1769
+ if( childSeq->combinator() != Complex_Selector::Combinator::ANCESTOR_OF ) {
1770
+ std::string msg("Can't append `");
1771
+ msg += childSeq->perform(&to_string);
1772
+ msg += "` to `";
1773
+ msg += parentSeqClone->perform(&to_string);;
1774
+ msg += "`";
1775
+ error(msg, pstate, backtrace);
1776
+ }
1777
+
1778
+ // Cannot be a Universal selector
1779
+ Type_Selector* pType = dynamic_cast<Type_Selector*>(base->head()->first());
1780
+ if(pType && pType->name() == "*") {
1781
+ std::string msg("Can't append `");
1782
+ msg += childSeq->perform(&to_string);
1783
+ msg += "` to `";
1784
+ msg += parentSeqClone->perform(&to_string);;
1785
+ msg += "`";
1786
+ error(msg, pstate, backtrace);
1787
+ }
1788
+
1789
+ // TODO: Add check for namespace stuff
1790
+
1791
+ // append any selectors in childSeq's head
1792
+ *(parentSeqClone->innermost()->head()) += (base->head());
1793
+
1794
+ // Set parentSeqClone new tail
1795
+ parentSeqClone->innermost()->tail( base->tail() );
1796
+
1797
+ newElements.push_back(parentSeqClone);
1798
+ }
1799
+ }
1800
+
1801
+ result->elements(newElements);
1802
+ }
1803
+
1804
+ Listize listize(ctx);
1805
+ return result->perform(&listize);
1806
+ }
1807
+
1808
+ Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
1809
+ BUILT_IN(selector_unify)
1810
+ {
1811
+ Selector_List* selector1 = ARGSEL("$selector1", Selector_List, p_contextualize);
1812
+ Selector_List* selector2 = ARGSEL("$selector2", Selector_List, p_contextualize);
1813
+
1814
+ Selector_List* result = selector1->unify_with(selector2, ctx);
1815
+ Listize listize(ctx);
1816
+ return result->perform(&listize);
1817
+ }
1818
+
1819
+ Signature simple_selectors_sig = "simple-selectors($selector)";
1820
+ BUILT_IN(simple_selectors)
1821
+ {
1822
+ Compound_Selector* sel = ARGSEL("$selector", Compound_Selector, p_contextualize);
1823
+
1824
+ To_String to_string;
1825
+ List* l = SASS_MEMORY_NEW(ctx.mem, List, sel->pstate(), sel->length(), SASS_COMMA);
1826
+
1827
+ for (size_t i = 0, L = sel->length(); i < L; ++i) {
1828
+ Simple_Selector* ss = (*sel)[i];
1829
+ std::string ss_string = ss->perform(&to_string) ;
1830
+
1831
+ *l << SASS_MEMORY_NEW(ctx.mem, String_Quoted, ss->pstate(), ss_string);
1832
+ }
1833
+
1834
+ return l;
1835
+ }
1836
+
1837
+ Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
1838
+ BUILT_IN(selector_extend)
1839
+ {
1840
+ Selector_List* selector = ARGSEL("$selector", Selector_List, p_contextualize);
1841
+ Selector_List* extendee = ARGSEL("$extendee", Selector_List, p_contextualize);
1842
+ Selector_List* extender = ARGSEL("$extender", Selector_List, p_contextualize);
1843
+
1844
+ ExtensionSubsetMap subset_map;
1845
+ extender->populate_extends(extendee, ctx, subset_map);
1846
+
1847
+ bool extendedSomething;
1848
+ Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, false, extendedSomething);
1849
+
1850
+ Listize listize(ctx);
1851
+ return result->perform(&listize);
1852
+ }
1853
+
1854
+ Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
1855
+ BUILT_IN(selector_replace)
1856
+ {
1857
+ Selector_List* selector = ARGSEL("$selector", Selector_List, p_contextualize);
1858
+ Selector_List* original = ARGSEL("$original", Selector_List, p_contextualize);
1859
+ Selector_List* replacement = ARGSEL("$replacement", Selector_List, p_contextualize);
1860
+
1861
+ ExtensionSubsetMap subset_map;
1862
+ replacement->populate_extends(original, ctx, subset_map);
1863
+
1864
+ bool extendedSomething;
1865
+ Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, true, extendedSomething);
1866
+
1867
+ Listize listize(ctx);
1868
+ return result->perform(&listize);
1869
+ }
1870
+
1871
+ Signature selector_parse_sig = "selector-parse($selector)";
1872
+ BUILT_IN(selector_parse)
1873
+ {
1874
+ Selector_List* sel = ARGSEL("$selector", Selector_List, p_contextualize);
1875
+
1876
+ Listize listize(ctx);
1877
+ return sel->perform(&listize);
1565
1878
  }
1566
1879
 
1567
1880
  Signature is_superselector_sig = "is-superselector($super, $sub)";
1568
1881
  BUILT_IN(is_superselector)
1569
1882
  {
1570
1883
  To_String to_string(&ctx, false);
1571
- Expression* ex_sup = ARG("$super", Expression);
1572
- Expression* ex_sub = ARG("$sub", Expression);
1573
- string sup_src = ex_sup->perform(&to_string) + "{";
1574
- string sub_src = ex_sub->perform(&to_string) + "{";
1575
- Selector_List* sel_sup = Parser::parse_selector(sup_src.c_str(), ctx);
1576
- Selector_List* sel_sub = Parser::parse_selector(sub_src.c_str(), ctx);
1884
+ Selector_List* sel_sup = ARGSEL("$super", Selector_List, p_contextualize);
1885
+ Selector_List* sel_sub = ARGSEL("$sub", Selector_List, p_contextualize);
1577
1886
  bool result = sel_sup->is_superselector_of(sel_sub);
1578
- return new (ctx.mem) Boolean(pstate, result);
1887
+ return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, result);
1579
1888
  }
1580
1889
 
1581
1890
  Signature unique_id_sig = "unique-id()";
1582
1891
  BUILT_IN(unique_id)
1583
1892
  {
1584
1893
  std::stringstream ss;
1585
- uniform_real_distribution<> distributor(0, 4294967296); // 16^8
1894
+ std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
1586
1895
  uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
1587
- ss << "u" << setfill('0') << setw(8) << std::hex << distributed;
1588
- return new (ctx.mem) String_Constant(pstate, ss.str());
1896
+ ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
1897
+ return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, ss.str());
1589
1898
  }
1590
1899
 
1591
1900
  }