sassc 1.0.0 → 1.1.0
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/Readme.md +1 -1
- data/ext/libsass/ast.cpp +264 -0
- data/ext/libsass/ast.hpp +52 -133
- data/ext/libsass/bind.cpp +23 -1
- data/ext/libsass/constants.cpp +3 -1
- data/ext/libsass/constants.hpp +3 -0
- data/ext/libsass/context.cpp +0 -1
- data/ext/libsass/debugger.hpp +84 -2
- data/ext/libsass/error_handling.cpp +14 -4
- data/ext/libsass/error_handling.hpp +3 -0
- data/ext/libsass/eval.cpp +44 -14
- data/ext/libsass/functions.cpp +37 -37
- data/ext/libsass/functions.hpp +0 -2
- data/ext/libsass/inspect.cpp +9 -2
- data/ext/libsass/output.cpp +7 -14
- data/ext/libsass/output.hpp +1 -2
- data/ext/libsass/parser.cpp +16 -4
- data/ext/libsass/position.hpp +5 -0
- data/ext/libsass/prelexer.cpp +5 -1
- data/ext/libsass/sass_values.cpp +15 -0
- data/ext/libsass/sass_values.h +3 -0
- data/ext/libsass/util.cpp +63 -7
- data/ext/libsass/util.hpp +2 -0
- data/lib/sassc/engine.rb +2 -0
- data/lib/sassc/native.rb +1 -1
- data/lib/sassc/version.rb +1 -1
- data/test/engine_test.rb +7 -0
- data/test/native_test.rb +10 -1
- metadata +2 -2
data/ext/libsass/bind.cpp
CHANGED
@@ -28,14 +28,22 @@ namespace Sass {
|
|
28
28
|
size_t ip = 0, LP = ps->length();
|
29
29
|
size_t ia = 0, LA = as->length();
|
30
30
|
while (ia < LA) {
|
31
|
+
Argument* a = (*as)[ia];
|
31
32
|
if (ip >= LP) {
|
33
|
+
// skip empty rest arguments
|
34
|
+
if (a->is_rest_argument()) {
|
35
|
+
if (List* l = dynamic_cast<List*>(a->value())) {
|
36
|
+
if (l->length() == 0) {
|
37
|
+
++ ia; continue;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
32
41
|
stringstream msg;
|
33
42
|
msg << callee << " only takes " << LP << " arguments; "
|
34
43
|
<< "given " << LA;
|
35
44
|
error(msg.str(), as->pstate());
|
36
45
|
}
|
37
46
|
Parameter* p = (*ps)[ip];
|
38
|
-
Argument* a = (*as)[ia];
|
39
47
|
|
40
48
|
// If the current parameter is the rest parameter, process and break the loop
|
41
49
|
if (p->is_rest_parameter()) {
|
@@ -48,6 +56,20 @@ namespace Sass {
|
|
48
56
|
else {
|
49
57
|
env->local_frame()[p->name()] = a->value();
|
50
58
|
}
|
59
|
+
} else if (a->is_keyword_argument()) {
|
60
|
+
|
61
|
+
// expand keyword arguments into their parameters
|
62
|
+
List* arglist = new (ctx.mem) List(p->pstate(), 0, List::COMMA, true);
|
63
|
+
env->local_frame()[p->name()] = arglist;
|
64
|
+
Map* argmap = static_cast<Map*>(a->value());
|
65
|
+
for (auto key : argmap->keys()) {
|
66
|
+
string name = unquote(static_cast<String_Constant*>(key)->value());
|
67
|
+
(*arglist) << new (ctx.mem) Argument(key->pstate(),
|
68
|
+
argmap->at(key),
|
69
|
+
name,
|
70
|
+
false);
|
71
|
+
}
|
72
|
+
|
51
73
|
} else {
|
52
74
|
|
53
75
|
// copy all remaining arguments into the rest parameter, preserving names
|
data/ext/libsass/constants.cpp
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
namespace Sass {
|
4
4
|
namespace Constants {
|
5
5
|
|
6
|
+
extern const unsigned long MaxCallStack = 1024;
|
7
|
+
|
6
8
|
// https://github.com/sass/libsass/issues/592
|
7
9
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
|
8
10
|
// https://github.com/sass/sass/issues/1495#issuecomment-61189114
|
@@ -138,7 +140,7 @@ namespace Sass {
|
|
138
140
|
extern const char arglist_name[] = "arglist";
|
139
141
|
|
140
142
|
// constants for uri parsing (RFC 3986 Appendix A.)
|
141
|
-
extern const char uri_chars[] = "
|
143
|
+
extern const char uri_chars[] = ":;/?!$%&#@|[]{}'`^\"*+-.,_=~";
|
142
144
|
|
143
145
|
// some specific constant character classes
|
144
146
|
// they must be static to be useable by lexer
|
data/ext/libsass/constants.hpp
CHANGED
@@ -4,6 +4,9 @@
|
|
4
4
|
namespace Sass {
|
5
5
|
namespace Constants {
|
6
6
|
|
7
|
+
// The maximum call stack that can be created
|
8
|
+
extern const unsigned long MaxCallStack;
|
9
|
+
|
7
10
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
|
8
11
|
// The following list of selectors is by increasing specificity:
|
9
12
|
extern const unsigned long Specificity_Star;
|
data/ext/libsass/context.cpp
CHANGED
@@ -512,7 +512,6 @@ namespace Sass {
|
|
512
512
|
register_function(ctx, index_sig, index, env);
|
513
513
|
register_function(ctx, join_sig, join, env);
|
514
514
|
register_function(ctx, append_sig, append, env);
|
515
|
-
register_function(ctx, compact_sig, compact, env);
|
516
515
|
register_function(ctx, zip_sig, zip, env);
|
517
516
|
register_function(ctx, list_separator_sig, list_separator, env);
|
518
517
|
// Map Functions
|
data/ext/libsass/debugger.hpp
CHANGED
@@ -290,6 +290,7 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
290
290
|
cerr << ind << "Import " << block;
|
291
291
|
cerr << " (" << pstate_source_position(node) << ")";
|
292
292
|
cerr << " " << block->tabs() << endl;
|
293
|
+
debug_ast(block->media_queries(), ind + " @ ");
|
293
294
|
// vector<string> files_;
|
294
295
|
for (auto imp : block->urls()) debug_ast(imp, "@ ", env);
|
295
296
|
} else if (dynamic_cast<Assignment*>(node)) {
|
@@ -342,7 +343,13 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
342
343
|
Definition* block = dynamic_cast<Definition*>(node);
|
343
344
|
cerr << ind << "Definition " << block;
|
344
345
|
cerr << " (" << pstate_source_position(node) << ")";
|
346
|
+
cerr << " [name: " << block->name() << "] ";
|
347
|
+
cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] ";
|
348
|
+
// this seems to lead to segfaults some times?
|
349
|
+
// cerr << " [signature: " << block->signature() << "] ";
|
350
|
+
cerr << " [native: " << block->native_function() << "] ";
|
345
351
|
cerr << " " << block->tabs() << endl;
|
352
|
+
debug_ast(block->parameters(), ind + " params: ", env);
|
346
353
|
if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
347
354
|
} else if (dynamic_cast<Mixin_Call*>(node)) {
|
348
355
|
Mixin_Call* block = dynamic_cast<Mixin_Call*>(node);
|
@@ -368,9 +375,14 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
368
375
|
else if (expression->type() == Textual::PERCENTAGE) cerr << " [PERCENTAGE]";
|
369
376
|
else if (expression->type() == Textual::DIMENSION) cerr << " [DIMENSION]";
|
370
377
|
else if (expression->type() == Textual::HEX) cerr << " [HEX]";
|
371
|
-
cerr << expression << " [" << expression->value() << "]"
|
378
|
+
cerr << expression << " [" << expression->value() << "]";
|
379
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
380
|
+
cerr << endl;
|
372
381
|
} else if (dynamic_cast<Variable*>(node)) {
|
373
382
|
Variable* expression = dynamic_cast<Variable*>(node);
|
383
|
+
cerr << ind << "Variable " << expression << " [" << expression->name() << "]";
|
384
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
385
|
+
cerr << endl;
|
374
386
|
cerr << ind << "Variable " << expression;
|
375
387
|
cerr << " (" << pstate_source_position(node) << ")";
|
376
388
|
cerr << " [" << expression->name() << "]" << endl;
|
@@ -378,6 +390,9 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
378
390
|
if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env);
|
379
391
|
} else if (dynamic_cast<Function_Call_Schema*>(node)) {
|
380
392
|
Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
|
393
|
+
cerr << ind << "Function_Call_Schema " << expression << "]";
|
394
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
395
|
+
cerr << endl;
|
381
396
|
cerr << ind << "Function_Call_Schema " << expression;
|
382
397
|
cerr << " (" << pstate_source_position(node) << ")";
|
383
398
|
cerr << "" << endl;
|
@@ -385,30 +400,65 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
385
400
|
debug_ast(expression->arguments(), ind + " args: ", env);
|
386
401
|
} else if (dynamic_cast<Function_Call*>(node)) {
|
387
402
|
Function_Call* expression = dynamic_cast<Function_Call*>(node);
|
403
|
+
cerr << ind << "Function_Call " << expression << " [" << expression->name() << "]";
|
404
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
405
|
+
cerr << endl;
|
388
406
|
cerr << ind << "Function_Call " << expression;
|
389
407
|
cerr << " (" << pstate_source_position(node) << ")";
|
390
408
|
cerr << " [" << expression->name() << "]" << endl;
|
391
409
|
debug_ast(expression->arguments(), ind + " args: ", env);
|
392
410
|
} else if (dynamic_cast<Arguments*>(node)) {
|
393
411
|
Arguments* expression = dynamic_cast<Arguments*>(node);
|
412
|
+
cerr << ind << "Arguments " << expression << "]";
|
413
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
414
|
+
cerr << endl;
|
394
415
|
cerr << ind << "Arguments " << expression;
|
395
416
|
cerr << " (" << pstate_source_position(node) << ")";
|
396
417
|
cerr << endl;
|
397
418
|
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
398
419
|
} else if (dynamic_cast<Argument*>(node)) {
|
399
420
|
Argument* expression = dynamic_cast<Argument*>(node);
|
421
|
+
cerr << ind << "Argument " << expression << " [" << expression->value() << "]";
|
422
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
423
|
+
if (expression->is_rest_argument()) cerr << " [is_rest_argument]";
|
424
|
+
if (expression->is_keyword_argument()) cerr << " [is_keyword_argument]";
|
425
|
+
cerr << endl;
|
400
426
|
cerr << ind << "Argument " << expression;
|
401
427
|
cerr << " (" << pstate_source_position(node) << ")";
|
402
|
-
cerr << " [" << expression->value() << "]"
|
428
|
+
cerr << " [" << expression->value() << "]";
|
429
|
+
cerr << " [name: " << expression->name() << "] ";
|
430
|
+
cerr << " [rest: " << expression->is_rest_argument() << "] ";
|
431
|
+
cerr << " [keyword: " << expression->is_keyword_argument() << "] " << endl;
|
403
432
|
debug_ast(expression->value(), ind + " value: ", env);
|
433
|
+
} else if (dynamic_cast<Parameters*>(node)) {
|
434
|
+
Parameters* expression = dynamic_cast<Parameters*>(node);
|
435
|
+
cerr << ind << "Parameters " << expression;
|
436
|
+
cerr << " (" << pstate_source_position(node) << ")";
|
437
|
+
cerr << " [has_optional: " << expression->has_optional_parameters() << "] ";
|
438
|
+
cerr << " [has_rest: " << expression->has_rest_parameter() << "] ";
|
439
|
+
cerr << endl;
|
440
|
+
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
441
|
+
} else if (dynamic_cast<Parameter*>(node)) {
|
442
|
+
Parameter* expression = dynamic_cast<Parameter*>(node);
|
443
|
+
cerr << ind << "Parameter " << expression;
|
444
|
+
cerr << " (" << pstate_source_position(node) << ")";
|
445
|
+
cerr << " [name: " << expression->name() << "] ";
|
446
|
+
cerr << " [default: " << expression->default_value() << "] ";
|
447
|
+
cerr << " [rest: " << expression->is_rest_parameter() << "] " << endl;
|
404
448
|
} else if (dynamic_cast<Unary_Expression*>(node)) {
|
405
449
|
Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
|
450
|
+
cerr << ind << "Unary_Expression " << expression << " [" << expression->type_name() << "]";
|
451
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
452
|
+
cerr << endl;
|
406
453
|
cerr << ind << "Unary_Expression " << expression;
|
407
454
|
cerr << " (" << pstate_source_position(node) << ")";
|
408
455
|
cerr << " [" << expression->type() << "]" << endl;
|
409
456
|
debug_ast(expression->operand(), ind + " operand: ", env);
|
410
457
|
} else if (dynamic_cast<Binary_Expression*>(node)) {
|
411
458
|
Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
|
459
|
+
cerr << ind << "Binary_Expression " << expression << " [" << expression->type_name() << "]";
|
460
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
461
|
+
cerr << endl;
|
412
462
|
cerr << ind << "Binary_Expression " << expression;
|
413
463
|
cerr << " (" << pstate_source_position(node) << ")";
|
414
464
|
cerr << " [" << expression->type() << "]" << endl;
|
@@ -426,7 +476,11 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
426
476
|
cerr << " (" << expression->length() << ") " <<
|
427
477
|
(expression->separator() == Sass::List::Separator::COMMA ? "Comma " : "Space ") <<
|
428
478
|
" [delayed: " << expression->is_delayed() << "] " <<
|
479
|
+
" [interpolant: " << expression->is_interpolant() << "]";
|
480
|
+
if (expression->is_arglist()) cerr << " [is_arglist]";
|
481
|
+
cerr << endl;
|
429
482
|
" [interpolant: " << expression->is_interpolant() << "] " <<
|
483
|
+
" [arglist: " << expression->is_arglist() << "] " <<
|
430
484
|
endl;
|
431
485
|
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
432
486
|
} else if (dynamic_cast<Content*>(node)) {
|
@@ -436,21 +490,36 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
436
490
|
cerr << " [Statement]" << endl;
|
437
491
|
} else if (dynamic_cast<Boolean*>(node)) {
|
438
492
|
Boolean* expression = dynamic_cast<Boolean*>(node);
|
493
|
+
cerr << ind << "Boolean " << expression << " [" << expression->value() << "]";
|
494
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
495
|
+
cerr << endl;
|
439
496
|
cerr << ind << "Boolean " << expression;
|
440
497
|
cerr << " (" << pstate_source_position(node) << ")";
|
441
498
|
cerr << " [" << expression->value() << "]" << endl;
|
442
499
|
} else if (dynamic_cast<Color*>(node)) {
|
443
500
|
Color* expression = dynamic_cast<Color*>(node);
|
501
|
+
cerr << ind << "Color " << expression << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]";
|
502
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
503
|
+
cerr << endl;
|
444
504
|
cerr << ind << "Color " << expression;
|
445
505
|
cerr << " (" << pstate_source_position(node) << ")";
|
446
506
|
cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << endl;
|
447
507
|
} else if (dynamic_cast<Number*>(node)) {
|
448
508
|
Number* expression = dynamic_cast<Number*>(node);
|
509
|
+
cerr << ind << "Number " << expression << " [" << expression->value() << expression->unit() << "]";
|
510
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
511
|
+
cerr << endl;
|
449
512
|
cerr << ind << "Number " << expression;
|
450
513
|
cerr << " (" << pstate_source_position(node) << ")";
|
451
514
|
cerr << " [" << expression->value() << expression->unit() << "]" << endl;
|
452
515
|
} else if (dynamic_cast<String_Quoted*>(node)) {
|
453
516
|
String_Quoted* expression = dynamic_cast<String_Quoted*>(node);
|
517
|
+
cerr << ind << "String_Quoted : " << expression << " [";
|
518
|
+
cerr << prettyprint(expression->value()) << "]";
|
519
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
520
|
+
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
|
521
|
+
if (expression->quote_mark()) cerr << " [quote_mark]";
|
522
|
+
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
|
454
523
|
cerr << ind << "String_Quoted : " << expression;
|
455
524
|
cerr << " (" << pstate_source_position(node) << ")";
|
456
525
|
cerr << " [" << prettyprint(expression->value()) << "]" <<
|
@@ -461,13 +530,23 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
461
530
|
} else if (dynamic_cast<String_Constant*>(node)) {
|
462
531
|
String_Constant* expression = dynamic_cast<String_Constant*>(node);
|
463
532
|
cerr << ind << "String_Constant : " << expression;
|
533
|
+
cerr << " [" << prettyprint(expression->value()) << "]";
|
534
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
535
|
+
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
|
536
|
+
cerr " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
|
537
|
+
cerr << ind << "String_Constant : " << expression;
|
464
538
|
cerr << " (" << pstate_source_position(node) << ")";
|
465
539
|
cerr << " [" << prettyprint(expression->value()) << "]" <<
|
466
540
|
(expression->is_delayed() ? " {delayed}" : "") <<
|
467
541
|
(expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
|
542
|
+
(expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") <<
|
468
543
|
" <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
|
469
544
|
} else if (dynamic_cast<String_Schema*>(node)) {
|
470
545
|
String_Schema* expression = dynamic_cast<String_Schema*>(node);
|
546
|
+
cerr << ind << "String_Schema " << expression << " [" << expression->concrete_type() << "]";
|
547
|
+
if (expression->is_delayed()) cerr << " [delayed]";
|
548
|
+
if (expression->has_interpolants()) cerr << " [has_interpolants]";
|
549
|
+
cerr " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
|
471
550
|
cerr << ind << "String_Schema " << expression;
|
472
551
|
cerr << " (" << pstate_source_position(node) << ")";
|
473
552
|
cerr << " " << expression->concrete_type() <<
|
@@ -476,6 +555,9 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
|
|
476
555
|
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
|
477
556
|
} else if (dynamic_cast<String*>(node)) {
|
478
557
|
String* expression = dynamic_cast<String*>(node);
|
558
|
+
cerr << ind << "String " << expression << expression->concrete_type();
|
559
|
+
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
|
560
|
+
cerr " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
|
479
561
|
cerr << ind << "String " << expression;
|
480
562
|
cerr << " (" << pstate_source_position(node) << ")";
|
481
563
|
cerr << expression->concrete_type() <<
|
@@ -8,18 +8,28 @@ namespace Sass {
|
|
8
8
|
: type(type), pstate(pstate), message(message)
|
9
9
|
{ }
|
10
10
|
|
11
|
-
void
|
11
|
+
void warn(string msg, ParserState pstate)
|
12
12
|
{
|
13
|
-
|
13
|
+
cerr << "Warning: " << msg<< endl;
|
14
14
|
}
|
15
15
|
|
16
|
-
void
|
16
|
+
void warn(string msg, ParserState pstate, Backtrace* bt)
|
17
17
|
{
|
18
|
-
|
19
18
|
Backtrace top(bt, pstate, "");
|
20
19
|
msg += top.to_string();
|
20
|
+
warn(msg, pstate);
|
21
|
+
}
|
21
22
|
|
23
|
+
void error(string msg, ParserState pstate)
|
24
|
+
{
|
22
25
|
throw Sass_Error(Sass_Error::syntax, pstate, msg);
|
23
26
|
}
|
24
27
|
|
28
|
+
void error(string msg, ParserState pstate, Backtrace* bt)
|
29
|
+
{
|
30
|
+
Backtrace top(bt, pstate, "");
|
31
|
+
msg += "\n" + top.to_string();
|
32
|
+
error(msg, pstate);
|
33
|
+
}
|
34
|
+
|
25
35
|
}
|
data/ext/libsass/eval.cpp
CHANGED
@@ -435,8 +435,23 @@ namespace Sass {
|
|
435
435
|
}
|
436
436
|
// not a logical connective, so go ahead and eval the rhs
|
437
437
|
Expression* rhs = b->right()->perform(this);
|
438
|
-
|
439
|
-
|
438
|
+
// maybe fully evaluate structure
|
439
|
+
if (op_type == Binary_Expression::EQ ||
|
440
|
+
op_type == Binary_Expression::NEQ ||
|
441
|
+
op_type == Binary_Expression::GT ||
|
442
|
+
op_type == Binary_Expression::GTE ||
|
443
|
+
op_type == Binary_Expression::LT ||
|
444
|
+
op_type == Binary_Expression::LTE)
|
445
|
+
{
|
446
|
+
rhs->is_expanded(false);
|
447
|
+
rhs->set_delayed(false);
|
448
|
+
rhs = rhs->perform(this);
|
449
|
+
}
|
450
|
+
else
|
451
|
+
{
|
452
|
+
rhs->is_delayed(false);
|
453
|
+
rhs = rhs->perform(this);
|
454
|
+
}
|
440
455
|
|
441
456
|
// see if it's a relational expression
|
442
457
|
switch(op_type) {
|
@@ -512,6 +527,9 @@ namespace Sass {
|
|
512
527
|
|
513
528
|
Expression* Eval::operator()(Function_Call* c)
|
514
529
|
{
|
530
|
+
if (backtrace->parent != NULL && backtrace->depth() > Constants::MaxCallStack) {
|
531
|
+
error("Stack depth exceeded max of " + to_string(Constants::MaxCallStack), c->pstate(), backtrace);
|
532
|
+
}
|
515
533
|
string name(Util::normalize_underscores(c->name()));
|
516
534
|
string full_name(name + "[f]");
|
517
535
|
Arguments* args = c->arguments();
|
@@ -700,7 +718,11 @@ namespace Sass {
|
|
700
718
|
if (auto str = dynamic_cast<String_Quoted*>(value)) {
|
701
719
|
value = new (ctx.mem) String_Quoted(*str);
|
702
720
|
} else if (auto str = dynamic_cast<String_Constant*>(value)) {
|
703
|
-
|
721
|
+
if (str->quote_mark()) {
|
722
|
+
value = new (ctx.mem) String_Quoted(str->pstate(), str->perform(&to_string));
|
723
|
+
} else {
|
724
|
+
value = new (ctx.mem) String_Constant(str->pstate(), unquote(str->value()));
|
725
|
+
}
|
704
726
|
}
|
705
727
|
}
|
706
728
|
else if (value->concrete_type() == Expression::LIST) {
|
@@ -785,6 +807,7 @@ namespace Sass {
|
|
785
807
|
|
786
808
|
Expression* Eval::operator()(Number* n)
|
787
809
|
{
|
810
|
+
n->normalize();
|
788
811
|
// behave according to as ruby sass (add leading zero)
|
789
812
|
return new (ctx.mem) Number(n->pstate(),
|
790
813
|
n->value(),
|
@@ -812,12 +835,18 @@ namespace Sass {
|
|
812
835
|
string Eval::interpolation(Expression* s) {
|
813
836
|
if (String_Quoted* str_quoted = dynamic_cast<String_Quoted*>(s)) {
|
814
837
|
if (str_quoted->quote_mark()) {
|
815
|
-
|
838
|
+
if (str_quoted->quote_mark() == '*' || str_quoted->is_delayed()) {
|
839
|
+
return interpolation(new (ctx.mem) String_Constant(*str_quoted));
|
840
|
+
} else {
|
841
|
+
return string_escape(quote(str_quoted->value(), str_quoted->quote_mark()));
|
842
|
+
}
|
816
843
|
} else {
|
817
844
|
return evacuate_escapes(str_quoted->value());
|
818
845
|
}
|
819
846
|
} else if (String_Constant* str_constant = dynamic_cast<String_Constant*>(s)) {
|
820
|
-
|
847
|
+
string str = str_constant->value();
|
848
|
+
if (!str_constant->quote_mark()) str = unquote(str);
|
849
|
+
return evacuate_escapes(str);
|
821
850
|
} else if (String_Schema* str_schema = dynamic_cast<String_Schema*>(s)) {
|
822
851
|
string res = "";
|
823
852
|
for(auto i : str_schema->elements())
|
@@ -872,6 +901,9 @@ namespace Sass {
|
|
872
901
|
{
|
873
902
|
string acc;
|
874
903
|
for (size_t i = 0, L = s->length(); i < L; ++i) {
|
904
|
+
if (String_Quoted* str_quoted = dynamic_cast<String_Quoted*>((*s)[i])) {
|
905
|
+
if (!str_quoted->is_delayed()) str_quoted->value(string_eval_escapes(str_quoted->value()));
|
906
|
+
}
|
875
907
|
acc += interpolation((*s)[i]);
|
876
908
|
}
|
877
909
|
String_Quoted* str = new (ctx.mem) String_Quoted(s->pstate(), acc);
|
@@ -1042,13 +1074,8 @@ namespace Sass {
|
|
1042
1074
|
} break;
|
1043
1075
|
|
1044
1076
|
case Expression::NUMBER: {
|
1045
|
-
|
1046
|
-
|
1047
|
-
Number tmp_r(*r);
|
1048
|
-
tmp_r.normalize(l->find_convertible_unit());
|
1049
|
-
return l->unit() == tmp_r.unit() && l->value() == tmp_r.value()
|
1050
|
-
? true
|
1051
|
-
: false;
|
1077
|
+
return *static_cast<Number*>(lhs) ==
|
1078
|
+
*static_cast<Number*>(rhs);
|
1052
1079
|
} break;
|
1053
1080
|
|
1054
1081
|
case Expression::COLOR: {
|
@@ -1139,8 +1166,8 @@ namespace Sass {
|
|
1139
1166
|
v->denominator_units() = r->denominator_units();
|
1140
1167
|
}
|
1141
1168
|
|
1142
|
-
v->value(ops[op](lv, tmp.value()));
|
1143
1169
|
if (op == Binary_Expression::MUL) {
|
1170
|
+
v->value(ops[op](lv, rv));
|
1144
1171
|
for (size_t i = 0, S = r->numerator_units().size(); i < S; ++i) {
|
1145
1172
|
v->numerator_units().push_back(r->numerator_units()[i]);
|
1146
1173
|
}
|
@@ -1149,14 +1176,17 @@ namespace Sass {
|
|
1149
1176
|
}
|
1150
1177
|
}
|
1151
1178
|
else if (op == Binary_Expression::DIV) {
|
1179
|
+
v->value(ops[op](lv, rv));
|
1152
1180
|
for (size_t i = 0, S = r->numerator_units().size(); i < S; ++i) {
|
1153
1181
|
v->denominator_units().push_back(r->numerator_units()[i]);
|
1154
1182
|
}
|
1155
1183
|
for (size_t i = 0, S = r->denominator_units().size(); i < S; ++i) {
|
1156
1184
|
v->numerator_units().push_back(r->denominator_units()[i]);
|
1157
1185
|
}
|
1186
|
+
} else {
|
1187
|
+
v->value(ops[op](lv, tmp.value()));
|
1158
1188
|
}
|
1159
|
-
v->normalize();
|
1189
|
+
// v->normalize();
|
1160
1190
|
return v;
|
1161
1191
|
}
|
1162
1192
|
|