sassc 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
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