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
@@ -12,12 +12,12 @@ namespace Sass {
12
12
 
13
13
  Output::~Output() { }
14
14
 
15
- void Output::fallback_impl(AST_Node* n)
15
+ void Output::fallback_impl(AST_Node_Ptr n)
16
16
  {
17
17
  return n->perform(this);
18
18
  }
19
19
 
20
- void Output::operator()(Number* n)
20
+ void Output::operator()(Number_Ptr n)
21
21
  {
22
22
  // use values to_string facility
23
23
  std::string res = n->to_string(opt);
@@ -30,12 +30,12 @@ namespace Sass {
30
30
  append_token(res, n);
31
31
  }
32
32
 
33
- void Output::operator()(Import* imp)
33
+ void Output::operator()(Import_Ptr imp)
34
34
  {
35
35
  top_nodes.push_back(imp);
36
36
  }
37
37
 
38
- void Output::operator()(Map* m)
38
+ void Output::operator()(Map_Ptr m)
39
39
  {
40
40
  std::string dbg(m->to_string(opt));
41
41
  error(dbg + " isn't a valid CSS value.", m->pstate());
@@ -85,7 +85,7 @@ namespace Sass {
85
85
 
86
86
  }
87
87
 
88
- void Output::operator()(Comment* c)
88
+ void Output::operator()(Comment_Ptr c)
89
89
  {
90
90
  std::string txt = c->text()->to_string(opt);
91
91
  // if (indentation && txt == "/**/") return;
@@ -107,17 +107,17 @@ namespace Sass {
107
107
  }
108
108
  }
109
109
 
110
- void Output::operator()(Ruleset* r)
110
+ void Output::operator()(Ruleset_Ptr r)
111
111
  {
112
- Selector* s = r->selector();
113
- Block* b = r->block();
112
+ Selector_Obj s = r->selector();
113
+ Block_Obj b = r->block();
114
114
 
115
115
  // Filter out rulesets that aren't printable (process its children though)
116
116
  if (!Util::isPrintable(r, output_style())) {
117
117
  for (size_t i = 0, L = b->length(); i < L; ++i) {
118
- Statement* stm = (*b)[i];
119
- if (dynamic_cast<Has_Block*>(stm)) {
120
- if (typeid(*stm) != typeid(Declaration)) {
118
+ const Statement_Obj& stm = b->at(i);
119
+ if (dynamic_cast<Has_Block_Ptr>(&stm)) {
120
+ if (!dynamic_cast<Declaration_Ptr>(&stm)) {
121
121
  stm->perform(this);
122
122
  }
123
123
  }
@@ -134,28 +134,25 @@ namespace Sass {
134
134
  append_string(ss.str());
135
135
  append_optional_linefeed();
136
136
  }
137
- s->perform(this);
138
- append_scope_opener(b);
137
+ if (s) s->perform(this);
138
+ append_scope_opener(&b);
139
139
  for (size_t i = 0, L = b->length(); i < L; ++i) {
140
- Statement* stm = (*b)[i];
140
+ Statement_Obj stm = b->at(i);
141
141
  bool bPrintExpression = true;
142
142
  // Check print conditions
143
- if (typeid(*stm) == typeid(Declaration)) {
144
- Declaration* dec = static_cast<Declaration*>(stm);
145
- if (dec->value()->concrete_type() == Expression::STRING) {
146
- String_Constant* valConst = static_cast<String_Constant*>(dec->value());
143
+ if (Declaration_Ptr dec = SASS_MEMORY_CAST(Declaration, stm)) {
144
+ if (String_Constant_Ptr valConst = SASS_MEMORY_CAST(String_Constant, dec->value())) {
147
145
  std::string val(valConst->value());
148
- if (auto qstr = dynamic_cast<String_Quoted*>(valConst)) {
146
+ if (String_Quoted_Ptr qstr = SASS_MEMORY_CAST_PTR(String_Quoted, valConst)) {
149
147
  if (!qstr->quote_mark() && val.empty()) {
150
148
  bPrintExpression = false;
151
149
  }
152
150
  }
153
151
  }
154
- else if (dec->value()->concrete_type() == Expression::LIST) {
155
- List* list = static_cast<List*>(dec->value());
152
+ else if (List_Ptr list = SASS_MEMORY_CAST(List, dec->value())) {
156
153
  bool all_invisible = true;
157
154
  for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
158
- Expression* item = (*list)[list_i];
155
+ Expression_Ptr item = &list->at(list_i);
159
156
  if (!item->is_invisible()) all_invisible = false;
160
157
  }
161
158
  if (all_invisible) bPrintExpression = false;
@@ -167,15 +164,15 @@ namespace Sass {
167
164
  }
168
165
  }
169
166
  if (output_style() == NESTED) indentation -= r->tabs();
170
- append_scope_closer(b);
167
+ append_scope_closer(&b);
171
168
 
172
169
  }
173
- void Output::operator()(Keyframe_Rule* r)
170
+ void Output::operator()(Keyframe_Rule_Ptr r)
174
171
  {
175
- Block* b = r->block();
176
- Selector* v = r->selector();
172
+ Block_Obj b = r->block();
173
+ Selector_Obj v = r->name();
177
174
 
178
- if (v) {
175
+ if (&v) {
179
176
  v->perform(this);
180
177
  }
181
178
 
@@ -186,25 +183,25 @@ namespace Sass {
186
183
 
187
184
  append_scope_opener();
188
185
  for (size_t i = 0, L = b->length(); i < L; ++i) {
189
- Statement* stm = (*b)[i];
186
+ Statement_Obj stm = b->at(i);
190
187
  stm->perform(this);
191
188
  if (i < L - 1) append_special_linefeed();
192
189
  }
193
190
  append_scope_closer();
194
191
  }
195
192
 
196
- void Output::operator()(Supports_Block* f)
193
+ void Output::operator()(Supports_Block_Ptr f)
197
194
  {
198
195
  if (f->is_invisible()) return;
199
196
 
200
- Supports_Condition* c = f->condition();
201
- Block* b = f->block();
197
+ Supports_Condition_Obj c = f->condition();
198
+ Block_Obj b = f->block();
202
199
 
203
200
  // Filter out feature blocks that aren't printable (process its children though)
204
201
  if (!Util::isPrintable(f, output_style())) {
205
202
  for (size_t i = 0, L = b->length(); i < L; ++i) {
206
- Statement* stm = (*b)[i];
207
- if (dynamic_cast<Has_Block*>(stm)) {
203
+ Statement_Obj stm = b->at(i);
204
+ if (dynamic_cast<Has_Block_Ptr>(&stm)) {
208
205
  stm->perform(this);
209
206
  }
210
207
  }
@@ -219,7 +216,7 @@ namespace Sass {
219
216
  append_scope_opener();
220
217
 
221
218
  for (size_t i = 0, L = b->length(); i < L; ++i) {
222
- Statement* stm = (*b)[i];
219
+ Statement_Obj stm = b->at(i);
223
220
  stm->perform(this);
224
221
  if (i < L - 1) append_special_linefeed();
225
222
  }
@@ -230,18 +227,17 @@ namespace Sass {
230
227
 
231
228
  }
232
229
 
233
- void Output::operator()(Media_Block* m)
230
+ void Output::operator()(Media_Block_Ptr m)
234
231
  {
235
232
  if (m->is_invisible()) return;
236
233
 
237
- List* q = m->media_queries();
238
- Block* b = m->block();
234
+ Block_Obj b = m->block();
239
235
 
240
236
  // Filter out media blocks that aren't printable (process its children though)
241
237
  if (!Util::isPrintable(m, output_style())) {
242
238
  for (size_t i = 0, L = b->length(); i < L; ++i) {
243
- Statement* stm = (*b)[i];
244
- if (dynamic_cast<Has_Block*>(stm)) {
239
+ Statement_Obj stm = b->at(i);
240
+ if (dynamic_cast<Has_Block_Ptr>(&stm)) {
245
241
  stm->perform(this);
246
242
  }
247
243
  }
@@ -252,12 +248,15 @@ namespace Sass {
252
248
  append_token("@media", m);
253
249
  append_mandatory_space();
254
250
  in_media_block = true;
255
- q->perform(this);
251
+ m->media_queries()->perform(this);
256
252
  in_media_block = false;
257
253
  append_scope_opener();
258
254
 
259
255
  for (size_t i = 0, L = b->length(); i < L; ++i) {
260
- if ((*b)[i]) (*b)[i]->perform(this);
256
+ if (b->at(i)) {
257
+ Statement_Obj stm = b->at(i);
258
+ stm->perform(this);
259
+ }
261
260
  if (i < L - 1) append_special_linefeed();
262
261
  }
263
262
 
@@ -265,12 +264,12 @@ namespace Sass {
265
264
  append_scope_closer();
266
265
  }
267
266
 
268
- void Output::operator()(Directive* a)
267
+ void Output::operator()(Directive_Ptr a)
269
268
  {
270
269
  std::string kwd = a->keyword();
271
- Selector* s = a->selector();
272
- Expression* v = a->value();
273
- Block* b = a->block();
270
+ Selector_Obj s = a->selector();
271
+ Expression_Obj v = a->value();
272
+ Block_Obj b = a->block();
274
273
 
275
274
  append_indentation();
276
275
  append_token(kwd, a);
@@ -283,7 +282,7 @@ namespace Sass {
283
282
  if (v) {
284
283
  append_mandatory_space();
285
284
  // ruby sass bug? should use options?
286
- append_token(v->to_string(/* opt */), v);
285
+ append_token(v->to_string(/* opt */), &v);
287
286
  }
288
287
  if (!b) {
289
288
  append_delimiter();
@@ -300,7 +299,7 @@ namespace Sass {
300
299
  bool format = kwd != "@font-face";;
301
300
 
302
301
  for (size_t i = 0, L = b->length(); i < L; ++i) {
303
- Statement* stm = (*b)[i];
302
+ Statement_Obj stm = b->at(i);
304
303
  stm->perform(this);
305
304
  if (i < L - 1 && format) append_special_linefeed();
306
305
  }
@@ -308,7 +307,7 @@ namespace Sass {
308
307
  append_scope_closer();
309
308
  }
310
309
 
311
- void Output::operator()(String_Quoted* s)
310
+ void Output::operator()(String_Quoted_Ptr s)
312
311
  {
313
312
  if (s->quote_mark()) {
314
313
  append_token(quote(s->value(), s->quote_mark()), s);
@@ -319,7 +318,7 @@ namespace Sass {
319
318
  }
320
319
  }
321
320
 
322
- void Output::operator()(String_Constant* s)
321
+ void Output::operator()(String_Constant_Ptr s)
323
322
  {
324
323
  std::string value(s->value());
325
324
  if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
@@ -28,24 +28,24 @@ namespace Sass {
28
28
 
29
29
  protected:
30
30
  std::string charset;
31
- std::vector<AST_Node*> top_nodes;
31
+ std::vector<AST_Node_Ptr> top_nodes;
32
32
 
33
33
  public:
34
34
  OutputBuffer get_buffer(void);
35
35
 
36
- virtual void operator()(Map*);
37
- virtual void operator()(Ruleset*);
38
- virtual void operator()(Supports_Block*);
39
- virtual void operator()(Media_Block*);
40
- virtual void operator()(Directive*);
41
- virtual void operator()(Keyframe_Rule*);
42
- virtual void operator()(Import*);
43
- virtual void operator()(Comment*);
44
- virtual void operator()(Number*);
45
- virtual void operator()(String_Quoted*);
46
- virtual void operator()(String_Constant*);
47
-
48
- void fallback_impl(AST_Node* n);
36
+ virtual void operator()(Map_Ptr);
37
+ virtual void operator()(Ruleset_Ptr);
38
+ virtual void operator()(Supports_Block_Ptr);
39
+ virtual void operator()(Media_Block_Ptr);
40
+ virtual void operator()(Directive_Ptr);
41
+ virtual void operator()(Keyframe_Rule_Ptr);
42
+ virtual void operator()(Import_Ptr);
43
+ virtual void operator()(Comment_Ptr);
44
+ virtual void operator()(Number_Ptr);
45
+ virtual void operator()(String_Quoted_Ptr);
46
+ virtual void operator()(String_Constant_Ptr);
47
+
48
+ void fallback_impl(AST_Node_Ptr n);
49
49
 
50
50
  };
51
51
 
@@ -39,7 +39,7 @@ namespace Sass {
39
39
  p.source = source ? source : beg;
40
40
  p.position = beg ? beg : p.source;
41
41
  p.end = p.position + strlen(p.position);
42
- Block* root = SASS_MEMORY_NEW(ctx.mem, Block, pstate);
42
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
43
43
  p.block_stack.push_back(root);
44
44
  root->is_root(true);
45
45
  return p;
@@ -53,7 +53,7 @@ namespace Sass {
53
53
  p.source = source ? source : beg;
54
54
  p.position = beg ? beg : p.source;
55
55
  p.end = end ? end : p.position + strlen(p.position);
56
- Block* root = SASS_MEMORY_NEW(ctx.mem, Block, pstate);
56
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
57
57
  p.block_stack.push_back(root);
58
58
  root->is_root(true);
59
59
  return p;
@@ -67,7 +67,7 @@ namespace Sass {
67
67
  pstate.offset.line = 0;
68
68
  }
69
69
 
70
- CommaSequence_Selector* Parser::parse_selector(const char* beg, Context& ctx, ParserState pstate, const char* source)
70
+ Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, ParserState pstate, const char* source)
71
71
  {
72
72
  Parser p = Parser::from_c_str(beg, ctx, pstate, source);
73
73
  // ToDo: ruby sass errors on parent references
@@ -87,23 +87,23 @@ namespace Sass {
87
87
  p.source = source ? source : t.begin;
88
88
  p.position = t.begin ? t.begin : p.source;
89
89
  p.end = t.end ? t.end : p.position + strlen(p.position);
90
- Block* root = SASS_MEMORY_NEW(ctx.mem, Block, pstate);
90
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
91
91
  p.block_stack.push_back(root);
92
92
  root->is_root(true);
93
93
  return p;
94
94
  }
95
95
 
96
96
  /* main entry point to parse root block */
97
- Block* Parser::parse()
97
+ Block_Obj Parser::parse()
98
98
  {
99
99
  bool is_root = false;
100
- Block* root = SASS_MEMORY_NEW(ctx.mem, Block, pstate, 0, true);
100
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate, 0, true);
101
101
  read_bom();
102
102
 
103
103
  // custom headers
104
104
  if (ctx.resources.size() == 1) {
105
105
  is_root = true;
106
- ctx.apply_custom_headers(root, path, pstate);
106
+ ctx.apply_custom_headers(&root, path, pstate);
107
107
  }
108
108
 
109
109
  block_stack.push_back(root);
@@ -124,7 +124,7 @@ namespace Sass {
124
124
  // convenience function for block parsing
125
125
  // will create a new block ad-hoc for you
126
126
  // this is the base block parsing function
127
- Block* Parser::parse_css_block(bool is_root)
127
+ Block_Obj Parser::parse_css_block(bool is_root)
128
128
  {
129
129
 
130
130
  // parse comments before block
@@ -135,30 +135,32 @@ namespace Sass {
135
135
  css_error("Invalid CSS", " after ", ": expected \"{\", was ");
136
136
  }
137
137
  // create new block and push to the selector stack
138
- Block* block = SASS_MEMORY_NEW(ctx.mem, Block, pstate, 0, is_root);
138
+ Block_Obj block = SASS_MEMORY_NEW(Block, pstate, 0, is_root);
139
139
  block_stack.push_back(block);
140
140
 
141
- if (!parse_block_nodes()) css_error("Invalid CSS", " after ", ": expected \"}\", was ");;
141
+ if (!parse_block_nodes()) css_error("Invalid CSS", " after ", ": expected \"}\", was ");
142
142
 
143
143
  if (!lex_css < exactly<'}'> >()) {
144
144
  css_error("Invalid CSS", " after ", ": expected \"}\", was ");
145
145
  }
146
146
 
147
147
  // update for end position
148
- block->update_pstate(pstate);
148
+ // this seems to be done somewhere else
149
+ // but that fixed selector schema issue
150
+ // block->update_pstate(pstate);
149
151
 
150
152
  // parse comments after block
151
153
  // lex < optional_css_comments >();
152
154
 
153
155
  block_stack.pop_back();
154
156
 
155
- return block;
157
+ return &block;
156
158
  }
157
159
 
158
160
  // convenience function for block parsing
159
161
  // will create a new block ad-hoc for you
160
162
  // also updates the `in_at_root` flag
161
- Block* Parser::parse_block(bool is_root)
163
+ Block_Obj Parser::parse_block(bool is_root)
162
164
  {
163
165
  LOCAL_FLAG(in_at_root, is_root);
164
166
  return parse_css_block(is_root);
@@ -199,7 +201,7 @@ namespace Sass {
199
201
  // semicolons must be lexed beforehand
200
202
  bool Parser::parse_block_node(bool is_root) {
201
203
 
202
- Block* block = block_stack.back();
204
+ Block_Obj block = block_stack.back();
203
205
 
204
206
  parse_block_comments();
205
207
 
@@ -212,20 +214,15 @@ namespace Sass {
212
214
  // also parse block comments
213
215
 
214
216
  // first parse everything that is allowed in functions
215
- if (lex < variable >(true)) { (*block) << parse_assignment(); }
216
- else if (lex < kwd_err >(true)) { (*block) << parse_error(); }
217
- else if (lex < kwd_dbg >(true)) { (*block) << parse_debug(); }
218
- else if (lex < kwd_warn >(true)) { (*block) << parse_warning(); }
219
- else if (lex < kwd_if_directive >(true)) { (*block) << parse_if_directive(); }
220
- else if (lex < kwd_for_directive >(true)) { (*block) << parse_for_directive(); }
221
- else if (lex < kwd_each_directive >(true)) { (*block) << parse_each_directive(); }
222
- else if (lex < kwd_while_directive >(true)) { (*block) << parse_while_directive(); }
223
- else if (lex < kwd_return_directive >(true)) { (*block) << parse_return_directive(); }
224
-
225
- // abort if we are in function context and have nothing parsed yet
226
- else if (stack.back() == Scope::Function) {
227
- error("Functions can only contain variable declarations and control directives.", pstate);
228
- }
217
+ if (lex < variable >(true)) { block->append(&parse_assignment()); }
218
+ else if (lex < kwd_err >(true)) { block->append(&parse_error()); }
219
+ else if (lex < kwd_dbg >(true)) { block->append(&parse_debug()); }
220
+ else if (lex < kwd_warn >(true)) { block->append(&parse_warning()); }
221
+ else if (lex < kwd_if_directive >(true)) { block->append(&parse_if_directive()); }
222
+ else if (lex < kwd_for_directive >(true)) { block->append(&parse_for_directive()); }
223
+ else if (lex < kwd_each_directive >(true)) { block->append(&parse_each_directive()); }
224
+ else if (lex < kwd_while_directive >(true)) { block->append(&parse_while_directive()); }
225
+ else if (lex < kwd_return_directive >(true)) { block->append(&parse_return_directive()); }
229
226
 
230
227
  // parse imports to process later
231
228
  else if (lex < kwd_import >(true)) {
@@ -235,48 +232,44 @@ namespace Sass {
235
232
  error("Import directives may not be used within control directives or mixins.", pstate);
236
233
  }
237
234
  }
238
- Import* imp = parse_import();
235
+ Import_Obj imp = parse_import();
239
236
  // if it is a url, we only add the statement
240
- if (!imp->urls().empty()) (*block) << imp;
237
+ if (!imp->urls().empty()) block->append(&imp);
241
238
  // process all resources now (add Import_Stub nodes)
242
239
  for (size_t i = 0, S = imp->incs().size(); i < S; ++i) {
243
- (*block) << SASS_MEMORY_NEW(ctx.mem, Import_Stub, pstate, imp->incs()[i]);
240
+ block->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i]));
244
241
  }
245
242
  }
246
243
 
247
244
  else if (lex < kwd_extend >(true)) {
248
- if (block->is_root()) {
249
- error("Extend directives may only be used within rules.", pstate);
250
- }
251
-
252
245
  Lookahead lookahead = lookahead_for_include(position);
253
246
  if (!lookahead.found) css_error("Invalid CSS", " after ", ": expected selector, was ");
254
- Selector* target;
255
- if (lookahead.has_interpolants) target = parse_selector_schema(lookahead.found);
256
- else target = parse_selector_list(true);
257
- (*block) << SASS_MEMORY_NEW(ctx.mem, Extension, pstate, target);
247
+ Selector_Obj target;
248
+ if (lookahead.has_interpolants) target = &parse_selector_schema(lookahead.found);
249
+ else target = &parse_selector_list(true);
250
+ block->append(SASS_MEMORY_NEW(Extension, pstate, &target));
258
251
  }
259
252
 
260
253
  // selector may contain interpolations which need delayed evaluation
261
254
  else if (!(lookahead_result = lookahead_for_selector(position)).error)
262
- { (*block) << parse_ruleset(lookahead_result, is_root); }
255
+ { block->append(&parse_ruleset(lookahead_result, is_root)); }
263
256
 
264
257
  // parse multiple specific keyword directives
265
- else if (lex < kwd_media >(true)) { (*block) << parse_media_block(); }
266
- else if (lex < kwd_at_root >(true)) { (*block) << parse_at_root_block(); }
267
- else if (lex < kwd_include_directive >(true)) { (*block) << parse_include_directive(); }
268
- else if (lex < kwd_content_directive >(true)) { (*block) << parse_content_directive(); }
269
- else if (lex < kwd_supports_directive >(true)) { (*block) << parse_supports_directive(); }
270
- else if (lex < kwd_mixin >(true)) { (*block) << parse_definition(Definition::MIXIN); }
271
- else if (lex < kwd_function >(true)) { (*block) << parse_definition(Definition::FUNCTION); }
258
+ else if (lex < kwd_media >(true)) { block->append(&parse_media_block()); }
259
+ else if (lex < kwd_at_root >(true)) { block->append(&parse_at_root_block()); }
260
+ else if (lex < kwd_include_directive >(true)) { block->append(&parse_include_directive()); }
261
+ else if (lex < kwd_content_directive >(true)) { block->append(&parse_content_directive()); }
262
+ else if (lex < kwd_supports_directive >(true)) { block->append(&parse_supports_directive()); }
263
+ else if (lex < kwd_mixin >(true)) { block->append(&parse_definition(Definition::MIXIN)); }
264
+ else if (lex < kwd_function >(true)) { block->append(&parse_definition(Definition::FUNCTION)); }
272
265
 
273
266
  // ignore the @charset directive for now
274
267
  else if (lex< kwd_charset_directive >(true)) { parse_charset_directive(); }
275
268
 
276
269
  // generic at keyword (keep last)
277
- else if (lex< re_special_directive >(true)) { (*block) << parse_special_directive(); }
278
- else if (lex< re_prefixed_directive >(true)) { (*block) << parse_prefixed_directive(); }
279
- else if (lex< at_keyword >(true)) { (*block) << parse_directive(); }
270
+ else if (lex< re_special_directive >(true)) { block->append(&parse_special_directive()); }
271
+ else if (lex< re_prefixed_directive >(true)) { block->append(&parse_prefixed_directive()); }
272
+ else if (lex< at_keyword >(true)) { block->append(&parse_directive()); }
280
273
 
281
274
  else if (is_root /* && block->is_root() */) {
282
275
  lex< css_whitespace >();
@@ -288,9 +281,9 @@ namespace Sass {
288
281
  {
289
282
  // ToDo: how does it handle parse errors?
290
283
  // maybe we are expected to parse something?
291
- Declaration* decl = parse_declaration();
284
+ Declaration_Obj decl = parse_declaration();
292
285
  decl->tabs(indentation);
293
- (*block) << decl;
286
+ block->append(&decl);
294
287
  // maybe we have a "sub-block"
295
288
  if (peek< exactly<'{'> >()) {
296
289
  if (decl->is_indented()) ++ indentation;
@@ -307,36 +300,36 @@ namespace Sass {
307
300
  // EO parse_block_nodes
308
301
 
309
302
  // parse imports inside the
310
- Import* Parser::parse_import()
303
+ Import_Obj Parser::parse_import()
311
304
  {
312
- Import* imp = SASS_MEMORY_NEW(ctx.mem, Import, pstate);
313
- std::vector<std::pair<std::string,Function_Call*>> to_import;
305
+ Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);
306
+ std::vector<std::pair<std::string,Function_Call_Obj>> to_import;
314
307
  bool first = true;
315
308
  do {
316
309
  while (lex< block_comment >());
317
310
  if (lex< quoted_string >()) {
318
- to_import.push_back(std::pair<std::string,Function_Call*>(std::string(lexed), 0));
311
+ to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), 0));
319
312
  }
320
313
  else if (lex< uri_prefix >()) {
321
- Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, pstate);
322
- Function_Call* result = SASS_MEMORY_NEW(ctx.mem, Function_Call, pstate, "url", args);
314
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
315
+ Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, "url", &args);
323
316
 
324
317
  if (lex< quoted_string >()) {
325
- Expression* the_url = parse_string();
326
- *args << SASS_MEMORY_NEW(ctx.mem, Argument, the_url->pstate(), the_url);
318
+ Expression_Obj the_url = &parse_string();
319
+ args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), &the_url));
327
320
  }
328
- else if (String* the_url = parse_url_function_argument()) {
329
- *args << SASS_MEMORY_NEW(ctx.mem, Argument, the_url->pstate(), the_url);
321
+ else if (String_Obj the_url = parse_url_function_argument()) {
322
+ args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), &the_url));
330
323
  }
331
324
  else if (peek < skip_over_scopes < exactly < '(' >, exactly < ')' > > >(position)) {
332
- Expression* the_url = parse_list(); // parse_interpolated_chunk(lexed);
333
- *args << SASS_MEMORY_NEW(ctx.mem, Argument, the_url->pstate(), the_url);
325
+ Expression_Obj the_url = parse_list(); // parse_interpolated_chunk(lexed);
326
+ args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), &the_url));
334
327
  }
335
328
  else {
336
329
  error("malformed URL", pstate);
337
330
  }
338
331
  if (!lex< exactly<')'> >()) error("URI is missing ')'", pstate);
339
- to_import.push_back(std::pair<std::string, Function_Call*>("", result));
332
+ to_import.push_back(std::pair<std::string, Function_Call_Obj>("", &result));
340
333
  }
341
334
  else {
342
335
  if (first) error("@import directive requires a url or quoted path", pstate);
@@ -346,56 +339,46 @@ namespace Sass {
346
339
  } while (lex_css< exactly<','> >());
347
340
 
348
341
  if (!peek_css< alternatives< exactly<';'>, exactly<'}'>, end_of_file > >()) {
349
- List* media_queries = parse_media_queries();
350
- imp->media_queries(media_queries);
342
+ List_Obj import_queries = parse_media_queries();
343
+ imp->import_queries(import_queries);
351
344
  }
352
345
 
353
346
  for(auto location : to_import) {
354
347
  if (location.second) {
355
- imp->urls().push_back(location.second);
356
- } else if (!ctx.call_importers(unquote(location.first), path, pstate, imp)) {
357
- ctx.import_url(imp, location.first, path);
348
+ imp->urls().push_back(&location.second);
349
+ } else if (!ctx.call_importers(unquote(location.first), path, pstate, &imp)) {
350
+ ctx.import_url(&imp, location.first, path);
358
351
  }
359
352
  }
360
353
 
361
354
  return imp;
362
355
  }
363
356
 
364
- Definition* Parser::parse_definition(Definition::Type which_type)
357
+ Definition_Obj Parser::parse_definition(Definition::Type which_type)
365
358
  {
366
- Scope parent = stack.empty() ? Scope::Rules : stack.back();
367
- if (parent != Scope::Root && parent != Scope::Rules && parent != Scope::Function) {
368
- if (which_type == Definition::FUNCTION) {
369
- error("Functions may not be defined within control directives or other mixins.", pstate);
370
- } else {
371
- error("Mixins may not be defined within control directives or other mixins.", pstate);
372
- }
373
-
374
- }
375
359
  std::string which_str(lexed);
376
360
  if (!lex< identifier >()) error("invalid name in " + which_str + " definition", pstate);
377
361
  std::string name(Util::normalize_underscores(lexed));
378
362
  if (which_type == Definition::FUNCTION && (name == "and" || name == "or" || name == "not"))
379
363
  { error("Invalid function name \"" + name + "\".", pstate); }
380
364
  ParserState source_position_of_def = pstate;
381
- Parameters* params = parse_parameters();
365
+ Parameters_Obj params = parse_parameters();
382
366
  if (which_type == Definition::MIXIN) stack.push_back(Scope::Mixin);
383
367
  else stack.push_back(Scope::Function);
384
- Block* body = parse_block();
368
+ Block_Obj body = parse_block();
385
369
  stack.pop_back();
386
- Definition* def = SASS_MEMORY_NEW(ctx.mem, Definition, source_position_of_def, name, params, body, which_type);
387
- return def;
370
+ return SASS_MEMORY_NEW(Definition, source_position_of_def, name, &params, &body, which_type);
388
371
  }
389
372
 
390
- Parameters* Parser::parse_parameters()
373
+ Parameters_Obj Parser::parse_parameters()
391
374
  {
392
375
  std::string name(lexed);
393
376
  Position position = after_token;
394
- Parameters* params = SASS_MEMORY_NEW(ctx.mem, Parameters, pstate);
377
+ Parameters_Obj params = SASS_MEMORY_NEW(Parameters, pstate);
395
378
  if (lex_css< exactly<'('> >()) {
396
379
  // if there's anything there at all
397
380
  if (!peek_css< exactly<')'> >()) {
398
- do (*params) << parse_parameter();
381
+ do params->append(&parse_parameter());
399
382
  while (lex_css< exactly<','> >());
400
383
  }
401
384
  if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
@@ -403,13 +386,13 @@ namespace Sass {
403
386
  return params;
404
387
  }
405
388
 
406
- Parameter* Parser::parse_parameter()
389
+ Parameter_Obj Parser::parse_parameter()
407
390
  {
408
391
  while (lex< alternatives < spaces, block_comment > >());
409
392
  lex < variable >();
410
393
  std::string name(Util::normalize_underscores(lexed));
411
394
  ParserState pos = pstate;
412
- Expression* val = 0;
395
+ Expression_Obj val;
413
396
  bool is_rest = false;
414
397
  while (lex< alternatives < spaces, block_comment > >());
415
398
  if (lex< exactly<':'> >()) { // there's a default value
@@ -419,19 +402,18 @@ namespace Sass {
419
402
  else if (lex< exactly< ellipsis > >()) {
420
403
  is_rest = true;
421
404
  }
422
- Parameter* p = SASS_MEMORY_NEW(ctx.mem, Parameter, pos, name, val, is_rest);
423
- return p;
405
+ return SASS_MEMORY_NEW(Parameter, pos, name, &val, is_rest);
424
406
  }
425
407
 
426
- Arguments* Parser::parse_arguments()
408
+ Arguments_Obj Parser::parse_arguments()
427
409
  {
428
410
  std::string name(lexed);
429
411
  Position position = after_token;
430
- Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, pstate);
412
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
431
413
  if (lex_css< exactly<'('> >()) {
432
414
  // if there's anything there at all
433
415
  if (!peek_css< exactly<')'> >()) {
434
- do (*args) << parse_argument();
416
+ do args->append(&parse_argument());
435
417
  while (lex_css< exactly<','> >());
436
418
  }
437
419
  if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
@@ -439,39 +421,39 @@ namespace Sass {
439
421
  return args;
440
422
  }
441
423
 
442
- Argument* Parser::parse_argument()
424
+ Argument_Obj Parser::parse_argument()
443
425
  {
444
426
  if (peek_css< sequence < exactly< hash_lbrace >, exactly< rbrace > > >()) {
445
427
  position += 2;
446
428
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
447
429
  }
448
430
 
449
- Argument* arg;
431
+ Argument_Obj arg;
450
432
  if (peek_css< sequence < variable, optional_css_comments, exactly<':'> > >()) {
451
433
  lex_css< variable >();
452
434
  std::string name(Util::normalize_underscores(lexed));
453
435
  ParserState p = pstate;
454
436
  lex_css< exactly<':'> >();
455
- Expression* val = parse_space_list();
456
- arg = SASS_MEMORY_NEW(ctx.mem, Argument, p, val, name);
437
+ Expression_Obj val = parse_space_list();
438
+ arg = SASS_MEMORY_NEW(Argument, p, val, name);
457
439
  }
458
440
  else {
459
441
  bool is_arglist = false;
460
442
  bool is_keyword = false;
461
- Expression* val = parse_space_list();
462
- List* l = dynamic_cast<List*>(val);
443
+ Expression_Obj val = parse_space_list();
444
+ List_Ptr l = SASS_MEMORY_CAST(List, val);
463
445
  if (lex_css< exactly< ellipsis > >()) {
464
446
  if (val->concrete_type() == Expression::MAP || (
465
447
  (l != NULL && l->separator() == SASS_HASH)
466
448
  )) is_keyword = true;
467
449
  else is_arglist = true;
468
450
  }
469
- arg = SASS_MEMORY_NEW(ctx.mem, Argument, pstate, val, "", is_arglist, is_keyword);
451
+ arg = SASS_MEMORY_NEW(Argument, pstate, val, "", is_arglist, is_keyword);
470
452
  }
471
453
  return arg;
472
454
  }
473
455
 
474
- Assignment* Parser::parse_assignment()
456
+ Assignment_Obj Parser::parse_assignment()
475
457
  {
476
458
  std::string name(Util::normalize_underscores(lexed));
477
459
  ParserState var_source_position = pstate;
@@ -479,10 +461,10 @@ namespace Sass {
479
461
  if (peek_css< alternatives < exactly<';'>, end_of_file > >()) {
480
462
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
481
463
  }
482
- Expression* val;
464
+ Expression_Obj val;
483
465
  Lookahead lookahead = lookahead_for_value(position);
484
466
  if (lookahead.has_interpolants && lookahead.found) {
485
- val = parse_value_schema(lookahead.found);
467
+ val = &parse_value_schema(lookahead.found);
486
468
  } else {
487
469
  val = parse_list();
488
470
  }
@@ -492,26 +474,26 @@ namespace Sass {
492
474
  if (lex< default_flag >()) is_default = true;
493
475
  else if (lex< global_flag >()) is_global = true;
494
476
  }
495
- Assignment* var = SASS_MEMORY_NEW(ctx.mem, Assignment, var_source_position, name, val, is_default, is_global);
496
- return var;
477
+ return SASS_MEMORY_NEW(Assignment, var_source_position, name, val, is_default, is_global);
497
478
  }
498
479
 
499
480
  // a ruleset connects a selector and a block
500
- Ruleset* Parser::parse_ruleset(Lookahead lookahead, bool is_root)
481
+ Ruleset_Obj Parser::parse_ruleset(Lookahead lookahead, bool is_root)
501
482
  {
502
483
  // make sure to move up the the last position
503
484
  lex < optional_css_whitespace >(false, true);
504
485
  // create the connector object (add parts later)
505
- Ruleset* ruleset = SASS_MEMORY_NEW(ctx.mem, Ruleset, pstate);
486
+ Ruleset_Obj ruleset = SASS_MEMORY_NEW(Ruleset, pstate);
506
487
  // parse selector static or as schema to be evaluated later
507
- if (lookahead.parsable) ruleset->selector(parse_selector_list(is_root));
508
- else ruleset->selector(parse_selector_schema(lookahead.found));
488
+ if (lookahead.parsable) ruleset->selector(&parse_selector_list(is_root));
489
+ else ruleset->selector(&parse_selector_schema(lookahead.found));
509
490
  // then parse the inner block
510
491
  stack.push_back(Scope::Rules);
511
492
  ruleset->block(parse_block());
512
493
  stack.pop_back();
513
494
  // update for end position
514
495
  ruleset->update_pstate(pstate);
496
+ ruleset->block()->update_pstate(pstate);
515
497
  // inherit is_root from parent block
516
498
  // need this info for sanity checks
517
499
  ruleset->is_root(is_root);
@@ -522,15 +504,15 @@ namespace Sass {
522
504
  // parse a selector schema that will be evaluated in the eval stage
523
505
  // uses a string schema internally to do the actual schema handling
524
506
  // in the eval stage we will be re-parse it into an actual selector
525
- Selector_Schema* Parser::parse_selector_schema(const char* end_of_selector)
507
+ Selector_Schema_Obj Parser::parse_selector_schema(const char* end_of_selector)
526
508
  {
527
509
  // move up to the start
528
510
  lex< optional_spaces >();
529
511
  const char* i = position;
530
512
  // selector schema re-uses string schema implementation
531
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
513
+ String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
532
514
  // the selector schema is pretty much just a wrapper for the string schema
533
- Selector_Schema* selector_schema = SASS_MEMORY_NEW(ctx.mem, Selector_Schema, pstate, schema);
515
+ Selector_Schema_Ptr selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
534
516
  selector_schema->media_block(last_media_block);
535
517
 
536
518
  // process until end
@@ -538,7 +520,14 @@ namespace Sass {
538
520
  // try to parse mutliple interpolants
539
521
  if (const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, end_of_selector)) {
540
522
  // accumulate the preceding segment if the position has advanced
541
- if (i < p) (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, p));
523
+ if (i < p) {
524
+ std::string parsed(i, p);
525
+ String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
526
+ pstate += Offset(parsed);
527
+ str->update_pstate(pstate);
528
+ schema->append(&str);
529
+ }
530
+
542
531
  // check if the interpolation only contains white-space (error out)
543
532
  if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;
544
533
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
@@ -546,12 +535,15 @@ namespace Sass {
546
535
  // skip over all nested inner interpolations up to our own delimiter
547
536
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, end_of_selector);
548
537
  // pass inner expression to the parser to resolve nested interpolations
549
- Expression* interpolant = Parser::from_c_str(p+2, j, ctx, pstate).parse_list();
538
+ pstate.add(p, p+2);
539
+ Expression_Obj interpolant = Parser::from_c_str(p+2, j, ctx, pstate).parse_list();
550
540
  // set status on the list expression
551
541
  interpolant->is_interpolant(true);
552
542
  // schema->has_interpolants(true);
553
543
  // add to the string schema
554
- (*schema) << interpolant;
544
+ schema->append(&interpolant);
545
+ // advance parser state
546
+ pstate.add(p+2, j);
555
547
  // advance position
556
548
  i = j;
557
549
  }
@@ -559,9 +551,15 @@ namespace Sass {
559
551
  // add the last segment if there is one
560
552
  else {
561
553
  // make sure to add the last bits of the string up to the end (if any)
562
- if (i < end_of_selector) (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, end_of_selector));
554
+ if (i < end_of_selector) {
555
+ std::string parsed(i, end_of_selector);
556
+ String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
557
+ pstate += Offset(parsed);
558
+ str->update_pstate(pstate);
559
+ i = end_of_selector;
560
+ schema->append(&str);
561
+ }
563
562
  // exit loop
564
- i = end_of_selector;
565
563
  }
566
564
  }
567
565
  // EO until eos
@@ -571,6 +569,9 @@ namespace Sass {
571
569
 
572
570
  // update for end position
573
571
  selector_schema->update_pstate(pstate);
572
+ schema->update_pstate(pstate);
573
+
574
+ after_token = before_token = pstate;
574
575
 
575
576
  // return parsed result
576
577
  return selector_schema;
@@ -589,14 +590,14 @@ namespace Sass {
589
590
  }
590
591
 
591
592
  // called after parsing `kwd_include_directive`
592
- Mixin_Call* Parser::parse_include_directive()
593
+ Mixin_Call_Obj Parser::parse_include_directive()
593
594
  {
594
595
  // lex identifier into `lexed` var
595
596
  lex_identifier(); // may error out
596
597
  // normalize underscores to hyphens
597
598
  std::string name(Util::normalize_underscores(lexed));
598
599
  // create the initial mixin call object
599
- Mixin_Call* call = SASS_MEMORY_NEW(ctx.mem, Mixin_Call, pstate, name, 0, 0);
600
+ Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, 0, 0);
600
601
  // parse mandatory arguments
601
602
  call->arguments(parse_arguments());
602
603
  // parse optional block
@@ -604,20 +605,19 @@ namespace Sass {
604
605
  call->block(parse_block());
605
606
  }
606
607
  // return ast node
607
- return call;
608
+ return call.detach();
608
609
  }
609
610
  // EO parse_include_directive
610
611
 
611
612
  // parse a list of complex selectors
612
613
  // this is the main entry point for most
613
- CommaSequence_Selector* Parser::parse_selector_list(bool in_root)
614
+ Selector_List_Obj Parser::parse_selector_list(bool in_root)
614
615
  {
615
616
  bool reloop = true;
616
617
  bool had_linefeed = false;
617
- Sequence_Selector* sel = 0;
618
- CommaSequence_Selector* group = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate);
618
+ Complex_Selector_Obj sel;
619
+ Selector_List_Obj group = SASS_MEMORY_NEW(Selector_List, pstate);
619
620
  group->media_block(last_media_block);
620
-
621
621
  do {
622
622
  reloop = false;
623
623
 
@@ -630,7 +630,7 @@ namespace Sass {
630
630
  // now parse the complex selector
631
631
  sel = parse_complex_selector(in_root);
632
632
 
633
- if (!sel) return group;
633
+ if (!sel) return group.detach();
634
634
 
635
635
  sel->has_line_feed(had_linefeed);
636
636
 
@@ -645,7 +645,7 @@ namespace Sass {
645
645
  had_linefeed = had_linefeed || peek_newline();
646
646
  // remember line break (also between some commas)
647
647
  }
648
- (*group) << sel;
648
+ group->append(sel);
649
649
  }
650
650
  while (reloop);
651
651
  while (lex_css< kwd_optional >()) {
@@ -654,7 +654,7 @@ namespace Sass {
654
654
  // update for end position
655
655
  group->update_pstate(pstate);
656
656
  if (sel) sel->last()->has_line_break(false);
657
- return group;
657
+ return group.detach();
658
658
  }
659
659
  // EO parse_selector_list
660
660
 
@@ -662,16 +662,16 @@ namespace Sass {
662
662
  // complex selector, with one of four combinator operations.
663
663
  // the compound selector (head) is optional, since the combinator
664
664
  // can come first in the whole selector sequence (like `> DIV').
665
- Sequence_Selector* Parser::parse_complex_selector(bool in_root)
665
+ Complex_Selector_Obj Parser::parse_complex_selector(bool in_root)
666
666
  {
667
667
 
668
- String* reference = 0;
668
+ String_Ptr reference = 0;
669
669
  lex < block_comment >();
670
-
671
- Sequence_Selector* sel = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate);
670
+ advanceToNextToken();
671
+ Complex_Selector_Obj sel = SASS_MEMORY_NEW(Complex_Selector, pstate);
672
672
 
673
673
  // parse the left hand side
674
- SimpleSequence_Selector* lhs = 0;
674
+ Compound_Selector_Obj lhs;
675
675
  // special case if it starts with combinator ([+~>])
676
676
  if (!peek_css< class_char < selector_combinator_ops > >()) {
677
677
  // parse the left hand side
@@ -682,27 +682,27 @@ namespace Sass {
682
682
  if (peek < end_of_file >()) return 0;
683
683
 
684
684
  // parse combinator between lhs and rhs
685
- Sequence_Selector::Combinator combinator;
686
- if (lex< exactly<'+'> >()) combinator = Sequence_Selector::ADJACENT_TO;
687
- else if (lex< exactly<'~'> >()) combinator = Sequence_Selector::PRECEDES;
688
- else if (lex< exactly<'>'> >()) combinator = Sequence_Selector::PARENT_OF;
685
+ Complex_Selector::Combinator combinator;
686
+ if (lex< exactly<'+'> >()) combinator = Complex_Selector::ADJACENT_TO;
687
+ else if (lex< exactly<'~'> >()) combinator = Complex_Selector::PRECEDES;
688
+ else if (lex< exactly<'>'> >()) combinator = Complex_Selector::PARENT_OF;
689
689
  else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
690
690
  // comments are allowed, but not spaces?
691
- combinator = Sequence_Selector::REFERENCE;
691
+ combinator = Complex_Selector::REFERENCE;
692
692
  if (!lex < re_reference_combinator >()) return 0;
693
- reference = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
693
+ reference = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
694
694
  if (!lex < exactly < '/' > >()) return 0; // ToDo: error msg?
695
695
  }
696
- else /* if (lex< zero >()) */ combinator = Sequence_Selector::ANCESTOR_OF;
696
+ else /* if (lex< zero >()) */ combinator = Complex_Selector::ANCESTOR_OF;
697
697
 
698
- if (!lhs && combinator == Sequence_Selector::ANCESTOR_OF) return 0;
698
+ if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return 0;
699
699
 
700
700
  // lex < block_comment >();
701
701
  sel->head(lhs);
702
702
  sel->combinator(combinator);
703
703
  sel->media_block(last_media_block);
704
704
 
705
- if (combinator == Sequence_Selector::REFERENCE) sel->reference(reference);
705
+ if (combinator == Complex_Selector::REFERENCE) sel->reference(reference);
706
706
  // has linfeed after combinator?
707
707
  sel->has_line_break(peek_newline());
708
708
  // sel->has_line_feed(has_line_feed);
@@ -717,17 +717,17 @@ namespace Sass {
717
717
  // also skip adding parent ref if we only have refs
718
718
  if (!sel->has_parent_ref() && !in_at_root && !in_root) {
719
719
  // create the objects to wrap parent selector reference
720
- SimpleSequence_Selector* head = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, pstate);
721
- Parent_Selector* parent = SASS_MEMORY_NEW(ctx.mem, Parent_Selector, pstate, false);
720
+ Compound_Selector_Obj head = SASS_MEMORY_NEW(Compound_Selector, pstate);
721
+ Parent_Selector_Ptr parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false);
722
722
  parent->media_block(last_media_block);
723
723
  head->media_block(last_media_block);
724
724
  // add simple selector
725
- (*head) << parent;
725
+ head->append(parent);
726
726
  // selector may not have any head yet
727
727
  if (!sel->head()) { sel->head(head); }
728
728
  // otherwise we need to create a new complex selector and set the old one as its tail
729
729
  else {
730
- sel = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate, Sequence_Selector::ANCESTOR_OF, head, sel);
730
+ sel = SASS_MEMORY_NEW(Complex_Selector, pstate, Complex_Selector::ANCESTOR_OF, head, sel);
731
731
  sel->media_block(last_media_block);
732
732
  }
733
733
  // peek for linefeed and remember result on head
@@ -735,7 +735,6 @@ namespace Sass {
735
735
  }
736
736
 
737
737
  sel->update_pstate(pstate);
738
-
739
738
  // complex selector
740
739
  return sel;
741
740
  }
@@ -744,10 +743,10 @@ namespace Sass {
744
743
  // parse one compound selector, which is basically
745
744
  // a list of simple selectors (directly adjacent)
746
745
  // lex them exactly (without skipping white-space)
747
- SimpleSequence_Selector* Parser::parse_compound_selector()
746
+ Compound_Selector_Obj Parser::parse_compound_selector()
748
747
  {
749
748
  // init an empty compound selector wrapper
750
- SimpleSequence_Selector* seq = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, pstate);
749
+ Compound_Selector_Obj seq = SASS_MEMORY_NEW(Compound_Selector, pstate);
751
750
  seq->media_block(last_media_block);
752
751
 
753
752
  // skip initial white-space
@@ -761,20 +760,20 @@ namespace Sass {
761
760
  // parse functional
762
761
  if (match < re_pseudo_selector >())
763
762
  {
764
- (*seq) << parse_simple_selector();
763
+ seq->append(&parse_simple_selector());
765
764
  }
766
765
  // parse parent selector
767
766
  else if (lex< exactly<'&'> >(false))
768
767
  {
769
768
  // this produces a linefeed!?
770
769
  seq->has_parent_reference(true);
771
- (*seq) << SASS_MEMORY_NEW(ctx.mem, Parent_Selector, pstate);
770
+ seq->append(SASS_MEMORY_NEW(Parent_Selector, pstate));
772
771
  // parent selector only allowed at start
773
772
  // upcoming Sass may allow also trailing
774
773
  if (seq->length() > 1) {
775
774
  ParserState state(pstate);
776
- Simple_Selector* cur = (*seq)[seq->length()-1];
777
- Simple_Selector* prev = (*seq)[seq->length()-2];
775
+ Simple_Selector_Obj cur = (*seq)[seq->length()-1];
776
+ Simple_Selector_Obj prev = (*seq)[seq->length()-2];
778
777
  std::string sel(prev->to_string({ NESTED, 5 }));
779
778
  std::string found(cur->to_string({ NESTED, 5 }));
780
779
  if (lex < identifier >()) { found += std::string(lexed); }
@@ -785,7 +784,7 @@ namespace Sass {
785
784
  // parse type selector
786
785
  else if (lex< re_type_selector >(false))
787
786
  {
788
- (*seq) << SASS_MEMORY_NEW(ctx.mem, Element_Selector, pstate, lexed);
787
+ seq->append(SASS_MEMORY_NEW(Element_Selector, pstate, lexed));
789
788
  }
790
789
  // peek for abort conditions
791
790
  else if (peek< spaces >()) break;
@@ -794,9 +793,9 @@ namespace Sass {
794
793
  else if (peek_css < class_char < complex_selector_delims > >()) break;
795
794
  // otherwise parse another simple selector
796
795
  else {
797
- Simple_Selector* sel = parse_simple_selector();
796
+ Simple_Selector_Obj sel = parse_simple_selector();
798
797
  if (!sel) return 0;
799
- (*seq) << sel;
798
+ seq->append(&sel);
800
799
  }
801
800
  }
802
801
 
@@ -810,35 +809,35 @@ namespace Sass {
810
809
  }
811
810
  // EO parse_compound_selector
812
811
 
813
- Simple_Selector* Parser::parse_simple_selector()
812
+ Simple_Selector_Obj Parser::parse_simple_selector()
814
813
  {
815
814
  lex < css_comments >(false);
816
815
  if (lex< class_name >()) {
817
- return SASS_MEMORY_NEW(ctx.mem, Class_Selector, pstate, lexed);
816
+ return SASS_MEMORY_NEW(Class_Selector, pstate, lexed);
818
817
  }
819
818
  else if (lex< id_name >()) {
820
- return SASS_MEMORY_NEW(ctx.mem, Id_Selector, pstate, lexed);
819
+ return SASS_MEMORY_NEW(Id_Selector, pstate, lexed);
821
820
  }
822
821
  else if (lex< quoted_string >()) {
823
- return SASS_MEMORY_NEW(ctx.mem, Element_Selector, pstate, unquote(lexed));
822
+ return SASS_MEMORY_NEW(Element_Selector, pstate, unquote(lexed));
824
823
  }
825
824
  else if (lex< alternatives < variable, number, static_reference_combinator > >()) {
826
- return SASS_MEMORY_NEW(ctx.mem, Element_Selector, pstate, lexed);
825
+ return SASS_MEMORY_NEW(Element_Selector, pstate, lexed);
827
826
  }
828
827
  else if (peek< pseudo_not >()) {
829
- return parse_negated_selector();
828
+ return &parse_negated_selector();
830
829
  }
831
830
  else if (peek< re_pseudo_selector >()) {
832
- return parse_pseudo_selector();
831
+ return &parse_pseudo_selector();
833
832
  }
834
833
  else if (peek< exactly<':'> >()) {
835
- return parse_pseudo_selector();
834
+ return &parse_pseudo_selector();
836
835
  }
837
836
  else if (lex < exactly<'['> >()) {
838
- return parse_attribute_selector();
837
+ return &parse_attribute_selector();
839
838
  }
840
839
  else if (lex< placeholder >()) {
841
- Placeholder_Selector* sel = SASS_MEMORY_NEW(ctx.mem, Placeholder_Selector, pstate, lexed);
840
+ Placeholder_Selector_Ptr sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
842
841
  sel->media_block(last_media_block);
843
842
  return sel;
844
843
  }
@@ -846,22 +845,22 @@ namespace Sass {
846
845
  return 0;
847
846
  }
848
847
 
849
- Wrapped_Selector* Parser::parse_negated_selector()
848
+ Wrapped_Selector_Obj Parser::parse_negated_selector()
850
849
  {
851
850
  lex< pseudo_not >();
852
851
  std::string name(lexed);
853
852
  ParserState nsource_position = pstate;
854
- Selector* negated = parse_selector_list(true);
853
+ Selector_List_Obj negated = parse_selector_list(true);
855
854
  if (!lex< exactly<')'> >()) {
856
855
  error("negated selector is missing ')'", pstate);
857
856
  }
858
857
  name.erase(name.size() - 1);
859
- return SASS_MEMORY_NEW(ctx.mem, Wrapped_Selector, nsource_position, name, negated);
858
+ return SASS_MEMORY_NEW(Wrapped_Selector, nsource_position, name, &negated);
860
859
  }
861
860
 
862
861
  // a pseudo selector often starts with one or two colons
863
862
  // it can contain more selectors inside parentheses
864
- Simple_Selector* Parser::parse_pseudo_selector() {
863
+ Simple_Selector_Obj Parser::parse_pseudo_selector() {
865
864
  if (lex< sequence<
866
865
  optional < pseudo_prefix >,
867
866
  // we keep the space within the name, strange enough
@@ -889,15 +888,15 @@ namespace Sass {
889
888
  >()
890
889
  ) {
891
890
  lex_css< alternatives < static_value, binomial > >();
892
- String_Constant* expr = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
891
+ String_Constant_Ptr expr = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
893
892
  if (expr && lex_css< exactly<')'> >()) {
894
893
  expr->can_compress_whitespace(true);
895
- return SASS_MEMORY_NEW(ctx.mem, Pseudo_Selector, p, name, expr);
894
+ return SASS_MEMORY_NEW(Pseudo_Selector, p, name, expr);
896
895
  }
897
896
  }
898
- else if (Selector* wrapped = parse_selector_list(true)) {
897
+ else if (Selector_List_Obj wrapped = parse_selector_list(true)) {
899
898
  if (wrapped && lex_css< exactly<')'> >()) {
900
- return SASS_MEMORY_NEW(ctx.mem, Wrapped_Selector, p, name, wrapped);
899
+ return SASS_MEMORY_NEW(Wrapped_Selector, p, name, &wrapped);
901
900
  }
902
901
  }
903
902
 
@@ -905,7 +904,7 @@ namespace Sass {
905
904
  // EO if pseudo selector
906
905
 
907
906
  else if (lex < sequence< optional < pseudo_prefix >, identifier > >()) {
908
- return SASS_MEMORY_NEW(ctx.mem, Pseudo_Selector, pstate, lexed);
907
+ return SASS_MEMORY_NEW(Pseudo_Selector, pstate, lexed);
909
908
  }
910
909
  else if(lex < pseudo_prefix >()) {
911
910
  css_error("Invalid CSS", " after ", ": expected pseudoclass or pseudoelement, was ");
@@ -917,52 +916,53 @@ namespace Sass {
917
916
  return 0;
918
917
  }
919
918
 
920
- Attribute_Selector* Parser::parse_attribute_selector()
919
+ Attribute_Selector_Obj Parser::parse_attribute_selector()
921
920
  {
922
921
  ParserState p = pstate;
923
922
  if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector", pstate);
924
923
  std::string name(lexed);
925
- if (lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) return SASS_MEMORY_NEW(ctx.mem, Attribute_Selector, p, name, "", 0);
924
+ if (lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", 0);
926
925
  if (!lex_css< alternatives< exact_match, class_match, dash_match,
927
926
  prefix_match, suffix_match, substring_match > >()) {
928
927
  error("invalid operator in attribute selector for " + name, pstate);
929
928
  }
930
929
  std::string matcher(lexed);
931
930
 
932
- String* value = 0;
931
+ String_Obj value = 0;
933
932
  if (lex_css< identifier >()) {
934
- value = SASS_MEMORY_NEW(ctx.mem, String_Constant, p, lexed);
933
+ value = SASS_MEMORY_NEW(String_Constant, p, lexed);
935
934
  }
936
935
  else if (lex_css< quoted_string >()) {
937
- value = parse_interpolated_chunk(lexed, true); // needed!
936
+ value = &parse_interpolated_chunk(lexed, true); // needed!
938
937
  }
939
938
  else {
940
939
  error("expected a string constant or identifier in attribute selector for " + name, pstate);
941
940
  }
942
941
 
943
942
  if (!lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) error("unterminated attribute selector for " + name, pstate);
944
- return SASS_MEMORY_NEW(ctx.mem, Attribute_Selector, p, name, matcher, value);
943
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value);
945
944
  }
946
945
 
947
946
  /* parse block comment and add to block */
948
947
  void Parser::parse_block_comments()
949
948
  {
950
- Block* block = block_stack.back();
949
+ Block_Obj block = block_stack.back();
950
+
951
951
  while (lex< block_comment >()) {
952
952
  bool is_important = lexed.begin[2] == '!';
953
953
  // flag on second param is to skip loosely over comments
954
- String* contents = parse_interpolated_chunk(lexed, true);
955
- (*block) << SASS_MEMORY_NEW(ctx.mem, Comment, pstate, contents, is_important);
954
+ String_Obj contents = parse_interpolated_chunk(lexed, true);
955
+ block->append(SASS_MEMORY_NEW(Comment, pstate, contents, is_important));
956
956
  }
957
957
  }
958
958
 
959
- Declaration* Parser::parse_declaration() {
960
- String* prop = 0;
959
+ Declaration_Obj Parser::parse_declaration() {
960
+ String_Obj prop;
961
961
  if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
962
962
  prop = parse_identifier_schema();
963
963
  }
964
964
  else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) {
965
- prop = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
965
+ prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
966
966
  }
967
967
  else {
968
968
  css_error("Invalid CSS", " after ", ": expected \"}\", was ");
@@ -974,29 +974,30 @@ namespace Sass {
974
974
  if (peek_css< exactly<';'> >()) error("style declaration must contain a value", pstate);
975
975
  if (peek_css< exactly<'{'> >()) is_indented = false; // don't indent if value is empty
976
976
  if (peek_css< static_value >()) {
977
- return SASS_MEMORY_NEW(ctx.mem, Declaration, prop->pstate(), prop, parse_static_value()/*, lex<kwd_important>()*/);
977
+ return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, &parse_static_value()/*, lex<kwd_important>()*/);
978
978
  }
979
979
  else {
980
- Expression* value;
980
+ Expression_Obj value;
981
981
  Lookahead lookahead = lookahead_for_value(position);
982
982
  if (lookahead.found) {
983
983
  if (lookahead.has_interpolants) {
984
- value = parse_value_schema(lookahead.found);
984
+ value = &parse_value_schema(lookahead.found);
985
985
  } else {
986
- value = parse_list(DELAYED);
986
+ value = &parse_list(DELAYED);
987
987
  }
988
988
  }
989
989
  else {
990
- value = parse_list(DELAYED);
991
- if (List* list = dynamic_cast<List*>(value)) {
990
+ value = &parse_list(DELAYED);
991
+ if (List_Ptr list = SASS_MEMORY_CAST(List, value)) {
992
992
  if (list->length() == 0 && !peek< exactly <'{'> >()) {
993
993
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
994
994
  }
995
995
  }
996
996
  }
997
997
  lex < css_comments >(false);
998
- auto decl = SASS_MEMORY_NEW(ctx.mem, Declaration, prop->pstate(), prop, value/*, lex<kwd_important>()*/);
998
+ Declaration_Obj decl = SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, value/*, lex<kwd_important>()*/);
999
999
  decl->is_indented(is_indented);
1000
+ decl->update_pstate(pstate);
1000
1001
  return decl;
1001
1002
  }
1002
1003
  }
@@ -1017,28 +1018,19 @@ namespace Sass {
1017
1018
  return positive;
1018
1019
  }
1019
1020
 
1020
- Expression* Parser::parse_map()
1021
+ Expression_Obj Parser::parse_map()
1021
1022
  {
1022
- Expression* key = parse_list();
1023
- List* map = SASS_MEMORY_NEW(ctx.mem, List, pstate, 0, SASS_HASH);
1024
- if (String_Quoted* str = dynamic_cast<String_Quoted*>(key)) {
1025
- if (!str->quote_mark() && !str->is_delayed()) {
1026
- if (const Color* col = name_to_color(str->value())) {
1027
- Color* c = SASS_MEMORY_NEW(ctx.mem, Color, *col);
1028
- c->pstate(str->pstate());
1029
- c->disp(str->value());
1030
- key = c;
1031
- }
1032
- }
1033
- }
1023
+ Expression_Obj key = parse_list();
1024
+ List_Obj map = SASS_MEMORY_NEW(List, pstate, 0, SASS_HASH);
1034
1025
 
1035
1026
  // it's not a map so return the lexed value as a list value
1036
1027
  if (!lex_css< exactly<':'> >())
1037
1028
  { return key; }
1038
1029
 
1039
- Expression* value = parse_space_list();
1030
+ Expression_Obj value = parse_space_list();
1040
1031
 
1041
- (*map) << key << value;
1032
+ map->append(key);
1033
+ map->append(value);
1042
1034
 
1043
1035
  while (lex_css< exactly<','> >())
1044
1036
  {
@@ -1046,43 +1038,34 @@ namespace Sass {
1046
1038
  if (peek_css< exactly<')'> >(position))
1047
1039
  { break; }
1048
1040
 
1049
- Expression* key = parse_space_list();
1050
- if (String_Quoted* str = dynamic_cast<String_Quoted*>(key)) {
1051
- if (!str->quote_mark() && !str->is_delayed()) {
1052
- if (const Color* col = name_to_color(str->value())) {
1053
- Color* c = SASS_MEMORY_NEW(ctx.mem, Color, *col);
1054
- c->pstate(str->pstate());
1055
- c->disp(str->value());
1056
- key = c;
1057
- }
1058
- }
1059
- }
1041
+ Expression_Obj key = parse_space_list();
1060
1042
 
1061
1043
  if (!(lex< exactly<':'> >()))
1062
1044
  { css_error("Invalid CSS", " after ", ": expected \":\", was "); }
1063
1045
 
1064
- Expression* value = parse_space_list();
1046
+ Expression_Obj value = parse_space_list();
1065
1047
 
1066
- (*map) << key << value;
1048
+ map->append(key);
1049
+ map->append(value);
1067
1050
  }
1068
1051
 
1069
1052
  ParserState ps = map->pstate();
1070
1053
  ps.offset = pstate - ps + pstate.offset;
1071
1054
  map->pstate(ps);
1072
1055
 
1073
- return map;
1056
+ return &map;
1074
1057
  }
1075
1058
 
1076
1059
  // parse list returns either a space separated list,
1077
1060
  // a comma separated list or any bare expression found.
1078
1061
  // so to speak: we unwrap items from lists if possible here!
1079
- Expression* Parser::parse_list(bool delayed)
1062
+ Expression_Obj Parser::parse_list(bool delayed)
1080
1063
  {
1081
1064
  return parse_comma_list(delayed);
1082
1065
  }
1083
1066
 
1084
1067
  // will return singletons unwrapped
1085
- Expression* Parser::parse_comma_list(bool delayed)
1068
+ Expression_Obj Parser::parse_comma_list(bool delayed)
1086
1069
  {
1087
1070
  // check if we have an empty list
1088
1071
  // return the empty list as such
@@ -1100,11 +1083,11 @@ namespace Sass {
1100
1083
  > >(position))
1101
1084
  {
1102
1085
  // return an empty list (nothing to delay)
1103
- return SASS_MEMORY_NEW(ctx.mem, List, pstate, 0);
1086
+ return SASS_MEMORY_NEW(List, pstate, 0);
1104
1087
  }
1105
1088
 
1106
1089
  // now try to parse a space list
1107
- Expression* list = parse_space_list();
1090
+ Expression_Obj list = parse_space_list();
1108
1091
  // if it's a singleton, return it (don't wrap it)
1109
1092
  if (!peek_css< exactly<','> >(position)) {
1110
1093
  // set_delay doesn't apply to list children
@@ -1114,9 +1097,9 @@ namespace Sass {
1114
1097
  }
1115
1098
 
1116
1099
  // if we got so far, we actually do have a comma list
1117
- List* comma_list = SASS_MEMORY_NEW(ctx.mem, List, pstate, 2, SASS_COMMA);
1100
+ List_Obj comma_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA);
1118
1101
  // wrap the first expression
1119
- (*comma_list) << list;
1102
+ comma_list->append(list);
1120
1103
 
1121
1104
  while (lex_css< exactly<','> >())
1122
1105
  {
@@ -1134,17 +1117,17 @@ namespace Sass {
1134
1117
  > >(position)
1135
1118
  ) { break; }
1136
1119
  // otherwise add another expression
1137
- (*comma_list) << parse_space_list();
1120
+ comma_list->append(parse_space_list());
1138
1121
  }
1139
1122
  // return the list
1140
- return comma_list;
1123
+ return &comma_list;
1141
1124
  }
1142
1125
  // EO parse_comma_list
1143
1126
 
1144
1127
  // will return singletons unwrapped
1145
- Expression* Parser::parse_space_list()
1128
+ Expression_Obj Parser::parse_space_list()
1146
1129
  {
1147
- Expression* disj1 = parse_disjunction();
1130
+ Expression_Obj disj1 = parse_disjunction();
1148
1131
  // if it's a singleton, return it (don't wrap it)
1149
1132
  if (peek_css< alternatives <
1150
1133
  // exactly<'!'>,
@@ -1161,8 +1144,8 @@ namespace Sass {
1161
1144
  > >(position)
1162
1145
  ) { return disj1; }
1163
1146
 
1164
- List* space_list = SASS_MEMORY_NEW(ctx.mem, List, pstate, 2, SASS_SPACE);
1165
- (*space_list) << disj1;
1147
+ List_Obj space_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_SPACE);
1148
+ space_list->append(disj1);
1166
1149
 
1167
1150
  while (!(peek_css< alternatives <
1168
1151
  // exactly<'!'>,
@@ -1179,28 +1162,28 @@ namespace Sass {
1179
1162
  > >(position)) && peek_css< optional_css_whitespace >() != end
1180
1163
  ) {
1181
1164
  // the space is parsed implicitly?
1182
- (*space_list) << parse_disjunction();
1165
+ space_list->append(parse_disjunction());
1183
1166
  }
1184
1167
  // return the list
1185
- return space_list;
1168
+ return &space_list;
1186
1169
  }
1187
1170
  // EO parse_space_list
1188
1171
 
1189
1172
  // parse logical OR operation
1190
- Expression* Parser::parse_disjunction()
1173
+ Expression_Obj Parser::parse_disjunction()
1191
1174
  {
1192
1175
  advanceToNextToken();
1193
1176
  ParserState state(pstate);
1194
1177
  // parse the left hand side conjunction
1195
- Expression* conj = parse_conjunction();
1178
+ Expression_Obj conj = parse_conjunction();
1196
1179
  // parse multiple right hand sides
1197
- std::vector<Expression*> operands;
1180
+ std::vector<Expression_Obj> operands;
1198
1181
  while (lex_css< kwd_or >())
1199
1182
  operands.push_back(parse_conjunction());
1200
1183
  // if it's a singleton, return it directly
1201
1184
  if (operands.size() == 0) return conj;
1202
1185
  // fold all operands into one binary expression
1203
- Expression* ex = fold_operands(conj, operands, { Sass_OP::OR });
1186
+ Expression_Obj ex = fold_operands(conj, operands, { Sass_OP::OR });
1204
1187
  state.offset = pstate - state + pstate.offset;
1205
1188
  ex->pstate(state);
1206
1189
  return ex;
@@ -1208,20 +1191,21 @@ namespace Sass {
1208
1191
  // EO parse_disjunction
1209
1192
 
1210
1193
  // parse logical AND operation
1211
- Expression* Parser::parse_conjunction()
1194
+ Expression_Obj Parser::parse_conjunction()
1212
1195
  {
1213
1196
  advanceToNextToken();
1214
1197
  ParserState state(pstate);
1215
1198
  // parse the left hand side relation
1216
- Expression* rel = parse_relation();
1199
+ Expression_Obj rel = parse_relation();
1217
1200
  // parse multiple right hand sides
1218
- std::vector<Expression*> operands;
1219
- while (lex_css< kwd_and >())
1220
- operands.push_back(parse_relation());
1201
+ std::vector<Expression_Obj> operands;
1202
+ while (lex_css< kwd_and >()) {
1203
+ operands.push_back(&parse_relation());
1204
+ }
1221
1205
  // if it's a singleton, return it directly
1222
1206
  if (operands.size() == 0) return rel;
1223
1207
  // fold all operands into one binary expression
1224
- Expression* ex = fold_operands(rel, operands, { Sass_OP::AND });
1208
+ Expression_Obj ex = fold_operands(rel, operands, { Sass_OP::AND });
1225
1209
  state.offset = pstate - state + pstate.offset;
1226
1210
  ex->pstate(state);
1227
1211
  return ex;
@@ -1229,13 +1213,13 @@ namespace Sass {
1229
1213
  // EO parse_conjunction
1230
1214
 
1231
1215
  // parse comparison operations
1232
- Expression* Parser::parse_relation()
1216
+ Expression_Obj Parser::parse_relation()
1233
1217
  {
1234
1218
  advanceToNextToken();
1235
1219
  ParserState state(pstate);
1236
1220
  // parse the left hand side expression
1237
- Expression* lhs = parse_expression();
1238
- std::vector<Expression*> operands;
1221
+ Expression_Obj lhs = parse_expression();
1222
+ std::vector<Expression_Obj> operands;
1239
1223
  std::vector<Operand> operators;
1240
1224
  // if it's a singleton, return it (don't wrap it)
1241
1225
  while (peek< alternatives <
@@ -1262,7 +1246,7 @@ namespace Sass {
1262
1246
  // is directly adjacent to expression?
1263
1247
  bool right_ws = peek < css_comments >() != NULL;
1264
1248
  operators.push_back({ op, left_ws, right_ws });
1265
- operands.push_back(parse_expression());
1249
+ operands.push_back(&parse_expression());
1266
1250
  left_ws = peek < css_comments >() != NULL;
1267
1251
  }
1268
1252
  // we are called recursively for list, so we first
@@ -1270,7 +1254,7 @@ namespace Sass {
1270
1254
  // correctly set to zero. After folding we also unwrap
1271
1255
  // single nested items. So we cannot set delay on the
1272
1256
  // returned result here, as we have lost nestings ...
1273
- Expression* ex = fold_operands(lhs, operands, operators);
1257
+ Expression_Obj ex = fold_operands(lhs, operands, operators);
1274
1258
  state.offset = pstate - state + pstate.offset;
1275
1259
  ex->pstate(state);
1276
1260
  return ex;
@@ -1282,14 +1266,14 @@ namespace Sass {
1282
1266
  // called from parse_for_directive
1283
1267
  // called from parse_media_expression
1284
1268
  // parse addition and subtraction operations
1285
- Expression* Parser::parse_expression()
1269
+ Expression_Obj Parser::parse_expression()
1286
1270
  {
1287
1271
  advanceToNextToken();
1288
1272
  ParserState state(pstate);
1289
1273
  // parses multiple add and subtract operations
1290
1274
  // NOTE: make sure that identifiers starting with
1291
1275
  // NOTE: dashes do NOT count as subtract operation
1292
- Expression* lhs = parse_operators();
1276
+ Expression_Obj lhs = parse_operators();
1293
1277
  // if it's a singleton, return it (don't wrap it)
1294
1278
  if (!(peek_css< exactly<'+'> >(position) ||
1295
1279
  // condition is a bit misterious, but some combinations should not be counted as operations
@@ -1298,7 +1282,7 @@ namespace Sass {
1298
1282
  peek< sequence < zero_plus < exactly <'-' > >, identifier > >(position))
1299
1283
  { return lhs; }
1300
1284
 
1301
- std::vector<Expression*> operands;
1285
+ std::vector<Expression_Obj> operands;
1302
1286
  std::vector<Operand> operators;
1303
1287
  bool left_ws = peek < css_comments >() != NULL;
1304
1288
  while (
@@ -1313,25 +1297,25 @@ namespace Sass {
1313
1297
 
1314
1298
  bool right_ws = peek < css_comments >() != NULL;
1315
1299
  operators.push_back({ lexed.to_string() == "+" ? Sass_OP::ADD : Sass_OP::SUB, left_ws, right_ws });
1316
- operands.push_back(parse_operators());
1300
+ operands.push_back(&parse_operators());
1317
1301
  left_ws = peek < css_comments >() != NULL;
1318
1302
  }
1319
1303
 
1320
1304
  if (operands.size() == 0) return lhs;
1321
- Expression* ex = fold_operands(lhs, operands, operators);
1305
+ Expression_Obj ex = fold_operands(lhs, operands, operators);
1322
1306
  state.offset = pstate - state + pstate.offset;
1323
1307
  ex->pstate(state);
1324
1308
  return ex;
1325
1309
  }
1326
1310
 
1327
1311
  // parse addition and subtraction operations
1328
- Expression* Parser::parse_operators()
1312
+ Expression_Obj Parser::parse_operators()
1329
1313
  {
1330
1314
  advanceToNextToken();
1331
1315
  ParserState state(pstate);
1332
- Expression* factor = parse_factor();
1316
+ Expression_Obj factor = parse_factor();
1333
1317
  // if it's a singleton, return it (don't wrap it)
1334
- std::vector<Expression*> operands; // factors
1318
+ std::vector<Expression_Obj> operands; // factors
1335
1319
  std::vector<Operand> operators; // ops
1336
1320
  // lex operations to apply to lhs
1337
1321
  const char* left_ws = peek < css_comments >();
@@ -1347,7 +1331,7 @@ namespace Sass {
1347
1331
  left_ws = peek < css_comments >();
1348
1332
  }
1349
1333
  // operands and operators to binary expression
1350
- Expression* ex = fold_operands(factor, operands, operators);
1334
+ Expression_Obj ex = fold_operands(factor, operands, operators);
1351
1335
  state.offset = pstate - state + pstate.offset;
1352
1336
  ex->pstate(state);
1353
1337
  return ex;
@@ -1357,67 +1341,67 @@ namespace Sass {
1357
1341
 
1358
1342
  // called from parse_operators
1359
1343
  // called from parse_value_schema
1360
- Expression* Parser::parse_factor()
1344
+ Expression_Obj Parser::parse_factor()
1361
1345
  {
1362
1346
  lex < css_comments >(false);
1363
1347
  if (lex_css< exactly<'('> >()) {
1364
1348
  // parse_map may return a list
1365
- Expression* value = parse_map();
1349
+ Expression_Obj value = parse_map();
1366
1350
  // lex the expected closing parenthesis
1367
1351
  if (!lex_css< exactly<')'> >()) error("unclosed parenthesis", pstate);
1368
1352
  // expression can be evaluated
1369
- return value;
1353
+ return &value;
1370
1354
  }
1371
1355
  // string may be interpolated
1372
1356
  // if (lex< quoted_string >()) {
1373
- // return parse_string();
1357
+ // return &parse_string();
1374
1358
  // }
1375
1359
  else if (peek< ie_property >()) {
1376
- return parse_ie_property();
1360
+ return &parse_ie_property();
1377
1361
  }
1378
1362
  else if (peek< ie_keyword_arg >()) {
1379
- return parse_ie_keyword_arg();
1363
+ return &parse_ie_keyword_arg();
1380
1364
  }
1381
1365
  else if (peek< sequence < calc_fn_call, exactly <'('> > >()) {
1382
- return parse_calc_function();
1366
+ return &parse_calc_function();
1383
1367
  }
1384
1368
  else if (lex < functional_schema >()) {
1385
- return parse_function_call_schema();
1369
+ return &parse_function_call_schema();
1386
1370
  }
1387
1371
  else if (lex< identifier_schema >()) {
1388
- String* string = parse_identifier_schema();
1389
- if (String_Schema* schema = dynamic_cast<String_Schema*>(string)) {
1372
+ String_Obj string = parse_identifier_schema();
1373
+ if (String_Schema_Ptr schema = SASS_MEMORY_CAST(String_Schema, string)) {
1390
1374
  if (lex < exactly < '(' > >()) {
1391
- *schema << parse_list();
1375
+ schema->append(&parse_list());
1392
1376
  lex < exactly < ')' > >();
1393
1377
  }
1394
1378
  }
1395
- return string;
1379
+ return &string;
1396
1380
  }
1397
1381
  else if (peek< sequence< uri_prefix, W, real_uri_value > >()) {
1398
- return parse_url_function_string();
1382
+ return &parse_url_function_string();
1399
1383
  }
1400
1384
  else if (peek< re_functional >()) {
1401
- return parse_function_call();
1385
+ return &parse_function_call();
1402
1386
  }
1403
1387
  else if (lex< exactly<'+'> >()) {
1404
- Unary_Expression* ex = SASS_MEMORY_NEW(ctx.mem, Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());
1388
+ Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, &parse_factor());
1405
1389
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1406
1390
  return ex;
1407
1391
  }
1408
1392
  else if (lex< exactly<'-'> >()) {
1409
- Unary_Expression* ex = SASS_MEMORY_NEW(ctx.mem, Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());
1393
+ Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, &parse_factor());
1410
1394
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1411
1395
  return ex;
1412
1396
  }
1413
1397
  else if (lex< sequence< kwd_not > >()) {
1414
- Unary_Expression* ex = SASS_MEMORY_NEW(ctx.mem, Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());
1398
+ Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, &parse_factor());
1415
1399
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1416
1400
  return ex;
1417
1401
  }
1418
1402
  else if (peek < sequence < one_plus < alternatives < css_whitespace, exactly<'-'>, exactly<'+'> > >, number > >()) {
1419
- if (parse_number_prefix()) return parse_value(); // prefix is positive
1420
- Unary_Expression* ex = SASS_MEMORY_NEW(ctx.mem, Unary_Expression, pstate, Unary_Expression::MINUS, parse_value());;
1403
+ if (parse_number_prefix()) return &parse_value(); // prefix is positive
1404
+ Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, &parse_value());
1421
1405
  if (ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1422
1406
  return ex;
1423
1407
  }
@@ -1427,74 +1411,74 @@ namespace Sass {
1427
1411
  }
1428
1412
 
1429
1413
  // parse one value for a list
1430
- Expression* Parser::parse_value()
1414
+ Expression_Obj Parser::parse_value()
1431
1415
  {
1432
1416
  lex< css_comments >(false);
1433
1417
  if (lex< ampersand >())
1434
1418
  {
1435
- return SASS_MEMORY_NEW(ctx.mem, Parent_Selector, pstate); }
1419
+ return SASS_MEMORY_NEW(Parent_Selector, pstate); }
1436
1420
 
1437
1421
  if (lex< kwd_important >())
1438
- { return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, "!important"); }
1422
+ { return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); }
1439
1423
 
1440
1424
  // parse `10%4px` into separated items and not a schema
1441
1425
  if (lex< sequence < percentage, lookahead < number > > >())
1442
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::PERCENTAGE, lexed); }
1426
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed); }
1443
1427
 
1444
1428
  if (lex< sequence < number, lookahead< sequence < op, number > > > >())
1445
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::NUMBER, lexed); }
1429
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed); }
1446
1430
 
1447
1431
  // string may be interpolated
1448
1432
  if (lex< sequence < quoted_string, lookahead < exactly <'-'> > > >())
1449
- { return parse_string(); }
1433
+ { return &parse_string(); }
1450
1434
 
1451
1435
  if (const char* stop = peek< value_schema >())
1452
- { return parse_value_schema(stop); }
1436
+ { return &parse_value_schema(stop); }
1453
1437
 
1454
1438
  // string may be interpolated
1455
1439
  if (lex< quoted_string >())
1456
- { return parse_string(); }
1440
+ { return &parse_string(); }
1457
1441
 
1458
1442
  if (lex< kwd_true >())
1459
- { return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, true); }
1443
+ { return SASS_MEMORY_NEW(Boolean, pstate, true); }
1460
1444
 
1461
1445
  if (lex< kwd_false >())
1462
- { return SASS_MEMORY_NEW(ctx.mem, Boolean, pstate, false); }
1446
+ { return SASS_MEMORY_NEW(Boolean, pstate, false); }
1463
1447
 
1464
1448
  if (lex< kwd_null >())
1465
- { return SASS_MEMORY_NEW(ctx.mem, Null, pstate); }
1449
+ { return SASS_MEMORY_NEW(Null, pstate); }
1466
1450
 
1467
1451
  if (lex< identifier >()) {
1468
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1452
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1469
1453
  }
1470
1454
 
1471
1455
  if (lex< percentage >())
1472
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::PERCENTAGE, lexed); }
1456
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed); }
1473
1457
 
1474
1458
  // match hex number first because 0x000 looks like a number followed by an identifier
1475
1459
  if (lex< sequence < alternatives< hex, hex0 >, negate < exactly<'-'> > > >())
1476
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::HEX, lexed); }
1460
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::HEX, lexed); }
1477
1461
 
1478
1462
  if (lex< sequence < exactly <'#'>, identifier > >())
1479
- { return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, lexed); }
1463
+ { return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }
1480
1464
 
1481
1465
  // also handle the 10em- foo special case
1482
1466
  // alternatives < exactly < '.' >, .. > -- `1.5em-.75em` is split into a list, not a binary expression
1483
1467
  if (lex< sequence< dimension, optional< sequence< exactly<'-'>, lookahead< alternatives < space > > > > > >())
1484
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::DIMENSION, lexed); }
1468
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::DIMENSION, lexed); }
1485
1469
 
1486
1470
  if (lex< sequence< static_component, one_plus< strict_identifier > > >())
1487
- { return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed); }
1471
+ { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
1488
1472
 
1489
1473
  if (lex< number >())
1490
- { return SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::NUMBER, lexed); }
1474
+ { return SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed); }
1491
1475
 
1492
1476
  if (lex< variable >())
1493
- { return SASS_MEMORY_NEW(ctx.mem, Variable, pstate, Util::normalize_underscores(lexed)); }
1477
+ { return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }
1494
1478
 
1495
1479
  // Special case handling for `%` proceeding an interpolant.
1496
1480
  if (lex< sequence< exactly<'%'>, optional< percentage > > >())
1497
- { return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed); }
1481
+ { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
1498
1482
 
1499
1483
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1500
1484
 
@@ -1504,7 +1488,7 @@ namespace Sass {
1504
1488
 
1505
1489
  // this parses interpolation inside other strings
1506
1490
  // means the result should later be quoted again
1507
- String* Parser::parse_interpolated_chunk(Token chunk, bool constant)
1491
+ String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant)
1508
1492
  {
1509
1493
  const char* i = chunk.begin;
1510
1494
  // see if there any interpolants
@@ -1512,12 +1496,12 @@ namespace Sass {
1512
1496
  find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
1513
1497
 
1514
1498
  if (!p) {
1515
- String_Quoted* str_quoted = SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, std::string(i, chunk.end));
1499
+ String_Quoted_Ptr str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end));
1516
1500
  if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
1517
1501
  return str_quoted;
1518
1502
  }
1519
1503
 
1520
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
1504
+ String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
1521
1505
  schema->is_interpolant(true);
1522
1506
  while (i < chunk.end) {
1523
1507
  p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
@@ -1525,7 +1509,7 @@ namespace Sass {
1525
1509
  if (p) {
1526
1510
  if (i < p) {
1527
1511
  // accumulate the preceding segment if it's nonempty
1528
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, p));
1512
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p)));
1529
1513
  }
1530
1514
  // we need to skip anything inside strings
1531
1515
  // create a new target in parser/prelexer
@@ -1535,9 +1519,9 @@ namespace Sass {
1535
1519
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, chunk.end); // find the closing brace
1536
1520
  if (j) { --j;
1537
1521
  // parse the interpolant and accumulate it
1538
- Expression* interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list();
1522
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list();
1539
1523
  interp_node->is_interpolant(true);
1540
- (*schema) << interp_node;
1524
+ schema->append(&interp_node);
1541
1525
  i = j;
1542
1526
  }
1543
1527
  else {
@@ -1547,7 +1531,7 @@ namespace Sass {
1547
1531
  }
1548
1532
  else { // no interpolants left; add the last segment if nonempty
1549
1533
  // check if we need quotes here (was not sure after merge)
1550
- if (i < chunk.end) (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, chunk.end));
1534
+ if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end)));
1551
1535
  break;
1552
1536
  }
1553
1537
  ++ i;
@@ -1556,15 +1540,7 @@ namespace Sass {
1556
1540
  return schema;
1557
1541
  }
1558
1542
 
1559
- String_Constant* Parser::parse_static_expression()
1560
- {
1561
- if (peek< sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number > >()) {
1562
- return parse_static_value();
1563
- }
1564
- return 0;
1565
- }
1566
-
1567
- String_Constant* Parser::parse_static_value()
1543
+ String_Constant_Obj Parser::parse_static_value()
1568
1544
  {
1569
1545
  lex< static_value >();
1570
1546
  Token str(lexed);
@@ -1574,16 +1550,16 @@ namespace Sass {
1574
1550
  --str.end;
1575
1551
  --position;
1576
1552
 
1577
- String_Constant* str_node = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, str.time_wspace());
1553
+ String_Constant_Ptr str_node = SASS_MEMORY_NEW(String_Constant, pstate, str.time_wspace());
1578
1554
  return str_node;
1579
1555
  }
1580
1556
 
1581
- String* Parser::parse_string()
1557
+ String_Obj Parser::parse_string()
1582
1558
  {
1583
1559
  return parse_interpolated_chunk(Token(lexed));
1584
1560
  }
1585
1561
 
1586
- String* Parser::parse_ie_property()
1562
+ String_Obj Parser::parse_ie_property()
1587
1563
  {
1588
1564
  lex< ie_property >();
1589
1565
  Token str(lexed);
@@ -1591,15 +1567,15 @@ namespace Sass {
1591
1567
  // see if there any interpolants
1592
1568
  const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(str.begin, str.end);
1593
1569
  if (!p) {
1594
- return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, std::string(str.begin, str.end));
1570
+ return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end));
1595
1571
  }
1596
1572
 
1597
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
1573
+ String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
1598
1574
  while (i < str.end) {
1599
1575
  p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);
1600
1576
  if (p) {
1601
1577
  if (i < p) {
1602
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, p)); // accumulate the preceding segment if it's nonempty
1578
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p))); // accumulate the preceding segment if it's nonempty
1603
1579
  }
1604
1580
  if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;
1605
1581
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
@@ -1607,9 +1583,9 @@ namespace Sass {
1607
1583
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, str.end); // find the closing brace
1608
1584
  if (j) {
1609
1585
  // parse the interpolant and accumulate it
1610
- Expression* interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list();
1586
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list();
1611
1587
  interp_node->is_interpolant(true);
1612
- (*schema) << interp_node;
1588
+ schema->append(&interp_node);
1613
1589
  i = j;
1614
1590
  }
1615
1591
  else {
@@ -1619,7 +1595,7 @@ namespace Sass {
1619
1595
  }
1620
1596
  else { // no interpolants left; add the last segment if nonempty
1621
1597
  if (i < str.end) {
1622
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(i, str.end));
1598
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, str.end)));
1623
1599
  }
1624
1600
  break;
1625
1601
  }
@@ -1627,27 +1603,27 @@ namespace Sass {
1627
1603
  return schema;
1628
1604
  }
1629
1605
 
1630
- String* Parser::parse_ie_keyword_arg()
1606
+ String_Obj Parser::parse_ie_keyword_arg()
1631
1607
  {
1632
- String_Schema* kwd_arg = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate, 3);
1608
+ String_Schema_Ptr kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);
1633
1609
  if (lex< variable >()) {
1634
- *kwd_arg << SASS_MEMORY_NEW(ctx.mem, Variable, pstate, Util::normalize_underscores(lexed));
1610
+ kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)));
1635
1611
  } else {
1636
1612
  lex< alternatives< identifier_schema, identifier > >();
1637
- *kwd_arg << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1613
+ kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1638
1614
  }
1639
1615
  lex< exactly<'='> >();
1640
- *kwd_arg << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1641
- if (peek< variable >()) *kwd_arg << parse_list();
1642
- else if (lex< number >()) *kwd_arg << SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::NUMBER, Util::normalize_decimals(lexed));
1643
- else if (peek < ie_keyword_arg_value >()) { *kwd_arg << parse_list(); }
1616
+ kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1617
+ if (peek< variable >()) kwd_arg->append(&parse_list());
1618
+ else if (lex< number >()) kwd_arg->append(SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, Util::normalize_decimals(lexed)));
1619
+ else if (peek < ie_keyword_arg_value >()) { kwd_arg->append(&parse_list()); }
1644
1620
  return kwd_arg;
1645
1621
  }
1646
1622
 
1647
- String_Schema* Parser::parse_value_schema(const char* stop)
1623
+ String_Schema_Obj Parser::parse_value_schema(const char* stop)
1648
1624
  {
1649
1625
  // initialize the string schema object to add tokens
1650
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
1626
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1651
1627
 
1652
1628
  if (peek<exactly<'}'>>()) {
1653
1629
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
@@ -1665,10 +1641,10 @@ namespace Sass {
1665
1641
  }
1666
1642
  if (need_space) {
1667
1643
  need_space = false;
1668
- // (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
1644
+ // schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
1669
1645
  }
1670
1646
  if ((e = peek< re_functional >()) && e < stop) {
1671
- (*schema) << parse_function_call();
1647
+ schema->append(&parse_function_call());
1672
1648
  }
1673
1649
  // lex an interpolant /#{...}/
1674
1650
  else if (lex< exactly < hash_lbrace > >()) {
@@ -1676,35 +1652,36 @@ namespace Sass {
1676
1652
  if (peek< exactly< rbrace > >()) {
1677
1653
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1678
1654
  }
1679
- Expression* ex = 0;
1655
+ Expression_Obj ex = 0;
1680
1656
  if (lex< re_static_expression >()) {
1681
- ex = SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1657
+ ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1682
1658
  } else {
1683
1659
  ex = parse_list();
1684
1660
  }
1685
1661
  ex->is_interpolant(true);
1686
- (*schema) << ex;
1687
- // ToDo: no error check here?
1688
- lex < exactly < rbrace > >();
1662
+ schema->append(ex);
1663
+ if (!lex < exactly < rbrace > >()) {
1664
+ css_error("Invalid CSS", " after ", ": expected \"}\", was ");
1665
+ }
1689
1666
  }
1690
1667
  // lex some string constants or other valid token
1691
1668
  // Note: [-+] chars are left over from i.e. `#{3}+3`
1692
1669
  else if (lex< alternatives < exactly<'%'>, exactly < '-' >, exactly < '+' > > >()) {
1693
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1670
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1694
1671
  }
1695
1672
  // lex a quoted string
1696
1673
  else if (lex< quoted_string >()) {
1697
1674
  // need_space = true;
1698
- // if (schema->length()) (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
1675
+ // if (schema->length()) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
1699
1676
  // else need_space = true;
1700
- (*schema) << parse_string();
1677
+ schema->append(&parse_string());
1701
1678
  if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
1702
1679
  // need_space = true;
1703
1680
  }
1704
1681
  if (peek < exactly < '-' > >()) break;
1705
1682
  }
1706
1683
  else if (lex< sequence < identifier > >()) {
1707
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
1684
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1708
1685
  if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
1709
1686
  // need_space = true;
1710
1687
  }
@@ -1712,30 +1689,30 @@ namespace Sass {
1712
1689
  // lex (normalized) variable
1713
1690
  else if (lex< variable >()) {
1714
1691
  std::string name(Util::normalize_underscores(lexed));
1715
- (*schema) << SASS_MEMORY_NEW(ctx.mem, Variable, pstate, name);
1692
+ schema->append(SASS_MEMORY_NEW(Variable, pstate, name));
1716
1693
  }
1717
1694
  // lex percentage value
1718
1695
  else if (lex< percentage >()) {
1719
- (*schema) << SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::PERCENTAGE, lexed);
1696
+ schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed));
1720
1697
  }
1721
1698
  // lex dimension value
1722
1699
  else if (lex< dimension >()) {
1723
- (*schema) << SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::DIMENSION, lexed);
1700
+ schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::DIMENSION, lexed));
1724
1701
  }
1725
1702
  // lex number value
1726
1703
  else if (lex< number >()) {
1727
- (*schema) << SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::NUMBER, lexed);
1704
+ schema->append( SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed));
1728
1705
  }
1729
1706
  // lex hex color value
1730
1707
  else if (lex< sequence < hex, negate < exactly < '-' > > > >()) {
1731
- (*schema) << SASS_MEMORY_NEW(ctx.mem, Textual, pstate, Textual::HEX, lexed);
1708
+ schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::HEX, lexed));
1732
1709
  }
1733
1710
  else if (lex< sequence < exactly <'#'>, identifier > >()) {
1734
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, lexed);
1711
+ schema->append(SASS_MEMORY_NEW(String_Quoted, pstate, lexed));
1735
1712
  }
1736
1713
  // lex a value in parentheses
1737
1714
  else if (peek< parenthese_scope >()) {
1738
- (*schema) << parse_factor();
1715
+ schema->append(&parse_factor());
1739
1716
  }
1740
1717
  else {
1741
1718
  break;
@@ -1743,7 +1720,7 @@ namespace Sass {
1743
1720
  ++num_items;
1744
1721
  }
1745
1722
  if (position != stop) {
1746
- (*schema) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(position, stop));
1723
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(position, stop)));
1747
1724
  position = stop;
1748
1725
  }
1749
1726
  end = ee;
@@ -1752,24 +1729,24 @@ namespace Sass {
1752
1729
 
1753
1730
  // this parses interpolation outside other strings
1754
1731
  // means the result must not be quoted again later
1755
- String* Parser::parse_identifier_schema()
1732
+ String_Obj Parser::parse_identifier_schema()
1756
1733
  {
1757
1734
  Token id(lexed);
1758
1735
  const char* i = id.begin;
1759
1736
  // see if there any interpolants
1760
1737
  const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(id.begin, id.end);
1761
1738
  if (!p) {
1762
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, std::string(id.begin, id.end));
1739
+ return SASS_MEMORY_NEW(String_Constant, pstate, std::string(id.begin, id.end));
1763
1740
  }
1764
1741
 
1765
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
1742
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1766
1743
  while (i < id.end) {
1767
1744
  p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, id.end);
1768
1745
  if (p) {
1769
1746
  if (i < p) {
1770
1747
  // accumulate the preceding segment if it's nonempty
1771
1748
  const char* o = position; position = i;
1772
- *schema << parse_value_schema(p);
1749
+ schema->append(&parse_value_schema(p));
1773
1750
  position = o;
1774
1751
  }
1775
1752
  // we need to skip anything inside strings
@@ -1780,9 +1757,9 @@ namespace Sass {
1780
1757
  const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, id.end); // find the closing brace
1781
1758
  if (j) {
1782
1759
  // parse the interpolant and accumulate it
1783
- Expression* interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list(DELAYED);
1760
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list(DELAYED);
1784
1761
  interp_node->is_interpolant(true);
1785
- (*schema) << interp_node;
1762
+ schema->append(interp_node);
1786
1763
  // schema->has_interpolants(true);
1787
1764
  i = j;
1788
1765
  }
@@ -1794,17 +1771,17 @@ namespace Sass {
1794
1771
  else { // no interpolants left; add the last segment if nonempty
1795
1772
  if (i < end) {
1796
1773
  const char* o = position; position = i;
1797
- *schema << parse_value_schema(id.end);
1774
+ schema->append(&parse_value_schema(id.end));
1798
1775
  position = o;
1799
1776
  }
1800
1777
  break;
1801
1778
  }
1802
1779
  }
1803
- return schema;
1780
+ return schema ? schema.detach() : 0;
1804
1781
  }
1805
1782
 
1806
1783
  // calc functions should preserve arguments
1807
- Function_Call* Parser::parse_calc_function()
1784
+ Function_Call_Obj Parser::parse_calc_function()
1808
1785
  {
1809
1786
  lex< identifier >();
1810
1787
  std::string name(lexed);
@@ -1819,13 +1796,13 @@ namespace Sass {
1819
1796
  exactly < ')' >
1820
1797
  > >();
1821
1798
 
1822
- Argument* arg = SASS_MEMORY_NEW(ctx.mem, Argument, arg_pos, parse_interpolated_chunk(Token(arg_beg, arg_end)));
1823
- Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, arg_pos);
1824
- *args << arg;
1825
- return SASS_MEMORY_NEW(ctx.mem, Function_Call, call_pos, name, args);
1799
+ Argument_Obj arg = SASS_MEMORY_NEW(Argument, arg_pos, &parse_interpolated_chunk(Token(arg_beg, arg_end)));
1800
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, arg_pos);
1801
+ args->append(&arg);
1802
+ return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
1826
1803
  }
1827
1804
 
1828
- String* Parser::parse_url_function_string()
1805
+ String_Obj Parser::parse_url_function_string()
1829
1806
  {
1830
1807
  std::string prefix("");
1831
1808
  if (lex< uri_prefix >()) {
@@ -1833,7 +1810,7 @@ namespace Sass {
1833
1810
  }
1834
1811
 
1835
1812
  lex < optional_spaces >();
1836
- String* url_string = parse_url_function_argument();
1813
+ String_Obj url_string = parse_url_function_argument();
1837
1814
 
1838
1815
  std::string suffix("");
1839
1816
  if (lex< real_uri_suffix >()) {
@@ -1841,23 +1818,23 @@ namespace Sass {
1841
1818
  }
1842
1819
 
1843
1820
  std::string uri("");
1844
- if (url_string) {
1821
+ if (&url_string) {
1845
1822
  uri = url_string->to_string({ NESTED, 5 });
1846
1823
  }
1847
1824
 
1848
- if (String_Schema* schema = dynamic_cast<String_Schema*>(url_string)) {
1849
- String_Schema* res = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
1850
- (*res) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, prefix);
1851
- (*res) += schema;
1852
- (*res) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, suffix);
1853
- return res;
1825
+ if (String_Schema_Ptr schema = dynamic_cast<String_Schema_Ptr>(&url_string)) {
1826
+ String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate);
1827
+ res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix));
1828
+ res->append(schema);
1829
+ res->append(SASS_MEMORY_NEW(String_Constant, pstate, suffix));
1830
+ return &res;
1854
1831
  } else {
1855
1832
  std::string res = prefix + uri + suffix;
1856
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, res);
1833
+ return SASS_MEMORY_NEW(String_Constant, pstate, res);
1857
1834
  }
1858
1835
  }
1859
1836
 
1860
- String* Parser::parse_url_function_argument()
1837
+ String_Obj Parser::parse_url_function_argument()
1861
1838
  {
1862
1839
  const char* p = position;
1863
1840
 
@@ -1873,63 +1850,63 @@ namespace Sass {
1873
1850
  pp = sequence< interpolant, real_uri_value >(pp);
1874
1851
  }
1875
1852
  position = pp;
1876
- return parse_interpolated_chunk(Token(p, position));
1853
+ return &parse_interpolated_chunk(Token(p, position));
1877
1854
  }
1878
1855
  else if (uri != "") {
1879
1856
  std::string res = Util::rtrim(uri);
1880
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, res);
1857
+ return SASS_MEMORY_NEW(String_Constant, pstate, res);
1881
1858
  }
1882
1859
 
1883
1860
  return 0;
1884
1861
  }
1885
1862
 
1886
- Function_Call* Parser::parse_function_call()
1863
+ Function_Call_Obj Parser::parse_function_call()
1887
1864
  {
1888
1865
  lex< identifier >();
1889
1866
  std::string name(lexed);
1890
1867
 
1891
1868
  ParserState call_pos = pstate;
1892
- Arguments* args = parse_arguments();
1893
- return SASS_MEMORY_NEW(ctx.mem, Function_Call, call_pos, name, args);
1869
+ Arguments_Obj args = parse_arguments();
1870
+ return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
1894
1871
  }
1895
1872
 
1896
- Function_Call_Schema* Parser::parse_function_call_schema()
1873
+ Function_Call_Schema_Obj Parser::parse_function_call_schema()
1897
1874
  {
1898
- String* name = parse_identifier_schema();
1875
+ String_Obj name = parse_identifier_schema();
1899
1876
  ParserState source_position_of_call = pstate;
1877
+ Arguments_Obj args = parse_arguments();
1900
1878
 
1901
- Function_Call_Schema* the_call = SASS_MEMORY_NEW(ctx.mem, Function_Call_Schema, source_position_of_call, name, parse_arguments());
1902
- return the_call;
1879
+ return SASS_MEMORY_NEW(Function_Call_Schema, source_position_of_call, name, args);
1903
1880
  }
1904
1881
 
1905
- Content* Parser::parse_content_directive()
1882
+ Content_Obj Parser::parse_content_directive()
1906
1883
  {
1907
- return SASS_MEMORY_NEW(ctx.mem, Content, pstate);
1884
+ return SASS_MEMORY_NEW(Content, pstate);
1908
1885
  }
1909
1886
 
1910
- If* Parser::parse_if_directive(bool else_if)
1887
+ If_Obj Parser::parse_if_directive(bool else_if)
1911
1888
  {
1912
1889
  stack.push_back(Scope::Control);
1913
1890
  ParserState if_source_position = pstate;
1914
1891
  bool root = block_stack.back()->is_root();
1915
- Expression* predicate = parse_list();
1916
- Block* block = parse_block(root);
1917
- Block* alternative = 0;
1892
+ Expression_Obj predicate = parse_list();
1893
+ Block_Obj block = parse_block(root);
1894
+ Block_Obj alternative = NULL;
1918
1895
 
1919
1896
  // only throw away comment if we parse a case
1920
1897
  // we want all other comments to be parsed
1921
1898
  if (lex_css< elseif_directive >()) {
1922
- alternative = SASS_MEMORY_NEW(ctx.mem, Block, pstate);
1923
- (*alternative) << parse_if_directive(true);
1899
+ alternative = SASS_MEMORY_NEW(Block, pstate);
1900
+ alternative->append(&parse_if_directive(true));
1924
1901
  }
1925
1902
  else if (lex_css< kwd_else_directive >()) {
1926
- alternative = parse_block(root);
1903
+ alternative = &parse_block(root);
1927
1904
  }
1928
1905
  stack.pop_back();
1929
- return SASS_MEMORY_NEW(ctx.mem, If, if_source_position, predicate, block, alternative);
1906
+ return SASS_MEMORY_NEW(If, if_source_position, predicate, block, alternative);
1930
1907
  }
1931
1908
 
1932
- For* Parser::parse_for_directive()
1909
+ For_Obj Parser::parse_for_directive()
1933
1910
  {
1934
1911
  stack.push_back(Scope::Control);
1935
1912
  ParserState for_source_position = pstate;
@@ -1937,15 +1914,15 @@ namespace Sass {
1937
1914
  lex_variable();
1938
1915
  std::string var(Util::normalize_underscores(lexed));
1939
1916
  if (!lex< kwd_from >()) error("expected 'from' keyword in @for directive", pstate);
1940
- Expression* lower_bound = parse_expression();
1917
+ Expression_Obj lower_bound = parse_expression();
1941
1918
  bool inclusive = false;
1942
1919
  if (lex< kwd_through >()) inclusive = true;
1943
1920
  else if (lex< kwd_to >()) inclusive = false;
1944
1921
  else error("expected 'through' or 'to' keyword in @for directive", pstate);
1945
- Expression* upper_bound = parse_expression();
1946
- Block* body = parse_block(root);
1922
+ Expression_Obj upper_bound = parse_expression();
1923
+ Block_Obj body = parse_block(root);
1947
1924
  stack.pop_back();
1948
- return SASS_MEMORY_NEW(ctx.mem, For, for_source_position, var, lower_bound, upper_bound, body, inclusive);
1925
+ return SASS_MEMORY_NEW(For, for_source_position, var, lower_bound, upper_bound, body, inclusive);
1949
1926
  }
1950
1927
 
1951
1928
  // helper to parse a var token
@@ -1974,7 +1951,7 @@ namespace Sass {
1974
1951
  return token;
1975
1952
  }
1976
1953
 
1977
- Each* Parser::parse_each_directive()
1954
+ Each_Obj Parser::parse_each_directive()
1978
1955
  {
1979
1956
  stack.push_back(Scope::Control);
1980
1957
  ParserState each_source_position = pstate;
@@ -1987,113 +1964,114 @@ namespace Sass {
1987
1964
  vars.push_back(Util::normalize_underscores(lexed));
1988
1965
  }
1989
1966
  if (!lex< kwd_in >()) error("expected 'in' keyword in @each directive", pstate);
1990
- Expression* list = parse_list();
1991
- Block* body = parse_block(root);
1967
+ Expression_Obj list = parse_list();
1968
+ Block_Obj body = parse_block(root);
1992
1969
  stack.pop_back();
1993
- return SASS_MEMORY_NEW(ctx.mem, Each, each_source_position, vars, list, body);
1970
+ return SASS_MEMORY_NEW(Each, each_source_position, vars, list, body);
1994
1971
  }
1995
1972
 
1996
1973
  // called after parsing `kwd_while_directive`
1997
- While* Parser::parse_while_directive()
1974
+ While_Obj Parser::parse_while_directive()
1998
1975
  {
1999
1976
  stack.push_back(Scope::Control);
2000
1977
  bool root = block_stack.back()->is_root();
2001
1978
  // create the initial while call object
2002
- While* call = SASS_MEMORY_NEW(ctx.mem, While, pstate, 0, 0);
1979
+ While_Obj call = SASS_MEMORY_NEW(While, pstate, 0, 0);
2003
1980
  // parse mandatory predicate
2004
- Expression* predicate = parse_list();
1981
+ Expression_Obj predicate = parse_list();
2005
1982
  call->predicate(predicate);
2006
1983
  // parse mandatory block
2007
1984
  call->block(parse_block(root));
2008
1985
  // return ast node
2009
1986
  stack.pop_back();
2010
1987
  // return ast node
2011
- return call;
1988
+ return call.detach();
2012
1989
  }
2013
1990
 
2014
1991
  // EO parse_while_directive
2015
- Media_Block* Parser::parse_media_block()
1992
+ Media_Block_Obj Parser::parse_media_block()
2016
1993
  {
2017
1994
  stack.push_back(Scope::Media);
2018
- Media_Block* media_block = SASS_MEMORY_NEW(ctx.mem, Media_Block, pstate, 0, 0);
1995
+ Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, 0, 0);
1996
+
2019
1997
  media_block->media_queries(parse_media_queries());
2020
1998
 
2021
- Media_Block* prev_media_block = last_media_block;
2022
- last_media_block = media_block;
1999
+ Media_Block_Obj prev_media_block = last_media_block;
2000
+ last_media_block = &media_block;
2023
2001
  media_block->block(parse_css_block());
2024
- last_media_block = prev_media_block;
2002
+ last_media_block = &prev_media_block;
2025
2003
  stack.pop_back();
2026
- return media_block;
2004
+ return media_block.detach();
2027
2005
  }
2028
2006
 
2029
- List* Parser::parse_media_queries()
2007
+ List_Obj Parser::parse_media_queries()
2030
2008
  {
2031
2009
  advanceToNextToken();
2032
- List* media_queries = SASS_MEMORY_NEW(ctx.mem, List, pstate, 0, SASS_COMMA);
2033
- if (!peek_css < exactly <'{'> >()) (*media_queries) << parse_media_query();
2034
- while (lex_css < exactly <','> >()) (*media_queries) << parse_media_query();
2035
- media_queries->update_pstate(pstate);
2036
- return media_queries;
2010
+ List_Obj queries = SASS_MEMORY_NEW(List, pstate, 0, SASS_COMMA);
2011
+ if (!peek_css < exactly <'{'> >()) queries->append(&parse_media_query());
2012
+ while (lex_css < exactly <','> >()) queries->append(&parse_media_query());
2013
+ queries->update_pstate(pstate);
2014
+ return queries.detach();
2037
2015
  }
2038
2016
 
2039
- // Expression* Parser::parse_media_query()
2040
- Media_Query* Parser::parse_media_query()
2017
+ // Expression_Ptr Parser::parse_media_query()
2018
+ Media_Query_Obj Parser::parse_media_query()
2041
2019
  {
2042
2020
  advanceToNextToken();
2043
- Media_Query* media_query = SASS_MEMORY_NEW(ctx.mem, Media_Query, pstate);
2021
+ Media_Query_Obj media_query = SASS_MEMORY_NEW(Media_Query, pstate);
2044
2022
  if (lex < kwd_not >()) { media_query->is_negated(true); lex < css_comments >(false); }
2045
2023
  else if (lex < kwd_only >()) { media_query->is_restricted(true); lex < css_comments >(false); }
2046
2024
 
2047
- if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema());
2048
- else if (lex < identifier >()) media_query->media_type(parse_interpolated_chunk(lexed));
2049
- else (*media_query) << parse_media_expression();
2025
+ if (lex < identifier_schema >()) media_query->media_type(&parse_identifier_schema());
2026
+ else if (lex < identifier >()) media_query->media_type(&parse_interpolated_chunk(lexed));
2027
+ else media_query->append(&parse_media_expression());
2050
2028
 
2051
- while (lex_css < kwd_and >()) (*media_query) << parse_media_expression();
2029
+ while (lex_css < kwd_and >()) media_query->append(&parse_media_expression());
2052
2030
  if (lex < identifier_schema >()) {
2053
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
2054
- *schema << media_query->media_type();
2055
- *schema << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, " ");
2056
- *schema << parse_identifier_schema();
2031
+ String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
2032
+ schema->append(&media_query->media_type());
2033
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2034
+ schema->append(&parse_identifier_schema());
2057
2035
  media_query->media_type(schema);
2058
2036
  }
2059
- while (lex_css < kwd_and >()) (*media_query) << parse_media_expression();
2037
+ while (lex_css < kwd_and >()) media_query->append(&parse_media_expression());
2060
2038
 
2061
2039
  media_query->update_pstate(pstate);
2062
2040
 
2063
2041
  return media_query;
2064
2042
  }
2065
2043
 
2066
- Media_Query_Expression* Parser::parse_media_expression()
2044
+ Media_Query_Expression_Obj Parser::parse_media_expression()
2067
2045
  {
2068
2046
  if (lex < identifier_schema >()) {
2069
- String* ss = parse_identifier_schema();
2070
- return SASS_MEMORY_NEW(ctx.mem, Media_Query_Expression, pstate, ss, 0, true);
2047
+ String_Obj ss = parse_identifier_schema();
2048
+ return SASS_MEMORY_NEW(Media_Query_Expression, pstate, &ss, 0, true);
2071
2049
  }
2072
2050
  if (!lex_css< exactly<'('> >()) {
2073
2051
  error("media query expression must begin with '('", pstate);
2074
2052
  }
2075
- Expression* feature = 0;
2053
+ Expression_Obj feature = 0;
2076
2054
  if (peek_css< exactly<')'> >()) {
2077
2055
  error("media feature required in media query expression", pstate);
2078
2056
  }
2079
- feature = parse_expression();
2080
- Expression* expression = 0;
2057
+ feature = &parse_expression();
2058
+ Expression_Obj expression = 0;
2081
2059
  if (lex_css< exactly<':'> >()) {
2082
- expression = parse_list(DELAYED);
2060
+ expression = &parse_list(DELAYED);
2083
2061
  }
2084
2062
  if (!lex_css< exactly<')'> >()) {
2085
2063
  error("unclosed parenthesis in media query expression", pstate);
2086
2064
  }
2087
- return SASS_MEMORY_NEW(ctx.mem, Media_Query_Expression, feature->pstate(), feature, expression);
2065
+ return SASS_MEMORY_NEW(Media_Query_Expression, feature->pstate(), feature, expression);
2088
2066
  }
2089
2067
 
2090
2068
  // lexed after `kwd_supports_directive`
2091
2069
  // these are very similar to media blocks
2092
- Supports_Block* Parser::parse_supports_directive()
2070
+ Supports_Block_Obj Parser::parse_supports_directive()
2093
2071
  {
2094
- Supports_Condition* cond = parse_supports_condition();
2072
+ Supports_Condition_Obj cond = parse_supports_condition();
2095
2073
  // create the ast node object for the support queries
2096
- Supports_Block* query = SASS_MEMORY_NEW(ctx.mem, Supports_Block, pstate, cond);
2074
+ Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond);
2097
2075
  // additional block is mandatory
2098
2076
  // parse inner block
2099
2077
  query->block(parse_block());
@@ -2103,27 +2081,27 @@ namespace Sass {
2103
2081
 
2104
2082
  // parse one query operation
2105
2083
  // may encounter nested queries
2106
- Supports_Condition* Parser::parse_supports_condition()
2084
+ Supports_Condition_Obj Parser::parse_supports_condition()
2107
2085
  {
2108
2086
  lex < css_whitespace >();
2109
- Supports_Condition* cond = parse_supports_negation();
2110
- if (!cond) cond = parse_supports_operator();
2111
- if (!cond) cond = parse_supports_interpolation();
2087
+ Supports_Condition_Obj cond = 0;
2088
+ if ((cond = parse_supports_negation())) return cond;
2089
+ if ((cond = parse_supports_operator())) return cond;
2090
+ if ((cond = parse_supports_interpolation())) return cond;
2112
2091
  return cond;
2113
2092
  }
2114
2093
 
2115
- Supports_Condition* Parser::parse_supports_negation()
2094
+ Supports_Condition_Obj Parser::parse_supports_negation()
2116
2095
  {
2117
2096
  if (!lex < kwd_not >()) return 0;
2118
-
2119
- Supports_Condition* cond = parse_supports_condition_in_parens();
2120
- return SASS_MEMORY_NEW(ctx.mem, Supports_Negation, pstate, cond);
2097
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens();
2098
+ return SASS_MEMORY_NEW(Supports_Negation, pstate, &cond);
2121
2099
  }
2122
2100
 
2123
- Supports_Condition* Parser::parse_supports_operator()
2101
+ Supports_Condition_Obj Parser::parse_supports_operator()
2124
2102
  {
2125
- Supports_Condition* cond = parse_supports_condition_in_parens();
2126
- if (!cond) return 0;
2103
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens();
2104
+ if (!&cond) return 0;
2127
2105
 
2128
2106
  while (true) {
2129
2107
  Supports_Operator::Operand op = Supports_Operator::OR;
@@ -2131,50 +2109,50 @@ namespace Sass {
2131
2109
  else if(!lex < kwd_or >()) { break; }
2132
2110
 
2133
2111
  lex < css_whitespace >();
2134
- Supports_Condition* right = parse_supports_condition_in_parens();
2112
+ Supports_Condition_Obj right = parse_supports_condition_in_parens();
2135
2113
 
2136
- // Supports_Condition* cc = SASS_MEMORY_NEW(ctx.mem, Supports_Condition, *static_cast<Supports_Condition*>(cond));
2137
- cond = SASS_MEMORY_NEW(ctx.mem, Supports_Operator, pstate, cond, right, op);
2114
+ // Supports_Condition_Ptr cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition_Ptr>(cond));
2115
+ cond = SASS_MEMORY_NEW(Supports_Operator, pstate, &cond, &right, op);
2138
2116
  }
2139
2117
  return cond;
2140
2118
  }
2141
2119
 
2142
- Supports_Condition* Parser::parse_supports_interpolation()
2120
+ Supports_Condition_Obj Parser::parse_supports_interpolation()
2143
2121
  {
2144
2122
  if (!lex < interpolant >()) return 0;
2145
2123
 
2146
- String* interp = parse_interpolated_chunk(lexed);
2124
+ String_Obj interp = parse_interpolated_chunk(lexed);
2147
2125
  if (!interp) return 0;
2148
2126
 
2149
- return SASS_MEMORY_NEW(ctx.mem, Supports_Interpolation, pstate, interp);
2127
+ return SASS_MEMORY_NEW(Supports_Interpolation, pstate, &interp);
2150
2128
  }
2151
2129
 
2152
2130
  // TODO: This needs some major work. Although feature conditions
2153
2131
  // look like declarations their semantics differ significantly
2154
- Supports_Condition* Parser::parse_supports_declaration()
2132
+ Supports_Condition_Obj Parser::parse_supports_declaration()
2155
2133
  {
2156
- Supports_Condition* cond = 0;
2134
+ Supports_Condition_Ptr cond = 0;
2157
2135
  // parse something declaration like
2158
- Declaration* declaration = parse_declaration();
2136
+ Declaration_Obj declaration = parse_declaration();
2159
2137
  if (!declaration) error("@supports condition expected declaration", pstate);
2160
- cond = SASS_MEMORY_NEW(ctx.mem, Supports_Declaration,
2138
+ cond = SASS_MEMORY_NEW(Supports_Declaration,
2161
2139
  declaration->pstate(),
2162
- declaration->property(),
2140
+ &declaration->property(),
2163
2141
  declaration->value());
2164
2142
  // ToDo: maybe we need an additional error condition?
2165
2143
  return cond;
2166
2144
  }
2167
2145
 
2168
- Supports_Condition* Parser::parse_supports_condition_in_parens()
2146
+ Supports_Condition_Obj Parser::parse_supports_condition_in_parens()
2169
2147
  {
2170
- Supports_Condition* interp = parse_supports_interpolation();
2171
- if (interp != 0) return interp;
2148
+ Supports_Condition_Obj interp = parse_supports_interpolation();
2149
+ if (&interp != 0) return interp;
2172
2150
 
2173
2151
  if (!lex < exactly <'('> >()) return 0;
2174
2152
  lex < css_whitespace >();
2175
2153
 
2176
- Supports_Condition* cond = parse_supports_condition();
2177
- if (cond != 0) {
2154
+ Supports_Condition_Obj cond = parse_supports_condition();
2155
+ if (&cond != 0) {
2178
2156
  if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration", pstate);
2179
2157
  } else {
2180
2158
  cond = parse_supports_declaration();
@@ -2184,11 +2162,11 @@ namespace Sass {
2184
2162
  return cond;
2185
2163
  }
2186
2164
 
2187
- At_Root_Block* Parser::parse_at_root_block()
2165
+ At_Root_Block_Obj Parser::parse_at_root_block()
2188
2166
  {
2189
2167
  ParserState at_source_position = pstate;
2190
- Block* body = 0;
2191
- At_Root_Query* expr = 0;
2168
+ Block_Obj body = 0;
2169
+ At_Root_Query_Obj expr;
2192
2170
  Lookahead lookahead_result;
2193
2171
  LOCAL_FLAG(in_at_root, true);
2194
2172
  if (lex_css< exactly<'('> >()) {
@@ -2196,19 +2174,19 @@ namespace Sass {
2196
2174
  }
2197
2175
  if (peek_css < exactly<'{'> >()) {
2198
2176
  lex <optional_spaces>();
2199
- body = parse_block(true);
2177
+ body = &parse_block(true);
2200
2178
  }
2201
2179
  else if ((lookahead_result = lookahead_for_selector(position)).found) {
2202
- Ruleset* r = parse_ruleset(lookahead_result, false);
2203
- body = SASS_MEMORY_NEW(ctx.mem, Block, r->pstate(), 1, true);
2204
- *body << r;
2180
+ Ruleset_Obj r = parse_ruleset(lookahead_result, false);
2181
+ body = SASS_MEMORY_NEW(Block, r->pstate(), 1, true);
2182
+ body->append(&r);
2205
2183
  }
2206
- At_Root_Block* at_root = SASS_MEMORY_NEW(ctx.mem, At_Root_Block, at_source_position, body);
2207
- if (expr) at_root->expression(expr);
2184
+ At_Root_Block_Obj at_root = SASS_MEMORY_NEW(At_Root_Block, at_source_position, body);
2185
+ if (&expr) at_root->expression(&expr);
2208
2186
  return at_root;
2209
2187
  }
2210
2188
 
2211
- At_Root_Query* Parser::parse_at_root_query()
2189
+ At_Root_Query_Obj Parser::parse_at_root_query()
2212
2190
  {
2213
2191
  if (peek< exactly<')'> >()) error("at-root feature required in at-root expression", pstate);
2214
2192
 
@@ -2216,40 +2194,40 @@ namespace Sass {
2216
2194
  css_error("Invalid CSS", " after ", ": expected \"with\" or \"without\", was ");
2217
2195
  }
2218
2196
 
2219
- Expression* feature = parse_list();
2197
+ Expression_Obj feature = parse_list();
2220
2198
  if (!lex_css< exactly<':'> >()) error("style declaration must contain a value", pstate);
2221
- Expression* expression = parse_list();
2222
- List* value = SASS_MEMORY_NEW(ctx.mem, List, feature->pstate(), 1);
2199
+ Expression_Obj expression = parse_list();
2200
+ List_Obj value = SASS_MEMORY_NEW(List, feature->pstate(), 1);
2223
2201
 
2224
2202
  if (expression->concrete_type() == Expression::LIST) {
2225
- value = static_cast<List*>(expression);
2203
+ value = SASS_MEMORY_CAST(List, expression);
2226
2204
  }
2227
- else *value << expression;
2205
+ else value->append(expression);
2228
2206
 
2229
- At_Root_Query* cond = SASS_MEMORY_NEW(ctx.mem, At_Root_Query,
2207
+ At_Root_Query_Obj cond = SASS_MEMORY_NEW(At_Root_Query,
2230
2208
  value->pstate(),
2231
2209
  feature,
2232
- value);
2210
+ &value);
2233
2211
  if (!lex_css< exactly<')'> >()) error("unclosed parenthesis in @at-root expression", pstate);
2234
2212
  return cond;
2235
2213
  }
2236
2214
 
2237
- Directive* Parser::parse_special_directive()
2215
+ Directive_Obj Parser::parse_special_directive()
2238
2216
  {
2239
2217
  std::string kwd(lexed);
2240
2218
 
2241
2219
  if (lexed == "@else") error("Invalid CSS: @else must come after @if", pstate);
2242
2220
 
2243
- Directive* at_rule = SASS_MEMORY_NEW(ctx.mem, Directive, pstate, kwd);
2221
+ Directive_Ptr at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2244
2222
  Lookahead lookahead = lookahead_for_include(position);
2245
2223
  if (lookahead.found && !lookahead.has_interpolants) {
2246
- at_rule->selector(parse_selector_list(true));
2224
+ at_rule->selector(&parse_selector_list(true));
2247
2225
  }
2248
2226
 
2249
2227
  lex < css_comments >(false);
2250
2228
 
2251
2229
  if (lex < static_property >()) {
2252
- at_rule->value(parse_interpolated_chunk(Token(lexed)));
2230
+ at_rule->value(&parse_interpolated_chunk(Token(lexed)));
2253
2231
  } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) {
2254
2232
  at_rule->value(parse_list());
2255
2233
  }
@@ -2263,24 +2241,24 @@ namespace Sass {
2263
2241
  return at_rule;
2264
2242
  }
2265
2243
 
2266
- Directive* Parser::parse_prefixed_directive()
2244
+ Directive_Obj Parser::parse_prefixed_directive()
2267
2245
  {
2268
2246
  std::string kwd(lexed);
2269
2247
 
2270
2248
  if (lexed == "@else") error("Invalid CSS: @else must come after @if", pstate);
2271
2249
 
2272
- Directive* at_rule = SASS_MEMORY_NEW(ctx.mem, Directive, pstate, kwd);
2250
+ Directive_Obj at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2273
2251
  Lookahead lookahead = lookahead_for_include(position);
2274
2252
  if (lookahead.found && !lookahead.has_interpolants) {
2275
- at_rule->selector(parse_selector_list(true));
2253
+ at_rule->selector(&parse_selector_list(true));
2276
2254
  }
2277
2255
 
2278
2256
  lex < css_comments >(false);
2279
2257
 
2280
2258
  if (lex < static_property >()) {
2281
- at_rule->value(parse_interpolated_chunk(Token(lexed)));
2259
+ at_rule->value(&parse_interpolated_chunk(Token(lexed)));
2282
2260
  } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) {
2283
- at_rule->value(parse_list());
2261
+ at_rule->value(&parse_list());
2284
2262
  }
2285
2263
 
2286
2264
  lex < css_comments >(false);
@@ -2293,41 +2271,41 @@ namespace Sass {
2293
2271
  }
2294
2272
 
2295
2273
 
2296
- Directive* Parser::parse_directive()
2274
+ Directive_Obj Parser::parse_directive()
2297
2275
  {
2298
- Directive* directive = SASS_MEMORY_NEW(ctx.mem, Directive, pstate, lexed);
2299
- Expression* val = parse_almost_any_value();
2276
+ Directive_Obj directive = SASS_MEMORY_NEW(Directive, pstate, lexed);
2277
+ String_Schema_Obj val = parse_almost_any_value();
2300
2278
  // strip left and right if they are of type string
2301
- directive->value(val);
2279
+ directive->value(&val);
2302
2280
  if (peek< exactly<'{'> >()) {
2303
2281
  directive->block(parse_block());
2304
2282
  }
2305
2283
  return directive;
2306
2284
  }
2307
2285
 
2308
- Expression* Parser::lex_interpolation()
2286
+ Expression_Obj Parser::lex_interpolation()
2309
2287
  {
2310
2288
  if (lex < interpolant >(true) != NULL) {
2311
- return parse_interpolated_chunk(lexed, true);
2289
+ return &parse_interpolated_chunk(lexed, true);
2312
2290
  }
2313
2291
  return 0;
2314
2292
  }
2315
2293
 
2316
- Expression* Parser::lex_interp_uri()
2294
+ Expression_Obj Parser::lex_interp_uri()
2317
2295
  {
2318
2296
  // create a string schema by lexing optional interpolations
2319
2297
  return lex_interp< re_string_uri_open, re_string_uri_close >();
2320
2298
  }
2321
2299
 
2322
- Expression* Parser::lex_interp_string()
2300
+ Expression_Obj Parser::lex_interp_string()
2323
2301
  {
2324
- Expression* rv = 0;
2325
- if ((rv = lex_interp< re_string_double_open, re_string_double_close >()) != NULL) return rv;
2326
- if ((rv = lex_interp< re_string_single_open, re_string_single_close >()) != NULL) return rv;
2302
+ Expression_Obj rv = 0;
2303
+ if ((rv = lex_interp< re_string_double_open, re_string_double_close >())) return rv;
2304
+ if ((rv = lex_interp< re_string_single_open, re_string_single_close >())) return rv;
2327
2305
  return rv;
2328
2306
  }
2329
2307
 
2330
- Expression* Parser::lex_almost_any_value_chars()
2308
+ Expression_Obj Parser::lex_almost_any_value_chars()
2331
2309
  {
2332
2310
  const char* match =
2333
2311
  lex <
@@ -2374,52 +2352,50 @@ namespace Sass {
2374
2352
  >
2375
2353
  >(false);
2376
2354
  if (match) {
2377
- // std::cerr << "[[" << std::string(lexed) << "]\n";
2378
- return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
2355
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
2379
2356
  }
2380
2357
  return NULL;
2381
2358
  }
2382
2359
 
2383
- Expression* Parser::lex_almost_any_value_token()
2360
+ Expression_Obj Parser::lex_almost_any_value_token()
2384
2361
  {
2385
- Expression* rv = 0;
2362
+ Expression_Obj rv = 0;
2386
2363
  if (*position == 0) return 0;
2387
- if ((rv = lex_almost_any_value_chars()) != NULL) return rv;
2388
- // if ((rv = lex_block_comment()) != NULL) return rv;
2389
- // if ((rv = lex_single_line_comment()) != NULL) return rv;
2390
- if ((rv = lex_interp_string()) != NULL) return rv;
2391
- if ((rv = lex_interp_uri()) != NULL) return rv;
2392
- if ((rv = lex_interpolation()) != NULL) return rv;
2364
+ if ((rv = &lex_almost_any_value_chars())) return rv;
2365
+ // if ((rv = lex_block_comment())) return rv;
2366
+ // if ((rv = lex_single_line_comment())) return rv;
2367
+ if ((rv = &lex_interp_string())) return rv;
2368
+ if ((rv = &lex_interp_uri())) return rv;
2369
+ if ((rv = &lex_interpolation())) return rv;
2393
2370
  return rv;
2394
2371
  }
2395
2372
 
2396
- String_Schema* Parser::parse_almost_any_value()
2373
+ String_Schema_Obj Parser::parse_almost_any_value()
2397
2374
  {
2398
2375
 
2399
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
2376
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2400
2377
  if (*position == 0) return 0;
2401
2378
  lex < spaces >(false);
2402
- Expression* token = lex_almost_any_value_token();
2379
+ Expression_Obj token = lex_almost_any_value_token();
2403
2380
  if (!token) return 0;
2404
- // std::cerr << "LEX [" << std::string(lexed) << "]\n";
2405
- *schema << token;
2381
+ schema->append(token);
2406
2382
  if (*position == 0) {
2407
2383
  schema->rtrim();
2408
- return schema;
2384
+ return schema.detach();
2409
2385
  }
2410
2386
 
2411
- while ((token = lex_almost_any_value_token())) {
2412
- *schema << token;
2387
+ while ((token = &lex_almost_any_value_token())) {
2388
+ schema->append(token);
2413
2389
  }
2414
2390
 
2415
2391
  lex < css_whitespace >();
2416
2392
 
2417
2393
  schema->rtrim();
2418
2394
 
2419
- return schema;
2395
+ return schema.detach();
2420
2396
  }
2421
2397
 
2422
- Warning* Parser::parse_warning()
2398
+ Warning_Obj Parser::parse_warning()
2423
2399
  {
2424
2400
  if (stack.back() != Scope::Root &&
2425
2401
  stack.back() != Scope::Function &&
@@ -2428,10 +2404,10 @@ namespace Sass {
2428
2404
  stack.back() != Scope::Rules) {
2429
2405
  error("Illegal nesting: Only properties may be nested beneath properties.", pstate);
2430
2406
  }
2431
- return SASS_MEMORY_NEW(ctx.mem, Warning, pstate, parse_list(DELAYED));
2407
+ return SASS_MEMORY_NEW(Warning, pstate, parse_list(DELAYED));
2432
2408
  }
2433
2409
 
2434
- Error* Parser::parse_error()
2410
+ Error_Obj Parser::parse_error()
2435
2411
  {
2436
2412
  if (stack.back() != Scope::Root &&
2437
2413
  stack.back() != Scope::Function &&
@@ -2440,10 +2416,10 @@ namespace Sass {
2440
2416
  stack.back() != Scope::Rules) {
2441
2417
  error("Illegal nesting: Only properties may be nested beneath properties.", pstate);
2442
2418
  }
2443
- return SASS_MEMORY_NEW(ctx.mem, Error, pstate, parse_list(DELAYED));
2419
+ return SASS_MEMORY_NEW(Error, pstate, parse_list(DELAYED));
2444
2420
  }
2445
2421
 
2446
- Debug* Parser::parse_debug()
2422
+ Debug_Obj Parser::parse_debug()
2447
2423
  {
2448
2424
  if (stack.back() != Scope::Root &&
2449
2425
  stack.back() != Scope::Function &&
@@ -2452,15 +2428,15 @@ namespace Sass {
2452
2428
  stack.back() != Scope::Rules) {
2453
2429
  error("Illegal nesting: Only properties may be nested beneath properties.", pstate);
2454
2430
  }
2455
- return SASS_MEMORY_NEW(ctx.mem, Debug, pstate, parse_list(DELAYED));
2431
+ return SASS_MEMORY_NEW(Debug, pstate, parse_list(DELAYED));
2456
2432
  }
2457
2433
 
2458
- Return* Parser::parse_return_directive()
2434
+ Return_Obj Parser::parse_return_directive()
2459
2435
  {
2460
2436
  // check that we do not have an empty list (ToDo: check if we got all cases)
2461
2437
  if (peek_css < alternatives < exactly < ';' >, exactly < '}' >, end_of_file > >())
2462
2438
  { css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); }
2463
- return SASS_MEMORY_NEW(ctx.mem, Return, pstate, parse_list());
2439
+ return SASS_MEMORY_NEW(Return, pstate, &parse_list());
2464
2440
  }
2465
2441
 
2466
2442
  Lookahead Parser::lookahead_for_selector(const char* start)
@@ -2662,17 +2638,17 @@ namespace Sass {
2662
2638
  }
2663
2639
 
2664
2640
 
2665
- Expression* Parser::fold_operands(Expression* base, std::vector<Expression*>& operands, Operand op)
2641
+ Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, Operand op)
2666
2642
  {
2667
2643
  for (size_t i = 0, S = operands.size(); i < S; ++i) {
2668
- base = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), op, base, operands[i]);
2644
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), op, &base, operands[i]);
2669
2645
  }
2670
2646
  return base;
2671
2647
  }
2672
2648
 
2673
- Expression* Parser::fold_operands(Expression* base, std::vector<Expression*>& operands, std::vector<Operand>& ops, size_t i)
2649
+ Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i)
2674
2650
  {
2675
- if (String_Schema* schema = dynamic_cast<String_Schema*>(base)) {
2651
+ if (String_Schema_Ptr schema = dynamic_cast<String_Schema_Ptr>(&base)) {
2676
2652
  // return schema;
2677
2653
  if (schema->has_interpolants()) {
2678
2654
  if (i + 1 < operands.size() && (
@@ -2686,8 +2662,8 @@ namespace Sass {
2686
2662
  || (ops[0].operand == Sass_OP::LTE)
2687
2663
  || (ops[0].operand == Sass_OP::GTE)
2688
2664
  )) {
2689
- Expression* rhs = fold_operands(operands[i], operands, ops, i + 1);
2690
- rhs = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[0], schema, rhs);
2665
+ Expression_Obj rhs = fold_operands(operands[i], operands, ops, i + 1);
2666
+ rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[0], schema, &rhs);
2691
2667
  return rhs;
2692
2668
  }
2693
2669
  // return schema;
@@ -2695,31 +2671,31 @@ namespace Sass {
2695
2671
  }
2696
2672
 
2697
2673
  for (size_t S = operands.size(); i < S; ++i) {
2698
- if (String_Schema* schema = dynamic_cast<String_Schema*>(operands[i])) {
2674
+ if (String_Schema_Ptr schema = dynamic_cast<String_Schema_Ptr>(&operands[i])) {
2699
2675
  if (schema->has_interpolants()) {
2700
2676
  if (i + 1 < S) {
2701
- Expression* rhs = fold_operands(operands[i+1], operands, ops, i + 2);
2702
- rhs = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[i], schema, rhs);
2703
- base = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[i], base, rhs);
2677
+ Expression_Obj rhs = fold_operands(operands[i+1], operands, ops, i + 2);
2678
+ rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], schema, &rhs);
2679
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], &base, &rhs);
2704
2680
  return base;
2705
2681
  }
2706
- base = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[i], base, operands[i]);
2682
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], &base, operands[i]);
2707
2683
  return base;
2708
2684
  } else {
2709
- base = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[i], base, operands[i]);
2685
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], &base, operands[i]);
2710
2686
  }
2711
2687
  } else {
2712
- base = SASS_MEMORY_NEW(ctx.mem, Binary_Expression, base->pstate(), ops[i], base, operands[i]);
2688
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], &base, operands[i]);
2713
2689
  }
2714
- Binary_Expression* b = static_cast<Binary_Expression*>(base);
2690
+ Binary_Expression_Ptr b = static_cast<Binary_Expression_Ptr>(&base);
2715
2691
  if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) {
2716
2692
  base->is_delayed(true);
2717
2693
  }
2718
2694
  }
2719
2695
  // nested binary expression are never to be delayed
2720
- if (Binary_Expression* b = dynamic_cast<Binary_Expression*>(base)) {
2721
- if (dynamic_cast<Binary_Expression*>(b->left())) base->set_delayed(false);
2722
- if (dynamic_cast<Binary_Expression*>(b->right())) base->set_delayed(false);
2696
+ if (Binary_Expression_Ptr b = dynamic_cast<Binary_Expression_Ptr>(&base)) {
2697
+ if (SASS_MEMORY_CAST(Binary_Expression, b->left())) base->set_delayed(false);
2698
+ if (SASS_MEMORY_CAST(Binary_Expression, b->right())) base->set_delayed(false);
2723
2699
  }
2724
2700
  return base;
2725
2701
  }