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