sassc 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/libsass/.gitignore +6 -0
- data/ext/libsass/.travis.yml +5 -1
- data/ext/libsass/Makefile +12 -3
- data/ext/libsass/Makefile.am +16 -28
- data/ext/libsass/Readme.md +1 -0
- data/ext/libsass/appveyor.yml +1 -2
- data/ext/libsass/ast.cpp +9 -0
- data/ext/libsass/ast.hpp +152 -55
- data/ext/libsass/ast_factory.hpp +2 -0
- data/ext/libsass/ast_fwd_decl.hpp +1 -0
- data/ext/libsass/backtrace.hpp +2 -2
- data/ext/libsass/bind.cpp +15 -13
- data/ext/libsass/configure.ac +17 -5
- data/ext/libsass/constants.cpp +22 -2
- data/ext/libsass/constants.hpp +21 -2
- data/ext/libsass/context.cpp +79 -57
- data/ext/libsass/context.hpp +23 -9
- data/ext/libsass/contextualize.cpp +2 -28
- data/ext/libsass/contextualize.hpp +6 -10
- data/ext/libsass/contextualize_eval.cpp +93 -0
- data/ext/libsass/contextualize_eval.hpp +44 -0
- data/ext/libsass/contrib/plugin.cpp +57 -0
- data/ext/libsass/cssize.cpp +3 -1
- data/ext/libsass/debugger.hpp +242 -83
- data/ext/libsass/emitter.cpp +1 -1
- data/ext/libsass/emitter.hpp +1 -1
- data/ext/libsass/environment.hpp +109 -25
- data/ext/libsass/error_handling.cpp +3 -3
- data/ext/libsass/error_handling.hpp +0 -1
- data/ext/libsass/eval.cpp +145 -61
- data/ext/libsass/eval.hpp +9 -1
- data/ext/libsass/expand.cpp +134 -60
- data/ext/libsass/expand.hpp +5 -2
- data/ext/libsass/extend.cpp +7 -5
- data/ext/libsass/file.cpp +176 -123
- data/ext/libsass/file.hpp +44 -7
- data/ext/libsass/functions.cpp +36 -17
- data/ext/libsass/functions.hpp +2 -2
- data/ext/libsass/inspect.cpp +23 -14
- data/ext/libsass/inspect.hpp +1 -0
- data/ext/libsass/json.cpp +132 -135
- data/ext/libsass/lexer.cpp +133 -0
- data/ext/libsass/lexer.hpp +239 -0
- data/ext/libsass/listize.cpp +83 -0
- data/ext/libsass/listize.hpp +41 -0
- data/ext/libsass/operation.hpp +2 -0
- data/ext/libsass/output.cpp +5 -6
- data/ext/libsass/parser.cpp +426 -388
- data/ext/libsass/parser.hpp +97 -109
- data/ext/libsass/plugins.cpp +15 -2
- data/ext/libsass/plugins.hpp +6 -4
- data/ext/libsass/position.cpp +52 -17
- data/ext/libsass/position.hpp +19 -17
- data/ext/libsass/prelexer.cpp +202 -235
- data/ext/libsass/prelexer.hpp +73 -333
- data/ext/libsass/sass.cpp +21 -11
- data/ext/libsass/sass.h +6 -6
- data/ext/libsass/sass_context.cpp +167 -81
- data/ext/libsass/sass_context.h +26 -6
- data/ext/libsass/sass_functions.cpp +49 -40
- data/ext/libsass/sass_functions.h +55 -43
- data/ext/libsass/sass_interface.cpp +9 -8
- data/ext/libsass/sass_interface.h +3 -3
- data/ext/libsass/sass_version.h +8 -0
- data/ext/libsass/sass_version.h.in +8 -0
- data/ext/libsass/script/ci-build-libsass +3 -3
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/source_map.cpp +2 -2
- data/ext/libsass/util.cpp +60 -11
- data/ext/libsass/util.hpp +6 -1
- data/ext/libsass/win/libsass.filters +12 -0
- data/ext/libsass/win/libsass.vcxproj +10 -0
- data/lib/sassc.rb +3 -1
- data/lib/sassc/cache_stores/base.rb +2 -0
- data/lib/sassc/dependency.rb +3 -1
- data/lib/sassc/engine.rb +31 -16
- data/lib/sassc/error.rb +3 -2
- data/lib/sassc/functions_handler.rb +54 -0
- data/lib/sassc/import_handler.rb +41 -0
- data/lib/sassc/importer.rb +4 -31
- data/lib/sassc/native.rb +1 -1
- data/lib/sassc/native/native_context_api.rb +3 -2
- data/lib/sassc/script.rb +0 -51
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -0
- data/test/custom_importer_test.rb +72 -69
- data/test/engine_test.rb +53 -54
- data/test/functions_test.rb +40 -39
- data/test/native_test.rb +145 -149
- data/test/output_style_test.rb +98 -0
- data/test/test_helper.rb +21 -7
- metadata +28 -2
data/ext/libsass/emitter.cpp
CHANGED
data/ext/libsass/emitter.hpp
CHANGED
data/ext/libsass/environment.hpp
CHANGED
@@ -5,7 +5,9 @@
|
|
5
5
|
#include <string>
|
6
6
|
#include <iostream>
|
7
7
|
|
8
|
+
#include "ast_fwd_decl.hpp"
|
8
9
|
#include "ast_def_macros.hpp"
|
10
|
+
#include "memory_manager.hpp"
|
9
11
|
|
10
12
|
namespace Sass {
|
11
13
|
using std::string;
|
@@ -16,56 +18,136 @@ namespace Sass {
|
|
16
18
|
template <typename T>
|
17
19
|
class Environment {
|
18
20
|
// TODO: test with unordered_map
|
19
|
-
map<string, T>
|
21
|
+
map<string, T> local_frame_;
|
20
22
|
ADD_PROPERTY(Environment*, parent);
|
21
23
|
|
22
24
|
public:
|
23
|
-
|
24
|
-
|
25
|
-
map<string, T>& current_frame() { return current_frame_; }
|
25
|
+
Memory_Manager<AST_Node> mem;
|
26
|
+
Environment() : local_frame_(map<string, T>()), parent_(0) { }
|
26
27
|
|
28
|
+
// link parent to create a stack
|
27
29
|
void link(Environment& env) { parent_ = &env; }
|
28
30
|
void link(Environment* env) { parent_ = env; }
|
29
31
|
|
30
|
-
|
32
|
+
// this is used to find the global frame
|
33
|
+
// which is the second last on the stack
|
34
|
+
bool is_lexical() const
|
35
|
+
{
|
36
|
+
return !! parent_ && parent_->parent_;
|
37
|
+
}
|
38
|
+
|
39
|
+
// only match the real root scope
|
40
|
+
// there is still a parent around
|
41
|
+
// not sure what it is actually use for
|
42
|
+
// I guess we store functions etc. there
|
43
|
+
bool is_root_scope() const
|
31
44
|
{
|
32
|
-
|
33
|
-
|
34
|
-
|
45
|
+
return parent_ && ! parent_->parent_;
|
46
|
+
}
|
47
|
+
|
48
|
+
// scope operates on the current frame
|
49
|
+
|
50
|
+
map<string, T>& local_frame() {
|
51
|
+
return local_frame_;
|
35
52
|
}
|
36
53
|
|
37
|
-
bool
|
38
|
-
{ return
|
54
|
+
bool has_local(const string& key) const
|
55
|
+
{ return local_frame_.count(key); }
|
39
56
|
|
40
|
-
|
57
|
+
T& get_local(const string& key)
|
58
|
+
{ return local_frame_[key]; }
|
59
|
+
|
60
|
+
void set_local(const string& key, T val)
|
61
|
+
{ local_frame_[key] = val; }
|
62
|
+
|
63
|
+
void del_local(const string& key)
|
64
|
+
{ local_frame_.erase(key); }
|
65
|
+
|
66
|
+
|
67
|
+
// global operates on the global frame
|
68
|
+
// which is the second last on the stack
|
69
|
+
|
70
|
+
Environment* global_env()
|
41
71
|
{
|
42
|
-
|
43
|
-
|
72
|
+
Environment* cur = this;
|
73
|
+
while (cur->is_lexical()) {
|
74
|
+
cur = cur->parent_;
|
75
|
+
}
|
76
|
+
return cur;
|
44
77
|
}
|
45
78
|
|
46
|
-
bool
|
79
|
+
bool has_global(const string& key)
|
80
|
+
{ return global_env()->has(key); }
|
81
|
+
|
82
|
+
T& get_global(const string& key)
|
83
|
+
{ return (*global_env())[key]; }
|
84
|
+
|
85
|
+
void set_global(const string& key, T val)
|
86
|
+
{ global_env()->local_frame_[key] = val; }
|
87
|
+
|
88
|
+
void del_global(const string& key)
|
89
|
+
{ global_env()->local_frame_.erase(key); }
|
90
|
+
|
91
|
+
// see if we have a lexical variable
|
92
|
+
// move down the stack but stop before we
|
93
|
+
// reach the global frame (is not included)
|
94
|
+
bool has_lexical(const string& key) const
|
47
95
|
{
|
48
|
-
|
49
|
-
|
96
|
+
auto cur = this;
|
97
|
+
while (cur->is_lexical()) {
|
98
|
+
if (cur->has_local(key)) return true;
|
99
|
+
cur = cur->parent_;
|
50
100
|
}
|
51
|
-
|
52
|
-
|
101
|
+
return false;
|
102
|
+
}
|
103
|
+
|
104
|
+
// see if we have a lexical we could update
|
105
|
+
// either update already existing lexical value
|
106
|
+
// or if flag is set, we create one if no lexical found
|
107
|
+
void set_lexical(const string& key, T val)
|
108
|
+
{
|
109
|
+
auto cur = this;
|
110
|
+
while (cur->is_lexical()) {
|
111
|
+
if (cur->has_local(key)) {
|
112
|
+
cur->set_local(key, val);
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
cur = cur->parent_;
|
53
116
|
}
|
54
|
-
|
55
|
-
|
117
|
+
set_local(key, val);
|
118
|
+
}
|
119
|
+
|
120
|
+
// look on the full stack for key
|
121
|
+
// include all scopes available
|
122
|
+
bool has(const string& key) const
|
123
|
+
{
|
124
|
+
auto cur = this;
|
125
|
+
while (cur) {
|
126
|
+
if (cur->has_local(key)) {
|
127
|
+
return true;
|
128
|
+
}
|
129
|
+
cur = cur->parent_;
|
56
130
|
}
|
131
|
+
return false;
|
57
132
|
}
|
58
133
|
|
59
|
-
|
134
|
+
// use array access for getter and setter functions
|
135
|
+
T& operator[](const string& key)
|
60
136
|
{
|
61
|
-
|
62
|
-
|
63
|
-
|
137
|
+
auto cur = this;
|
138
|
+
while (cur) {
|
139
|
+
if (cur->has_local(key)) {
|
140
|
+
return cur->get_local(key);
|
141
|
+
}
|
142
|
+
cur = cur->parent_;
|
143
|
+
}
|
144
|
+
return get_local(key);
|
64
145
|
}
|
65
146
|
|
147
|
+
#ifdef DEBUG
|
66
148
|
void print()
|
67
149
|
{
|
68
|
-
for (typename map<string, T>::iterator i =
|
150
|
+
for (typename map<string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
|
69
151
|
cerr << i->first << endl;
|
70
152
|
}
|
71
153
|
if (parent_) {
|
@@ -73,6 +155,8 @@ namespace Sass {
|
|
73
155
|
parent_->print();
|
74
156
|
}
|
75
157
|
}
|
158
|
+
#endif
|
159
|
+
|
76
160
|
};
|
77
161
|
}
|
78
162
|
|
@@ -9,12 +9,12 @@ namespace Sass {
|
|
9
9
|
{ }
|
10
10
|
|
11
11
|
void error(string msg, ParserState pstate)
|
12
|
-
{
|
12
|
+
{
|
13
|
+
throw Sass_Error(Sass_Error::syntax, pstate, msg);
|
14
|
+
}
|
13
15
|
|
14
16
|
void error(string msg, ParserState pstate, Backtrace* bt)
|
15
17
|
{
|
16
|
-
if (!pstate.path.empty() && Prelexer::quoted_string(pstate.path.c_str()))
|
17
|
-
pstate.path = pstate.path.substr(1, pstate.path.size() - 1);
|
18
18
|
|
19
19
|
Backtrace top(bt, pstate, "");
|
20
20
|
msg += top.to_string();
|
data/ext/libsass/eval.cpp
CHANGED
@@ -31,12 +31,21 @@ namespace Sass {
|
|
31
31
|
add, sub, mul, div, fmod
|
32
32
|
};
|
33
33
|
|
34
|
-
Eval::Eval(Context& ctx, Env* env, Backtrace* bt)
|
35
|
-
: ctx(ctx), env(env), backtrace(bt) { }
|
34
|
+
Eval::Eval(Context& ctx, Contextualize* contextualize, Listize* listize, Env* env, Backtrace* bt)
|
35
|
+
: ctx(ctx), contextualize(contextualize), listize(listize), env(env), backtrace(bt) { }
|
36
36
|
Eval::~Eval() { }
|
37
37
|
|
38
38
|
Eval* Eval::with(Env* e, Backtrace* bt) // for setting the env before eval'ing an expression
|
39
39
|
{
|
40
|
+
contextualize = contextualize->with(0, e, bt);
|
41
|
+
env = e;
|
42
|
+
backtrace = bt;
|
43
|
+
return this;
|
44
|
+
}
|
45
|
+
|
46
|
+
Eval* Eval::with(Selector* c, Env* e, Backtrace* bt, Selector* p, Selector* ex) // for setting the env before eval'ing an expression
|
47
|
+
{
|
48
|
+
contextualize = contextualize->with(c, e, bt, p, ex);
|
40
49
|
env = e;
|
41
50
|
backtrace = bt;
|
42
51
|
return this;
|
@@ -55,12 +64,59 @@ namespace Sass {
|
|
55
64
|
Expression* Eval::operator()(Assignment* a)
|
56
65
|
{
|
57
66
|
string var(a->variable());
|
58
|
-
if (
|
59
|
-
|
60
|
-
|
67
|
+
if (a->is_global()) {
|
68
|
+
if (a->is_default()) {
|
69
|
+
if (env->has_global(var)) {
|
70
|
+
Expression* e = dynamic_cast<Expression*>(env->get_global(var));
|
71
|
+
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
72
|
+
env->set_global(var, a->value()->perform(this));
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
env->set_global(var, a->value()->perform(this));
|
77
|
+
}
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
env->set_global(var, a->value()->perform(this));
|
81
|
+
}
|
82
|
+
}
|
83
|
+
else if (a->is_default()) {
|
84
|
+
if (env->has_lexical(var)) {
|
85
|
+
auto cur = env;
|
86
|
+
while (cur && cur->is_lexical()) {
|
87
|
+
if (cur->has_local(var)) {
|
88
|
+
if (AST_Node* node = cur->get_local(var)) {
|
89
|
+
Expression* e = dynamic_cast<Expression*>(node);
|
90
|
+
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
91
|
+
cur->set_local(var, a->value()->perform(this));
|
92
|
+
}
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
throw runtime_error("Env not in sync");
|
96
|
+
}
|
97
|
+
return 0;
|
98
|
+
}
|
99
|
+
cur = cur->parent();
|
100
|
+
}
|
101
|
+
throw runtime_error("Env not in sync");
|
102
|
+
}
|
103
|
+
else if (env->has_global(var)) {
|
104
|
+
if (AST_Node* node = env->get_global(var)) {
|
105
|
+
Expression* e = dynamic_cast<Expression*>(node);
|
106
|
+
if (!e || e->concrete_type() == Expression::NULL_VAL) {
|
107
|
+
env->set_global(var, a->value()->perform(this));
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
else if (env->is_lexical()) {
|
112
|
+
env->set_local(var, a->value()->perform(this));
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
env->set_local(var, a->value()->perform(this));
|
116
|
+
}
|
61
117
|
}
|
62
118
|
else {
|
63
|
-
env->
|
119
|
+
env->set_lexical(var, a->value()->perform(this));
|
64
120
|
}
|
65
121
|
return 0;
|
66
122
|
}
|
@@ -77,6 +133,8 @@ namespace Sass {
|
|
77
133
|
return 0;
|
78
134
|
}
|
79
135
|
|
136
|
+
// For does not create a new env scope
|
137
|
+
// But iteration vars are reset afterwards
|
80
138
|
Expression* Eval::operator()(For* f)
|
81
139
|
{
|
82
140
|
string variable(f->variable());
|
@@ -88,19 +146,30 @@ namespace Sass {
|
|
88
146
|
if (high->concrete_type() != Expression::NUMBER) {
|
89
147
|
error("upper bound of `@for` directive must be numeric", high->pstate());
|
90
148
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
149
|
+
Number* sass_start = static_cast<Number*>(low);
|
150
|
+
Number* sass_end = static_cast<Number*>(high);
|
151
|
+
// check if units are valid for sequence
|
152
|
+
if (sass_start->unit() != sass_end->unit()) {
|
153
|
+
stringstream msg; msg << "Incompatible units: '"
|
154
|
+
<< sass_start->unit() << "' and '"
|
155
|
+
<< sass_end->unit() << "'.";
|
156
|
+
error(msg.str(), low->pstate(), backtrace);
|
157
|
+
}
|
158
|
+
double start = sass_start->value();
|
159
|
+
double end = sass_end->value();
|
160
|
+
// only create iterator once in this environment
|
161
|
+
Number* it = new (env->mem) Number(low->pstate(), start, sass_end->unit());
|
162
|
+
AST_Node* old_var = env->has_local(variable) ? env->get_local(variable) : 0;
|
163
|
+
env->set_local(variable, it);
|
97
164
|
Block* body = f->block();
|
98
165
|
Expression* val = 0;
|
99
166
|
if (start < end) {
|
100
167
|
if (f->is_inclusive()) ++end;
|
101
168
|
for (double i = start;
|
102
169
|
i < end;
|
103
|
-
|
170
|
+
++i) {
|
171
|
+
it->value(i);
|
172
|
+
env->set_local(variable, it);
|
104
173
|
val = body->perform(this);
|
105
174
|
if (val) break;
|
106
175
|
}
|
@@ -108,15 +177,21 @@ namespace Sass {
|
|
108
177
|
if (f->is_inclusive()) --end;
|
109
178
|
for (double i = start;
|
110
179
|
i > end;
|
111
|
-
|
180
|
+
--i) {
|
181
|
+
it->value(i);
|
182
|
+
env->set_local(variable, it);
|
112
183
|
val = body->perform(this);
|
113
184
|
if (val) break;
|
114
185
|
}
|
115
186
|
}
|
116
|
-
|
187
|
+
// restore original environment
|
188
|
+
if (!old_var) env->del_local(variable);
|
189
|
+
else env->set_local(variable, old_var);
|
117
190
|
return val;
|
118
191
|
}
|
119
192
|
|
193
|
+
// Eval does not create a new env scope
|
194
|
+
// But iteration vars are reset afterwards
|
120
195
|
Expression* Eval::operator()(Each* e)
|
121
196
|
{
|
122
197
|
vector<string> variables(e->variables());
|
@@ -133,10 +208,12 @@ namespace Sass {
|
|
133
208
|
else {
|
134
209
|
list = static_cast<List*>(expr);
|
135
210
|
}
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
211
|
+
// remember variables and then reset them
|
212
|
+
vector<AST_Node*> old_vars(variables.size());
|
213
|
+
for (size_t i = 0, L = variables.size(); i < L; ++i) {
|
214
|
+
old_vars[i] = env->has_local(variables[i]) ? env->get_local(variables[i]) : 0;
|
215
|
+
env->set_local(variables[i], 0);
|
216
|
+
}
|
140
217
|
Block* body = e->block();
|
141
218
|
Expression* val = 0;
|
142
219
|
|
@@ -148,10 +225,10 @@ namespace Sass {
|
|
148
225
|
List* variable = new (ctx.mem) List(map->pstate(), 2, List::SPACE);
|
149
226
|
*variable << key;
|
150
227
|
*variable << value;
|
151
|
-
(
|
228
|
+
env->set_local(variables[0], variable);
|
152
229
|
} else {
|
153
|
-
(
|
154
|
-
(
|
230
|
+
env->set_local(variables[0], key);
|
231
|
+
env->set_local(variables[1], value);
|
155
232
|
}
|
156
233
|
|
157
234
|
val = body->perform(this);
|
@@ -170,10 +247,10 @@ namespace Sass {
|
|
170
247
|
}
|
171
248
|
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
172
249
|
if (j < variable->length()) {
|
173
|
-
(
|
250
|
+
env->set_local(variables[j], (*variable)[j]);
|
174
251
|
}
|
175
252
|
else {
|
176
|
-
(
|
253
|
+
env->set_local(variables[j], new (ctx.mem) Null(expr->pstate()));
|
177
254
|
}
|
178
255
|
val = body->perform(this);
|
179
256
|
if (val) break;
|
@@ -181,7 +258,11 @@ namespace Sass {
|
|
181
258
|
if (val) break;
|
182
259
|
}
|
183
260
|
}
|
184
|
-
|
261
|
+
// restore original environment
|
262
|
+
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
263
|
+
if(!old_vars[j]) env->del_local(variables[j]);
|
264
|
+
else env->set_local(variables[j], old_vars[j]);
|
265
|
+
}
|
185
266
|
return val;
|
186
267
|
}
|
187
268
|
|
@@ -212,12 +293,13 @@ namespace Sass {
|
|
212
293
|
Definition* def = static_cast<Definition*>((*env)["@warn[f]"]);
|
213
294
|
// Block* body = def->block();
|
214
295
|
// Native_Function func = def->native_function();
|
215
|
-
|
296
|
+
Sass_Function_Entry c_function = def->c_function();
|
297
|
+
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
216
298
|
|
217
299
|
To_C to_c;
|
218
300
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
|
219
301
|
sass_list_set_value(c_args, 0, message->perform(&to_c));
|
220
|
-
Sass_Value* c_val = c_func(c_args,
|
302
|
+
Sass_Value* c_val = c_func(c_args, c_function, ctx.c_options);
|
221
303
|
sass_delete_value(c_args);
|
222
304
|
sass_delete_value(c_val);
|
223
305
|
return 0;
|
@@ -243,12 +325,13 @@ namespace Sass {
|
|
243
325
|
Definition* def = static_cast<Definition*>((*env)["@error[f]"]);
|
244
326
|
// Block* body = def->block();
|
245
327
|
// Native_Function func = def->native_function();
|
246
|
-
|
328
|
+
Sass_Function_Entry c_function = def->c_function();
|
329
|
+
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
247
330
|
|
248
331
|
To_C to_c;
|
249
332
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
|
250
333
|
sass_list_set_value(c_args, 0, message->perform(&to_c));
|
251
|
-
Sass_Value* c_val = c_func(c_args,
|
334
|
+
Sass_Value* c_val = c_func(c_args, c_function, ctx.c_options);
|
252
335
|
sass_delete_value(c_args);
|
253
336
|
sass_delete_value(c_val);
|
254
337
|
return 0;
|
@@ -256,10 +339,7 @@ namespace Sass {
|
|
256
339
|
}
|
257
340
|
|
258
341
|
string result(unquote(message->perform(&to_string)));
|
259
|
-
|
260
|
-
cerr << "Error: " << result;
|
261
|
-
cerr << top.to_string(true);
|
262
|
-
cerr << endl << endl;
|
342
|
+
error(result, e->pstate());
|
263
343
|
return 0;
|
264
344
|
}
|
265
345
|
|
@@ -274,12 +354,13 @@ namespace Sass {
|
|
274
354
|
Definition* def = static_cast<Definition*>((*env)["@debug[f]"]);
|
275
355
|
// Block* body = def->block();
|
276
356
|
// Native_Function func = def->native_function();
|
277
|
-
|
357
|
+
Sass_Function_Entry c_function = def->c_function();
|
358
|
+
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
278
359
|
|
279
360
|
To_C to_c;
|
280
361
|
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
|
281
362
|
sass_list_set_value(c_args, 0, message->perform(&to_c));
|
282
|
-
Sass_Value* c_val = c_func(c_args,
|
363
|
+
Sass_Value* c_val = c_func(c_args, c_function, ctx.c_options);
|
283
364
|
sass_delete_value(c_args);
|
284
365
|
sass_delete_value(c_val);
|
285
366
|
return 0;
|
@@ -431,7 +512,8 @@ namespace Sass {
|
|
431
512
|
|
432
513
|
Expression* Eval::operator()(Function_Call* c)
|
433
514
|
{
|
434
|
-
string
|
515
|
+
string name(Util::normalize_underscores(c->name()));
|
516
|
+
string full_name(name + "[f]");
|
435
517
|
Arguments* args = c->arguments();
|
436
518
|
if (full_name != "if[f]") {
|
437
519
|
args = static_cast<Arguments*>(args->perform(this));
|
@@ -458,7 +540,7 @@ namespace Sass {
|
|
458
540
|
Definition* def = static_cast<Definition*>((*env)[full_name]);
|
459
541
|
Block* body = def->block();
|
460
542
|
Native_Function func = def->native_function();
|
461
|
-
|
543
|
+
Sass_Function_Entry c_function = def->c_function();
|
462
544
|
|
463
545
|
if (full_name != "if[f]") {
|
464
546
|
for (size_t i = 0, L = args->length(); i < L; ++i) {
|
@@ -509,8 +591,9 @@ namespace Sass {
|
|
509
591
|
env = old_env;
|
510
592
|
}
|
511
593
|
// else if it's a user-defined c function
|
512
|
-
else if (
|
594
|
+
else if (c_function) {
|
513
595
|
|
596
|
+
Sass_Function_Fn c_func = sass_function_get_function(c_function);
|
514
597
|
if (full_name == "*[f]") {
|
515
598
|
String_Constant *str = new (ctx.mem) String_Constant(c->pstate(), c->name());
|
516
599
|
Arguments* new_args = new (ctx.mem) Arguments(c->pstate());
|
@@ -528,14 +611,14 @@ namespace Sass {
|
|
528
611
|
backtrace = &here;
|
529
612
|
|
530
613
|
To_C to_c;
|
531
|
-
union Sass_Value* c_args = sass_make_list(env->
|
614
|
+
union Sass_Value* c_args = sass_make_list(env->local_frame().size(), SASS_COMMA);
|
532
615
|
for(size_t i = 0; i < params[0].length(); i++) {
|
533
616
|
string key = params[0][i]->name();
|
534
|
-
AST_Node* node = env->
|
617
|
+
AST_Node* node = env->local_frame().at(key);
|
535
618
|
Expression* arg = static_cast<Expression*>(node);
|
536
619
|
sass_list_set_value(c_args, i, arg->perform(&to_c));
|
537
620
|
}
|
538
|
-
Sass_Value* c_val = c_func(c_args,
|
621
|
+
Sass_Value* c_val = c_func(c_args, c_function, ctx.c_options);
|
539
622
|
if (sass_value_get_tag(c_val) == SASS_ERROR) {
|
540
623
|
error("error in C function " + c->name() + ": " + sass_error_get_message(c_val), c->pstate(), backtrace);
|
541
624
|
} else if (sass_value_get_tag(c_val) == SASS_WARNING) {
|
@@ -671,7 +754,7 @@ namespace Sass {
|
|
671
754
|
case Textual::DIMENSION:
|
672
755
|
result = new (ctx.mem) Number(t->pstate(),
|
673
756
|
sass_atof(num.c_str()),
|
674
|
-
Token(number(text.c_str())
|
757
|
+
Token(number(text.c_str())),
|
675
758
|
zero);
|
676
759
|
break;
|
677
760
|
case Textual::HEX: {
|
@@ -727,21 +810,15 @@ namespace Sass {
|
|
727
810
|
}
|
728
811
|
|
729
812
|
string Eval::interpolation(Expression* s) {
|
730
|
-
|
731
813
|
if (String_Quoted* str_quoted = dynamic_cast<String_Quoted*>(s)) {
|
732
|
-
|
733
814
|
if (str_quoted->quote_mark()) {
|
734
815
|
return string_escape(str_quoted->value());
|
735
816
|
} else {
|
736
817
|
return evacuate_escapes(str_quoted->value());
|
737
818
|
}
|
738
|
-
|
739
819
|
} else if (String_Constant* str_constant = dynamic_cast<String_Constant*>(s)) {
|
740
|
-
|
741
820
|
return evacuate_escapes(str_constant->value());
|
742
|
-
|
743
821
|
} else if (String_Schema* str_schema = dynamic_cast<String_Schema*>(s)) {
|
744
|
-
|
745
822
|
string res = "";
|
746
823
|
for(auto i : str_schema->elements())
|
747
824
|
res += (interpolation(i));
|
@@ -753,9 +830,7 @@ namespace Sass {
|
|
753
830
|
} else {
|
754
831
|
return evacuate_quotes(unq);
|
755
832
|
}
|
756
|
-
|
757
833
|
} else if (List* list = dynamic_cast<List*>(s)) {
|
758
|
-
|
759
834
|
string acc = ""; // ToDo: different output styles
|
760
835
|
string sep = list->separator() == List::Separator::COMMA ? "," : " ";
|
761
836
|
if (ctx.output_style != COMPRESSED && sep == ",") sep += " ";
|
@@ -766,30 +841,30 @@ namespace Sass {
|
|
766
841
|
initial = true;
|
767
842
|
}
|
768
843
|
return evacuate_quotes(acc);
|
769
|
-
|
770
844
|
} else if (Variable* var = dynamic_cast<Variable*>(s)) {
|
771
|
-
|
772
845
|
string name(var->name());
|
773
846
|
if (!env->has(name)) error("Undefined variable: \"" + var->name() + "\".", var->pstate());
|
774
847
|
Expression* value = static_cast<Expression*>((*env)[name]);
|
775
848
|
return evacuate_quotes(interpolation(value));
|
776
|
-
|
777
849
|
} else if (Binary_Expression* var = dynamic_cast<Binary_Expression*>(s)) {
|
778
|
-
|
779
|
-
Expression* ex = operator()(var);
|
850
|
+
Expression* ex = var->perform(this);
|
780
851
|
return evacuate_quotes(interpolation(ex));
|
781
|
-
|
782
852
|
} else if (Function_Call* var = dynamic_cast<Function_Call*>(s)) {
|
783
|
-
|
784
|
-
|
853
|
+
Expression* ex = var->perform(this);
|
854
|
+
return evacuate_quotes(interpolation(ex));
|
855
|
+
} else if (Parent_Selector* var = dynamic_cast<Parent_Selector*>(s)) {
|
856
|
+
Expression* ex = var->perform(this);
|
857
|
+
return evacuate_quotes(interpolation(ex));
|
858
|
+
} else if (Unary_Expression* var = dynamic_cast<Unary_Expression*>(s)) {
|
859
|
+
Expression* ex = var->perform(this);
|
860
|
+
return evacuate_quotes(interpolation(ex));
|
861
|
+
} else if (Selector* var = dynamic_cast<Selector*>(s)) {
|
862
|
+
Expression* ex = var->perform(this);
|
785
863
|
return evacuate_quotes(interpolation(ex));
|
786
|
-
|
787
864
|
} else {
|
788
|
-
|
789
865
|
To_String to_string(&ctx);
|
790
866
|
// to_string.in_decl_list = true;
|
791
867
|
return evacuate_quotes(s->perform(&to_string));
|
792
|
-
|
793
868
|
}
|
794
869
|
}
|
795
870
|
|
@@ -938,6 +1013,15 @@ namespace Sass {
|
|
938
1013
|
return 0;
|
939
1014
|
}
|
940
1015
|
|
1016
|
+
Expression* Eval::operator()(Parent_Selector* p)
|
1017
|
+
{
|
1018
|
+
Selector* s = p->perform(contextualize);
|
1019
|
+
// access to parent selector may return 0
|
1020
|
+
Selector_List* l = static_cast<Selector_List*>(s);
|
1021
|
+
if (!s) { l = new (ctx.mem) Selector_List(p->pstate()); }
|
1022
|
+
return l->perform(listize);
|
1023
|
+
}
|
1024
|
+
|
941
1025
|
inline Expression* Eval::fallback_impl(AST_Node* n)
|
942
1026
|
{
|
943
1027
|
return static_cast<Expression*>(n);
|