sassc4 2.4.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 +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +97 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +51 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/contrib/plugin.cpp +60 -0
- data/ext/libsass/include/sass/base.h +97 -0
- data/ext/libsass/include/sass/context.h +174 -0
- data/ext/libsass/include/sass/functions.h +139 -0
- data/ext/libsass/include/sass/values.h +145 -0
- data/ext/libsass/include/sass/version.h +12 -0
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/include/sass2scss.h +120 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +953 -0
- data/ext/libsass/src/ast.hpp +1064 -0
- data/ext/libsass/src/ast2c.cpp +80 -0
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +140 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
- data/ext/libsass/src/ast_helpers.hpp +316 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1070 -0
- data/ext/libsass/src/ast_selectors.hpp +523 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/b64/cencode.h +32 -0
- data/ext/libsass/src/b64/encode.h +79 -0
- data/ext/libsass/src/backtrace.cpp +50 -0
- data/ext/libsass/src/backtrace.hpp +29 -0
- data/ext/libsass/src/base64vlq.cpp +47 -0
- data/ext/libsass/src/base64vlq.hpp +30 -0
- data/ext/libsass/src/bind.cpp +312 -0
- data/ext/libsass/src/bind.hpp +15 -0
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/src/cencode.c +106 -0
- data/ext/libsass/src/check_nesting.cpp +393 -0
- data/ext/libsass/src/check_nesting.hpp +70 -0
- data/ext/libsass/src/color_maps.cpp +652 -0
- data/ext/libsass/src/color_maps.hpp +323 -0
- data/ext/libsass/src/color_spaces.cpp +241 -0
- data/ext/libsass/src/color_spaces.hpp +227 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +870 -0
- data/ext/libsass/src/context.hpp +140 -0
- data/ext/libsass/src/cssize.cpp +521 -0
- data/ext/libsass/src/cssize.hpp +71 -0
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debug.hpp +43 -0
- data/ext/libsass/src/debugger.hpp +964 -0
- data/ext/libsass/src/emitter.cpp +297 -0
- data/ext/libsass/src/emitter.hpp +101 -0
- data/ext/libsass/src/environment.cpp +260 -0
- data/ext/libsass/src/environment.hpp +124 -0
- data/ext/libsass/src/error_handling.cpp +239 -0
- data/ext/libsass/src/error_handling.hpp +248 -0
- data/ext/libsass/src/eval.cpp +1543 -0
- data/ext/libsass/src/eval.hpp +110 -0
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +875 -0
- data/ext/libsass/src/expand.hpp +98 -0
- data/ext/libsass/src/extender.cpp +1226 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +531 -0
- data/ext/libsass/src/file.hpp +124 -0
- data/ext/libsass/src/fn_colors.cpp +836 -0
- data/ext/libsass/src/fn_colors.hpp +99 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +248 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +246 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +159 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1126 -0
- data/ext/libsass/src/inspect.hpp +101 -0
- data/ext/libsass/src/json.cpp +1436 -0
- data/ext/libsass/src/json.hpp +117 -0
- data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
- data/ext/libsass/src/lexer.cpp +122 -0
- data/ext/libsass/src/lexer.hpp +304 -0
- data/ext/libsass/src/listize.cpp +70 -0
- data/ext/libsass/src/listize.hpp +37 -0
- data/ext/libsass/src/mapping.hpp +19 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +223 -0
- data/ext/libsass/src/operators.cpp +267 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +320 -0
- data/ext/libsass/src/output.hpp +47 -0
- data/ext/libsass/src/parser.cpp +3059 -0
- data/ext/libsass/src/parser.hpp +395 -0
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +188 -0
- data/ext/libsass/src/plugins.hpp +57 -0
- data/ext/libsass/src/position.cpp +163 -0
- data/ext/libsass/src/position.hpp +147 -0
- data/ext/libsass/src/prelexer.cpp +1780 -0
- data/ext/libsass/src/prelexer.hpp +484 -0
- data/ext/libsass/src/remove_placeholders.cpp +86 -0
- data/ext/libsass/src/remove_placeholders.hpp +37 -0
- data/ext/libsass/src/sass.cpp +156 -0
- data/ext/libsass/src/sass.hpp +147 -0
- data/ext/libsass/src/sass2scss.cpp +895 -0
- data/ext/libsass/src/sass_context.cpp +742 -0
- data/ext/libsass/src/sass_context.hpp +129 -0
- data/ext/libsass/src/sass_functions.cpp +210 -0
- data/ext/libsass/src/sass_functions.hpp +50 -0
- data/ext/libsass/src/sass_values.cpp +362 -0
- data/ext/libsass/src/sass_values.hpp +82 -0
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +202 -0
- data/ext/libsass/src/source_map.hpp +65 -0
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +114 -0
- data/ext/libsass/src/to_value.hpp +46 -0
- data/ext/libsass/src/units.cpp +507 -0
- data/ext/libsass/src/units.hpp +110 -0
- data/ext/libsass/src/utf8/checked.h +336 -0
- data/ext/libsass/src/utf8/core.h +332 -0
- data/ext/libsass/src/utf8/unchecked.h +235 -0
- data/ext/libsass/src/utf8.h +34 -0
- data/ext/libsass/src/utf8_string.cpp +104 -0
- data/ext/libsass/src/utf8_string.hpp +38 -0
- data/ext/libsass/src/util.cpp +723 -0
- data/ext/libsass/src/util.hpp +105 -0
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +140 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +141 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +73 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +159 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +64 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +17 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +69 -0
- data/test/css_color_level4_test.rb +168 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +340 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +396 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include <cmath>
|
|
6
|
+
#include "operators.hpp"
|
|
7
|
+
|
|
8
|
+
namespace Sass {
|
|
9
|
+
|
|
10
|
+
namespace Operators {
|
|
11
|
+
|
|
12
|
+
inline double add(double x, double y) { return x + y; }
|
|
13
|
+
inline double sub(double x, double y) { return x - y; }
|
|
14
|
+
inline double mul(double x, double y) { return x * y; }
|
|
15
|
+
inline double div(double x, double y) { return x / y; } // x/0 checked by caller
|
|
16
|
+
|
|
17
|
+
inline double mod(double x, double y) { // x/0 checked by caller
|
|
18
|
+
if ((x > 0 && y < 0) || (x < 0 && y > 0)) {
|
|
19
|
+
double ret = std::fmod(x, y);
|
|
20
|
+
return ret ? ret + y : ret;
|
|
21
|
+
} else {
|
|
22
|
+
return std::fmod(x, y);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
typedef double (*bop)(double, double);
|
|
27
|
+
bop ops[Sass_OP::NUM_OPS] = {
|
|
28
|
+
0, 0, // and, or
|
|
29
|
+
0, 0, 0, 0, 0, 0, // eq, neq, gt, gte, lt, lte
|
|
30
|
+
add, sub, mul, div, mod
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/* static function, has no pstate or traces */
|
|
34
|
+
bool eq(ExpressionObj lhs, ExpressionObj rhs)
|
|
35
|
+
{
|
|
36
|
+
// operation is undefined if one is not a number
|
|
37
|
+
if (!lhs || !rhs) throw Exception::UndefinedOperation(lhs, rhs, Sass_OP::EQ);
|
|
38
|
+
// use compare operator from ast node
|
|
39
|
+
return *lhs == *rhs;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* static function, throws OperationError, has no pstate or traces */
|
|
43
|
+
bool cmp(ExpressionObj lhs, ExpressionObj rhs, const Sass_OP op)
|
|
44
|
+
{
|
|
45
|
+
// can only compare numbers!?
|
|
46
|
+
Number_Obj l = Cast<Number>(lhs);
|
|
47
|
+
Number_Obj r = Cast<Number>(rhs);
|
|
48
|
+
// operation is undefined if one is not a number
|
|
49
|
+
if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op);
|
|
50
|
+
// use compare operator from ast node
|
|
51
|
+
return *l < *r;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* static functions, throws OperationError, has no pstate or traces */
|
|
55
|
+
bool lt(ExpressionObj lhs, ExpressionObj rhs) { return cmp(lhs, rhs, Sass_OP::LT); }
|
|
56
|
+
bool neq(ExpressionObj lhs, ExpressionObj rhs) { return eq(lhs, rhs) == false; }
|
|
57
|
+
bool gt(ExpressionObj lhs, ExpressionObj rhs) { return !cmp(lhs, rhs, Sass_OP::GT) && neq(lhs, rhs); }
|
|
58
|
+
bool lte(ExpressionObj lhs, ExpressionObj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
|
|
59
|
+
bool gte(ExpressionObj lhs, ExpressionObj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
|
|
60
|
+
|
|
61
|
+
/* colour math deprecation warning */
|
|
62
|
+
void op_color_deprecation(enum Sass_OP op, sass::string lsh, sass::string rhs, const SourceSpan& pstate)
|
|
63
|
+
{
|
|
64
|
+
deprecated(
|
|
65
|
+
"The operation `" + lsh + " " + sass_op_to_name(op) + " " + rhs +
|
|
66
|
+
"` is deprecated and will be an error in future versions.",
|
|
67
|
+
"Consider using Sass's color functions instead.\n"
|
|
68
|
+
"https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions",
|
|
69
|
+
/*with_column=*/false, pstate);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
73
|
+
Value* op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)
|
|
74
|
+
{
|
|
75
|
+
enum Sass_OP op = operand.operand;
|
|
76
|
+
|
|
77
|
+
String_Quoted* lqstr = Cast<String_Quoted>(&lhs);
|
|
78
|
+
String_Quoted* rqstr = Cast<String_Quoted>(&rhs);
|
|
79
|
+
|
|
80
|
+
sass::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
|
|
81
|
+
sass::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
|
|
82
|
+
|
|
83
|
+
if (Cast<Null>(&lhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
|
|
84
|
+
if (Cast<Null>(&rhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
|
|
85
|
+
|
|
86
|
+
sass::string sep;
|
|
87
|
+
switch (op) {
|
|
88
|
+
case Sass_OP::ADD: sep = ""; break;
|
|
89
|
+
case Sass_OP::SUB: sep = "-"; break;
|
|
90
|
+
case Sass_OP::DIV: sep = "/"; break;
|
|
91
|
+
case Sass_OP::EQ: sep = "=="; break;
|
|
92
|
+
case Sass_OP::NEQ: sep = "!="; break;
|
|
93
|
+
case Sass_OP::LT: sep = "<"; break;
|
|
94
|
+
case Sass_OP::GT: sep = ">"; break;
|
|
95
|
+
case Sass_OP::LTE: sep = "<="; break;
|
|
96
|
+
case Sass_OP::GTE: sep = ">="; break;
|
|
97
|
+
default:
|
|
98
|
+
throw Exception::UndefinedOperation(&lhs, &rhs, op);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (op == Sass_OP::ADD) {
|
|
103
|
+
// create string that might be quoted on output (but do not unquote what we pass)
|
|
104
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, lstr + rstr, 0, false, true);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// add whitespace around operator
|
|
108
|
+
// but only if result is not delayed
|
|
109
|
+
if (sep != "" && delayed == false) {
|
|
110
|
+
if (operand.ws_before) sep = " " + sep;
|
|
111
|
+
if (operand.ws_after) sep = sep + " ";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (op == Sass_OP::SUB || op == Sass_OP::DIV) {
|
|
115
|
+
if (lqstr && lqstr->quote_mark()) lstr = quote(lstr);
|
|
116
|
+
if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* ToDo: allow to operate also with hsla colors */
|
|
123
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
124
|
+
Value* op_colors(enum Sass_OP op, const Color_RGBA& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)
|
|
125
|
+
{
|
|
126
|
+
|
|
127
|
+
if (lhs.a() != rhs.a()) {
|
|
128
|
+
throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
|
|
129
|
+
}
|
|
130
|
+
if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && (!rhs.r() || !rhs.g() || !rhs.b())) {
|
|
131
|
+
throw Exception::ZeroDivisionError(lhs, rhs);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
|
|
135
|
+
|
|
136
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
|
137
|
+
pstate,
|
|
138
|
+
ops[op](lhs.r(), rhs.r()),
|
|
139
|
+
ops[op](lhs.g(), rhs.g()),
|
|
140
|
+
ops[op](lhs.b(), rhs.b()),
|
|
141
|
+
lhs.a());
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
145
|
+
Value* op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)
|
|
146
|
+
{
|
|
147
|
+
double lval = lhs.value();
|
|
148
|
+
double rval = rhs.value();
|
|
149
|
+
|
|
150
|
+
if (op == Sass_OP::MOD && rval == 0) {
|
|
151
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (op == Sass_OP::DIV && rval == 0) {
|
|
155
|
+
sass::string result(lval ? "Infinity" : "NaN");
|
|
156
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
size_t l_n_units = lhs.numerators.size();
|
|
160
|
+
size_t l_d_units = lhs.numerators.size();
|
|
161
|
+
size_t r_n_units = rhs.denominators.size();
|
|
162
|
+
size_t r_d_units = rhs.denominators.size();
|
|
163
|
+
// optimize out the most common and simplest case
|
|
164
|
+
if (l_n_units == r_n_units && l_d_units == r_d_units) {
|
|
165
|
+
if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {
|
|
166
|
+
if (lhs.numerators == rhs.numerators) {
|
|
167
|
+
if (lhs.denominators == rhs.denominators) {
|
|
168
|
+
Number* v = SASS_MEMORY_COPY(&lhs);
|
|
169
|
+
v->value(ops[op](lval, rval));
|
|
170
|
+
return v;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
Number_Obj v = SASS_MEMORY_COPY(&lhs);
|
|
177
|
+
|
|
178
|
+
if (lhs.is_unitless() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
|
|
179
|
+
v->numerators = rhs.numerators;
|
|
180
|
+
v->denominators = rhs.denominators;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (op == Sass_OP::MUL) {
|
|
184
|
+
v->value(ops[op](lval, rval));
|
|
185
|
+
v->numerators.insert(v->numerators.end(),
|
|
186
|
+
rhs.numerators.begin(), rhs.numerators.end()
|
|
187
|
+
);
|
|
188
|
+
v->denominators.insert(v->denominators.end(),
|
|
189
|
+
rhs.denominators.begin(), rhs.denominators.end()
|
|
190
|
+
);
|
|
191
|
+
v->reduce();
|
|
192
|
+
}
|
|
193
|
+
else if (op == Sass_OP::DIV) {
|
|
194
|
+
v->value(ops[op](lval, rval));
|
|
195
|
+
v->numerators.insert(v->numerators.end(),
|
|
196
|
+
rhs.denominators.begin(), rhs.denominators.end()
|
|
197
|
+
);
|
|
198
|
+
v->denominators.insert(v->denominators.end(),
|
|
199
|
+
rhs.numerators.begin(), rhs.numerators.end()
|
|
200
|
+
);
|
|
201
|
+
v->reduce();
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
Number ln(lhs), rn(rhs);
|
|
205
|
+
ln.reduce(); rn.reduce();
|
|
206
|
+
double f(rn.convert_factor(ln));
|
|
207
|
+
v->value(ops[op](lval, rn.value() * f));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
v->pstate(pstate);
|
|
211
|
+
return v.detach();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
215
|
+
Value* op_number_color(enum Sass_OP op, const Number& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)
|
|
216
|
+
{
|
|
217
|
+
double lval = lhs.value();
|
|
218
|
+
|
|
219
|
+
switch (op) {
|
|
220
|
+
case Sass_OP::ADD:
|
|
221
|
+
case Sass_OP::MUL: {
|
|
222
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate);
|
|
223
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
|
224
|
+
pstate,
|
|
225
|
+
ops[op](lval, rhs.r()),
|
|
226
|
+
ops[op](lval, rhs.g()),
|
|
227
|
+
ops[op](lval, rhs.b()),
|
|
228
|
+
rhs.a());
|
|
229
|
+
}
|
|
230
|
+
case Sass_OP::SUB:
|
|
231
|
+
case Sass_OP::DIV: {
|
|
232
|
+
sass::string color(rhs.to_string(opt));
|
|
233
|
+
op_color_deprecation(op, lhs.to_string(), color, pstate);
|
|
234
|
+
return SASS_MEMORY_NEW(String_Quoted,
|
|
235
|
+
pstate,
|
|
236
|
+
lhs.to_string(opt)
|
|
237
|
+
+ sass_op_separator(op)
|
|
238
|
+
+ color);
|
|
239
|
+
}
|
|
240
|
+
default: break;
|
|
241
|
+
}
|
|
242
|
+
throw Exception::UndefinedOperation(&lhs, &rhs, op);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
246
|
+
Value* op_color_number(enum Sass_OP op, const Color_RGBA& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)
|
|
247
|
+
{
|
|
248
|
+
double rval = rhs.value();
|
|
249
|
+
|
|
250
|
+
if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && rval == 0) {
|
|
251
|
+
// comparison of Fixnum with Float failed?
|
|
252
|
+
throw Exception::ZeroDivisionError(lhs, rhs);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
|
|
256
|
+
|
|
257
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
|
258
|
+
pstate,
|
|
259
|
+
ops[op](lhs.r(), rval),
|
|
260
|
+
ops[op](lhs.g(), rval),
|
|
261
|
+
ops[op](lhs.b(), rval),
|
|
262
|
+
lhs.a());
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef SASS_OPERATORS_H
|
|
2
|
+
#define SASS_OPERATORS_H
|
|
3
|
+
|
|
4
|
+
#include "values.hpp"
|
|
5
|
+
#include "sass/values.h"
|
|
6
|
+
|
|
7
|
+
namespace Sass {
|
|
8
|
+
|
|
9
|
+
namespace Operators {
|
|
10
|
+
|
|
11
|
+
// equality operator using AST Node operator==
|
|
12
|
+
bool eq(ExpressionObj, ExpressionObj);
|
|
13
|
+
bool neq(ExpressionObj, ExpressionObj);
|
|
14
|
+
// specific operators based on cmp and eq
|
|
15
|
+
bool lt(ExpressionObj, ExpressionObj);
|
|
16
|
+
bool gt(ExpressionObj, ExpressionObj);
|
|
17
|
+
bool lte(ExpressionObj, ExpressionObj);
|
|
18
|
+
bool gte(ExpressionObj, ExpressionObj);
|
|
19
|
+
// arithmetic for all the combinations that matter
|
|
20
|
+
Value* op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);
|
|
21
|
+
Value* op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);
|
|
22
|
+
Value* op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);
|
|
23
|
+
Value* op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);
|
|
24
|
+
Value* op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);
|
|
25
|
+
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#endif
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#ifndef SASS_ORDERED_MAP_H
|
|
2
|
+
#define SASS_ORDERED_MAP_H
|
|
3
|
+
|
|
4
|
+
namespace Sass {
|
|
5
|
+
|
|
6
|
+
// ##########################################################################
|
|
7
|
+
// Very simple and limited container for insert ordered hash map.
|
|
8
|
+
// Piggy-back implementation on std::unordered_map and sass::vector
|
|
9
|
+
// ##########################################################################
|
|
10
|
+
template<
|
|
11
|
+
class Key,
|
|
12
|
+
class T,
|
|
13
|
+
class Hash = std::hash<Key>,
|
|
14
|
+
class KeyEqual = std::equal_to<Key>,
|
|
15
|
+
class Allocator = std::allocator<std::pair<const Key, T>>
|
|
16
|
+
>
|
|
17
|
+
class ordered_map {
|
|
18
|
+
|
|
19
|
+
private:
|
|
20
|
+
|
|
21
|
+
using map_type = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>;
|
|
22
|
+
using map_iterator = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>::iterator;
|
|
23
|
+
using map_const_iterator = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>::const_iterator;
|
|
24
|
+
|
|
25
|
+
// The main unordered map
|
|
26
|
+
map_type _map;
|
|
27
|
+
|
|
28
|
+
// Keep insertion order
|
|
29
|
+
sass::vector<Key> _keys;
|
|
30
|
+
sass::vector<T> _values;
|
|
31
|
+
|
|
32
|
+
const KeyEqual _keyEqual;
|
|
33
|
+
|
|
34
|
+
public:
|
|
35
|
+
|
|
36
|
+
ordered_map() :
|
|
37
|
+
_keyEqual(KeyEqual())
|
|
38
|
+
{
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ordered_map& operator= (const ordered_map& other) {
|
|
42
|
+
_map = other._map;
|
|
43
|
+
_keys = other._keys;
|
|
44
|
+
_values = other._values;
|
|
45
|
+
return *this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
std::pair<Key, T> front() {
|
|
49
|
+
return std::make_pair(
|
|
50
|
+
_keys.front(),
|
|
51
|
+
_values.front()
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
bool empty() const {
|
|
56
|
+
return _keys.empty();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void insert(const Key& key, const T& val) {
|
|
60
|
+
if (!hasKey(key)) {
|
|
61
|
+
_values.push_back(val);
|
|
62
|
+
_keys.push_back(key);
|
|
63
|
+
}
|
|
64
|
+
_map[key] = val;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
bool hasKey(const Key& key) const {
|
|
68
|
+
return _map.find(key) != _map.end();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
bool erase(const Key& key) {
|
|
72
|
+
_map.erase(key);
|
|
73
|
+
// find the position in the array
|
|
74
|
+
for (size_t i = 0; i < _keys.size(); i += 1) {
|
|
75
|
+
if (_keyEqual(key, _keys[i])) {
|
|
76
|
+
_keys.erase(_keys.begin() + i);
|
|
77
|
+
_values.erase(_values.begin() + i);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const sass::vector<Key>& keys() const { return _keys; }
|
|
85
|
+
const sass::vector<T>& values() const { return _values; }
|
|
86
|
+
|
|
87
|
+
const T& get(const Key& key) {
|
|
88
|
+
if (hasKey(key)) {
|
|
89
|
+
return _map[key];
|
|
90
|
+
}
|
|
91
|
+
throw std::runtime_error("Key does not exist");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
using iterator = typename sass::vector<Key>::iterator;
|
|
95
|
+
using const_iterator = typename sass::vector<Key>::const_iterator;
|
|
96
|
+
using reverse_iterator = typename sass::vector<Key>::reverse_iterator;
|
|
97
|
+
using const_reverse_iterator = typename sass::vector<Key>::const_reverse_iterator;
|
|
98
|
+
|
|
99
|
+
typename sass::vector<Key>::iterator end() { return _keys.end(); }
|
|
100
|
+
typename sass::vector<Key>::iterator begin() { return _keys.begin(); }
|
|
101
|
+
typename sass::vector<Key>::reverse_iterator rend() { return _keys.rend(); }
|
|
102
|
+
typename sass::vector<Key>::reverse_iterator rbegin() { return _keys.rbegin(); }
|
|
103
|
+
typename sass::vector<Key>::const_iterator end() const { return _keys.end(); }
|
|
104
|
+
typename sass::vector<Key>::const_iterator begin() const { return _keys.begin(); }
|
|
105
|
+
typename sass::vector<Key>::const_reverse_iterator rend() const { return _keys.rend(); }
|
|
106
|
+
typename sass::vector<Key>::const_reverse_iterator rbegin() const { return _keys.rbegin(); }
|
|
107
|
+
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#endif
|