sassc 1.0.0 → 1.1.0
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/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
|
|