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,10 +12,10 @@ namespace Sass {
12
12
  class Expand;
13
13
  class Context;
14
14
 
15
- class Eval : public Operation_CRTP<Expression*, Eval> {
15
+ class Eval : public Operation_CRTP<Expression_Ptr, Eval> {
16
16
 
17
17
  private:
18
- Expression* fallback_impl(AST_Node* n);
18
+ Expression_Ptr fallback_impl(AST_Node_Ptr n);
19
19
 
20
20
  public:
21
21
  Expand& exp;
@@ -27,83 +27,82 @@ namespace Sass {
27
27
  bool is_in_comment;
28
28
 
29
29
  Env* environment();
30
- Context& context();
31
- CommaSequence_Selector* selector();
32
30
  Backtrace* backtrace();
31
+ Selector_List_Obj selector();
33
32
 
34
33
  // for evaluating function bodies
35
- Expression* operator()(Block*);
36
- Expression* operator()(Assignment*);
37
- Expression* operator()(If*);
38
- Expression* operator()(For*);
39
- Expression* operator()(Each*);
40
- Expression* operator()(While*);
41
- Expression* operator()(Return*);
42
- Expression* operator()(Warning*);
43
- Expression* operator()(Error*);
44
- Expression* operator()(Debug*);
45
-
46
- Expression* operator()(List*);
47
- Expression* operator()(Map*);
48
- Expression* operator()(Binary_Expression*);
49
- Expression* operator()(Unary_Expression*);
50
- Expression* operator()(Function_Call*);
51
- Expression* operator()(Function_Call_Schema*);
52
- Expression* operator()(Variable*);
53
- Expression* operator()(Textual*);
54
- Expression* operator()(Number*);
55
- Expression* operator()(Color*);
56
- Expression* operator()(Boolean*);
57
- Expression* operator()(String_Schema*);
58
- Expression* operator()(String_Quoted*);
59
- Expression* operator()(String_Constant*);
60
- // Expression* operator()(CommaSequence_Selector*);
61
- Expression* operator()(Media_Query*);
62
- Expression* operator()(Media_Query_Expression*);
63
- Expression* operator()(At_Root_Query*);
64
- Expression* operator()(Supports_Operator*);
65
- Expression* operator()(Supports_Negation*);
66
- Expression* operator()(Supports_Declaration*);
67
- Expression* operator()(Supports_Interpolation*);
68
- Expression* operator()(Null*);
69
- Expression* operator()(Argument*);
70
- Expression* operator()(Arguments*);
71
- Expression* operator()(Comment*);
34
+ Expression_Ptr operator()(Block_Ptr);
35
+ Expression_Ptr operator()(Assignment_Ptr);
36
+ Expression_Ptr operator()(If_Ptr);
37
+ Expression_Ptr operator()(For_Ptr);
38
+ Expression_Ptr operator()(Each_Ptr);
39
+ Expression_Ptr operator()(While_Ptr);
40
+ Expression_Ptr operator()(Return_Ptr);
41
+ Expression_Ptr operator()(Warning_Ptr);
42
+ Expression_Ptr operator()(Error_Ptr);
43
+ Expression_Ptr operator()(Debug_Ptr);
44
+
45
+ Expression_Ptr operator()(List_Ptr);
46
+ Expression_Ptr operator()(Map_Ptr);
47
+ Expression_Ptr operator()(Binary_Expression_Ptr);
48
+ Expression_Ptr operator()(Unary_Expression_Ptr);
49
+ Expression_Ptr operator()(Function_Call_Ptr);
50
+ Expression_Ptr operator()(Function_Call_Schema_Ptr);
51
+ Expression_Ptr operator()(Variable_Ptr);
52
+ Expression_Ptr operator()(Textual_Ptr);
53
+ Expression_Ptr operator()(Number_Ptr);
54
+ Expression_Ptr operator()(Color_Ptr);
55
+ Expression_Ptr operator()(Boolean_Ptr);
56
+ Expression_Ptr operator()(String_Schema_Ptr);
57
+ Expression_Ptr operator()(String_Quoted_Ptr);
58
+ Expression_Ptr operator()(String_Constant_Ptr);
59
+ // Expression_Ptr operator()(Selector_List_Ptr);
60
+ Expression_Ptr operator()(Media_Query_Ptr);
61
+ Expression_Ptr operator()(Media_Query_Expression_Ptr);
62
+ Expression_Ptr operator()(At_Root_Query_Ptr);
63
+ Expression_Ptr operator()(Supports_Operator_Ptr);
64
+ Expression_Ptr operator()(Supports_Negation_Ptr);
65
+ Expression_Ptr operator()(Supports_Declaration_Ptr);
66
+ Expression_Ptr operator()(Supports_Interpolation_Ptr);
67
+ Expression_Ptr operator()(Null_Ptr);
68
+ Expression_Ptr operator()(Argument_Ptr);
69
+ Expression_Ptr operator()(Arguments_Ptr);
70
+ Expression_Ptr operator()(Comment_Ptr);
72
71
 
73
72
  // these will return selectors
74
- CommaSequence_Selector* operator()(CommaSequence_Selector*);
75
- CommaSequence_Selector* operator()(Sequence_Selector*);
76
- Attribute_Selector* operator()(Attribute_Selector*);
73
+ Selector_List_Ptr operator()(Selector_List_Ptr);
74
+ Selector_List_Ptr operator()(Complex_Selector_Ptr);
75
+ Attribute_Selector_Ptr operator()(Attribute_Selector_Ptr);
77
76
  // they don't have any specific implementatio (yet)
78
- Element_Selector* operator()(Element_Selector* s) { return s; };
79
- Pseudo_Selector* operator()(Pseudo_Selector* s) { return s; };
80
- Wrapped_Selector* operator()(Wrapped_Selector* s) { return s; };
81
- Class_Selector* operator()(Class_Selector* s) { return s; };
82
- Id_Selector* operator()(Id_Selector* s) { return s; };
83
- Placeholder_Selector* operator()(Placeholder_Selector* s) { return s; };
77
+ Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; };
78
+ Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; };
79
+ Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s) { return s; };
80
+ Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; };
81
+ Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; };
82
+ Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; };
84
83
  // actual evaluated selectors
85
- CommaSequence_Selector* operator()(Selector_Schema*);
86
- Expression* operator()(Parent_Selector*);
84
+ Selector_List_Ptr operator()(Selector_Schema_Ptr);
85
+ Expression_Ptr operator()(Parent_Selector_Ptr);
87
86
 
88
87
  template <typename U>
89
- Expression* fallback(U x) { return fallback_impl(x); }
88
+ Expression_Ptr fallback(U x) { return fallback_impl(x); }
90
89
 
91
90
  // -- only need to define two comparisons, and the rest can be implemented in terms of them
92
- static bool eq(Expression*, Expression*);
93
- static bool lt(Expression*, Expression*, std::string op);
91
+ static bool eq(Expression_Obj, Expression_Obj);
92
+ static bool lt(Expression_Obj, Expression_Obj, std::string op);
94
93
  // -- arithmetic on the combinations that matter
95
- static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
96
- static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
97
- static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
98
- static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
99
- static Value* op_strings(Memory_Manager&, Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false);
94
+ static Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
95
+ static Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
96
+ static Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
97
+ static Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
98
+ static Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false);
100
99
 
101
100
  private:
102
- void interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl = false);
101
+ void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false);
103
102
 
104
103
  };
105
104
 
106
- Expression* cval_to_astnode(Memory_Manager& mem, union Sass_Value* v, Context& ctx, Backtrace* backtrace, ParserState pstate = ParserState("[AST]"));
105
+ Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtrace* backtrace, ParserState pstate = ParserState("[AST]"));
107
106
 
108
107
  }
109
108
 
@@ -2,6 +2,7 @@
2
2
  #include <iostream>
3
3
  #include <typeinfo>
4
4
 
5
+ #include "ast.hpp"
5
6
  #include "expand.hpp"
6
7
  #include "bind.hpp"
7
8
  #include "eval.hpp"
@@ -12,29 +13,26 @@
12
13
  namespace Sass {
13
14
 
14
15
  // simple endless recursion protection
15
- const unsigned int maxRecursion = 500;
16
- static unsigned int recursions = 0;
16
+ const size_t maxRecursion = 500;
17
17
 
18
- Expand::Expand(Context& ctx, Env* env, Backtrace* bt, std::vector<CommaSequence_Selector*>* stack)
18
+ Expand::Expand(Context& ctx, Env* env, Backtrace* bt, std::vector<Selector_List_Obj>* stack)
19
19
  : ctx(ctx),
20
20
  eval(Eval(*this)),
21
- env_stack(std::vector<Env*>()),
22
- block_stack(std::vector<Block*>()),
23
- call_stack(std::vector<AST_Node*>()),
24
- property_stack(std::vector<String*>()),
25
- selector_stack(std::vector<CommaSequence_Selector*>()),
26
- media_block_stack(std::vector<Media_Block*>()),
27
- backtrace_stack(std::vector<Backtrace*>()),
21
+ recursions(0),
28
22
  in_keyframes(false),
29
23
  at_root_without_rule(false),
30
- old_at_root_without_rule(false)
24
+ old_at_root_without_rule(false),
25
+ env_stack(std::vector<Env*>()),
26
+ block_stack(std::vector<Block_Ptr>()),
27
+ call_stack(std::vector<AST_Node_Obj>()),
28
+ selector_stack(std::vector<Selector_List_Obj>()),
29
+ media_block_stack(std::vector<Media_Block_Ptr>()),
30
+ backtrace_stack(std::vector<Backtrace*>())
31
31
  {
32
32
  env_stack.push_back(0);
33
33
  env_stack.push_back(env);
34
34
  block_stack.push_back(0);
35
35
  call_stack.push_back(0);
36
- // import_stack.push_back(0);
37
- property_stack.push_back(0);
38
36
  if (stack == NULL) { selector_stack.push_back(0); }
39
37
  else { selector_stack.insert(selector_stack.end(), stack->begin(), stack->end()); }
40
38
  media_block_stack.push_back(0);
@@ -54,7 +52,7 @@ namespace Sass {
54
52
  return 0;
55
53
  }
56
54
 
57
- CommaSequence_Selector* Expand::selector()
55
+ Selector_List_Obj Expand::selector()
58
56
  {
59
57
  if (selector_stack.size() > 0)
60
58
  return selector_stack.back();
@@ -69,40 +67,42 @@ namespace Sass {
69
67
  }
70
68
 
71
69
  // blocks create new variable scopes
72
- Statement* Expand::operator()(Block* b)
70
+ Block_Ptr Expand::operator()(Block_Ptr b)
73
71
  {
74
72
  // create new local environment
75
73
  // set the current env as parent
76
74
  Env env(environment());
77
75
  // copy the block object (add items later)
78
- Block* bb = SASS_MEMORY_NEW(ctx.mem, Block,
76
+ Block_Obj bb = SASS_MEMORY_NEW(Block,
79
77
  b->pstate(),
80
78
  b->length(),
81
79
  b->is_root());
82
80
  // setup block and env stack
83
- this->block_stack.push_back(bb);
81
+ this->block_stack.push_back(&bb);
84
82
  this->env_stack.push_back(&env);
85
83
  // operate on block
84
+ // this may throw up!
86
85
  this->append_block(b);
87
86
  // revert block and env stack
88
87
  this->block_stack.pop_back();
89
88
  this->env_stack.pop_back();
90
89
  // return copy
91
- return bb;
90
+ return bb.detach();
92
91
  }
93
92
 
94
- Statement* Expand::operator()(Ruleset* r)
93
+ Statement_Ptr Expand::operator()(Ruleset_Ptr r)
95
94
  {
96
95
  LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
97
96
 
98
97
  if (in_keyframes) {
99
- Keyframe_Rule* k = SASS_MEMORY_NEW(ctx.mem, Keyframe_Rule, r->pstate(), r->block()->perform(this)->block());
98
+ Block_Ptr bb = operator()(&r->block());
99
+ Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
100
100
  if (r->selector()) {
101
101
  selector_stack.push_back(0);
102
- k->selector(static_cast<CommaSequence_Selector*>(r->selector()->perform(&eval)));
102
+ k->name(SASS_MEMORY_CAST_PTR(Selector_List, r->selector()->perform(&eval)));
103
103
  selector_stack.pop_back();
104
104
  }
105
- return k;
105
+ return k.detach();
106
106
  }
107
107
 
108
108
  // reset when leaving scope
@@ -110,46 +110,48 @@ namespace Sass {
110
110
 
111
111
  // do some special checks for the base level rules
112
112
  if (r->is_root()) {
113
- if (CommaSequence_Selector* selector_list = dynamic_cast<CommaSequence_Selector*>(r->selector())) {
114
- for (Sequence_Selector* complex_selector : selector_list->elements()) {
115
- Sequence_Selector* tail = complex_selector;
113
+ if (Selector_List_Ptr selector_list = SASS_MEMORY_CAST(Selector_List, r->selector())) {
114
+ for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
115
+ Complex_Selector_Ptr tail = &complex_selector;
116
116
  while (tail) {
117
- if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) {
118
- if (dynamic_cast<Parent_Selector*>(header) == NULL) continue; // skip all others
117
+ if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
118
+ if (SASS_MEMORY_CAST(Parent_Selector, header) == NULL) continue; // skip all others
119
119
  std::string sel_str(complex_selector->to_string(ctx.c_options));
120
120
  error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), backtrace());
121
121
  }
122
- tail = tail->tail();
122
+ tail = &tail->tail();
123
123
  }
124
124
  }
125
125
  }
126
126
  }
127
127
 
128
- Expression* ex = r->selector()->perform(&eval);
129
- CommaSequence_Selector* sel = dynamic_cast<CommaSequence_Selector*>(ex);
128
+ Expression_Obj ex = 0;
129
+ if (r->selector()) ex = r->selector()->perform(&eval);
130
+ Selector_List_Obj sel = SASS_MEMORY_CAST(Selector_List, ex);
130
131
  if (sel == 0) throw std::runtime_error("Expanded null selector");
131
132
 
132
133
  if (sel->length() == 0 || sel->has_parent_ref()) {
133
134
  bool has_parent_selector = false;
134
135
  for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
135
- CommaSequence_Selector* ll = selector_stack.at(i);
136
+ Selector_List_Obj ll = selector_stack.at(i);
136
137
  has_parent_selector = ll != 0 && ll->length() > 0;
137
138
  }
138
- if (!has_parent_selector) {
139
+ if (sel->has_real_parent_ref() && !has_parent_selector) {
139
140
  error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), backtrace());
140
141
  }
141
142
  }
142
143
 
143
- selector_stack.push_back(sel);
144
+ selector_stack.push_back(&sel);
144
145
  Env env(environment());
145
146
  if (block_stack.back()->is_root()) {
146
147
  env_stack.push_back(&env);
147
148
  }
148
149
  sel->set_media_block(media_block_stack.back());
149
- Block* blk = r->block()->perform(this)->block();
150
- Ruleset* rr = SASS_MEMORY_NEW(ctx.mem, Ruleset,
150
+ Block_Obj blk = 0;
151
+ if (r->block()) blk = operator()(&r->block());
152
+ Ruleset_Ptr rr = SASS_MEMORY_NEW(Ruleset,
151
153
  r->pstate(),
152
- sel,
154
+ &sel,
153
155
  blk);
154
156
  selector_stack.pop_back();
155
157
  if (block_stack.back()->is_root()) {
@@ -162,66 +164,70 @@ namespace Sass {
162
164
  return rr;
163
165
  }
164
166
 
165
- Statement* Expand::operator()(Supports_Block* f)
167
+ Statement_Ptr Expand::operator()(Supports_Block_Ptr f)
166
168
  {
167
- Expression* condition = f->condition()->perform(&eval);
168
- Supports_Block* ff = SASS_MEMORY_NEW(ctx.mem, Supports_Block,
169
+ Expression_Obj condition = f->condition()->perform(&eval);
170
+ Supports_Block_Obj ff = SASS_MEMORY_NEW(Supports_Block,
169
171
  f->pstate(),
170
- static_cast<Supports_Condition*>(condition),
171
- f->block()->perform(this)->block());
172
- return ff;
172
+ SASS_MEMORY_CAST(Supports_Condition, condition),
173
+ operator()(&f->block()));
174
+ return ff.detach();
173
175
  }
174
176
 
175
- Statement* Expand::operator()(Media_Block* m)
177
+ Statement_Ptr Expand::operator()(Media_Block_Ptr m)
176
178
  {
177
179
  media_block_stack.push_back(m);
178
- Expression* mq = m->media_queries()->perform(&eval);
180
+ Expression_Obj mq = m->media_queries()->perform(&eval);
179
181
  std::string str_mq(mq->to_string(ctx.c_options));
180
182
  char* str = sass_copy_c_string(str_mq.c_str());
181
183
  ctx.strings.push_back(str);
182
184
  Parser p(Parser::from_c_str(str, ctx, mq->pstate()));
183
- mq = p.parse_media_queries();
184
- Media_Block* mm = SASS_MEMORY_NEW(ctx.mem, Media_Block,
185
+ mq = &p.parse_media_queries(); // re-assign now
186
+ List_Obj ls = SASS_MEMORY_CAST_PTR(List, mq->perform(&eval));
187
+ Block_Obj blk = operator()(&m->block());
188
+ Media_Block_Ptr mm = SASS_MEMORY_NEW(Media_Block,
185
189
  m->pstate(),
186
- static_cast<List*>(mq->perform(&eval)),
187
- m->block()->perform(this)->block(),
190
+ ls,
191
+ blk,
188
192
  0);
189
193
  media_block_stack.pop_back();
190
194
  mm->tabs(m->tabs());
191
195
  return mm;
192
196
  }
193
197
 
194
- Statement* Expand::operator()(At_Root_Block* a)
198
+ Statement_Ptr Expand::operator()(At_Root_Block_Ptr a)
195
199
  {
196
- Block* ab = a->block();
197
- Expression* ae = a->expression();
200
+ Block_Obj ab = a->block();
201
+ Expression_Obj ae = &a->expression();
198
202
 
199
203
  if (ae) ae = ae->perform(&eval);
200
- else ae = SASS_MEMORY_NEW(ctx.mem, At_Root_Query, a->pstate());
204
+ else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
201
205
 
202
206
  LOCAL_FLAG(at_root_without_rule, true);
203
207
  LOCAL_FLAG(in_keyframes, false);
204
208
 
205
- Block* bb = ab ? ab->perform(this)->block() : 0;
206
- At_Root_Block* aa = SASS_MEMORY_NEW(ctx.mem, At_Root_Block,
209
+ ;
210
+
211
+ Block_Obj bb = ab ? operator()(&ab) : NULL;
212
+ At_Root_Block_Obj aa = SASS_MEMORY_NEW(At_Root_Block,
207
213
  a->pstate(),
208
214
  bb,
209
- static_cast<At_Root_Query*>(ae));
210
- return aa;
215
+ SASS_MEMORY_CAST(At_Root_Query, ae));
216
+ return aa.detach();
211
217
  }
212
218
 
213
- Statement* Expand::operator()(Directive* a)
219
+ Statement_Ptr Expand::operator()(Directive_Ptr a)
214
220
  {
215
221
  LOCAL_FLAG(in_keyframes, a->is_keyframes());
216
- Block* ab = a->block();
217
- Selector* as = a->selector();
218
- Expression* av = a->value();
222
+ Block_Ptr ab = &a->block();
223
+ Selector_Ptr as = &a->selector();
224
+ Expression_Ptr av = &a->value();
219
225
  selector_stack.push_back(0);
220
226
  if (av) av = av->perform(&eval);
221
- if (as) as = dynamic_cast<Selector*>(as->perform(&eval));
227
+ if (as) as = SASS_MEMORY_CAST_PTR(Selector, as->perform(&eval));
222
228
  selector_stack.pop_back();
223
- Block* bb = ab ? ab->perform(this)->block() : 0;
224
- Directive* aa = SASS_MEMORY_NEW(ctx.mem, Directive,
229
+ Block_Ptr bb = ab ? operator()(ab) : NULL;
230
+ Directive_Ptr aa = SASS_MEMORY_NEW(Directive,
225
231
  a->pstate(),
226
232
  a->keyword(),
227
233
  as,
@@ -230,17 +236,23 @@ namespace Sass {
230
236
  return aa;
231
237
  }
232
238
 
233
- Statement* Expand::operator()(Declaration* d)
239
+ Statement_Ptr Expand::operator()(Declaration_Ptr d)
234
240
  {
235
- Block* ab = d->block();
236
- String* old_p = d->property();
237
- String* new_p = static_cast<String*>(old_p->perform(&eval));
238
- Expression* value = d->value()->perform(&eval);
239
- Block* bb = ab ? ab->perform(this)->block() : 0;
241
+ Block_Obj ab = d->block();
242
+ String_Obj old_p = d->property();
243
+ Expression_Obj prop = old_p->perform(&eval);
244
+ String_Obj new_p = SASS_MEMORY_CAST(String, prop);
245
+ // we might get a color back
246
+ if (!new_p) {
247
+ std::string str(prop->to_string(ctx.c_options));
248
+ new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
249
+ }
250
+ Expression_Obj value = d->value()->perform(&eval);
251
+ Block_Obj bb = ab ? operator()(&ab) : NULL;
240
252
  if (!bb) {
241
253
  if (!value || (value->is_invisible() && !d->is_important())) return 0;
242
254
  }
243
- Declaration* decl = SASS_MEMORY_NEW(ctx.mem, Declaration,
255
+ Declaration_Ptr decl = SASS_MEMORY_NEW(Declaration,
244
256
  d->pstate(),
245
257
  new_p,
246
258
  value,
@@ -250,14 +262,14 @@ namespace Sass {
250
262
  return decl;
251
263
  }
252
264
 
253
- Statement* Expand::operator()(Assignment* a)
265
+ Statement_Ptr Expand::operator()(Assignment_Ptr a)
254
266
  {
255
267
  Env* env = environment();
256
268
  std::string var(a->variable());
257
269
  if (a->is_global()) {
258
270
  if (a->is_default()) {
259
271
  if (env->has_global(var)) {
260
- Expression* e = dynamic_cast<Expression*>(env->get_global(var));
272
+ Expression_Obj e = SASS_MEMORY_CAST(Expression, env->get_global(var));
261
273
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
262
274
  env->set_global(var, a->value()->perform(&eval));
263
275
  }
@@ -275,8 +287,8 @@ namespace Sass {
275
287
  auto cur = env;
276
288
  while (cur && cur->is_lexical()) {
277
289
  if (cur->has_local(var)) {
278
- if (AST_Node* node = cur->get_local(var)) {
279
- Expression* e = dynamic_cast<Expression*>(node);
290
+ if (AST_Node_Obj node = cur->get_local(var)) {
291
+ Expression_Obj e = SASS_MEMORY_CAST(Expression, node);
280
292
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
281
293
  cur->set_local(var, a->value()->perform(&eval));
282
294
  }
@@ -291,8 +303,8 @@ namespace Sass {
291
303
  throw std::runtime_error("Env not in sync");
292
304
  }
293
305
  else if (env->has_global(var)) {
294
- if (AST_Node* node = env->get_global(var)) {
295
- Expression* e = dynamic_cast<Expression*>(node);
306
+ if (AST_Node_Obj node = env->get_global(var)) {
307
+ Expression_Obj e = SASS_MEMORY_CAST(Expression, node);
296
308
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
297
309
  env->set_global(var, a->value()->perform(&eval));
298
310
  }
@@ -311,26 +323,26 @@ namespace Sass {
311
323
  return 0;
312
324
  }
313
325
 
314
- Statement* Expand::operator()(Import* imp)
326
+ Statement_Ptr Expand::operator()(Import_Ptr imp)
315
327
  {
316
- Import* result = SASS_MEMORY_NEW(ctx.mem, Import, imp->pstate());
317
- if (imp->media_queries() && imp->media_queries()->size()) {
318
- Expression* ex = imp->media_queries()->perform(&eval);
319
- result->media_queries(dynamic_cast<List*>(ex));
328
+ Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
329
+ if (imp->import_queries() && imp->import_queries()->size()) {
330
+ Expression_Obj ex = imp->import_queries()->perform(&eval);
331
+ result->import_queries(SASS_MEMORY_CAST(List, ex));
320
332
  }
321
333
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
322
334
  result->urls().push_back(imp->urls()[i]->perform(&eval));
323
335
  }
324
336
  // all resources have been dropped for Input_Stubs
325
337
  // for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}
326
- return result;
338
+ return result.detach();
327
339
  }
328
340
 
329
- Statement* Expand::operator()(Import_Stub* i)
341
+ Statement_Ptr Expand::operator()(Import_Stub_Ptr i)
330
342
  {
331
343
  // get parent node from call stack
332
- AST_Node* parent = call_stack.back();
333
- if (parent && dynamic_cast<Block*>(parent) == NULL) {
344
+ AST_Node_Obj parent = call_stack.back();
345
+ if (SASS_MEMORY_CAST(Block, parent) == NULL) {
334
346
  error("Import directives may not be used within control directives or mixins.", i->pstate());
335
347
  }
336
348
  // we don't seem to need that actually afterall
@@ -341,52 +353,53 @@ namespace Sass {
341
353
  );
342
354
  ctx.import_stack.push_back(import);
343
355
  const std::string& abs_path(i->resource().abs_path);
344
- append_block(ctx.sheets.at(abs_path).root);
356
+ append_block(&ctx.sheets.at(abs_path).root);
345
357
  sass_delete_import(ctx.import_stack.back());
346
358
  ctx.import_stack.pop_back();
347
359
  return 0;
348
360
  }
349
361
 
350
- Statement* Expand::operator()(Warning* w)
362
+ Statement_Ptr Expand::operator()(Warning_Ptr w)
351
363
  {
352
364
  // eval handles this too, because warnings may occur in functions
353
365
  w->perform(&eval);
354
366
  return 0;
355
367
  }
356
368
 
357
- Statement* Expand::operator()(Error* e)
369
+ Statement_Ptr Expand::operator()(Error_Ptr e)
358
370
  {
359
371
  // eval handles this too, because errors may occur in functions
360
372
  e->perform(&eval);
361
373
  return 0;
362
374
  }
363
375
 
364
- Statement* Expand::operator()(Debug* d)
376
+ Statement_Ptr Expand::operator()(Debug_Ptr d)
365
377
  {
366
378
  // eval handles this too, because warnings may occur in functions
367
379
  d->perform(&eval);
368
380
  return 0;
369
381
  }
370
382
 
371
- Statement* Expand::operator()(Comment* c)
383
+ Statement_Ptr Expand::operator()(Comment_Ptr c)
372
384
  {
373
385
  eval.is_in_comment = true;
374
- auto rv = SASS_MEMORY_NEW(ctx.mem, Comment, c->pstate(), static_cast<String*>(c->text()->perform(&eval)), c->is_important());
386
+ Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), SASS_MEMORY_CAST_PTR(String, c->text()->perform(&eval)), c->is_important());
375
387
  eval.is_in_comment = false;
376
388
  // TODO: eval the text, once we're parsing/storing it as a String_Schema
377
389
  return rv;
378
390
  }
379
391
 
380
- Statement* Expand::operator()(If* i)
392
+ Statement_Ptr Expand::operator()(If_Ptr i)
381
393
  {
382
394
  Env env(environment(), true);
383
395
  env_stack.push_back(&env);
384
396
  call_stack.push_back(i);
385
- if (*i->predicate()->perform(&eval)) {
386
- append_block(i->block());
397
+ Expression_Obj rv = i->predicate()->perform(&eval);
398
+ if (*rv) {
399
+ append_block(&i->block());
387
400
  }
388
401
  else {
389
- Block* alt = i->alternative();
402
+ Block_Ptr alt = &i->alternative();
390
403
  if (alt) append_block(alt);
391
404
  }
392
405
  call_stack.pop_back();
@@ -396,19 +409,19 @@ namespace Sass {
396
409
 
397
410
  // For does not create a new env scope
398
411
  // But iteration vars are reset afterwards
399
- Statement* Expand::operator()(For* f)
412
+ Statement_Ptr Expand::operator()(For_Ptr f)
400
413
  {
401
414
  std::string variable(f->variable());
402
- Expression* low = f->lower_bound()->perform(&eval);
415
+ Expression_Obj low = f->lower_bound()->perform(&eval);
403
416
  if (low->concrete_type() != Expression::NUMBER) {
404
417
  throw Exception::TypeMismatch(*low, "integer");
405
418
  }
406
- Expression* high = f->upper_bound()->perform(&eval);
419
+ Expression_Obj high = f->upper_bound()->perform(&eval);
407
420
  if (high->concrete_type() != Expression::NUMBER) {
408
421
  throw Exception::TypeMismatch(*high, "integer");
409
422
  }
410
- Number* sass_start = static_cast<Number*>(low);
411
- Number* sass_end = static_cast<Number*>(high);
423
+ Number_Obj sass_start = SASS_MEMORY_CAST(Number, low);
424
+ Number_Obj sass_end = SASS_MEMORY_CAST(Number, high);
412
425
  // check if units are valid for sequence
413
426
  if (sass_start->unit() != sass_end->unit()) {
414
427
  std::stringstream msg; msg << "Incompatible units: '"
@@ -422,16 +435,17 @@ namespace Sass {
422
435
  Env env(environment(), true);
423
436
  env_stack.push_back(&env);
424
437
  call_stack.push_back(f);
425
- Number* it = SASS_MEMORY_NEW(env.mem, Number, low->pstate(), start, sass_end->unit());
426
- env.set_local(variable, it);
427
- Block* body = f->block();
438
+ Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), start, sass_end->unit());
439
+ env.set_local(variable, &it);
440
+ Block_Ptr body = &f->block();
428
441
  if (start < end) {
429
442
  if (f->is_inclusive()) ++end;
430
443
  for (double i = start;
431
444
  i < end;
432
445
  ++i) {
446
+ it = SASS_MEMORY_COPY(it);
433
447
  it->value(i);
434
- env.set_local(variable, it);
448
+ env.set_local(variable, &it);
435
449
  append_block(body);
436
450
  }
437
451
  } else {
@@ -439,8 +453,9 @@ namespace Sass {
439
453
  for (double i = start;
440
454
  i > end;
441
455
  --i) {
456
+ it = SASS_MEMORY_COPY(it);
442
457
  it->value(i);
443
- env.set_local(variable, it);
458
+ env.set_local(variable, &it);
444
459
  append_block(body);
445
460
  }
446
461
  }
@@ -451,78 +466,79 @@ namespace Sass {
451
466
 
452
467
  // Eval does not create a new env scope
453
468
  // But iteration vars are reset afterwards
454
- Statement* Expand::operator()(Each* e)
469
+ Statement_Ptr Expand::operator()(Each_Ptr e)
455
470
  {
456
471
  std::vector<std::string> variables(e->variables());
457
- Expression* expr = e->list()->perform(&eval);
458
- Vectorized<Expression*>* list = 0;
459
- Map* map = 0;
472
+ Expression_Obj expr = e->list()->perform(&eval);
473
+ List_Obj list = 0;
474
+ Map_Obj map;
460
475
  if (expr->concrete_type() == Expression::MAP) {
461
- map = static_cast<Map*>(expr);
476
+ map = SASS_MEMORY_CAST(Map, expr);
462
477
  }
463
- else if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(expr)) {
464
- Listize listize(ctx.mem);
465
- list = dynamic_cast<List*>(ls->perform(&listize));
478
+ else if (Selector_List_Ptr ls = SASS_MEMORY_CAST(Selector_List, expr)) {
479
+ Listize listize;
480
+ Expression_Obj rv = ls->perform(&listize);
481
+ list = SASS_MEMORY_CAST(List, rv);
466
482
  }
467
483
  else if (expr->concrete_type() != Expression::LIST) {
468
- list = SASS_MEMORY_NEW(ctx.mem, List, expr->pstate(), 1, SASS_COMMA);
469
- *list << expr;
484
+ list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);
485
+ list->append(expr);
470
486
  }
471
487
  else {
472
- list = static_cast<List*>(expr);
488
+ list = SASS_MEMORY_CAST(List, expr);
473
489
  }
474
490
  // remember variables and then reset them
475
491
  Env env(environment(), true);
476
492
  env_stack.push_back(&env);
477
493
  call_stack.push_back(e);
478
- Block* body = e->block();
494
+ Block_Ptr body = &e->block();
479
495
 
480
496
  if (map) {
481
497
  for (auto key : map->keys()) {
482
- Expression* k = key->perform(&eval);
483
- Expression* v = map->at(key)->perform(&eval);
498
+ Expression_Obj k = key->perform(&eval);
499
+ Expression_Obj v = map->at(key)->perform(&eval);
484
500
 
485
501
  if (variables.size() == 1) {
486
- List* variable = SASS_MEMORY_NEW(ctx.mem, List, map->pstate(), 2, SASS_SPACE);
487
- *variable << k;
488
- *variable << v;
489
- env.set_local(variables[0], variable);
502
+ List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
503
+ variable->append(k);
504
+ variable->append(v);
505
+ env.set_local(variables[0], &variable);
490
506
  } else {
491
- env.set_local(variables[0], k);
492
- env.set_local(variables[1], v);
507
+ env.set_local(variables[0], &k);
508
+ env.set_local(variables[1], &v);
493
509
  }
494
510
  append_block(body);
495
511
  }
496
512
  }
497
513
  else {
498
514
  // bool arglist = list->is_arglist();
499
- if (list->length() == 1 && dynamic_cast<CommaSequence_Selector*>(list)) {
500
- list = dynamic_cast<Vectorized<Expression*>*>(list);
515
+ if (list->length() == 1 && SASS_MEMORY_CAST(Selector_List, list)) {
516
+ list = SASS_MEMORY_CAST(List, list);
501
517
  }
502
518
  for (size_t i = 0, L = list->length(); i < L; ++i) {
503
- Expression* e = (*list)[i];
519
+ Expression_Obj e = list->at(i);
504
520
  // unwrap value if the expression is an argument
505
- if (Argument* arg = dynamic_cast<Argument*>(e)) e = arg->value();
521
+ if (Argument_Obj arg = SASS_MEMORY_CAST(Argument, e)) e = arg->value();
506
522
  // check if we got passed a list of args (investigate)
507
- if (List* scalars = dynamic_cast<List*>(e)) {
523
+ if (List_Obj scalars = SASS_MEMORY_CAST(List, e)) {
508
524
  if (variables.size() == 1) {
509
- Expression* var = scalars;
525
+ List_Obj var = scalars;
510
526
  // if (arglist) var = (*scalars)[0];
511
- env.set_local(variables[0], var);
527
+ env.set_local(variables[0], &var);
512
528
  } else {
513
529
  for (size_t j = 0, K = variables.size(); j < K; ++j) {
514
- Expression* res = j >= scalars->length()
515
- ? SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate())
530
+ Expression_Obj res = j >= scalars->length()
531
+ ? SASS_MEMORY_NEW(Null, expr->pstate())
516
532
  : (*scalars)[j]->perform(&eval);
517
- env.set_local(variables[j], res);
533
+ env.set_local(variables[j], &res);
518
534
  }
519
535
  }
520
536
  } else {
521
537
  if (variables.size() > 0) {
522
- env.set_local(variables[0], e);
538
+ env.set_local(variables.at(0), &e);
523
539
  for (size_t j = 1, K = variables.size(); j < K; ++j) {
524
- Expression* res = SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate());
525
- env.set_local(variables[j], res);
540
+ Expression_Obj res = SASS_MEMORY_NEW(Null, expr->pstate());
541
+ env.set_local(variables[j], &res);
526
542
  }
527
543
  }
528
544
  }
@@ -534,36 +550,38 @@ namespace Sass {
534
550
  return 0;
535
551
  }
536
552
 
537
- Statement* Expand::operator()(While* w)
553
+ Statement_Ptr Expand::operator()(While_Ptr w)
538
554
  {
539
- Expression* pred = w->predicate();
540
- Block* body = w->block();
555
+ Expression_Obj pred = w->predicate();
556
+ Block_Ptr body = &w->block();
541
557
  Env env(environment(), true);
542
558
  env_stack.push_back(&env);
543
559
  call_stack.push_back(w);
544
- while (*pred->perform(&eval)) {
560
+ Expression_Obj cond = pred->perform(&eval);
561
+ while (*&cond) {
545
562
  append_block(body);
563
+ cond = pred->perform(&eval);
546
564
  }
547
565
  call_stack.pop_back();
548
566
  env_stack.pop_back();
549
567
  return 0;
550
568
  }
551
569
 
552
- Statement* Expand::operator()(Return* r)
570
+ Statement_Ptr Expand::operator()(Return_Ptr r)
553
571
  {
554
572
  error("@return may only be used within a function", r->pstate(), backtrace());
555
573
  return 0;
556
574
  }
557
575
 
558
576
 
559
- void Expand::expand_selector_list(Selector* s, CommaSequence_Selector* extender) {
577
+ void Expand::expand_selector_list(Selector_Obj s, Selector_List_Obj extender) {
560
578
 
561
- if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(s)) {
562
- for (Sequence_Selector* complex_selector : sl->elements()) {
563
- Sequence_Selector* tail = complex_selector;
579
+ if (Selector_List_Obj sl = SASS_MEMORY_CAST(Selector_List, s)) {
580
+ for (Complex_Selector_Obj complex_selector : sl->elements()) {
581
+ Complex_Selector_Obj tail = complex_selector;
564
582
  while (tail) {
565
- if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) {
566
- if (dynamic_cast<Parent_Selector*>(header) == NULL) continue; // skip all others
583
+ if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
584
+ if (SASS_MEMORY_CAST(Parent_Selector, header) == NULL) continue; // skip all others
567
585
  std::string sel_str(complex_selector->to_string(ctx.c_options));
568
586
  error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), backtrace());
569
587
  }
@@ -573,78 +591,78 @@ namespace Sass {
573
591
  }
574
592
 
575
593
 
576
- CommaSequence_Selector* contextualized = dynamic_cast<CommaSequence_Selector*>(s->perform(&eval));
577
- if (contextualized == NULL) return;
594
+ Selector_List_Obj contextualized = SASS_MEMORY_CAST_PTR(Selector_List, s->perform(&eval));
595
+ if (contextualized == false) return;
578
596
  for (auto complex_sel : contextualized->elements()) {
579
- Sequence_Selector* c = complex_sel;
597
+ Complex_Selector_Obj c = complex_sel;
580
598
  if (!c->head() || c->tail()) {
581
599
  std::string sel_str(contextualized->to_string(ctx.c_options));
582
600
  error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace());
583
601
  }
584
- SimpleSequence_Selector* placeholder = c->head();
602
+ Compound_Selector_Obj placeholder = c->head();
585
603
  if (contextualized->is_optional()) placeholder->is_optional(true);
586
604
  for (size_t i = 0, L = extender->length(); i < L; ++i) {
587
- Sequence_Selector* sel = (*extender)[i];
605
+ Complex_Selector_Obj sel = (*extender)[i];
588
606
  if (!(sel->head() && sel->head()->length() > 0 &&
589
- dynamic_cast<Parent_Selector*>((*sel->head())[0])))
607
+ SASS_MEMORY_CAST(Parent_Selector, (*sel->head())[0])))
590
608
  {
591
- SimpleSequence_Selector* hh = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, (*extender)[i]->pstate());
609
+ Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
592
610
  hh->media_block((*extender)[i]->media_block());
593
- Sequence_Selector* ssel = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, (*extender)[i]->pstate());
611
+ Complex_Selector_Obj ssel = SASS_MEMORY_NEW(Complex_Selector, (*extender)[i]->pstate());
594
612
  ssel->media_block((*extender)[i]->media_block());
595
613
  if (sel->has_line_feed()) ssel->has_line_feed(true);
596
- Parent_Selector* ps = SASS_MEMORY_NEW(ctx.mem, Parent_Selector, (*extender)[i]->pstate());
614
+ Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
597
615
  ps->media_block((*extender)[i]->media_block());
598
- *hh << ps;
616
+ hh->append(&ps);
599
617
  ssel->tail(sel);
600
618
  ssel->head(hh);
601
619
  sel = ssel;
602
620
  }
603
621
  // if (c->has_line_feed()) sel->has_line_feed(true);
604
- ctx.subset_map.put(placeholder->to_str_vec(), std::make_pair(sel, placeholder));
622
+ ctx.subset_map.put(placeholder, std::make_pair(sel, placeholder));
605
623
  }
606
624
  }
607
625
 
608
626
  }
609
627
 
610
- Statement* Expand::operator()(Extension* e)
628
+ Statement* Expand::operator()(Extension_Ptr e)
611
629
  {
612
- if (CommaSequence_Selector* extender = dynamic_cast<CommaSequence_Selector*>(selector())) {
613
- Selector* s = e->selector();
614
- CommaSequence_Selector* sl = NULL;
630
+ if (Selector_List_Obj extender = SASS_MEMORY_CAST(Selector_List, selector())) {
631
+ Selector_Obj s = e->selector();
632
+ Selector_List_Obj sl = NULL;
615
633
  // check if we already have a valid selector list
616
- if ((sl = dynamic_cast<CommaSequence_Selector*>(s))) {}
634
+ if ((sl = SASS_MEMORY_CAST(Selector_List, s))) {}
617
635
  // convert selector schema to a selector list
618
- else if (Selector_Schema* schema = dynamic_cast<Selector_Schema*>(s)) {
636
+ else if (Selector_Schema_Obj schema = SASS_MEMORY_CAST(Selector_Schema, s)) {
619
637
  if (schema->has_real_parent_ref()) {
620
- sl = eval(schema);
638
+ sl = eval(&schema);
621
639
  } else {
622
640
  selector_stack.push_back(0);
623
- sl = eval(schema);
641
+ sl = eval(&schema);
624
642
  sl->remove_parent_selectors();
625
643
  selector_stack.pop_back();
626
644
  }
627
645
  }
628
646
  // abort on invalid selector
629
- if (sl == NULL) return NULL;
630
- for (Sequence_Selector* cs : *sl) {
631
- if (cs != NULL && cs->head() != NULL) {
647
+ if (sl.isNull()) return NULL;
648
+ for (Complex_Selector_Obj cs : sl->elements()) {
649
+ if (!cs.isNull() && !cs->head().isNull()) {
632
650
  cs->head()->media_block(media_block_stack.back());
633
651
  }
634
652
  }
635
653
  selector_stack.push_back(0);
636
- expand_selector_list(sl, extender);
654
+ expand_selector_list(&sl, extender);
637
655
  selector_stack.pop_back();
638
656
  }
639
657
  return 0;
640
658
  }
641
659
 
642
- Statement* Expand::operator()(Definition* d)
660
+ Statement_Ptr Expand::operator()(Definition_Ptr d)
643
661
  {
644
662
  Env* env = environment();
645
- Definition* dd = SASS_MEMORY_NEW(ctx.mem, Definition, *d);
663
+ Definition_Obj dd = SASS_MEMORY_COPY(d);
646
664
  env->local_frame()[d->name() +
647
- (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
665
+ (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = &dd;
648
666
 
649
667
  if (d->type() == Definition::FUNCTION && (
650
668
  Prelexer::calc_fn_call(d->name().c_str()) ||
@@ -659,60 +677,60 @@ namespace Sass {
659
677
  );
660
678
  }
661
679
 
662
-
663
680
  // set the static link so we can have lexical scoping
664
681
  dd->environment(env);
665
682
  return 0;
666
683
  }
667
684
 
668
- Statement* Expand::operator()(Mixin_Call* c)
685
+ Statement_Ptr Expand::operator()(Mixin_Call_Ptr c)
669
686
  {
670
- recursions ++;
671
687
 
672
688
  if (recursions > maxRecursion) {
673
689
  throw Exception::StackError(*c);
674
690
  }
675
691
 
692
+ recursions ++;
693
+
676
694
  Env* env = environment();
677
695
  std::string full_name(c->name() + "[m]");
678
696
  if (!env->has(full_name)) {
679
697
  error("no mixin named " + c->name(), c->pstate(), backtrace());
680
698
  }
681
- Definition* def = static_cast<Definition*>((*env)[full_name]);
682
- Block* body = def->block();
683
- Parameters* params = def->parameters();
699
+ Definition_Obj def = SASS_MEMORY_CAST(Definition, (*env)[full_name]);
700
+ Block_Obj body = def->block();
701
+ Parameters_Obj params = def->parameters();
684
702
 
685
703
  if (c->block() && c->name() != "@content" && !body->has_content()) {
686
704
  error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), backtrace());
687
705
  }
688
- Arguments* args = static_cast<Arguments*>(c->arguments()
689
- ->perform(&eval));
706
+ Expression_Obj rv = c->arguments()->perform(&eval);
707
+ Arguments_Obj args = SASS_MEMORY_CAST(Arguments, rv);
690
708
  Backtrace new_bt(backtrace(), c->pstate(), ", in mixin `" + c->name() + "`");
691
709
  backtrace_stack.push_back(&new_bt);
692
710
  Env new_env(def->environment());
693
711
  env_stack.push_back(&new_env);
694
712
  if (c->block()) {
695
713
  // represent mixin content blocks as thunks/closures
696
- Definition* thunk = SASS_MEMORY_NEW(ctx.mem, Definition,
714
+ Definition_Obj thunk = SASS_MEMORY_NEW(Definition,
697
715
  c->pstate(),
698
716
  "@content",
699
- SASS_MEMORY_NEW(ctx.mem, Parameters, c->pstate()),
717
+ SASS_MEMORY_NEW(Parameters, c->pstate()),
700
718
  c->block(),
701
719
  Definition::MIXIN);
702
720
  thunk->environment(env);
703
- new_env.local_frame()["@content[m]"] = thunk;
721
+ new_env.local_frame()["@content[m]"] = &thunk;
704
722
  }
705
723
 
706
724
  bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
707
725
 
708
- Block* trace_block = SASS_MEMORY_NEW(ctx.mem, Block, c->pstate());
709
- Trace* trace = SASS_MEMORY_NEW(ctx.mem, Trace, c->pstate(), c->name(), trace_block);
726
+ Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
727
+ Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
710
728
 
711
729
 
712
- block_stack.push_back(trace_block);
713
- for (auto bb : *body) {
714
- Statement* ith = bb->perform(this);
715
- if (ith) *trace->block() << ith;
730
+ block_stack.push_back(&trace_block);
731
+ for (auto bb : body->elements()) {
732
+ Statement_Obj ith = bb->perform(this);
733
+ if (ith) trace->block()->append(ith);
716
734
  }
717
735
  block_stack.pop_back();
718
736
 
@@ -720,10 +738,10 @@ namespace Sass {
720
738
  backtrace_stack.pop_back();
721
739
 
722
740
  recursions --;
723
- return trace;
741
+ return trace.detach();
724
742
  }
725
743
 
726
- Statement* Expand::operator()(Content* c)
744
+ Statement_Ptr Expand::operator()(Content_Ptr c)
727
745
  {
728
746
  Env* env = environment();
729
747
  // convert @content directives into mixin calls to the underlying thunk
@@ -733,36 +751,37 @@ namespace Sass {
733
751
  selector_stack.push_back(0);
734
752
  }
735
753
 
736
- Mixin_Call* call = SASS_MEMORY_NEW(ctx.mem, Mixin_Call,
754
+ Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,
737
755
  c->pstate(),
738
756
  "@content",
739
- SASS_MEMORY_NEW(ctx.mem, Arguments, c->pstate()));
757
+ SASS_MEMORY_NEW(Arguments, c->pstate()));
740
758
 
741
- Trace* trace = dynamic_cast<Trace*>(call->perform(this));
759
+ Trace_Obj trace = SASS_MEMORY_CAST_PTR(Trace, call->perform(this));
742
760
 
743
761
  if (block_stack.back()->is_root()) {
744
762
  selector_stack.pop_back();
745
763
  }
746
764
 
747
- return trace;
765
+ return trace.detach();
748
766
  }
749
767
 
750
768
  // produce an error if something is not implemented
751
- inline Statement* Expand::fallback_impl(AST_Node* n)
769
+ inline Statement_Ptr Expand::fallback_impl(AST_Node_Ptr n)
752
770
  {
753
771
  std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name();
754
- String_Quoted* msg = SASS_MEMORY_NEW(ctx.mem, String_Quoted, ParserState("[WARN]"), err);
772
+ String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err);
755
773
  error("unknown internal error; please contact the LibSass maintainers", n->pstate(), backtrace());
756
- return SASS_MEMORY_NEW(ctx.mem, Warning, ParserState("[WARN]"), msg);
774
+ return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), &msg);
757
775
  }
758
776
 
759
777
  // process and add to last block on stack
760
- inline void Expand::append_block(Block* b)
778
+ inline void Expand::append_block(Block_Ptr b)
761
779
  {
762
780
  if (b->is_root()) call_stack.push_back(b);
763
781
  for (size_t i = 0, L = b->length(); i < L; ++i) {
764
- Statement* ith = (*b)[i]->perform(this);
765
- if (ith) *block_stack.back() << ith;
782
+ Statement_Ptr stm = &b->at(i);
783
+ Statement_Obj ith = stm->perform(this);
784
+ if (ith) block_stack.back()->append(ith);
766
785
  }
767
786
  if (b->is_root()) call_stack.pop_back();
768
787
  }