sassc 1.11.1 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/README.md +3 -2
  4. data/ext/libsass/Makefile.conf +2 -1
  5. data/ext/libsass/appveyor.yml +10 -5
  6. data/ext/libsass/docs/dev-ast-memory.md +223 -0
  7. data/ext/libsass/include/sass/base.h +2 -0
  8. data/ext/libsass/script/bootstrap +7 -4
  9. data/ext/libsass/script/ci-build-libsass +3 -3
  10. data/ext/libsass/script/ci-install-compiler +2 -0
  11. data/ext/libsass/script/ci-report-coverage +2 -1
  12. data/ext/libsass/script/test-leaks.pl +103 -0
  13. data/ext/libsass/src/ast.cpp +621 -495
  14. data/ext/libsass/src/ast.hpp +801 -367
  15. data/ext/libsass/src/ast_def_macros.hpp +5 -5
  16. data/ext/libsass/src/ast_fwd_decl.hpp +312 -14
  17. data/ext/libsass/src/bind.cpp +54 -51
  18. data/ext/libsass/src/bind.hpp +3 -7
  19. data/ext/libsass/src/check_nesting.cpp +117 -120
  20. data/ext/libsass/src/check_nesting.hpp +38 -34
  21. data/ext/libsass/src/color_maps.cpp +3 -3
  22. data/ext/libsass/src/color_maps.hpp +3 -3
  23. data/ext/libsass/src/context.cpp +33 -34
  24. data/ext/libsass/src/context.hpp +12 -14
  25. data/ext/libsass/src/cssize.cpp +200 -228
  26. data/ext/libsass/src/cssize.hpp +49 -49
  27. data/ext/libsass/src/debugger.hpp +260 -241
  28. data/ext/libsass/src/emitter.cpp +6 -6
  29. data/ext/libsass/src/emitter.hpp +7 -7
  30. data/ext/libsass/src/environment.cpp +2 -2
  31. data/ext/libsass/src/environment.hpp +0 -2
  32. data/ext/libsass/src/error_handling.cpp +5 -5
  33. data/ext/libsass/src/error_handling.hpp +12 -12
  34. data/ext/libsass/src/eval.cpp +412 -401
  35. data/ext/libsass/src/eval.hpp +61 -62
  36. data/ext/libsass/src/expand.cpp +223 -204
  37. data/ext/libsass/src/expand.hpp +42 -42
  38. data/ext/libsass/src/extend.cpp +198 -201
  39. data/ext/libsass/src/extend.hpp +12 -14
  40. data/ext/libsass/src/file.hpp +4 -5
  41. data/ext/libsass/src/functions.cpp +413 -418
  42. data/ext/libsass/src/functions.hpp +7 -10
  43. data/ext/libsass/src/inspect.cpp +115 -109
  44. data/ext/libsass/src/inspect.hpp +69 -69
  45. data/ext/libsass/src/listize.cpp +31 -33
  46. data/ext/libsass/src/listize.hpp +8 -10
  47. data/ext/libsass/src/memory/SharedPtr.cpp +116 -0
  48. data/ext/libsass/src/memory/SharedPtr.hpp +202 -0
  49. data/ext/libsass/src/node.cpp +45 -43
  50. data/ext/libsass/src/node.hpp +15 -15
  51. data/ext/libsass/src/operation.hpp +136 -136
  52. data/ext/libsass/src/output.cpp +48 -49
  53. data/ext/libsass/src/output.hpp +14 -14
  54. data/ext/libsass/src/parser.cpp +530 -554
  55. data/ext/libsass/src/parser.hpp +91 -96
  56. data/ext/libsass/src/prelexer.cpp +13 -10
  57. data/ext/libsass/src/remove_placeholders.cpp +25 -21
  58. data/ext/libsass/src/remove_placeholders.hpp +7 -7
  59. data/ext/libsass/src/sass2scss.cpp +2 -1
  60. data/ext/libsass/src/sass_context.cpp +125 -107
  61. data/ext/libsass/src/sass_context.hpp +1 -1
  62. data/ext/libsass/src/sass_util.hpp +5 -5
  63. data/ext/libsass/src/sass_values.cpp +27 -27
  64. data/ext/libsass/src/source_map.cpp +2 -2
  65. data/ext/libsass/src/source_map.hpp +2 -2
  66. data/ext/libsass/src/subset_map.cpp +57 -0
  67. data/ext/libsass/src/subset_map.hpp +8 -76
  68. data/ext/libsass/src/to_c.cpp +13 -13
  69. data/ext/libsass/src/to_c.hpp +14 -14
  70. data/ext/libsass/src/to_value.cpp +20 -20
  71. data/ext/libsass/src/to_value.hpp +20 -21
  72. data/ext/libsass/src/util.cpp +55 -88
  73. data/ext/libsass/src/util.hpp +9 -13
  74. data/ext/libsass/src/values.cpp +27 -26
  75. data/ext/libsass/src/values.hpp +2 -2
  76. data/ext/libsass/test/test_subset_map.cpp +69 -69
  77. data/ext/libsass/win/libsass.targets +3 -2
  78. data/ext/libsass/win/libsass.vcxproj.filters +9 -6
  79. data/lib/sassc/version.rb +1 -1
  80. data/sassc.gemspec +0 -1
  81. data/test/native_test.rb +1 -1
  82. metadata +7 -5
  83. data/ext/libsass/src/ast_factory.hpp +0 -92
  84. data/ext/libsass/src/memory_manager.cpp +0 -77
  85. data/ext/libsass/src/memory_manager.hpp +0 -48
@@ -45,11 +45,11 @@ namespace Sass {
45
45
  void Emitter::set_filename(const std::string& str)
46
46
  { wbuf.smap.file = str; }
47
47
 
48
- void Emitter::schedule_mapping(const AST_Node* node)
48
+ void Emitter::schedule_mapping(const AST_Node_Ptr node)
49
49
  { scheduled_mapping = node; }
50
- void Emitter::add_open_mapping(const AST_Node* node)
50
+ void Emitter::add_open_mapping(const AST_Node_Ptr node)
51
51
  { wbuf.smap.add_open_mapping(node); }
52
- void Emitter::add_close_mapping(const AST_Node* node)
52
+ void Emitter::add_close_mapping(const AST_Node_Ptr node)
53
53
  { wbuf.smap.add_close_mapping(node); }
54
54
  ParserState Emitter::remap(const ParserState& pstate)
55
55
  { return wbuf.smap.remap(pstate); }
@@ -139,7 +139,7 @@ namespace Sass {
139
139
 
140
140
  // append some text or token to the buffer
141
141
  // this adds source-mappings for node start and end
142
- void Emitter::append_token(const std::string& text, const AST_Node* node)
142
+ void Emitter::append_token(const std::string& text, const AST_Node_Ptr node)
143
143
  {
144
144
  flush_schedules();
145
145
  add_open_mapping(node);
@@ -239,7 +239,7 @@ namespace Sass {
239
239
  }
240
240
  }
241
241
 
242
- void Emitter::append_scope_opener(AST_Node* node)
242
+ void Emitter::append_scope_opener(AST_Node_Ptr node)
243
243
  {
244
244
  scheduled_linefeed = 0;
245
245
  append_optional_space();
@@ -250,7 +250,7 @@ namespace Sass {
250
250
  // append_optional_space();
251
251
  ++ indentation;
252
252
  }
253
- void Emitter::append_scope_closer(AST_Node* node)
253
+ void Emitter::append_scope_closer(AST_Node_Ptr node)
254
254
  {
255
255
  -- indentation;
256
256
  scheduled_linefeed = 0;
@@ -25,9 +25,9 @@ namespace Sass {
25
25
  // proxy methods for source maps
26
26
  void add_source_index(size_t idx);
27
27
  void set_filename(const std::string& str);
28
- void add_open_mapping(const AST_Node* node);
29
- void add_close_mapping(const AST_Node* node);
30
- void schedule_mapping(const AST_Node* node);
28
+ void add_open_mapping(const AST_Node_Ptr node);
29
+ void add_close_mapping(const AST_Node_Ptr node);
30
+ void schedule_mapping(const AST_Node_Ptr node);
31
31
  std::string render_srcmap(Context &ctx);
32
32
  ParserState remap(const ParserState& pstate);
33
33
 
@@ -37,7 +37,7 @@ namespace Sass {
37
37
  size_t scheduled_space;
38
38
  size_t scheduled_linefeed;
39
39
  bool scheduled_delimiter;
40
- const AST_Node* scheduled_mapping;
40
+ AST_Node_Ptr scheduled_mapping;
41
41
 
42
42
  public:
43
43
  // output strings different in comments
@@ -70,7 +70,7 @@ namespace Sass {
70
70
  void append_wspace(const std::string& text);
71
71
  // append some text or token to the buffer
72
72
  // this adds source-mappings for node start and end
73
- void append_token(const std::string& text, const AST_Node* node);
73
+ void append_token(const std::string& text, const AST_Node_Ptr node);
74
74
 
75
75
  public: // syntax sugar
76
76
  void append_indentation();
@@ -79,8 +79,8 @@ namespace Sass {
79
79
  void append_special_linefeed(void);
80
80
  void append_optional_linefeed(void);
81
81
  void append_mandatory_linefeed(void);
82
- void append_scope_opener(AST_Node* node = 0);
83
- void append_scope_closer(AST_Node* node = 0);
82
+ void append_scope_opener(AST_Node_Ptr node = 0);
83
+ void append_scope_closer(AST_Node_Ptr node = 0);
84
84
  void append_comma_separator(void);
85
85
  void append_colon_separator(void);
86
86
  void append_delimiter(void);
@@ -179,7 +179,7 @@ namespace Sass {
179
179
  for (typename std::map<std::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
180
180
  if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
181
181
  std::cerr << prefix << std::string(indent, ' ') << i->first << " " << i->second;
182
- if (Value* val = dynamic_cast<Value*>(i->second))
182
+ if (Value_Ptr val = SASS_MEMORY_CAST_PTR(Value, i->second))
183
183
  { std::cerr << " : " << val->to_string(); }
184
184
  std::cerr << std::endl;
185
185
  }
@@ -189,7 +189,7 @@ namespace Sass {
189
189
  #endif
190
190
 
191
191
  // compile implementation for AST_Node
192
- template class Environment<AST_Node*>;
192
+ template class Environment<AST_Node_Obj>;
193
193
 
194
194
  }
195
195
 
@@ -6,7 +6,6 @@
6
6
 
7
7
  #include "ast_fwd_decl.hpp"
8
8
  #include "ast_def_macros.hpp"
9
- #include "memory_manager.hpp"
10
9
 
11
10
  namespace Sass {
12
11
 
@@ -18,7 +17,6 @@ namespace Sass {
18
17
  ADD_PROPERTY(bool, is_shadow)
19
18
 
20
19
  public:
21
- Memory_Manager mem;
22
20
  Environment(bool is_shadow = false);
23
21
  Environment(Environment* env, bool is_shadow = false);
24
22
  Environment(Environment& env, bool is_shadow = false);
@@ -21,7 +21,7 @@ namespace Sass {
21
21
  { }
22
22
 
23
23
 
24
- InvalidParent::InvalidParent(Selector* parent, Selector* selector)
24
+ InvalidParent::InvalidParent(Selector_Ptr parent, Selector_Ptr selector)
25
25
  : Base(selector->pstate()), parent(parent), selector(selector)
26
26
  {
27
27
  msg = "Invalid parent selector for \"";
@@ -31,7 +31,7 @@ namespace Sass {
31
31
  msg += "\"";
32
32
  }
33
33
 
34
- InvalidArgumentType::InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value* value)
34
+ InvalidArgumentType::InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value_Ptr value)
35
35
  : Base(pstate), fn(fn), arg(arg), type(type), value(value)
36
36
  {
37
37
  msg = arg + ": \"";
@@ -52,7 +52,7 @@ namespace Sass {
52
52
  : Base(pstate, msg, import_stack)
53
53
  { }
54
54
 
55
- UndefinedOperation::UndefinedOperation(const Expression* lhs, const Expression* rhs, const std::string& op)
55
+ UndefinedOperation::UndefinedOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op)
56
56
  : lhs(lhs), rhs(rhs), op(op)
57
57
  {
58
58
  msg = def_op_msg + ": \"";
@@ -62,7 +62,7 @@ namespace Sass {
62
62
  msg += "\".";
63
63
  }
64
64
 
65
- InvalidNullOperation::InvalidNullOperation(const Expression* lhs, const Expression* rhs, const std::string& op)
65
+ InvalidNullOperation::InvalidNullOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op)
66
66
  : UndefinedOperation(lhs, rhs, op)
67
67
  {
68
68
  msg = def_op_null_msg + ": \"";
@@ -120,7 +120,7 @@ namespace Sass {
120
120
  msg += "'.";
121
121
  }
122
122
 
123
- AlphaChannelsNotEqual::AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, const std::string& op)
123
+ AlphaChannelsNotEqual::AlphaChannelsNotEqual(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op)
124
124
  : lhs(lhs), rhs(rhs), op(op)
125
125
  {
126
126
  msg = "Alpha channels must be equal: ";
@@ -38,10 +38,10 @@ namespace Sass {
38
38
 
39
39
  class InvalidParent : public Base {
40
40
  protected:
41
- Selector* parent;
42
- Selector* selector;
41
+ Selector_Ptr parent;
42
+ Selector_Ptr selector;
43
43
  public:
44
- InvalidParent(Selector* parent, Selector* selector);
44
+ InvalidParent(Selector_Ptr parent, Selector_Ptr selector);
45
45
  virtual ~InvalidParent() throw() {};
46
46
  };
47
47
 
@@ -60,9 +60,9 @@ namespace Sass {
60
60
  std::string fn;
61
61
  std::string arg;
62
62
  std::string type;
63
- const Value* value;
63
+ const Value_Ptr value;
64
64
  public:
65
- InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value* value = 0);
65
+ InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value_Ptr value = 0);
66
66
  virtual ~InvalidArgumentType() throw() {};
67
67
  };
68
68
 
@@ -145,28 +145,28 @@ namespace Sass {
145
145
 
146
146
  class UndefinedOperation : public OperationError {
147
147
  protected:
148
- const Expression* lhs;
149
- const Expression* rhs;
148
+ Expression_Ptr_Const lhs;
149
+ Expression_Ptr_Const rhs;
150
150
  const std::string op;
151
151
  public:
152
- UndefinedOperation(const Expression* lhs, const Expression* rhs, const std::string& op);
152
+ UndefinedOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op);
153
153
  // virtual const char* errtype() const { return "Error"; }
154
154
  virtual ~UndefinedOperation() throw() {};
155
155
  };
156
156
 
157
157
  class InvalidNullOperation : public UndefinedOperation {
158
158
  public:
159
- InvalidNullOperation(const Expression* lhs, const Expression* rhs, const std::string& op);
159
+ InvalidNullOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op);
160
160
  virtual ~InvalidNullOperation() throw() {};
161
161
  };
162
162
 
163
163
  class AlphaChannelsNotEqual : public OperationError {
164
164
  protected:
165
- const Expression* lhs;
166
- const Expression* rhs;
165
+ Expression_Ptr_Const lhs;
166
+ Expression_Ptr_Const rhs;
167
167
  const std::string op;
168
168
  public:
169
- AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, const std::string& op);
169
+ AlphaChannelsNotEqual(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op);
170
170
  // virtual const char* errtype() const { return "Error"; }
171
171
  virtual ~AlphaChannelsNotEqual() throw() {};
172
172
  };
@@ -54,17 +54,12 @@ namespace Sass {
54
54
  { }
55
55
  Eval::~Eval() { }
56
56
 
57
- Context& Eval::context()
58
- {
59
- return ctx;
60
- }
61
-
62
57
  Env* Eval::environment()
63
58
  {
64
59
  return exp.environment();
65
60
  }
66
61
 
67
- CommaSequence_Selector* Eval::selector()
62
+ Selector_List_Obj Eval::selector()
68
63
  {
69
64
  return exp.selector();
70
65
  }
@@ -74,24 +69,24 @@ namespace Sass {
74
69
  return exp.backtrace();
75
70
  }
76
71
 
77
- Expression* Eval::operator()(Block* b)
72
+ Expression_Ptr Eval::operator()(Block_Ptr b)
78
73
  {
79
- Expression* val = 0;
74
+ Expression_Ptr val = 0;
80
75
  for (size_t i = 0, L = b->length(); i < L; ++i) {
81
- val = (*b)[i]->perform(this);
76
+ val = b->at(i)->perform(this);
82
77
  if (val) return val;
83
78
  }
84
79
  return val;
85
80
  }
86
81
 
87
- Expression* Eval::operator()(Assignment* a)
82
+ Expression_Ptr Eval::operator()(Assignment_Ptr a)
88
83
  {
89
84
  Env* env = exp.environment();
90
85
  std::string var(a->variable());
91
86
  if (a->is_global()) {
92
87
  if (a->is_default()) {
93
88
  if (env->has_global(var)) {
94
- Expression* e = dynamic_cast<Expression*>(env->get_global(var));
89
+ Expression_Ptr e = SASS_MEMORY_CAST(Expression, env->get_global(var));
95
90
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
96
91
  env->set_global(var, a->value()->perform(this));
97
92
  }
@@ -109,8 +104,8 @@ namespace Sass {
109
104
  auto cur = env;
110
105
  while (cur && cur->is_lexical()) {
111
106
  if (cur->has_local(var)) {
112
- if (AST_Node* node = cur->get_local(var)) {
113
- Expression* e = dynamic_cast<Expression*>(node);
107
+ if (AST_Node_Obj node = cur->get_local(var)) {
108
+ Expression_Ptr e = SASS_MEMORY_CAST(Expression, node);
114
109
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
115
110
  cur->set_local(var, a->value()->perform(this));
116
111
  }
@@ -125,8 +120,8 @@ namespace Sass {
125
120
  throw std::runtime_error("Env not in sync");
126
121
  }
127
122
  else if (env->has_global(var)) {
128
- if (AST_Node* node = env->get_global(var)) {
129
- Expression* e = dynamic_cast<Expression*>(node);
123
+ if (AST_Node_Obj node = env->get_global(var)) {
124
+ Expression_Ptr e = SASS_MEMORY_CAST(Expression, node);
130
125
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
131
126
  env->set_global(var, a->value()->perform(this));
132
127
  }
@@ -145,42 +140,43 @@ namespace Sass {
145
140
  return 0;
146
141
  }
147
142
 
148
- Expression* Eval::operator()(If* i)
143
+ Expression_Ptr Eval::operator()(If_Ptr i)
149
144
  {
150
- Expression* rv = 0;
145
+ Expression_Obj rv = 0;
151
146
  Env env(exp.environment());
152
147
  exp.env_stack.push_back(&env);
153
- if (*i->predicate()->perform(this)) {
148
+ Expression_Obj cond = i->predicate()->perform(this);
149
+ if (!cond->is_false()) {
154
150
  rv = i->block()->perform(this);
155
151
  }
156
152
  else {
157
- Block* alt = i->alternative();
153
+ Block_Obj alt = i->alternative();
158
154
  if (alt) rv = alt->perform(this);
159
155
  }
160
156
  exp.env_stack.pop_back();
161
- return rv;
157
+ return rv.detach();
162
158
  }
163
159
 
164
160
  // For does not create a new env scope
165
161
  // But iteration vars are reset afterwards
166
- Expression* Eval::operator()(For* f)
162
+ Expression_Ptr Eval::operator()(For_Ptr f)
167
163
  {
168
164
  std::string variable(f->variable());
169
- Expression* low = f->lower_bound()->perform(this);
165
+ Expression_Obj low = f->lower_bound()->perform(this);
170
166
  if (low->concrete_type() != Expression::NUMBER) {
171
167
  throw Exception::TypeMismatch(*low, "integer");
172
168
  }
173
- Expression* high = f->upper_bound()->perform(this);
169
+ Expression_Obj high = f->upper_bound()->perform(this);
174
170
  if (high->concrete_type() != Expression::NUMBER) {
175
171
  throw Exception::TypeMismatch(*high, "integer");
176
172
  }
177
- Number* sass_start = static_cast<Number*>(low);
178
- Number* sass_end = static_cast<Number*>(high);
173
+ Number_Obj sass_start = SASS_MEMORY_CAST(Number, low);
174
+ Number_Obj sass_end = SASS_MEMORY_CAST(Number, high);
179
175
  // check if units are valid for sequence
180
176
  if (sass_start->unit() != sass_end->unit()) {
181
177
  std::stringstream msg; msg << "Incompatible units: '"
182
- << sass_start->unit() << "' and '"
183
- << sass_end->unit() << "'.";
178
+ << sass_end->unit() << "' and '"
179
+ << sass_start->unit() << "'.";
184
180
  error(msg.str(), low->pstate(), backtrace());
185
181
  }
186
182
  double start = sass_start->value();
@@ -188,10 +184,10 @@ namespace Sass {
188
184
  // only create iterator once in this environment
189
185
  Env env(environment(), true);
190
186
  exp.env_stack.push_back(&env);
191
- Number* it = SASS_MEMORY_NEW(env.mem, Number, low->pstate(), start, sass_end->unit());
187
+ Number_Ptr it = SASS_MEMORY_NEW(Number, low->pstate(), start, sass_end->unit());
192
188
  env.set_local(variable, it);
193
- Block* body = f->block();
194
- Expression* val = 0;
189
+ Block_Obj body = f->block();
190
+ Expression_Ptr val = 0;
195
191
  if (start < end) {
196
192
  if (f->is_inclusive()) ++end;
197
193
  for (double i = start;
@@ -219,44 +215,45 @@ namespace Sass {
219
215
 
220
216
  // Eval does not create a new env scope
221
217
  // But iteration vars are reset afterwards
222
- Expression* Eval::operator()(Each* e)
218
+ Expression_Ptr Eval::operator()(Each_Ptr e)
223
219
  {
224
220
  std::vector<std::string> variables(e->variables());
225
- Expression* expr = e->list()->perform(this);
221
+ Expression_Obj expr = e->list()->perform(this);
226
222
  Env env(environment(), true);
227
223
  exp.env_stack.push_back(&env);
228
- Vectorized<Expression*>* list = 0;
229
- Map* map = 0;
224
+ List_Obj list = 0;
225
+ Map_Ptr map = 0;
230
226
  if (expr->concrete_type() == Expression::MAP) {
231
- map = static_cast<Map*>(expr);
227
+ map = SASS_MEMORY_CAST(Map, expr);
232
228
  }
233
- else if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(expr)) {
234
- Listize listize(ctx.mem);
235
- list = dynamic_cast<List*>(ls->perform(&listize));
229
+ else if (Selector_List_Ptr ls = SASS_MEMORY_CAST(Selector_List, expr)) {
230
+ Listize listize;
231
+ Expression_Obj rv = ls->perform(&listize);
232
+ list = dynamic_cast<List_Ptr>(&rv);
236
233
  }
237
234
  else if (expr->concrete_type() != Expression::LIST) {
238
- list = SASS_MEMORY_NEW(ctx.mem, List, expr->pstate(), 1, SASS_COMMA);
239
- *list << expr;
235
+ list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);
236
+ list->append(expr);
240
237
  }
241
238
  else {
242
- list = static_cast<List*>(expr);
239
+ list = SASS_MEMORY_CAST(List, expr);
243
240
  }
244
241
 
245
- Block* body = e->block();
246
- Expression* val = 0;
242
+ Block_Obj body = e->block();
243
+ Expression_Obj val = 0;
247
244
 
248
245
  if (map) {
249
- for (auto key : map->keys()) {
250
- Expression* value = map->at(key);
246
+ for (Expression_Obj key : map->keys()) {
247
+ Expression_Obj value = map->at(key);
251
248
 
252
249
  if (variables.size() == 1) {
253
- List* variable = SASS_MEMORY_NEW(ctx.mem, List, map->pstate(), 2, SASS_SPACE);
254
- *variable << key;
255
- *variable << value;
250
+ List_Ptr variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
251
+ variable->append(key);
252
+ variable->append(value);
256
253
  env.set_local(variables[0], variable);
257
254
  } else {
258
- env.set_local(variables[0], key);
259
- env.set_local(variables[1], value);
255
+ env.set_local(variables[0], &key);
256
+ env.set_local(variables[1], &value);
260
257
  }
261
258
 
262
259
  val = body->perform(this);
@@ -264,33 +261,33 @@ namespace Sass {
264
261
  }
265
262
  }
266
263
  else {
267
- if (list->length() == 1 && dynamic_cast<CommaSequence_Selector*>(list)) {
268
- list = dynamic_cast<Vectorized<Expression*>*>(list);
264
+ if (list->length() == 1 && SASS_MEMORY_CAST(Selector_List, list)) {
265
+ list = SASS_MEMORY_CAST(List, list);
269
266
  }
270
267
  for (size_t i = 0, L = list->length(); i < L; ++i) {
271
- Expression* e = (*list)[i];
268
+ Expression_Ptr e = &list->at(i);
272
269
  // unwrap value if the expression is an argument
273
- if (Argument* arg = dynamic_cast<Argument*>(e)) e = arg->value();
270
+ if (Argument_Ptr arg = SASS_MEMORY_CAST_PTR(Argument, e)) e = &arg->value();
274
271
  // check if we got passed a list of args (investigate)
275
- if (List* scalars = dynamic_cast<List*>(e)) {
272
+ if (List_Ptr scalars = SASS_MEMORY_CAST_PTR(List, e)) {
276
273
  if (variables.size() == 1) {
277
- Expression* var = scalars;
274
+ Expression_Ptr var = scalars;
278
275
  env.set_local(variables[0], var);
279
276
  } else {
280
277
  // XXX: this is never hit via spec tests
281
278
  for (size_t j = 0, K = variables.size(); j < K; ++j) {
282
- Expression* res = j >= scalars->length()
283
- ? SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate())
284
- : (*scalars)[j];
279
+ Expression_Ptr res = j >= scalars->length()
280
+ ? SASS_MEMORY_NEW(Null, expr->pstate())
281
+ : &scalars->at(j);
285
282
  env.set_local(variables[j], res);
286
283
  }
287
284
  }
288
285
  } else {
289
286
  if (variables.size() > 0) {
290
- env.set_local(variables[0], e);
287
+ env.set_local(variables.at(0), e);
291
288
  for (size_t j = 1, K = variables.size(); j < K; ++j) {
292
289
  // XXX: this is never hit via spec tests
293
- Expression* res = SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate());
290
+ Expression_Ptr res = SASS_MEMORY_NEW(Null, expr->pstate());
294
291
  env.set_local(variables[j], res);
295
292
  }
296
293
  }
@@ -300,43 +297,45 @@ namespace Sass {
300
297
  }
301
298
  }
302
299
  exp.env_stack.pop_back();
303
- return val;
300
+ return val.detach();
304
301
  }
305
302
 
306
- Expression* Eval::operator()(While* w)
303
+ Expression_Ptr Eval::operator()(While_Ptr w)
307
304
  {
308
- Expression* pred = w->predicate();
309
- Block* body = w->block();
305
+ Expression_Obj pred = w->predicate();
306
+ Block_Obj body = w->block();
310
307
  Env env(environment(), true);
311
308
  exp.env_stack.push_back(&env);
312
- while (*pred->perform(this)) {
313
- Expression* val = body->perform(this);
309
+ Expression_Obj cond = pred->perform(this);
310
+ while (!cond->is_false()) {
311
+ Expression_Obj val = body->perform(this);
314
312
  if (val) {
315
313
  exp.env_stack.pop_back();
316
- return val;
314
+ return val.detach();
317
315
  }
316
+ cond = pred->perform(this);
318
317
  }
319
318
  exp.env_stack.pop_back();
320
319
  return 0;
321
320
  }
322
321
 
323
- Expression* Eval::operator()(Return* r)
322
+ Expression_Ptr Eval::operator()(Return_Ptr r)
324
323
  {
325
324
  return r->value()->perform(this);
326
325
  }
327
326
 
328
- Expression* Eval::operator()(Warning* w)
327
+ Expression_Ptr Eval::operator()(Warning_Ptr w)
329
328
  {
330
329
  Sass_Output_Style outstyle = ctx.c_options.output_style;
331
330
  ctx.c_options.output_style = NESTED;
332
- Expression* message = w->message()->perform(this);
331
+ Expression_Obj message = w->message()->perform(this);
333
332
  Env* env = exp.environment();
334
333
 
335
334
  // try to use generic function
336
335
  if (env->has("@warn[f]")) {
337
336
 
338
- Definition* def = static_cast<Definition*>((*env)["@warn[f]"]);
339
- // Block* body = def->block();
337
+ Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@warn[f]"]);
338
+ // Block_Obj body = def->block();
340
339
  // Native_Function func = def->native_function();
341
340
  Sass_Function_Entry c_function = def->c_function();
342
341
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
@@ -361,18 +360,18 @@ namespace Sass {
361
360
  return 0;
362
361
  }
363
362
 
364
- Expression* Eval::operator()(Error* e)
363
+ Expression_Ptr Eval::operator()(Error_Ptr e)
365
364
  {
366
365
  Sass_Output_Style outstyle = ctx.c_options.output_style;
367
366
  ctx.c_options.output_style = NESTED;
368
- Expression* message = e->message()->perform(this);
367
+ Expression_Obj message = e->message()->perform(this);
369
368
  Env* env = exp.environment();
370
369
 
371
370
  // try to use generic function
372
371
  if (env->has("@error[f]")) {
373
372
 
374
- Definition* def = static_cast<Definition*>((*env)["@error[f]"]);
375
- // Block* body = def->block();
373
+ Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@error[f]"]);
374
+ // Block_Obj body = def->block();
376
375
  // Native_Function func = def->native_function();
377
376
  Sass_Function_Entry c_function = def->c_function();
378
377
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
@@ -394,18 +393,18 @@ namespace Sass {
394
393
  return 0;
395
394
  }
396
395
 
397
- Expression* Eval::operator()(Debug* d)
396
+ Expression_Ptr Eval::operator()(Debug_Ptr d)
398
397
  {
399
398
  Sass_Output_Style outstyle = ctx.c_options.output_style;
400
399
  ctx.c_options.output_style = NESTED;
401
- Expression* message = d->value()->perform(this);
400
+ Expression_Obj message = d->value()->perform(this);
402
401
  Env* env = exp.environment();
403
402
 
404
403
  // try to use generic function
405
404
  if (env->has("@debug[f]")) {
406
405
 
407
- Definition* def = static_cast<Definition*>((*env)["@debug[f]"]);
408
- // Block* body = def->block();
406
+ Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@debug[f]"]);
407
+ // Block_Obj body = def->block();
409
408
  // Native_Function func = def->native_function();
410
409
  Sass_Function_Entry c_function = def->c_function();
411
410
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
@@ -433,17 +432,17 @@ namespace Sass {
433
432
  return 0;
434
433
  }
435
434
 
436
- Expression* Eval::operator()(List* l)
435
+ Expression_Ptr Eval::operator()(List_Ptr l)
437
436
  {
438
437
  // special case for unevaluated map
439
438
  if (l->separator() == SASS_HASH) {
440
- Map* lm = SASS_MEMORY_NEW(ctx.mem, Map,
439
+ Map_Obj lm = SASS_MEMORY_NEW(Map,
441
440
  l->pstate(),
442
441
  l->length() / 2);
443
442
  for (size_t i = 0, L = l->length(); i < L; i += 2)
444
443
  {
445
- Expression* key = (*l)[i+0]->perform(this);
446
- Expression* val = (*l)[i+1]->perform(this);
444
+ Expression_Ptr key = (*l)[i+0]->perform(this);
445
+ Expression_Ptr val = (*l)[i+1]->perform(this);
447
446
  // make sure the color key never displays its real name
448
447
  key->is_delayed(true); // verified
449
448
  *lm << std::make_pair(key, val);
@@ -458,21 +457,21 @@ namespace Sass {
458
457
  // check if we should expand it
459
458
  if (l->is_expanded()) return l;
460
459
  // regular case for unevaluated lists
461
- List* ll = SASS_MEMORY_NEW(ctx.mem, List,
460
+ List_Obj ll = SASS_MEMORY_NEW(List,
462
461
  l->pstate(),
463
462
  l->length(),
464
463
  l->separator(),
465
464
  l->is_arglist());
466
465
  for (size_t i = 0, L = l->length(); i < L; ++i) {
467
- *ll << (*l)[i]->perform(this);
466
+ ll->append((*l)[i]->perform(this));
468
467
  }
469
468
  ll->is_interpolant(l->is_interpolant());
470
469
  ll->from_selector(l->from_selector());
471
470
  ll->is_expanded(true);
472
- return ll;
471
+ return ll.detach();
473
472
  }
474
473
 
475
- Expression* Eval::operator()(Map* m)
474
+ Expression_Ptr Eval::operator()(Map_Ptr m)
476
475
  {
477
476
  if (m->is_expanded()) return m;
478
477
 
@@ -482,12 +481,12 @@ namespace Sass {
482
481
  throw Exception::DuplicateKeyError(*m, *m);
483
482
  }
484
483
 
485
- Map* mm = SASS_MEMORY_NEW(ctx.mem, Map,
484
+ Map_Obj mm = SASS_MEMORY_NEW(Map,
486
485
  m->pstate(),
487
486
  m->length());
488
487
  for (auto key : m->keys()) {
489
- Expression* ex_key = key->perform(this);
490
- Expression* ex_val = m->at(key)->perform(this);
488
+ Expression_Ptr ex_key = key->perform(this);
489
+ Expression_Ptr ex_val = m->at(key)->perform(this);
491
490
  *mm << std::make_pair(ex_key, ex_val);
492
491
  }
493
492
 
@@ -497,54 +496,54 @@ namespace Sass {
497
496
  }
498
497
 
499
498
  mm->is_expanded(true);
500
- return mm;
499
+ return mm.detach();
501
500
  }
502
501
 
503
- Expression* Eval::operator()(Binary_Expression* b)
502
+ Expression_Ptr Eval::operator()(Binary_Expression_Ptr b_in)
504
503
  {
505
504
 
506
- String_Schema* ret_schema = 0;
505
+ String_Schema_Obj ret_schema;
506
+ Binary_Expression_Obj b = b_in;
507
507
  enum Sass_OP op_type = b->type();
508
508
 
509
509
  // only the last item will be used to eval the binary expression
510
- if (String_Schema* s_l = dynamic_cast<String_Schema*>(b->left())) {
510
+ if (String_Schema_Ptr s_l = SASS_MEMORY_CAST(String_Schema, b->left())) {
511
511
  if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) {
512
- ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, b->pstate());
513
- Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
514
- b->op(), s_l->last(), b->right());
512
+ ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
513
+ Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
514
+ b->op(), &s_l->last(), b->right());
515
515
  bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified
516
516
  for (size_t i = 0; i < s_l->length() - 1; ++i) {
517
- *ret_schema << s_l->at(i)->perform(this);
517
+ ret_schema->append(s_l->at(i)->perform(this));
518
518
  }
519
- *ret_schema << bin_ex->perform(this);
519
+ ret_schema->append(bin_ex->perform(this));
520
520
  return ret_schema->perform(this);
521
521
  }
522
522
  }
523
- if (String_Schema* s_r = dynamic_cast<String_Schema*>(b->right())) {
523
+ if (String_Schema_Ptr s_r = SASS_MEMORY_CAST(String_Schema, b->right())) {
524
+
524
525
  if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) {
525
- ret_schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, b->pstate());
526
- Binary_Expression* bin_ex = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, b->pstate(),
527
- b->op(), b->left(), s_r->first());
526
+ ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());
527
+ Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),
528
+ b->op(), b->left(), &s_r->first());
528
529
  bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified
529
- *ret_schema << bin_ex->perform(this);
530
+ ret_schema->append(bin_ex->perform(this));
530
531
  for (size_t i = 1; i < s_r->length(); ++i) {
531
- *ret_schema << s_r->at(i)->perform(this);
532
+ ret_schema->append(s_r->at(i)->perform(this));
532
533
  }
533
534
  return ret_schema->perform(this);
534
535
  }
535
536
  }
536
537
 
537
-
538
- b = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, *b);
539
538
  // don't eval delayed expressions (the '/' when used as a separator)
540
539
  if (!force && op_type == Sass_OP::DIV && b->is_delayed()) {
541
540
  b->right(b->right()->perform(this));
542
541
  b->left(b->left()->perform(this));
543
- return b;
542
+ return b.detach();
544
543
  }
545
544
 
546
- Expression* lhs = b->left();
547
- Expression* rhs = b->right();
545
+ Expression_Obj lhs = b->left();
546
+ Expression_Obj rhs = b->right();
548
547
 
549
548
  // fully evaluate their values
550
549
  if (op_type == Sass_OP::EQ ||
@@ -566,29 +565,32 @@ namespace Sass {
566
565
  lhs = lhs->perform(this);
567
566
  }
568
567
 
568
+ Binary_Expression_Obj u3 = b;
569
569
  switch (op_type) {
570
- case Sass_OP::AND:
571
- return *lhs ? b->right()->perform(this) : lhs;
572
- break;
570
+ case Sass_OP::AND: {
571
+ return *lhs ? b->right()->perform(this) : lhs.detach();
572
+ } break;
573
573
 
574
- case Sass_OP::OR:
575
- return *lhs ? lhs : b->right()->perform(this);
576
- break;
574
+ case Sass_OP::OR: {
575
+ return *lhs ? lhs.detach() : b->right()->perform(this);
576
+ } break;
577
577
 
578
578
  default:
579
579
  break;
580
580
  }
581
581
  // not a logical connective, so go ahead and eval the rhs
582
582
  rhs = rhs->perform(this);
583
+ AST_Node_Obj lu = &lhs;
584
+ AST_Node_Obj ru = &rhs;
583
585
 
584
586
  Expression::Concrete_Type l_type = lhs->concrete_type();
585
587
  Expression::Concrete_Type r_type = rhs->concrete_type();
586
588
 
587
589
  // Is one of the operands an interpolant?
588
- String_Schema* s1 = dynamic_cast<String_Schema*>(b->left());
589
- String_Schema* s2 = dynamic_cast<String_Schema*>(b->right());
590
- Binary_Expression* b1 = dynamic_cast<Binary_Expression*>(b->left());
591
- Binary_Expression* b2 = dynamic_cast<Binary_Expression*>(b->right());
590
+ String_Schema_Obj s1 = SASS_MEMORY_CAST(String_Schema, b->left());
591
+ String_Schema_Obj s2 = SASS_MEMORY_CAST(String_Schema, b->right());
592
+ Binary_Expression_Obj b1 = SASS_MEMORY_CAST(Binary_Expression, b->left());
593
+ Binary_Expression_Obj b2 = SASS_MEMORY_CAST(Binary_Expression, b->right());
592
594
 
593
595
  bool schema_op = false;
594
596
 
@@ -599,35 +601,36 @@ namespace Sass {
599
601
 
600
602
  if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants()) || force_delay)
601
603
  {
602
- // If possible upgrade LHS to a number
603
604
  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 ||
604
605
  op_type == Sass_OP::EQ) {
605
- if (String_Constant* str = dynamic_cast<String_Constant*>(lhs)) {
606
+ // If possible upgrade LHS to a number (for number to string compare)
607
+ if (String_Constant_Ptr str = SASS_MEMORY_CAST(String_Constant, lhs)) {
606
608
  std::string value(str->value());
607
609
  const char* start = value.c_str();
608
610
  if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) {
609
- lhs = SASS_MEMORY_NEW(ctx.mem, Textual, b->pstate(), Textual::DIMENSION, str->value());
610
- lhs = lhs->perform(this);
611
+ Textual_Obj l = SASS_MEMORY_NEW(Textual, b->pstate(), Textual::DIMENSION, str->value());
612
+ lhs = l->perform(this);
611
613
  }
612
614
  }
613
- if (String_Constant* str = dynamic_cast<String_Constant*>(rhs)) {
615
+ // If possible upgrade RHS to a number (for string to number compare)
616
+ if (String_Constant_Ptr str = SASS_MEMORY_CAST(String_Constant, rhs)) {
614
617
  std::string value(str->value());
615
618
  const char* start = value.c_str();
616
- if (Prelexer::sequence < Prelexer::number >(start) != 0) {
617
- rhs = SASS_MEMORY_NEW(ctx.mem, Textual, b->pstate(), Textual::DIMENSION, str->value());
618
- rhs = rhs->perform(this);
619
+ if (Prelexer::sequence < Prelexer::dimension, Prelexer::number >(start) != 0) {
620
+ Textual_Obj r = SASS_MEMORY_NEW(Textual, b->pstate(), Textual::DIMENSION, str->value());
621
+ rhs = r->perform(this);
619
622
  }
620
623
  }
621
624
  }
622
625
 
623
- To_Value to_value(ctx, ctx.mem);
624
- Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
625
- Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
626
+ To_Value to_value(ctx);
627
+ Value_Obj v_l = dynamic_cast<Value_Ptr>(lhs->perform(&to_value));
628
+ Value_Obj v_r = dynamic_cast<Value_Ptr>(rhs->perform(&to_value));
626
629
  l_type = lhs->concrete_type();
627
630
  r_type = rhs->concrete_type();
628
631
 
629
632
  if (s2 && s2->has_interpolants() && s2->length()) {
630
- Textual* front = dynamic_cast<Textual*>(s2->elements().front());
633
+ Textual_Obj front = SASS_MEMORY_CAST(Textual, s2->elements().front());
631
634
  if (front && !front->is_interpolant())
632
635
  {
633
636
  // XXX: this is never hit via spec tests
@@ -643,7 +646,7 @@ namespace Sass {
643
646
  str += b->separator();
644
647
  if (b->op().ws_after) str += " ";
645
648
  str += v_r->to_string(ctx.c_options);
646
- String_Constant* val = SASS_MEMORY_NEW(ctx.mem, String_Constant, b->pstate(), str);
649
+ String_Constant_Ptr val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str);
647
650
  val->is_interpolant(b->left()->has_interpolant());
648
651
  return val;
649
652
  }
@@ -652,12 +655,12 @@ namespace Sass {
652
655
  // see if it's a relational expression
653
656
  try {
654
657
  switch(op_type) {
655
- case Sass_OP::EQ: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), eq(lhs, rhs));
656
- case Sass_OP::NEQ: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), !eq(lhs, rhs));
657
- case Sass_OP::GT: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), !lt(lhs, rhs, "gt") && !eq(lhs, rhs));
658
- case Sass_OP::GTE: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), !lt(lhs, rhs, "gte"));
659
- case Sass_OP::LT: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), lt(lhs, rhs, "lt"));
660
- case Sass_OP::LTE: return SASS_MEMORY_NEW(ctx.mem, Boolean, b->pstate(), lt(lhs, rhs, "lte") || eq(lhs, rhs));
658
+ case Sass_OP::EQ: return SASS_MEMORY_NEW(Boolean, b->pstate(), eq(lhs, rhs));
659
+ case Sass_OP::NEQ: return SASS_MEMORY_NEW(Boolean, b->pstate(), !eq(lhs, rhs));
660
+ case Sass_OP::GT: return SASS_MEMORY_NEW(Boolean, b->pstate(), !lt(lhs, rhs, "gt") && !eq(lhs, rhs));
661
+ case Sass_OP::GTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), !lt(lhs, rhs, "gte"));
662
+ case Sass_OP::LT: return SASS_MEMORY_NEW(Boolean, b->pstate(), lt(lhs, rhs, "lt"));
663
+ case Sass_OP::LTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), lt(lhs, rhs, "lte") || eq(lhs, rhs));
661
664
  default: break;
662
665
  }
663
666
  }
@@ -672,33 +675,34 @@ namespace Sass {
672
675
 
673
676
  // ToDo: throw error in op functions
674
677
  // ToDo: then catch and re-throw them
675
- Expression* rv = 0;
678
+ Expression_Obj rv = 0;
676
679
  try {
677
680
  ParserState pstate(b->pstate());
678
681
  if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
679
- const Number* l_n = dynamic_cast<const Number*>(lhs);
680
- const Number* r_n = dynamic_cast<const Number*>(rhs);
681
- rv = op_numbers(ctx.mem, op_type, *l_n, *r_n, ctx.c_options, &pstate);
682
+ Number_Ptr l_n = SASS_MEMORY_CAST(Number, lhs);
683
+ Number_Ptr r_n = SASS_MEMORY_CAST(Number, rhs);
684
+ rv = op_numbers(op_type, *l_n, *r_n, ctx.c_options, &pstate);
682
685
  }
683
686
  else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
684
- const Number* l_n = dynamic_cast<const Number*>(lhs);
685
- const Color* r_c = dynamic_cast<const Color*>(rhs);
686
- rv = op_number_color(ctx.mem, op_type, *l_n, *r_c, ctx.c_options, &pstate);
687
+ Number_Ptr l_n = SASS_MEMORY_CAST(Number, lhs);
688
+ Color_Ptr r_c = SASS_MEMORY_CAST(Color, rhs);
689
+ rv = op_number_color(op_type, *l_n, *r_c, ctx.c_options, &pstate);
687
690
  }
688
691
  else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
689
- const Color* l_c = dynamic_cast<const Color*>(lhs);
690
- const Number* r_n = dynamic_cast<const Number*>(rhs);
691
- rv = op_color_number(ctx.mem, op_type, *l_c, *r_n, ctx.c_options, &pstate);
692
+ Color_Ptr l_c = SASS_MEMORY_CAST(Color, lhs);
693
+ Number_Ptr r_n = SASS_MEMORY_CAST(Number, rhs);
694
+ rv = op_color_number(op_type, *l_c, *r_n, ctx.c_options, &pstate);
692
695
  }
693
696
  else if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
694
- const Color* l_c = dynamic_cast<const Color*>(lhs);
695
- const Color* r_c = dynamic_cast<const Color*>(rhs);
696
- rv = op_colors(ctx.mem, op_type, *l_c, *r_c, ctx.c_options, &pstate);
697
+ Color_Ptr l_c = SASS_MEMORY_CAST(Color, lhs);
698
+ Color_Ptr r_c = SASS_MEMORY_CAST(Color, rhs);
699
+ rv = op_colors(op_type, *l_c, *r_c, ctx.c_options, &pstate);
697
700
  }
698
701
  else {
699
- To_Value to_value(ctx, ctx.mem);
700
- Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
701
- Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
702
+ To_Value to_value(ctx);
703
+ // this will leak if perform does not return a value!
704
+ Value_Obj v_l = SASS_MEMORY_CAST_PTR(Value, lhs->perform(&to_value));
705
+ Value_Obj v_r = SASS_MEMORY_CAST_PTR(Value, rhs->perform(&to_value));
702
706
  bool interpolant = b->is_right_interpolant() ||
703
707
  b->is_left_interpolant() ||
704
708
  b->is_interpolant();
@@ -711,15 +715,15 @@ namespace Sass {
711
715
  if (r_type == Expression::MAP) {
712
716
  throw Exception::InvalidValue(*v_r);
713
717
  }
714
- Value* ex = op_strings(ctx.mem, b->op(), *v_l, *v_r, ctx.c_options, &pstate, !interpolant); // pass true to compress
715
- if (String_Constant* str = dynamic_cast<String_Constant*>(ex))
718
+ Value_Ptr ex = op_strings(b->op(), *v_l, *v_r, ctx.c_options, &pstate, !interpolant); // pass true to compress
719
+ if (String_Constant_Ptr str = dynamic_cast<String_Constant_Ptr>(ex))
716
720
  {
717
721
  if (str->concrete_type() == Expression::STRING)
718
722
  {
719
- String_Constant* lstr = dynamic_cast<String_Constant*>(lhs);
720
- String_Constant* rstr = dynamic_cast<String_Constant*>(rhs);
723
+ String_Constant_Ptr lstr = SASS_MEMORY_CAST(String_Constant, lhs);
724
+ String_Constant_Ptr rstr = SASS_MEMORY_CAST(String_Constant, rhs);
721
725
  if (op_type != Sass_OP::SUB) {
722
- if (String_Constant* org = lstr ? lstr : rstr)
726
+ if (String_Constant_Ptr org = lstr ? lstr : rstr)
723
727
  { str->quote_mark(org->quote_mark()); }
724
728
  }
725
729
  }
@@ -741,20 +745,21 @@ namespace Sass {
741
745
  rv = s2->perform(this);
742
746
  }
743
747
  }
744
- return rv;
748
+
749
+ return rv.detach();
745
750
 
746
751
  }
747
752
 
748
- Expression* Eval::operator()(Unary_Expression* u)
753
+ Expression_Ptr Eval::operator()(Unary_Expression_Ptr u)
749
754
  {
750
- Expression* operand = u->operand()->perform(this);
755
+ Expression_Obj operand = u->operand()->perform(this);
751
756
  if (u->type() == Unary_Expression::NOT) {
752
- Boolean* result = SASS_MEMORY_NEW(ctx.mem, Boolean, u->pstate(), (bool)*operand);
757
+ Boolean_Ptr result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand);
753
758
  result->value(!result->value());
754
759
  return result;
755
760
  }
756
761
  else if (operand->concrete_type() == Expression::NUMBER) {
757
- Number* result = SASS_MEMORY_NEW(ctx.mem, Number, *static_cast<Number*>(operand));
762
+ Number_Ptr result = SASS_MEMORY_NEW(Number, static_cast<Number_Ptr>(&operand));
758
763
  result->value(u->type() == Unary_Expression::MINUS
759
764
  ? -result->value()
760
765
  : result->value());
@@ -763,16 +768,16 @@ namespace Sass {
763
768
  else {
764
769
  // Special cases: +/- variables which evaluate to null ouput just +/-,
765
770
  // but +/- null itself outputs the string
766
- if (operand->concrete_type() == Expression::NULL_VAL && dynamic_cast<Variable*>(u->operand())) {
767
- u->operand(SASS_MEMORY_NEW(ctx.mem, String_Quoted, u->pstate(), ""));
771
+ if (operand->concrete_type() == Expression::NULL_VAL && SASS_MEMORY_CAST(Variable, u->operand())) {
772
+ u->operand(SASS_MEMORY_NEW(String_Quoted, u->pstate(), ""));
768
773
  }
769
774
  // Never apply unary opertions on colors @see #2140
770
775
  else if (operand->concrete_type() == Expression::COLOR) {
771
- Color* c = dynamic_cast<Color*>(operand);
776
+ Color_Ptr c = dynamic_cast<Color_Ptr>(&operand);
772
777
 
773
778
  // Use the color name if this was eval with one
774
779
  if (c->disp().length() > 0) {
775
- operand = SASS_MEMORY_NEW(ctx.mem, String_Constant, operand->pstate(), c->disp());
780
+ operand = SASS_MEMORY_NEW(String_Constant, operand->pstate(), c->disp());
776
781
  u->operand(operand);
777
782
  }
778
783
  }
@@ -780,7 +785,7 @@ namespace Sass {
780
785
  u->operand(operand);
781
786
  }
782
787
 
783
- String_Constant* result = SASS_MEMORY_NEW(ctx.mem, String_Quoted,
788
+ String_Constant_Ptr result = SASS_MEMORY_NEW(String_Quoted,
784
789
  u->pstate(),
785
790
  u->inspect());
786
791
  return result;
@@ -789,7 +794,7 @@ namespace Sass {
789
794
  return u;
790
795
  }
791
796
 
792
- Expression* Eval::operator()(Function_Call* c)
797
+ Expression_Ptr Eval::operator()(Function_Call_Ptr c)
793
798
  {
794
799
  if (backtrace()->parent != NULL && backtrace()->depth() > Constants::MaxCallStack) {
795
800
  // XXX: this is never hit via spec tests
@@ -799,25 +804,26 @@ namespace Sass {
799
804
  }
800
805
  std::string name(Util::normalize_underscores(c->name()));
801
806
  std::string full_name(name + "[f]");
802
- Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, *c->arguments());
807
+ // we make a clone here, need to implement that further
808
+ Arguments_Obj args = c->arguments();
803
809
 
804
810
  Env* env = environment();
805
- if (!env->has(full_name)) {
811
+ if (!env->has(full_name) || (!c->via_call() && Prelexer::re_special_fun(name.c_str()))) {
806
812
  if (!env->has("*[f]")) {
807
- for (Argument* arg : args->elements()) {
808
- if (List* ls = dynamic_cast<List*>(arg->value())) {
813
+ for (Argument_Obj arg : args->elements()) {
814
+ if (List_Obj ls = SASS_MEMORY_CAST(List, arg->value())) {
809
815
  if (ls->size() == 0) error("() isn't a valid CSS value.", c->pstate());
810
816
  }
811
817
  }
812
- args = static_cast<Arguments*>(args->perform(this));
813
- Function_Call* lit = SASS_MEMORY_NEW(ctx.mem, Function_Call,
818
+ args = SASS_MEMORY_CAST_PTR(Arguments, args->perform(this));
819
+ Function_Call_Obj lit = SASS_MEMORY_NEW(Function_Call,
814
820
  c->pstate(),
815
821
  c->name(),
816
- args);
822
+ &args);
817
823
  if (args->has_named_arguments()) {
818
824
  error("Function " + c->name() + " doesn't support keyword arguments", c->pstate());
819
825
  }
820
- String_Quoted* str = SASS_MEMORY_NEW(ctx.mem, String_Quoted,
826
+ String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted,
821
827
  c->pstate(),
822
828
  lit->to_string(ctx.c_options));
823
829
  str->is_interpolant(c->is_interpolant());
@@ -833,9 +839,9 @@ namespace Sass {
833
839
  args->set_delayed(false); // verified
834
840
  }
835
841
  if (full_name != "if[f]") {
836
- args = static_cast<Arguments*>(args->perform(this));
842
+ args = SASS_MEMORY_CAST_PTR(Arguments, args->perform(this));
837
843
  }
838
- Definition* def = static_cast<Definition*>((*env)[full_name]);
844
+ Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)[full_name]);
839
845
 
840
846
  if (def->is_overload_stub()) {
841
847
  std::stringstream ss;
@@ -843,7 +849,7 @@ namespace Sass {
843
849
  // account for rest arguments
844
850
  if (args->has_rest_argument() && args->length() > 0) {
845
851
  // get the rest arguments list
846
- List* rest = dynamic_cast<List*>(args->last()->value());
852
+ List_Ptr rest = SASS_MEMORY_CAST(List, args->last()->value());
847
853
  // arguments before rest argument plus rest
848
854
  if (rest) L += rest->length() - 1;
849
855
  }
@@ -851,15 +857,15 @@ namespace Sass {
851
857
  full_name = ss.str();
852
858
  std::string resolved_name(full_name);
853
859
  if (!env->has(resolved_name)) error("overloaded function `" + std::string(c->name()) + "` given wrong number of arguments", c->pstate());
854
- def = static_cast<Definition*>((*env)[resolved_name]);
860
+ def = SASS_MEMORY_CAST(Definition, (*env)[resolved_name]);
855
861
  }
856
862
 
857
- Expression* result = c;
858
- Block* body = def->block();
863
+ Expression_Obj result = c;
864
+ Block_Obj body = def->block();
859
865
  Native_Function func = def->native_function();
860
866
  Sass_Function_Entry c_function = def->c_function();
861
867
 
862
- Parameters* params = def->parameters();
868
+ Parameters_Obj params = def->parameters();
863
869
  Env fn_env(def->environment());
864
870
  exp.env_stack.push_back(&fn_env);
865
871
 
@@ -868,9 +874,15 @@ namespace Sass {
868
874
  Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
869
875
  exp.backtrace_stack.push_back(&here);
870
876
  // eval the body if user-defined or special, invoke underlying CPP function if native
871
- if (body && !Prelexer::re_special_fun(name.c_str())) { result = body->perform(this); }
872
- else if (func) { result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace(), exp.selector_stack); }
873
- if (!result) error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
877
+ if (body /* && !Prelexer::re_special_fun(name.c_str()) */) {
878
+ result = body->perform(this);
879
+ }
880
+ else if (func) {
881
+ result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace(), exp.selector_stack);
882
+ }
883
+ if (!result) {
884
+ error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
885
+ }
874
886
  exp.backtrace_stack.pop_back();
875
887
  }
876
888
 
@@ -879,10 +891,10 @@ namespace Sass {
879
891
  else if (c_function) {
880
892
  Sass_Function_Fn c_func = sass_function_get_function(c_function);
881
893
  if (full_name == "*[f]") {
882
- String_Quoted *str = SASS_MEMORY_NEW(ctx.mem, String_Quoted, c->pstate(), c->name());
883
- Arguments* new_args = SASS_MEMORY_NEW(ctx.mem, Arguments, c->pstate());
884
- *new_args << SASS_MEMORY_NEW(ctx.mem, Argument, c->pstate(), str);
885
- *new_args += args;
894
+ String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, c->pstate(), c->name());
895
+ Arguments_Obj new_args = SASS_MEMORY_NEW(Arguments, c->pstate());
896
+ new_args->append(SASS_MEMORY_NEW(Argument, c->pstate(), &str));
897
+ new_args->concat(&args);
886
898
  args = new_args;
887
899
  }
888
900
 
@@ -894,11 +906,12 @@ namespace Sass {
894
906
  exp.backtrace_stack.push_back(&here);
895
907
 
896
908
  To_C to_c;
897
- union Sass_Value* c_args = sass_make_list(params[0].length(), SASS_COMMA);
898
- for(size_t i = 0; i < params[0].length(); i++) {
899
- std::string key = params[0][i]->name();
900
- AST_Node* node = fn_env.get_local(key);
901
- Expression* arg = static_cast<Expression*>(node);
909
+ union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA);
910
+ for(size_t i = 0; i < params->length(); i++) {
911
+ Parameter_Obj param = params->at(i);
912
+ std::string key = param->name();
913
+ AST_Node_Obj node = fn_env.get_local(key);
914
+ Expression_Obj arg = SASS_MEMORY_CAST(Expression, node);
902
915
  sass_list_set_value(c_args, i, arg->perform(&to_c));
903
916
  }
904
917
  union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler);
@@ -907,7 +920,7 @@ namespace Sass {
907
920
  } else if (sass_value_get_tag(c_val) == SASS_WARNING) {
908
921
  error("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val), c->pstate(), backtrace());
909
922
  }
910
- result = cval_to_astnode(ctx.mem, c_val, ctx, backtrace(), c->pstate());
923
+ result = cval_to_astnode(c_val, backtrace(), c->pstate());
911
924
 
912
925
  exp.backtrace_stack.pop_back();
913
926
  sass_delete_value(c_args);
@@ -923,45 +936,49 @@ namespace Sass {
923
936
  result = result->perform(this);
924
937
  result->is_interpolant(c->is_interpolant());
925
938
  exp.env_stack.pop_back();
926
- return result;
939
+ return result.detach();
927
940
  }
928
941
 
929
- Expression* Eval::operator()(Function_Call_Schema* s)
942
+ Expression_Ptr Eval::operator()(Function_Call_Schema_Ptr s)
930
943
  {
931
- Expression* evaluated_name = s->name()->perform(this);
932
- Expression* evaluated_args = s->arguments()->perform(this);
933
- String_Schema* ss = SASS_MEMORY_NEW(ctx.mem, String_Schema, s->pstate(), 2);
934
- (*ss) << evaluated_name << evaluated_args;
944
+ Expression_Ptr evaluated_name = s->name()->perform(this);
945
+ Expression_Ptr evaluated_args = s->arguments()->perform(this);
946
+ String_Schema_Obj ss = SASS_MEMORY_NEW(String_Schema, s->pstate(), 2);
947
+ ss->append(evaluated_name);
948
+ ss->append(evaluated_args);
935
949
  return ss->perform(this);
936
950
  }
937
951
 
938
- Expression* Eval::operator()(Variable* v)
952
+ Expression_Ptr Eval::operator()(Variable_Ptr v)
939
953
  {
940
954
  std::string name(v->name());
941
- Expression* value = 0;
955
+ Expression_Obj value = 0;
942
956
  Env* env = environment();
943
- if (env->has(name)) value = static_cast<Expression*>((*env)[name]);
957
+ if (env->has(name)) {
958
+ value = SASS_MEMORY_CAST(Expression, (*env)[name]);
959
+ }
944
960
  else error("Undefined variable: \"" + v->name() + "\".", v->pstate());
945
- if (typeid(*value) == typeid(Argument)) value = static_cast<Argument*>(value)->value();
961
+ if (typeid(*value) == typeid(Argument)) {
962
+ value = SASS_MEMORY_CAST(Argument, value)->value();
963
+ }
946
964
 
947
965
  // behave according to as ruby sass (add leading zero)
948
- if (value->concrete_type() == Expression::NUMBER) {
949
- value = SASS_MEMORY_NEW(ctx.mem, Number, *static_cast<Number*>(value));
950
- static_cast<Number*>(value)->zero(true);
966
+ if (Number_Ptr nr = SASS_MEMORY_CAST(Number, value)) {
967
+ nr->zero(true);
951
968
  }
952
969
 
953
970
  value->is_interpolant(v->is_interpolant());
954
971
  if (force) value->is_expanded(false);
955
972
  value->set_delayed(false); // verified
956
973
  value = value->perform(this);
957
- if(!force) (*env)[name] = value;
958
- return value;
974
+ if(!force) (*env)[name] = &value;
975
+ return value.detach();
959
976
  }
960
977
 
961
- Expression* Eval::operator()(Textual* t)
978
+ Expression_Ptr Eval::operator()(Textual_Ptr t)
962
979
  {
963
980
  using Prelexer::number;
964
- Expression* result = 0;
981
+ Expression_Obj result = 0;
965
982
  size_t L = t->value().length();
966
983
  bool zero = !( (L > 0 && t->value().substr(0, 1) == ".") ||
967
984
  (L > 1 && t->value().substr(0, 2) == "0.") ||
@@ -979,21 +996,21 @@ namespace Sass {
979
996
  switch (t->type())
980
997
  {
981
998
  case Textual::NUMBER:
982
- result = SASS_MEMORY_NEW(ctx.mem, Number,
999
+ result = SASS_MEMORY_NEW(Number,
983
1000
  t->pstate(),
984
1001
  sass_atof(num.c_str()),
985
1002
  "",
986
1003
  zero);
987
1004
  break;
988
1005
  case Textual::PERCENTAGE:
989
- result = SASS_MEMORY_NEW(ctx.mem, Number,
1006
+ result = SASS_MEMORY_NEW(Number,
990
1007
  t->pstate(),
991
1008
  sass_atof(num.c_str()),
992
1009
  "%",
993
1010
  true);
994
1011
  break;
995
1012
  case Textual::DIMENSION:
996
- result = SASS_MEMORY_NEW(ctx.mem, Number,
1013
+ result = SASS_MEMORY_NEW(Number,
997
1014
  t->pstate(),
998
1015
  sass_atof(num.c_str()),
999
1016
  Token(number(text.c_str())),
@@ -1001,7 +1018,7 @@ namespace Sass {
1001
1018
  break;
1002
1019
  case Textual::HEX: {
1003
1020
  if (t->value().substr(0, 1) != "#") {
1004
- result = SASS_MEMORY_NEW(ctx.mem, String_Quoted, t->pstate(), t->value());
1021
+ result = SASS_MEMORY_NEW(String_Quoted, t->pstate(), t->value());
1005
1022
  break;
1006
1023
  }
1007
1024
  std::string hext(t->value().substr(1)); // chop off the '#'
@@ -1009,7 +1026,7 @@ namespace Sass {
1009
1026
  std::string r(hext.substr(0,2));
1010
1027
  std::string g(hext.substr(2,2));
1011
1028
  std::string b(hext.substr(4,2));
1012
- result = SASS_MEMORY_NEW(ctx.mem, Color,
1029
+ result = SASS_MEMORY_NEW(Color,
1013
1030
  t->pstate(),
1014
1031
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
1015
1032
  static_cast<double>(strtol(g.c_str(), NULL, 16)),
@@ -1018,7 +1035,7 @@ namespace Sass {
1018
1035
  t->value());
1019
1036
  }
1020
1037
  else {
1021
- result = SASS_MEMORY_NEW(ctx.mem, Color,
1038
+ result = SASS_MEMORY_NEW(Color,
1022
1039
  t->pstate(),
1023
1040
  static_cast<double>(strtol(std::string(2,hext[0]).c_str(), NULL, 16)),
1024
1041
  static_cast<double>(strtol(std::string(2,hext[1]).c_str(), NULL, 16)),
@@ -1029,71 +1046,71 @@ namespace Sass {
1029
1046
  } break;
1030
1047
  }
1031
1048
  result->is_interpolant(t->is_interpolant());
1032
- return result;
1049
+ return result.detach();
1033
1050
  }
1034
1051
 
1035
- Expression* Eval::operator()(Color* c)
1052
+ Expression_Ptr Eval::operator()(Color_Ptr c)
1036
1053
  {
1037
1054
  return c;
1038
1055
  }
1039
1056
 
1040
- Expression* Eval::operator()(Number* n)
1057
+ Expression_Ptr Eval::operator()(Number_Ptr n)
1041
1058
  {
1042
1059
  return n;
1043
1060
  }
1044
1061
 
1045
- Expression* Eval::operator()(Boolean* b)
1062
+ Expression_Ptr Eval::operator()(Boolean_Ptr b)
1046
1063
  {
1047
1064
  return b;
1048
1065
  }
1049
1066
 
1050
- void Eval::interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl) {
1067
+ void Eval::interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl) {
1051
1068
 
1052
1069
  bool needs_closing_brace = false;
1053
1070
 
1054
- if (Arguments* args = dynamic_cast<Arguments*>(ex)) {
1055
- List* ll = SASS_MEMORY_NEW(ctx.mem, List, args->pstate(), 0, SASS_COMMA);
1056
- for(auto arg : *args) {
1057
- *ll << arg->value();
1071
+ if (Arguments_Ptr args = SASS_MEMORY_CAST(Arguments, ex)) {
1072
+ List_Ptr ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA);
1073
+ for(auto arg : args->elements()) {
1074
+ ll->append(arg->value());
1058
1075
  }
1059
1076
  ll->is_interpolant(args->is_interpolant());
1060
1077
  needs_closing_brace = true;
1061
1078
  res += "(";
1062
1079
  ex = ll;
1063
1080
  }
1064
- if (Number* nr = dynamic_cast<Number*>(ex)) {
1081
+ if (Number_Ptr nr = SASS_MEMORY_CAST(Number, ex)) {
1065
1082
  if (!nr->is_valid_css_unit()) {
1066
1083
  throw Exception::InvalidValue(*nr);
1067
1084
  }
1068
1085
  }
1069
- if (Argument* arg = dynamic_cast<Argument*>(ex)) {
1070
- ex = arg->value();
1086
+ if (Argument_Ptr arg = SASS_MEMORY_CAST(Argument, ex)) {
1087
+ ex = &arg->value();
1071
1088
  }
1072
- if (String_Quoted* sq = dynamic_cast<String_Quoted*>(ex)) {
1089
+ if (String_Quoted_Ptr sq = SASS_MEMORY_CAST(String_Quoted, ex)) {
1073
1090
  if (was_itpl) {
1074
1091
  bool was_interpolant = ex->is_interpolant();
1075
- ex = SASS_MEMORY_NEW(ctx.mem, String_Constant, sq->pstate(), sq->value());
1092
+ ex = SASS_MEMORY_NEW(String_Constant, sq->pstate(), sq->value());
1076
1093
  ex->is_interpolant(was_interpolant);
1077
1094
  }
1078
1095
  }
1079
1096
 
1080
- if (dynamic_cast<Null*>(ex)) { return; }
1097
+ if (SASS_MEMORY_CAST(Null, ex)) { return; }
1081
1098
 
1082
1099
  // parent selector needs another go
1083
- if (dynamic_cast<Parent_Selector*>(ex)) {
1100
+ if (SASS_MEMORY_CAST(Parent_Selector, ex)) {
1084
1101
  // XXX: this is never hit via spec tests
1085
1102
  ex = ex->perform(this);
1086
1103
  }
1087
1104
 
1088
- if (List* l = dynamic_cast<List*>(ex)) {
1089
- List* ll = SASS_MEMORY_NEW(ctx.mem, List, l->pstate(), 0, l->separator());
1105
+ if (List_Ptr l = SASS_MEMORY_CAST(List, ex)) {
1106
+ List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());
1090
1107
  // this fixes an issue with bourbon sample, not really sure why
1091
- // if (l->size() && dynamic_cast<Null*>((*l)[0])) { res += ""; }
1092
- for(auto item : *l) {
1108
+ // if (l->size() && dynamic_cast<Null_Ptr>((*l)[0])) { res += ""; }
1109
+ for(Expression_Obj item : *l) {
1093
1110
  item->is_interpolant(l->is_interpolant());
1094
- std::string rl(""); interpolation(ctx, rl, item, into_quotes, l->is_interpolant());
1095
- bool is_null = dynamic_cast<Null*>(item) != 0; // rl != ""
1096
- if (!is_null) *ll << SASS_MEMORY_NEW(ctx.mem, String_Quoted, item->pstate(), rl);
1111
+ std::string rl(""); interpolation(ctx, rl, &item, into_quotes, l->is_interpolant());
1112
+ bool is_null = dynamic_cast<Null_Ptr>(&item) != 0; // rl != ""
1113
+ if (!is_null) ll->append(SASS_MEMORY_NEW(String_Quoted, item->pstate(), rl));
1097
1114
  }
1098
1115
  // Check indicates that we probably should not get a list
1099
1116
  // here. Normally single list items are already unwrapped.
@@ -1111,7 +1128,7 @@ namespace Sass {
1111
1128
  // Value
1112
1129
  // Textual
1113
1130
  // Function_Call
1114
- // CommaSequence_Selector
1131
+ // Selector_List
1115
1132
  // String_Quoted
1116
1133
  // String_Constant
1117
1134
  // Parent_Selector
@@ -1129,14 +1146,14 @@ namespace Sass {
1129
1146
 
1130
1147
  }
1131
1148
 
1132
- Expression* Eval::operator()(String_Schema* s)
1149
+ Expression_Ptr Eval::operator()(String_Schema_Ptr s)
1133
1150
  {
1134
1151
  size_t L = s->length();
1135
1152
  bool into_quotes = false;
1136
1153
  if (L > 1) {
1137
- if (!dynamic_cast<String_Quoted*>((*s)[0]) && !dynamic_cast<String_Quoted*>((*s)[L - 1])) {
1138
- if (String_Constant* l = dynamic_cast<String_Constant*>((*s)[0])) {
1139
- if (String_Constant* r = dynamic_cast<String_Constant*>((*s)[L - 1])) {
1154
+ if (!SASS_MEMORY_CAST(String_Quoted, (*s)[0]) && !SASS_MEMORY_CAST(String_Quoted, (*s)[L - 1])) {
1155
+ if (String_Constant_Ptr l = SASS_MEMORY_CAST(String_Constant, (*s)[0])) {
1156
+ if (String_Constant_Ptr r = SASS_MEMORY_CAST(String_Constant, (*s)[L - 1])) {
1140
1157
  if (r->value().size() > 0) {
1141
1158
  if (l->value()[0] == '"' && r->value()[r->value().size() - 1] == '"') into_quotes = true;
1142
1159
  if (l->value()[0] == '\'' && r->value()[r->value().size() - 1] == '\'') into_quotes = true;
@@ -1149,34 +1166,34 @@ namespace Sass {
1149
1166
  bool was_interpolant = false;
1150
1167
  std::string res("");
1151
1168
  for (size_t i = 0; i < L; ++i) {
1152
- bool is_quoted = dynamic_cast<String_Quoted*>((*s)[i]) != NULL;
1169
+ bool is_quoted = SASS_MEMORY_CAST(String_Quoted, (*s)[i]) != NULL;
1153
1170
  if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
1154
1171
  else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
1155
- Expression* ex = (*s)[i]->perform(this);
1172
+ Expression_Obj ex = (*s)[i]->perform(this);
1156
1173
  interpolation(ctx, res, ex, into_quotes, ex->is_interpolant());
1157
- was_quoted = dynamic_cast<String_Quoted*>((*s)[i]) != NULL;
1174
+ was_quoted = SASS_MEMORY_CAST(String_Quoted, (*s)[i]) != NULL;
1158
1175
  was_interpolant = (*s)[i]->is_interpolant();
1159
1176
 
1160
1177
  }
1161
1178
  if (!s->is_interpolant()) {
1162
- if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(ctx.mem, Null, s->pstate());
1163
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, s->pstate(), res);
1179
+ if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(Null, s->pstate());
1180
+ return SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
1164
1181
  }
1165
1182
  // string schema seems to have a special unquoting behavior (also handles "nested" quotes)
1166
- String_Quoted* str = SASS_MEMORY_NEW(ctx.mem, String_Quoted, s->pstate(), res, 0, false, false, false);
1183
+ String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false);
1167
1184
  // if (s->is_interpolant()) str->quote_mark(0);
1168
- // String_Constant* str = SASS_MEMORY_NEW(ctx.mem, String_Constant, s->pstate(), res);
1185
+ // String_Constant_Ptr str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
1169
1186
  if (str->quote_mark()) str->quote_mark('*');
1170
1187
  else if (!is_in_comment) str->value(string_to_output(str->value()));
1171
1188
  str->is_interpolant(s->is_interpolant());
1172
- return str;
1189
+ return str.detach();
1173
1190
  }
1174
1191
 
1175
1192
 
1176
- Expression* Eval::operator()(String_Constant* s)
1193
+ Expression_Ptr Eval::operator()(String_Constant_Ptr s)
1177
1194
  {
1178
1195
  if (!s->is_delayed() && name_to_color(s->value())) {
1179
- Color* c = SASS_MEMORY_NEW(ctx.mem, Color, *name_to_color(s->value()));
1196
+ Color_Ptr c = SASS_MEMORY_COPY(name_to_color(s->value())); // copy
1180
1197
  c->pstate(s->pstate());
1181
1198
  c->disp(s->value());
1182
1199
  c->is_delayed(true);
@@ -1185,119 +1202,117 @@ namespace Sass {
1185
1202
  return s;
1186
1203
  }
1187
1204
 
1188
- Expression* Eval::operator()(String_Quoted* s)
1205
+ Expression_Ptr Eval::operator()(String_Quoted_Ptr s)
1189
1206
  {
1190
- String_Quoted* str = SASS_MEMORY_NEW(ctx.mem, String_Quoted, s->pstate(), "");
1207
+ String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), "");
1191
1208
  str->value(s->value());
1192
1209
  str->quote_mark(s->quote_mark());
1193
1210
  str->is_interpolant(s->is_interpolant());
1194
1211
  return str;
1195
1212
  }
1196
1213
 
1197
- Expression* Eval::operator()(Supports_Operator* c)
1214
+ Expression_Ptr Eval::operator()(Supports_Operator_Ptr c)
1198
1215
  {
1199
- Expression* left = c->left()->perform(this);
1200
- Expression* right = c->right()->perform(this);
1201
- Supports_Operator* cc = SASS_MEMORY_NEW(ctx.mem, Supports_Operator,
1216
+ Expression_Ptr left = c->left()->perform(this);
1217
+ Expression_Ptr right = c->right()->perform(this);
1218
+ Supports_Operator_Ptr cc = SASS_MEMORY_NEW(Supports_Operator,
1202
1219
  c->pstate(),
1203
- static_cast<Supports_Condition*>(left),
1204
- static_cast<Supports_Condition*>(right),
1220
+ dynamic_cast<Supports_Condition_Ptr>(left),
1221
+ dynamic_cast<Supports_Condition_Ptr>(right),
1205
1222
  c->operand());
1206
1223
  return cc;
1207
1224
  }
1208
1225
 
1209
- Expression* Eval::operator()(Supports_Negation* c)
1226
+ Expression_Ptr Eval::operator()(Supports_Negation_Ptr c)
1210
1227
  {
1211
- Expression* condition = c->condition()->perform(this);
1212
- Supports_Negation* cc = SASS_MEMORY_NEW(ctx.mem, Supports_Negation,
1228
+ Expression_Ptr condition = c->condition()->perform(this);
1229
+ Supports_Negation_Ptr cc = SASS_MEMORY_NEW(Supports_Negation,
1213
1230
  c->pstate(),
1214
- static_cast<Supports_Condition*>(condition));
1231
+ dynamic_cast<Supports_Condition_Ptr>(condition));
1215
1232
  return cc;
1216
1233
  }
1217
1234
 
1218
- Expression* Eval::operator()(Supports_Declaration* c)
1235
+ Expression_Ptr Eval::operator()(Supports_Declaration_Ptr c)
1219
1236
  {
1220
- Expression* feature = c->feature()->perform(this);
1221
- Expression* value = c->value()->perform(this);
1222
- Supports_Declaration* cc = SASS_MEMORY_NEW(ctx.mem, Supports_Declaration,
1237
+ Expression_Ptr feature = c->feature()->perform(this);
1238
+ Expression_Ptr value = c->value()->perform(this);
1239
+ Supports_Declaration_Ptr cc = SASS_MEMORY_NEW(Supports_Declaration,
1223
1240
  c->pstate(),
1224
1241
  feature,
1225
1242
  value);
1226
1243
  return cc;
1227
1244
  }
1228
1245
 
1229
- Expression* Eval::operator()(Supports_Interpolation* c)
1246
+ Expression_Ptr Eval::operator()(Supports_Interpolation_Ptr c)
1230
1247
  {
1231
- Expression* value = c->value()->perform(this);
1232
- Supports_Interpolation* cc = SASS_MEMORY_NEW(ctx.mem, Supports_Interpolation,
1248
+ Expression_Ptr value = c->value()->perform(this);
1249
+ Supports_Interpolation_Ptr cc = SASS_MEMORY_NEW(Supports_Interpolation,
1233
1250
  c->pstate(),
1234
1251
  value);
1235
1252
  return cc;
1236
1253
  }
1237
1254
 
1238
- Expression* Eval::operator()(At_Root_Query* e)
1255
+ Expression_Ptr Eval::operator()(At_Root_Query_Ptr e)
1239
1256
  {
1240
- Expression* feature = e->feature();
1257
+ Expression_Obj feature = e->feature();
1241
1258
  feature = (feature ? feature->perform(this) : 0);
1242
- Expression* value = e->value();
1259
+ Expression_Obj value = e->value();
1243
1260
  value = (value ? value->perform(this) : 0);
1244
- Expression* ee = SASS_MEMORY_NEW(ctx.mem, At_Root_Query,
1261
+ Expression_Ptr ee = SASS_MEMORY_NEW(At_Root_Query,
1245
1262
  e->pstate(),
1246
- static_cast<String*>(feature),
1263
+ dynamic_cast<String_Ptr>(&feature),
1247
1264
  value);
1248
1265
  return ee;
1249
1266
  }
1250
1267
 
1251
- Expression* Eval::operator()(Media_Query* q)
1268
+ Expression_Ptr Eval::operator()(Media_Query_Ptr q)
1252
1269
  {
1253
- String* t = q->media_type();
1254
- t = static_cast<String*>(t ? t->perform(this) : 0);
1255
- Media_Query* qq = SASS_MEMORY_NEW(ctx.mem, Media_Query,
1270
+ String_Obj t = q->media_type();
1271
+ t = static_cast<String_Ptr>(&t ? t->perform(this) : 0);
1272
+ Media_Query_Obj qq = SASS_MEMORY_NEW(Media_Query,
1256
1273
  q->pstate(),
1257
- t,
1274
+ &t,
1258
1275
  q->length(),
1259
1276
  q->is_negated(),
1260
1277
  q->is_restricted());
1261
1278
  for (size_t i = 0, L = q->length(); i < L; ++i) {
1262
- *qq << static_cast<Media_Query_Expression*>((*q)[i]->perform(this));
1279
+ qq->append(static_cast<Media_Query_Expression_Ptr>((*q)[i]->perform(this)));
1263
1280
  }
1264
- return qq;
1281
+ return qq.detach();
1265
1282
  }
1266
1283
 
1267
- Expression* Eval::operator()(Media_Query_Expression* e)
1284
+ Expression_Ptr Eval::operator()(Media_Query_Expression_Ptr e)
1268
1285
  {
1269
- Expression* feature = e->feature();
1286
+ Expression_Obj feature = e->feature();
1270
1287
  feature = (feature ? feature->perform(this) : 0);
1271
- if (feature && dynamic_cast<String_Quoted*>(feature)) {
1272
- feature = SASS_MEMORY_NEW(ctx.mem, String_Quoted,
1288
+ if (feature && SASS_MEMORY_CAST(String_Quoted, feature)) {
1289
+ feature = SASS_MEMORY_NEW(String_Quoted,
1273
1290
  feature->pstate(),
1274
- dynamic_cast<String_Quoted*>(feature)->value());
1291
+ SASS_MEMORY_CAST(String_Quoted, feature)->value());
1275
1292
  }
1276
- Expression* value = e->value();
1293
+ Expression_Obj value = e->value();
1277
1294
  value = (value ? value->perform(this) : 0);
1278
- if (value && dynamic_cast<String_Quoted*>(value)) {
1295
+ if (value && SASS_MEMORY_CAST(String_Quoted, value)) {
1279
1296
  // XXX: this is never hit via spec tests
1280
- value = SASS_MEMORY_NEW(ctx.mem, String_Quoted,
1297
+ value = SASS_MEMORY_NEW(String_Quoted,
1281
1298
  value->pstate(),
1282
- dynamic_cast<String_Quoted*>(value)->value());
1299
+ SASS_MEMORY_CAST(String_Quoted, value)->value());
1283
1300
  }
1284
- return SASS_MEMORY_NEW(ctx.mem, Media_Query_Expression,
1301
+ return SASS_MEMORY_NEW(Media_Query_Expression,
1285
1302
  e->pstate(),
1286
1303
  feature,
1287
1304
  value,
1288
1305
  e->is_interpolated());
1289
1306
  }
1290
1307
 
1291
- Expression* Eval::operator()(Null* n)
1308
+ Expression_Ptr Eval::operator()(Null_Ptr n)
1292
1309
  {
1293
1310
  return n;
1294
1311
  }
1295
1312
 
1296
- Expression* Eval::operator()(Argument* a)
1313
+ Expression_Ptr Eval::operator()(Argument_Ptr a)
1297
1314
  {
1298
- Expression* val = a->value();
1299
- val = val->perform(this);
1300
-
1315
+ Expression_Obj val = a->value()->perform(this);
1301
1316
  bool is_rest_argument = a->is_rest_argument();
1302
1317
  bool is_keyword_argument = a->is_keyword_argument();
1303
1318
 
@@ -1307,16 +1322,16 @@ namespace Sass {
1307
1322
  is_keyword_argument = true;
1308
1323
  }
1309
1324
  else if(val->concrete_type() != Expression::LIST) {
1310
- List* wrapper = SASS_MEMORY_NEW(ctx.mem, List,
1325
+ List_Obj wrapper = SASS_MEMORY_NEW(List,
1311
1326
  val->pstate(),
1312
1327
  0,
1313
1328
  SASS_COMMA,
1314
1329
  true);
1315
- *wrapper << val;
1316
- val = wrapper;
1330
+ wrapper->append(val);
1331
+ val = &wrapper;
1317
1332
  }
1318
1333
  }
1319
- return SASS_MEMORY_NEW(ctx.mem, Argument,
1334
+ return SASS_MEMORY_NEW(Argument,
1320
1335
  a->pstate(),
1321
1336
  val,
1322
1337
  a->name(),
@@ -1324,104 +1339,103 @@ namespace Sass {
1324
1339
  is_keyword_argument);
1325
1340
  }
1326
1341
 
1327
- Expression* Eval::operator()(Arguments* a)
1342
+ Expression_Ptr Eval::operator()(Arguments_Ptr a)
1328
1343
  {
1329
- Arguments* aa = SASS_MEMORY_NEW(ctx.mem, Arguments, a->pstate());
1330
- if (a->length() == 0) return aa;
1344
+ Arguments_Obj aa = SASS_MEMORY_NEW(Arguments, a->pstate());
1345
+ if (a->length() == 0) return aa.detach();
1331
1346
  for (size_t i = 0, L = a->length(); i < L; ++i) {
1332
- Argument* arg = static_cast<Argument*>((*a)[i]->perform(this));
1347
+ Expression_Obj rv = (*a)[i]->perform(this);
1348
+ Argument_Ptr arg = SASS_MEMORY_CAST(Argument, rv);
1333
1349
  if (!(arg->is_rest_argument() || arg->is_keyword_argument())) {
1334
- *aa << arg;
1350
+ aa->append(arg);
1335
1351
  }
1336
1352
  }
1337
1353
 
1338
1354
  if (a->has_rest_argument()) {
1339
- Expression* splat = static_cast<Argument*>(
1340
- a->get_rest_argument()->perform(this)
1341
- )->value()->perform(this);
1355
+ Expression_Obj rest = a->get_rest_argument()->perform(this);
1356
+ Expression_Obj splat = SASS_MEMORY_CAST(Argument, rest)->value()->perform(this);
1342
1357
 
1343
1358
  Sass_Separator separator = SASS_COMMA;
1344
- List* ls = dynamic_cast<List*>(splat);
1345
- Map* ms = dynamic_cast<Map*>(splat);
1359
+ List_Ptr ls = SASS_MEMORY_CAST(List, splat);
1360
+ Map_Ptr ms = SASS_MEMORY_CAST(Map, splat);
1346
1361
 
1347
- List* arglist = SASS_MEMORY_NEW(ctx.mem, List,
1362
+ List_Obj arglist = SASS_MEMORY_NEW(List,
1348
1363
  splat->pstate(),
1349
1364
  0,
1350
1365
  ls ? ls->separator() : separator,
1351
1366
  true);
1352
1367
 
1353
1368
  if (ls && ls->is_arglist()) {
1354
- for (auto as : *ls) *arglist << as;
1369
+ arglist->concat(ls);
1355
1370
  } else if (ms) {
1356
- *aa << SASS_MEMORY_NEW(ctx.mem, Argument, splat->pstate(), ms, "", false, true);
1371
+ aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), ms, "", false, true));
1357
1372
  } else if (ls) {
1358
- for (auto as : *ls) *arglist << as;
1373
+ arglist->concat(ls);
1359
1374
  } else {
1360
- *arglist << splat;
1375
+ arglist->append(splat);
1361
1376
  }
1362
1377
  if (arglist->length()) {
1363
- *aa << SASS_MEMORY_NEW(ctx.mem, Argument, splat->pstate(), arglist, "", true);
1378
+ aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), &arglist, "", true));
1364
1379
  }
1365
1380
  }
1366
1381
 
1367
1382
  if (a->has_keyword_argument()) {
1368
- Expression* kwarg = static_cast<Argument*>(
1369
- a->get_keyword_argument()->perform(this)
1370
- )->value()->perform(this);
1383
+ Expression_Obj rv = a->get_keyword_argument()->perform(this);
1384
+ Argument_Ptr rvarg = SASS_MEMORY_CAST(Argument, rv);
1385
+ Expression_Obj kwarg = rvarg->value()->perform(this);
1371
1386
 
1372
- *aa << SASS_MEMORY_NEW(ctx.mem, Argument, kwarg->pstate(), kwarg, "", false, true);
1387
+ aa->append(SASS_MEMORY_NEW(Argument, kwarg->pstate(), kwarg, "", false, true));
1373
1388
  }
1374
-
1375
- return aa;
1389
+ return aa.detach();
1376
1390
  }
1377
1391
 
1378
- Expression* Eval::operator()(Comment* c)
1392
+ Expression_Ptr Eval::operator()(Comment_Ptr c)
1379
1393
  {
1380
1394
  return 0;
1381
1395
  }
1382
1396
 
1383
- inline Expression* Eval::fallback_impl(AST_Node* n)
1397
+ inline Expression_Ptr Eval::fallback_impl(AST_Node_Ptr n)
1384
1398
  {
1385
- return static_cast<Expression*>(n);
1399
+ return static_cast<Expression_Ptr>(n);
1386
1400
  }
1387
1401
 
1388
1402
  // All the binary helpers.
1389
1403
 
1390
- bool Eval::eq(Expression* lhs, Expression* rhs)
1404
+ bool Eval::eq(Expression_Obj lhs, Expression_Obj rhs)
1391
1405
  {
1392
1406
  // use compare operator from ast node
1393
1407
  return lhs && rhs && *lhs == *rhs;
1394
1408
  }
1395
1409
 
1396
- bool Eval::lt(Expression* lhs, Expression* rhs, std::string op)
1410
+ bool Eval::lt(Expression_Obj lhs, Expression_Obj rhs, std::string op)
1397
1411
  {
1398
- Number* l = dynamic_cast<Number*>(lhs);
1399
- Number* r = dynamic_cast<Number*>(rhs);
1412
+ Number_Obj l = SASS_MEMORY_CAST(Number, lhs);
1413
+ Number_Obj r = SASS_MEMORY_CAST(Number, rhs);
1400
1414
  // use compare operator from ast node
1401
- if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op);
1415
+ if (!l || !r) throw Exception::UndefinedOperation(&lhs, &rhs, op);
1402
1416
  // use compare operator from ast node
1403
1417
  return *l < *r;
1404
1418
  }
1405
1419
 
1406
- Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1420
+ Value_Ptr Eval::op_numbers(enum Sass_OP op, const Number& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1407
1421
  {
1408
1422
  double lv = l.value();
1409
1423
  double rv = r.value();
1410
1424
  if (op == Sass_OP::DIV && rv == 0) {
1411
1425
  // XXX: this is never hit via spec tests
1412
- return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : l.pstate(), lv ? "Infinity" : "NaN");
1426
+ return SASS_MEMORY_NEW(String_Quoted, pstate ? *pstate : l.pstate(), lv ? "Infinity" : "NaN");
1413
1427
  }
1414
1428
  if (op == Sass_OP::MOD && !rv) {
1415
1429
  // XXX: this is never hit via spec tests
1416
1430
  throw Exception::ZeroDivisionError(l, r);
1417
1431
  }
1418
1432
 
1419
- Number tmp(r);
1433
+ Number tmp(&r); // copy
1420
1434
  bool strict = op != Sass_OP::MUL && op != Sass_OP::DIV;
1421
1435
  tmp.normalize(l.find_convertible_unit(), strict);
1422
1436
  std::string l_unit(l.unit());
1423
1437
  std::string r_unit(tmp.unit());
1424
- Number* v = SASS_MEMORY_NEW(mem, Number, l);
1438
+ Number_Obj v = SASS_MEMORY_COPY(&l); // copy
1425
1439
  v->pstate(pstate ? *pstate : l.pstate());
1426
1440
  if (l_unit.empty() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
1427
1441
  v->numerator_units() = r.numerator_units();
@@ -1446,25 +1460,23 @@ namespace Sass {
1446
1460
  v->numerator_units().push_back(r.denominator_units()[i]);
1447
1461
  }
1448
1462
  } else {
1449
- Number rh(r);
1450
- v->value(ops[op](lv, rh.value() * r.convert_factor(l)));
1463
+ v->value(ops[op](lv, r.value() * r.convert_factor(l)));
1451
1464
  // v->normalize();
1452
- return v;
1465
+ return v.detach();
1453
1466
 
1454
1467
  v->value(ops[op](lv, tmp.value()));
1455
1468
  }
1456
1469
  v->normalize();
1457
- return v;
1470
+ return v.detach();
1458
1471
  }
1459
1472
 
1460
- Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, struct Sass_Inspect_Options opt, ParserState* pstate)
1473
+ Value_Ptr Eval::op_number_color(enum Sass_OP op, const Number& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1461
1474
  {
1462
- Color r(rh);
1463
1475
  double lv = l.value();
1464
1476
  switch (op) {
1465
1477
  case Sass_OP::ADD:
1466
1478
  case Sass_OP::MUL: {
1467
- return SASS_MEMORY_NEW(mem, Color,
1479
+ return SASS_MEMORY_NEW(Color,
1468
1480
  pstate ? *pstate : l.pstate(),
1469
1481
  ops[op](lv, r.r()),
1470
1482
  ops[op](lv, r.g()),
@@ -1475,7 +1487,7 @@ namespace Sass {
1475
1487
  case Sass_OP::DIV: {
1476
1488
  std::string sep(op == Sass_OP::SUB ? "-" : "/");
1477
1489
  std::string color(r.to_string(opt));
1478
- return SASS_MEMORY_NEW(mem, String_Quoted,
1490
+ return SASS_MEMORY_NEW(String_Quoted,
1479
1491
  pstate ? *pstate : l.pstate(),
1480
1492
  l.to_string(opt)
1481
1493
  + sep
@@ -1487,17 +1499,17 @@ namespace Sass {
1487
1499
  default: break; // caller should ensure that we don't get here
1488
1500
  }
1489
1501
  // unreachable
1490
- return SASS_MEMORY_NEW(mem, Color, rh);
1502
+ return NULL;
1491
1503
  }
1492
1504
 
1493
- Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1505
+ Value_Ptr Eval::op_color_number(enum Sass_OP op, const Color& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1494
1506
  {
1495
1507
  double rv = r.value();
1496
1508
  if (op == Sass_OP::DIV && !rv) {
1497
1509
  // comparison of Fixnum with Float failed?
1498
1510
  throw Exception::ZeroDivisionError(l, r);
1499
1511
  }
1500
- return SASS_MEMORY_NEW(mem, Color,
1512
+ return SASS_MEMORY_NEW(Color,
1501
1513
  pstate ? *pstate : l.pstate(),
1502
1514
  ops[op](l.r(), rv),
1503
1515
  ops[op](l.g(), rv),
@@ -1505,7 +1517,7 @@ namespace Sass {
1505
1517
  l.a());
1506
1518
  }
1507
1519
 
1508
- Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1520
+ Value_Ptr Eval::op_colors(enum Sass_OP op, const Color& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate)
1509
1521
  {
1510
1522
  if (l.a() != r.a()) {
1511
1523
  throw Exception::AlphaChannelsNotEqual(&l, &r, "+");
@@ -1514,7 +1526,7 @@ namespace Sass {
1514
1526
  // comparison of Fixnum with Float failed?
1515
1527
  throw Exception::ZeroDivisionError(l, r);
1516
1528
  }
1517
- return SASS_MEMORY_NEW(mem, Color,
1529
+ return SASS_MEMORY_NEW(Color,
1518
1530
  pstate ? *pstate : l.pstate(),
1519
1531
  ops[op](l.r(), r.r()),
1520
1532
  ops[op](l.g(), r.g()),
@@ -1522,14 +1534,14 @@ namespace Sass {
1522
1534
  l.a());
1523
1535
  }
1524
1536
 
1525
- Value* Eval::op_strings(Memory_Manager& mem, Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, ParserState* pstate, bool delayed)
1537
+ Value_Ptr Eval::op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, ParserState* pstate, bool delayed)
1526
1538
  {
1527
1539
  Expression::Concrete_Type ltype = lhs.concrete_type();
1528
1540
  Expression::Concrete_Type rtype = rhs.concrete_type();
1529
1541
  enum Sass_OP op = operand.operand;
1530
1542
 
1531
- String_Quoted* lqstr = dynamic_cast<String_Quoted*>(&lhs);
1532
- String_Quoted* rqstr = dynamic_cast<String_Quoted*>(&rhs);
1543
+ String_Quoted_Ptr lqstr = dynamic_cast<String_Quoted_Ptr>(&lhs);
1544
+ String_Quoted_Ptr rqstr = dynamic_cast<String_Quoted_Ptr>(&rhs);
1533
1545
 
1534
1546
  std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
1535
1547
  std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
@@ -1557,7 +1569,7 @@ namespace Sass {
1557
1569
  (sep != "/" || !rqstr || !rqstr->quote_mark()) */
1558
1570
  ) {
1559
1571
  // create a new string that might be quoted on output (but do not unquote what we pass)
1560
- return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : lhs.pstate(), lstr + rstr, 0, false, true);
1572
+ return SASS_MEMORY_NEW(String_Quoted, pstate ? *pstate : lhs.pstate(), lstr + rstr, 0, false, true);
1561
1573
  }
1562
1574
 
1563
1575
  if (sep != "" && !delayed) {
@@ -1570,49 +1582,49 @@ namespace Sass {
1570
1582
  if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);
1571
1583
  }
1572
1584
 
1573
- return SASS_MEMORY_NEW(mem, String_Constant, pstate ? *pstate : lhs.pstate(), lstr + sep + rstr);
1585
+ return SASS_MEMORY_NEW(String_Constant, pstate ? *pstate : lhs.pstate(), lstr + sep + rstr);
1574
1586
  }
1575
1587
 
1576
- Expression* cval_to_astnode(Memory_Manager& mem, union Sass_Value* v, Context& ctx, Backtrace* backtrace, ParserState pstate)
1588
+ Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtrace* backtrace, ParserState pstate)
1577
1589
  {
1578
1590
  using std::strlen;
1579
1591
  using std::strcpy;
1580
- Expression* e = 0;
1592
+ Expression_Ptr e = NULL;
1581
1593
  switch (sass_value_get_tag(v)) {
1582
1594
  case SASS_BOOLEAN: {
1583
- e = SASS_MEMORY_NEW(mem, Boolean, pstate, !!sass_boolean_get_value(v));
1595
+ e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v));
1584
1596
  } break;
1585
1597
  case SASS_NUMBER: {
1586
- e = SASS_MEMORY_NEW(mem, Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));
1598
+ e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));
1587
1599
  } break;
1588
1600
  case SASS_COLOR: {
1589
- e = SASS_MEMORY_NEW(mem, Color, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v));
1601
+ 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));
1590
1602
  } break;
1591
1603
  case SASS_STRING: {
1592
1604
  if (sass_string_is_quoted(v))
1593
- e = SASS_MEMORY_NEW(mem, String_Quoted, pstate, sass_string_get_value(v));
1605
+ e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v));
1594
1606
  else {
1595
- e = SASS_MEMORY_NEW(mem, String_Constant, pstate, sass_string_get_value(v));
1607
+ e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v));
1596
1608
  }
1597
1609
  } break;
1598
1610
  case SASS_LIST: {
1599
- List* l = SASS_MEMORY_NEW(mem, List, pstate, sass_list_get_length(v), sass_list_get_separator(v));
1611
+ List_Ptr l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v));
1600
1612
  for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) {
1601
- *l << cval_to_astnode(mem, sass_list_get_value(v, i), ctx, backtrace, pstate);
1613
+ l->append(cval_to_astnode(sass_list_get_value(v, i), backtrace, pstate));
1602
1614
  }
1603
1615
  e = l;
1604
1616
  } break;
1605
1617
  case SASS_MAP: {
1606
- Map* m = SASS_MEMORY_NEW(mem, Map, pstate);
1618
+ Map_Ptr m = SASS_MEMORY_NEW(Map, pstate);
1607
1619
  for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) {
1608
1620
  *m << std::make_pair(
1609
- cval_to_astnode(mem, sass_map_get_key(v, i), ctx, backtrace, pstate),
1610
- cval_to_astnode(mem, sass_map_get_value(v, i), ctx, backtrace, pstate));
1621
+ cval_to_astnode(sass_map_get_key(v, i), backtrace, pstate),
1622
+ cval_to_astnode(sass_map_get_value(v, i), backtrace, pstate));
1611
1623
  }
1612
1624
  e = m;
1613
1625
  } break;
1614
1626
  case SASS_NULL: {
1615
- e = SASS_MEMORY_NEW(mem, Null, pstate);
1627
+ e = SASS_MEMORY_NEW(Null, pstate);
1616
1628
  } break;
1617
1629
  case SASS_ERROR: {
1618
1630
  error("Error in C function: " + std::string(sass_error_get_message(v)), pstate, backtrace);
@@ -1624,15 +1636,15 @@ namespace Sass {
1624
1636
  return e;
1625
1637
  }
1626
1638
 
1627
- CommaSequence_Selector* Eval::operator()(CommaSequence_Selector* s)
1639
+ Selector_List_Ptr Eval::operator()(Selector_List_Ptr s)
1628
1640
  {
1629
- std::vector<CommaSequence_Selector*> rv;
1630
- CommaSequence_Selector* sl = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, s->pstate());
1641
+ std::vector<Selector_List_Obj> rv;
1642
+ Selector_List_Obj sl = SASS_MEMORY_NEW(Selector_List, s->pstate());
1631
1643
  sl->is_optional(s->is_optional());
1632
1644
  sl->media_block(s->media_block());
1633
1645
  sl->is_optional(s->is_optional());
1634
1646
  for (size_t i = 0, iL = s->length(); i < iL; ++i) {
1635
- rv.push_back(operator()((*s)[i]));
1647
+ rv.push_back(operator()(&(*s)[i]));
1636
1648
  }
1637
1649
 
1638
1650
  // we should actually permutate parent first
@@ -1642,7 +1654,7 @@ namespace Sass {
1642
1654
  bool abort = true;
1643
1655
  for (size_t i = 0, iL = rv.size(); i < iL; ++i) {
1644
1656
  if (rv[i]->length() > round) {
1645
- *sl << (*rv[i])[round];
1657
+ sl->append((*rv[i])[round]);
1646
1658
  abort = false;
1647
1659
  }
1648
1660
  }
@@ -1653,49 +1665,48 @@ namespace Sass {
1653
1665
  }
1654
1666
 
1655
1667
  }
1656
- return sl;
1668
+ return sl.detach();
1657
1669
  }
1658
1670
 
1659
1671
 
1660
- CommaSequence_Selector* Eval::operator()(Sequence_Selector* s)
1672
+ Selector_List_Ptr Eval::operator()(Complex_Selector_Ptr s)
1661
1673
  {
1662
1674
  bool implicit_parent = !exp.old_at_root_without_rule;
1663
- return s->resolve_parent_refs(ctx, selector(), implicit_parent);
1664
-
1675
+ return s->resolve_parent_refs(ctx, exp.selector_stack, implicit_parent);
1665
1676
  }
1666
1677
 
1667
1678
  // XXX: this is never hit via spec tests
1668
- Attribute_Selector* Eval::operator()(Attribute_Selector* s)
1679
+ Attribute_Selector_Ptr Eval::operator()(Attribute_Selector_Ptr s)
1669
1680
  {
1670
- String* attr = s->value();
1671
- if (attr) { attr = static_cast<String*>(attr->perform(this)); }
1672
- Attribute_Selector* ss = SASS_MEMORY_NEW(ctx.mem, Attribute_Selector, *s);
1681
+ String_Obj attr = s->value();
1682
+ if (attr) { attr = static_cast<String_Ptr>(attr->perform(this)); }
1683
+ Attribute_Selector_Ptr ss = SASS_MEMORY_COPY(s);
1673
1684
  ss->value(attr);
1674
1685
  return ss;
1675
1686
  }
1676
1687
 
1677
- CommaSequence_Selector* Eval::operator()(Selector_Schema* s)
1688
+ Selector_List_Ptr Eval::operator()(Selector_Schema_Ptr s)
1678
1689
  {
1679
1690
  // the parser will look for a brace to end the selector
1680
- std::string result_str(s->contents()->perform(this)->to_string(ctx.c_options));
1691
+ Expression_Obj sel = s->contents()->perform(this);
1692
+ std::string result_str(sel->to_string(ctx.c_options));
1681
1693
  result_str = unquote(Util::rtrim(result_str)) + "\n{";
1682
1694
  Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
1683
1695
  p.last_media_block = s->media_block();
1684
- CommaSequence_Selector* sl = p.parse_selector_list(exp.block_stack.back()->is_root());
1696
+ Selector_List_Obj sl = p.parse_selector_list(exp.block_stack.back()->is_root());
1685
1697
  if (s->has_parent_ref()) sl->remove_parent_selectors();
1686
- return operator()(sl);
1698
+ return operator()(&sl);
1687
1699
  }
1688
1700
 
1689
- Expression* Eval::operator()(Parent_Selector* p)
1701
+ Expression_Ptr Eval::operator()(Parent_Selector_Ptr p)
1690
1702
  {
1691
- CommaSequence_Selector* pr = selector();
1692
- if (pr) {
1703
+ if (Selector_List_Obj pr = selector()) {
1693
1704
  exp.selector_stack.pop_back();
1694
- pr = operator()(pr);
1695
- exp.selector_stack.push_back(pr);
1696
- return pr;
1705
+ Selector_List_Obj rv = operator()(&pr);
1706
+ exp.selector_stack.push_back(rv);
1707
+ return rv.detach();
1697
1708
  } else {
1698
- return SASS_MEMORY_NEW(ctx.mem, Null, p->pstate());
1709
+ return SASS_MEMORY_NEW(Null, p->pstate());
1699
1710
  }
1700
1711
  }
1701
1712