sassc 2.0.1 → 2.1.0.pre1

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.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -0,0 +1,130 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "ast.hpp"
6
+ #include "context.hpp"
7
+ #include "node.hpp"
8
+ #include "eval.hpp"
9
+ #include "extend.hpp"
10
+ #include "emitter.hpp"
11
+ #include "color_maps.hpp"
12
+ #include "ast_fwd_decl.hpp"
13
+ #include <set>
14
+ #include <iomanip>
15
+ #include <iostream>
16
+ #include <algorithm>
17
+ #include <functional>
18
+ #include <cctype>
19
+ #include <locale>
20
+
21
+ #include "ast_values.hpp"
22
+
23
+ namespace Sass {
24
+
25
+ /////////////////////////////////////////////////////////////////////////
26
+ /////////////////////////////////////////////////////////////////////////
27
+
28
+ Supports_Block::Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block)
29
+ : Has_Block(pstate, block), condition_(condition)
30
+ { statement_type(SUPPORTS); }
31
+ Supports_Block::Supports_Block(const Supports_Block* ptr)
32
+ : Has_Block(ptr), condition_(ptr->condition_)
33
+ { statement_type(SUPPORTS); }
34
+ bool Supports_Block::bubbles() { return true; }
35
+
36
+ /////////////////////////////////////////////////////////////////////////
37
+ /////////////////////////////////////////////////////////////////////////
38
+
39
+ Supports_Condition::Supports_Condition(ParserState pstate)
40
+ : Expression(pstate)
41
+ { }
42
+
43
+ Supports_Condition::Supports_Condition(const Supports_Condition* ptr)
44
+ : Expression(ptr)
45
+ { }
46
+
47
+ /////////////////////////////////////////////////////////////////////////
48
+ /////////////////////////////////////////////////////////////////////////
49
+
50
+ Supports_Operator::Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o)
51
+ : Supports_Condition(pstate), left_(l), right_(r), operand_(o)
52
+ { }
53
+ Supports_Operator::Supports_Operator(const Supports_Operator* ptr)
54
+ : Supports_Condition(ptr),
55
+ left_(ptr->left_),
56
+ right_(ptr->right_),
57
+ operand_(ptr->operand_)
58
+ { }
59
+
60
+ bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const
61
+ {
62
+ if (Supports_Operator_Obj op = Cast<Supports_Operator>(cond)) {
63
+ return op->operand() != operand();
64
+ }
65
+ return Cast<Supports_Negation>(cond) != NULL;
66
+ }
67
+
68
+ /////////////////////////////////////////////////////////////////////////
69
+ /////////////////////////////////////////////////////////////////////////
70
+
71
+ Supports_Negation::Supports_Negation(ParserState pstate, Supports_Condition_Obj c)
72
+ : Supports_Condition(pstate), condition_(c)
73
+ { }
74
+ Supports_Negation::Supports_Negation(const Supports_Negation* ptr)
75
+ : Supports_Condition(ptr), condition_(ptr->condition_)
76
+ { }
77
+
78
+ bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const
79
+ {
80
+ return Cast<Supports_Negation>(cond) ||
81
+ Cast<Supports_Operator>(cond);
82
+ }
83
+
84
+ /////////////////////////////////////////////////////////////////////////
85
+ /////////////////////////////////////////////////////////////////////////
86
+
87
+ Supports_Declaration::Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v)
88
+ : Supports_Condition(pstate), feature_(f), value_(v)
89
+ { }
90
+ Supports_Declaration::Supports_Declaration(const Supports_Declaration* ptr)
91
+ : Supports_Condition(ptr),
92
+ feature_(ptr->feature_),
93
+ value_(ptr->value_)
94
+ { }
95
+
96
+ bool Supports_Declaration::needs_parens(Supports_Condition_Obj cond) const
97
+ {
98
+ return false;
99
+ }
100
+
101
+ /////////////////////////////////////////////////////////////////////////
102
+ /////////////////////////////////////////////////////////////////////////
103
+
104
+ Supports_Interpolation::Supports_Interpolation(ParserState pstate, Expression_Obj v)
105
+ : Supports_Condition(pstate), value_(v)
106
+ { }
107
+ Supports_Interpolation::Supports_Interpolation(const Supports_Interpolation* ptr)
108
+ : Supports_Condition(ptr),
109
+ value_(ptr->value_)
110
+ { }
111
+
112
+ bool Supports_Interpolation::needs_parens(Supports_Condition_Obj cond) const
113
+ {
114
+ return false;
115
+ }
116
+
117
+ /////////////////////////////////////////////////////////////////////////
118
+ /////////////////////////////////////////////////////////////////////////
119
+
120
+ IMPLEMENT_AST_OPERATORS(Supports_Block);
121
+ IMPLEMENT_AST_OPERATORS(Supports_Condition);
122
+ IMPLEMENT_AST_OPERATORS(Supports_Operator);
123
+ IMPLEMENT_AST_OPERATORS(Supports_Negation);
124
+ IMPLEMENT_AST_OPERATORS(Supports_Declaration);
125
+ IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
126
+
127
+ /////////////////////////////////////////////////////////////////////////
128
+ /////////////////////////////////////////////////////////////////////////
129
+
130
+ }
@@ -0,0 +1,121 @@
1
+ #ifndef SASS_AST_SUPPORTS_H
2
+ #define SASS_AST_SUPPORTS_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
8
+ #include <set>
9
+ #include <deque>
10
+ #include <vector>
11
+ #include <string>
12
+ #include <sstream>
13
+ #include <iostream>
14
+ #include <typeinfo>
15
+ #include <algorithm>
16
+ #include "sass/base.h"
17
+ #include "ast_fwd_decl.hpp"
18
+
19
+ #include "util.hpp"
20
+ #include "units.hpp"
21
+ #include "context.hpp"
22
+ #include "position.hpp"
23
+ #include "constants.hpp"
24
+ #include "operation.hpp"
25
+ #include "position.hpp"
26
+ #include "inspect.hpp"
27
+ #include "source_map.hpp"
28
+ #include "environment.hpp"
29
+ #include "error_handling.hpp"
30
+ #include "ast_def_macros.hpp"
31
+ #include "ast_fwd_decl.hpp"
32
+ #include "source_map.hpp"
33
+ #include "fn_utils.hpp"
34
+
35
+ #include "sass.h"
36
+
37
+ namespace Sass {
38
+
39
+ ////////////////////
40
+ // `@supports` rule.
41
+ ////////////////////
42
+ class Supports_Block : public Has_Block {
43
+ ADD_PROPERTY(Supports_Condition_Obj, condition)
44
+ public:
45
+ Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = {});
46
+ bool bubbles() override;
47
+ ATTACH_AST_OPERATIONS(Supports_Block)
48
+ ATTACH_CRTP_PERFORM_METHODS()
49
+ };
50
+
51
+ //////////////////////////////////////////////////////
52
+ // The abstract superclass of all Supports conditions.
53
+ //////////////////////////////////////////////////////
54
+ class Supports_Condition : public Expression {
55
+ public:
56
+ Supports_Condition(ParserState pstate);
57
+ virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
58
+ ATTACH_AST_OPERATIONS(Supports_Condition)
59
+ ATTACH_CRTP_PERFORM_METHODS()
60
+ };
61
+
62
+ ////////////////////////////////////////////////////////////
63
+ // An operator condition (e.g. `CONDITION1 and CONDITION2`).
64
+ ////////////////////////////////////////////////////////////
65
+ class Supports_Operator : public Supports_Condition {
66
+ public:
67
+ enum Operand { AND, OR };
68
+ private:
69
+ ADD_PROPERTY(Supports_Condition_Obj, left);
70
+ ADD_PROPERTY(Supports_Condition_Obj, right);
71
+ ADD_PROPERTY(Operand, operand);
72
+ public:
73
+ Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o);
74
+ virtual bool needs_parens(Supports_Condition_Obj cond) const override;
75
+ ATTACH_AST_OPERATIONS(Supports_Operator)
76
+ ATTACH_CRTP_PERFORM_METHODS()
77
+ };
78
+
79
+ //////////////////////////////////////////
80
+ // A negation condition (`not CONDITION`).
81
+ //////////////////////////////////////////
82
+ class Supports_Negation : public Supports_Condition {
83
+ private:
84
+ ADD_PROPERTY(Supports_Condition_Obj, condition);
85
+ public:
86
+ Supports_Negation(ParserState pstate, Supports_Condition_Obj c);
87
+ virtual bool needs_parens(Supports_Condition_Obj cond) const override;
88
+ ATTACH_AST_OPERATIONS(Supports_Negation)
89
+ ATTACH_CRTP_PERFORM_METHODS()
90
+ };
91
+
92
+ /////////////////////////////////////////////////////
93
+ // A declaration condition (e.g. `(feature: value)`).
94
+ /////////////////////////////////////////////////////
95
+ class Supports_Declaration : public Supports_Condition {
96
+ private:
97
+ ADD_PROPERTY(Expression_Obj, feature);
98
+ ADD_PROPERTY(Expression_Obj, value);
99
+ public:
100
+ Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v);
101
+ virtual bool needs_parens(Supports_Condition_Obj cond) const override;
102
+ ATTACH_AST_OPERATIONS(Supports_Declaration)
103
+ ATTACH_CRTP_PERFORM_METHODS()
104
+ };
105
+
106
+ ///////////////////////////////////////////////
107
+ // An interpolation condition (e.g. `#{$var}`).
108
+ ///////////////////////////////////////////////
109
+ class Supports_Interpolation : public Supports_Condition {
110
+ private:
111
+ ADD_PROPERTY(Expression_Obj, value);
112
+ public:
113
+ Supports_Interpolation(ParserState pstate, Expression_Obj v);
114
+ virtual bool needs_parens(Supports_Condition_Obj cond) const override;
115
+ ATTACH_AST_OPERATIONS(Supports_Interpolation)
116
+ ATTACH_CRTP_PERFORM_METHODS()
117
+ };
118
+
119
+ }
120
+
121
+ #endif
@@ -0,0 +1,967 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "ast.hpp"
6
+ #include "context.hpp"
7
+ #include "node.hpp"
8
+ #include "eval.hpp"
9
+ #include "extend.hpp"
10
+ #include "emitter.hpp"
11
+ #include "color_maps.hpp"
12
+ #include "ast_fwd_decl.hpp"
13
+ #include <set>
14
+ #include <iomanip>
15
+ #include <iostream>
16
+ #include <algorithm>
17
+ #include <functional>
18
+ #include <cctype>
19
+ #include <locale>
20
+
21
+ #include "ast_values.hpp"
22
+
23
+ namespace Sass {
24
+
25
+ void str_rtrim(std::string& str, const std::string& delimiters = " \f\n\r\t\v")
26
+ {
27
+ str.erase( str.find_last_not_of( delimiters ) + 1 );
28
+ }
29
+
30
+ /////////////////////////////////////////////////////////////////////////
31
+ /////////////////////////////////////////////////////////////////////////
32
+
33
+ PreValue::PreValue(ParserState pstate, bool d, bool e, bool i, Type ct)
34
+ : Expression(pstate, d, e, i, ct)
35
+ { }
36
+ PreValue::PreValue(const PreValue* ptr)
37
+ : Expression(ptr)
38
+ { }
39
+
40
+ /////////////////////////////////////////////////////////////////////////
41
+ /////////////////////////////////////////////////////////////////////////
42
+
43
+ Value::Value(ParserState pstate, bool d, bool e, bool i, Type ct)
44
+ : PreValue(pstate, d, e, i, ct)
45
+ { }
46
+ Value::Value(const Value* ptr)
47
+ : PreValue(ptr)
48
+ { }
49
+
50
+ /////////////////////////////////////////////////////////////////////////
51
+ /////////////////////////////////////////////////////////////////////////
52
+
53
+ List::List(ParserState pstate, size_t size, enum Sass_Separator sep, bool argl, bool bracket)
54
+ : Value(pstate),
55
+ Vectorized<Expression_Obj>(size),
56
+ separator_(sep),
57
+ is_arglist_(argl),
58
+ is_bracketed_(bracket),
59
+ from_selector_(false)
60
+ { concrete_type(LIST); }
61
+
62
+ List::List(const List* ptr)
63
+ : Value(ptr),
64
+ Vectorized<Expression_Obj>(*ptr),
65
+ separator_(ptr->separator_),
66
+ is_arglist_(ptr->is_arglist_),
67
+ is_bracketed_(ptr->is_bracketed_),
68
+ from_selector_(ptr->from_selector_)
69
+ { concrete_type(LIST); }
70
+
71
+ size_t List::hash() const
72
+ {
73
+ if (hash_ == 0) {
74
+ hash_ = std::hash<std::string>()(sep_string());
75
+ hash_combine(hash_, std::hash<bool>()(is_bracketed()));
76
+ for (size_t i = 0, L = length(); i < L; ++i)
77
+ hash_combine(hash_, (elements()[i])->hash());
78
+ }
79
+ return hash_;
80
+ }
81
+
82
+ void List::set_delayed(bool delayed)
83
+ {
84
+ is_delayed(delayed);
85
+ // don't set children
86
+ }
87
+
88
+ bool List::operator== (const Expression& rhs) const
89
+ {
90
+ if (auto r = Cast<List>(&rhs)) {
91
+ if (length() != r->length()) return false;
92
+ if (separator() != r->separator()) return false;
93
+ if (is_bracketed() != r->is_bracketed()) return false;
94
+ for (size_t i = 0, L = length(); i < L; ++i) {
95
+ auto rv = r->at(i);
96
+ auto lv = this->at(i);
97
+ if (!lv && rv) return false;
98
+ else if (!rv && lv) return false;
99
+ else if (*lv != *rv) return false;
100
+ }
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+
106
+ size_t List::size() const {
107
+ if (!is_arglist_) return length();
108
+ // arglist expects a list of arguments
109
+ // so we need to break before keywords
110
+ for (size_t i = 0, L = length(); i < L; ++i) {
111
+ Expression_Obj obj = this->at(i);
112
+ if (Argument* arg = Cast<Argument>(obj)) {
113
+ if (!arg->name().empty()) return i;
114
+ }
115
+ }
116
+ return length();
117
+ }
118
+
119
+
120
+ Expression_Obj List::value_at_index(size_t i) {
121
+ Expression_Obj obj = this->at(i);
122
+ if (is_arglist_) {
123
+ if (Argument* arg = Cast<Argument>(obj)) {
124
+ return arg->value();
125
+ } else {
126
+ return obj;
127
+ }
128
+ } else {
129
+ return obj;
130
+ }
131
+ }
132
+
133
+ /////////////////////////////////////////////////////////////////////////
134
+ /////////////////////////////////////////////////////////////////////////
135
+
136
+ Map::Map(ParserState pstate, size_t size)
137
+ : Value(pstate),
138
+ Hashed(size)
139
+ { concrete_type(MAP); }
140
+
141
+ Map::Map(const Map* ptr)
142
+ : Value(ptr),
143
+ Hashed(*ptr)
144
+ { concrete_type(MAP); }
145
+
146
+ bool Map::operator== (const Expression& rhs) const
147
+ {
148
+ if (auto r = Cast<Map>(&rhs)) {
149
+ if (length() != r->length()) return false;
150
+ for (auto key : keys()) {
151
+ auto rv = r->at(key);
152
+ auto lv = this->at(key);
153
+ if (!lv && rv) return false;
154
+ else if (!rv && lv) return false;
155
+ else if (*lv != *rv) return false;
156
+ }
157
+ return true;
158
+ }
159
+ return false;
160
+ }
161
+
162
+ List_Obj Map::to_list(ParserState& pstate) {
163
+ List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
164
+
165
+ for (auto key : keys()) {
166
+ List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
167
+ l->append(key);
168
+ l->append(at(key));
169
+ ret->append(l);
170
+ }
171
+
172
+ return ret;
173
+ }
174
+
175
+ size_t Map::hash() const
176
+ {
177
+ if (hash_ == 0) {
178
+ for (auto key : keys()) {
179
+ hash_combine(hash_, key->hash());
180
+ hash_combine(hash_, at(key)->hash());
181
+ }
182
+ }
183
+
184
+ return hash_;
185
+ }
186
+
187
+ /////////////////////////////////////////////////////////////////////////
188
+ /////////////////////////////////////////////////////////////////////////
189
+
190
+ Binary_Expression::Binary_Expression(ParserState pstate,
191
+ Operand op, Expression_Obj lhs, Expression_Obj rhs)
192
+ : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
193
+ { }
194
+
195
+ Binary_Expression::Binary_Expression(const Binary_Expression* ptr)
196
+ : PreValue(ptr),
197
+ op_(ptr->op_),
198
+ left_(ptr->left_),
199
+ right_(ptr->right_),
200
+ hash_(ptr->hash_)
201
+ { }
202
+
203
+ bool Binary_Expression::is_left_interpolant(void) const
204
+ {
205
+ return is_interpolant() || (left() && left()->is_left_interpolant());
206
+ }
207
+ bool Binary_Expression::is_right_interpolant(void) const
208
+ {
209
+ return is_interpolant() || (right() && right()->is_right_interpolant());
210
+ }
211
+
212
+ const std::string Binary_Expression::type_name()
213
+ {
214
+ return sass_op_to_name(optype());
215
+ }
216
+
217
+ const std::string Binary_Expression::separator()
218
+ {
219
+ return sass_op_separator(optype());
220
+ }
221
+
222
+ bool Binary_Expression::has_interpolant() const
223
+ {
224
+ return is_left_interpolant() ||
225
+ is_right_interpolant();
226
+ }
227
+
228
+ void Binary_Expression::set_delayed(bool delayed)
229
+ {
230
+ right()->set_delayed(delayed);
231
+ left()->set_delayed(delayed);
232
+ is_delayed(delayed);
233
+ }
234
+
235
+ bool Binary_Expression::operator==(const Expression& rhs) const
236
+ {
237
+ if (auto m = Cast<Binary_Expression>(&rhs)) {
238
+ return type() == m->type() &&
239
+ *left() == *m->left() &&
240
+ *right() == *m->right();
241
+ }
242
+ return false;
243
+ }
244
+
245
+ size_t Binary_Expression::hash() const
246
+ {
247
+ if (hash_ == 0) {
248
+ hash_ = std::hash<size_t>()(optype());
249
+ hash_combine(hash_, left()->hash());
250
+ hash_combine(hash_, right()->hash());
251
+ }
252
+ return hash_;
253
+ }
254
+
255
+ /////////////////////////////////////////////////////////////////////////
256
+ /////////////////////////////////////////////////////////////////////////
257
+
258
+ Function::Function(ParserState pstate, Definition_Obj def, bool css)
259
+ : Value(pstate), definition_(def), is_css_(css)
260
+ { concrete_type(FUNCTION_VAL); }
261
+
262
+ Function::Function(const Function* ptr)
263
+ : Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
264
+ { concrete_type(FUNCTION_VAL); }
265
+
266
+ bool Function::operator== (const Expression& rhs) const
267
+ {
268
+ if (auto r = Cast<Function>(&rhs)) {
269
+ auto d1 = Cast<Definition>(definition());
270
+ auto d2 = Cast<Definition>(r->definition());
271
+ return d1 && d2 && d1 == d2 && is_css() == r->is_css();
272
+ }
273
+ return false;
274
+ }
275
+
276
+ std::string Function::name() {
277
+ if (definition_) {
278
+ return definition_->name();
279
+ }
280
+ return "";
281
+ }
282
+
283
+ /////////////////////////////////////////////////////////////////////////
284
+ /////////////////////////////////////////////////////////////////////////
285
+
286
+ Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args, void* cookie)
287
+ : PreValue(pstate), sname_(n), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
288
+ { concrete_type(FUNCTION); }
289
+ Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args, Function_Obj func)
290
+ : PreValue(pstate), sname_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
291
+ { concrete_type(FUNCTION); }
292
+ Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args)
293
+ : PreValue(pstate), sname_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
294
+ { concrete_type(FUNCTION); }
295
+
296
+ Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
297
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
298
+ { concrete_type(FUNCTION); }
299
+ Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args, Function_Obj func)
300
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
301
+ { concrete_type(FUNCTION); }
302
+ Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
303
+ : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), via_call_(false), cookie_(0), hash_(0)
304
+ { concrete_type(FUNCTION); }
305
+
306
+ Function_Call::Function_Call(const Function_Call* ptr)
307
+ : PreValue(ptr),
308
+ sname_(ptr->sname_),
309
+ arguments_(ptr->arguments_),
310
+ func_(ptr->func_),
311
+ via_call_(ptr->via_call_),
312
+ cookie_(ptr->cookie_),
313
+ hash_(ptr->hash_)
314
+ { concrete_type(FUNCTION); }
315
+
316
+ bool Function_Call::operator==(const Expression& rhs) const
317
+ {
318
+ if (auto m = Cast<Function_Call>(&rhs)) {
319
+ if (*sname() != *m->sname()) return false;
320
+ if (arguments()->length() != m->arguments()->length()) return false;
321
+ for (size_t i = 0, L = arguments()->length(); i < L; ++i)
322
+ if (*arguments()->get(i) != *m->arguments()->get(i)) return false;
323
+ return true;
324
+ }
325
+ return false;
326
+ }
327
+
328
+ size_t Function_Call::hash() const
329
+ {
330
+ if (hash_ == 0) {
331
+ hash_ = std::hash<std::string>()(name());
332
+ for (auto argument : arguments()->elements())
333
+ hash_combine(hash_, argument->hash());
334
+ }
335
+ return hash_;
336
+ }
337
+
338
+ std::string Function_Call::name() const
339
+ {
340
+ return sname();
341
+ }
342
+
343
+ bool Function_Call::is_css() {
344
+ if (func_) return func_->is_css();
345
+ return false;
346
+ }
347
+
348
+ /////////////////////////////////////////////////////////////////////////
349
+ /////////////////////////////////////////////////////////////////////////
350
+
351
+ Variable::Variable(ParserState pstate, std::string n)
352
+ : PreValue(pstate), name_(n)
353
+ { concrete_type(VARIABLE); }
354
+
355
+ Variable::Variable(const Variable* ptr)
356
+ : PreValue(ptr), name_(ptr->name_)
357
+ { concrete_type(VARIABLE); }
358
+
359
+ bool Variable::operator==(const Expression& rhs) const
360
+ {
361
+ if (auto e = Cast<Variable>(&rhs)) {
362
+ return name() == e->name();
363
+ }
364
+ return false;
365
+ }
366
+
367
+ size_t Variable::hash() const
368
+ {
369
+ return std::hash<std::string>()(name());
370
+ }
371
+
372
+ /////////////////////////////////////////////////////////////////////////
373
+ /////////////////////////////////////////////////////////////////////////
374
+
375
+ Number::Number(ParserState pstate, double val, std::string u, bool zero)
376
+ : Value(pstate),
377
+ Units(),
378
+ value_(val),
379
+ zero_(zero),
380
+ hash_(0)
381
+ {
382
+ size_t l = 0;
383
+ size_t r;
384
+ if (!u.empty()) {
385
+ bool nominator = true;
386
+ while (true) {
387
+ r = u.find_first_of("*/", l);
388
+ std::string unit(u.substr(l, r == std::string::npos ? r : r - l));
389
+ if (!unit.empty()) {
390
+ if (nominator) numerators.push_back(unit);
391
+ else denominators.push_back(unit);
392
+ }
393
+ if (r == std::string::npos) break;
394
+ // ToDo: should error for multiple slashes
395
+ // if (!nominator && u[r] == '/') error(...)
396
+ if (u[r] == '/')
397
+ nominator = false;
398
+ // strange math parsing?
399
+ // else if (u[r] == '*')
400
+ // nominator = true;
401
+ l = r + 1;
402
+ }
403
+ }
404
+ concrete_type(NUMBER);
405
+ }
406
+
407
+ Number::Number(const Number* ptr)
408
+ : Value(ptr),
409
+ Units(ptr),
410
+ value_(ptr->value_), zero_(ptr->zero_),
411
+ hash_(ptr->hash_)
412
+ { concrete_type(NUMBER); }
413
+
414
+ // cancel out unnecessary units
415
+ void Number::reduce()
416
+ {
417
+ // apply conversion factor
418
+ value_ *= this->Units::reduce();
419
+ }
420
+
421
+ void Number::normalize()
422
+ {
423
+ // apply conversion factor
424
+ value_ *= this->Units::normalize();
425
+ }
426
+
427
+ size_t Number::hash() const
428
+ {
429
+ if (hash_ == 0) {
430
+ hash_ = std::hash<double>()(value_);
431
+ for (const auto numerator : numerators)
432
+ hash_combine(hash_, std::hash<std::string>()(numerator));
433
+ for (const auto denominator : denominators)
434
+ hash_combine(hash_, std::hash<std::string>()(denominator));
435
+ }
436
+ return hash_;
437
+ }
438
+
439
+ bool Number::operator== (const Expression& rhs) const
440
+ {
441
+ if (auto n = Cast<Number>(&rhs)) {
442
+ return *this == *n;
443
+ }
444
+ return false;
445
+ }
446
+
447
+ bool Number::operator== (const Number& rhs) const
448
+ {
449
+ // unitless or only having one unit are equivalent (3.4)
450
+ // therefore we need to reduce the units beforehand
451
+ Number l(*this), r(rhs); l.reduce(); r.reduce();
452
+ size_t lhs_units = l.numerators.size() + l.denominators.size();
453
+ size_t rhs_units = r.numerators.size() + r.denominators.size();
454
+ if (!lhs_units || !rhs_units) {
455
+ return NEAR_EQUAL(l.value(), r.value());
456
+ }
457
+ // ensure both have same units
458
+ l.normalize(); r.normalize();
459
+ Units &lhs_unit = l, &rhs_unit = r;
460
+ return lhs_unit == rhs_unit &&
461
+ NEAR_EQUAL(l.value(), r.value());
462
+ }
463
+
464
+ bool Number::operator< (const Number& rhs) const
465
+ {
466
+ // unitless or only having one unit are equivalent (3.4)
467
+ // therefore we need to reduce the units beforehand
468
+ Number l(*this), r(rhs); l.reduce(); r.reduce();
469
+ size_t lhs_units = l.numerators.size() + l.denominators.size();
470
+ size_t rhs_units = r.numerators.size() + r.denominators.size();
471
+ if (!lhs_units || !rhs_units) {
472
+ return l.value() < r.value();
473
+ }
474
+ // ensure both have same units
475
+ l.normalize(); r.normalize();
476
+ Units &lhs_unit = l, &rhs_unit = r;
477
+ if (!(lhs_unit == rhs_unit)) {
478
+ /* ToDo: do we always get usefull backtraces? */
479
+ throw Exception::IncompatibleUnits(rhs, *this);
480
+ }
481
+ if (lhs_unit == rhs_unit) {
482
+ return l.value() < r.value();
483
+ } else {
484
+ return lhs_unit < rhs_unit;
485
+ }
486
+ }
487
+
488
+ /////////////////////////////////////////////////////////////////////////
489
+ /////////////////////////////////////////////////////////////////////////
490
+
491
+ Color::Color(ParserState pstate, double a, const std::string disp)
492
+ : Value(pstate),
493
+ disp_(disp), a_(a),
494
+ hash_(0)
495
+ { concrete_type(COLOR); }
496
+
497
+ Color::Color(const Color* ptr)
498
+ : Value(ptr->pstate()),
499
+ // reset on copy
500
+ disp_(""),
501
+ a_(ptr->a_),
502
+ hash_(ptr->hash_)
503
+ { concrete_type(COLOR); }
504
+
505
+ bool Color::operator== (const Expression& rhs) const
506
+ {
507
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
508
+ return *this == *r;
509
+ }
510
+ else if (auto r = Cast<Color_HSLA>(&rhs)) {
511
+ return *this == *r;
512
+ }
513
+ else if (auto r = Cast<Color>(&rhs)) {
514
+ return a_ == r->a();
515
+ }
516
+ return false;
517
+ }
518
+
519
+ /////////////////////////////////////////////////////////////////////////
520
+ /////////////////////////////////////////////////////////////////////////
521
+
522
+ Color_RGBA::Color_RGBA(ParserState pstate, double r, double g, double b, double a, const std::string disp)
523
+ : Color(pstate, a, disp),
524
+ r_(r), g_(g), b_(b)
525
+ { concrete_type(COLOR); }
526
+
527
+ Color_RGBA::Color_RGBA(const Color_RGBA* ptr)
528
+ : Color(ptr),
529
+ r_(ptr->r_),
530
+ g_(ptr->g_),
531
+ b_(ptr->b_)
532
+ { concrete_type(COLOR); }
533
+
534
+ bool Color_RGBA::operator== (const Expression& rhs) const
535
+ {
536
+ if (auto r = Cast<Color_RGBA>(&rhs)) {
537
+ return r_ == r->r() &&
538
+ g_ == r->g() &&
539
+ b_ == r->b() &&
540
+ a_ == r->a();
541
+ }
542
+ return false;
543
+ }
544
+
545
+ size_t Color_RGBA::hash() const
546
+ {
547
+ if (hash_ == 0) {
548
+ hash_ = std::hash<std::string>()("RGBA");
549
+ hash_combine(hash_, std::hash<double>()(a_));
550
+ hash_combine(hash_, std::hash<double>()(r_));
551
+ hash_combine(hash_, std::hash<double>()(g_));
552
+ hash_combine(hash_, std::hash<double>()(b_));
553
+ }
554
+ return hash_;
555
+ }
556
+
557
+ Color_HSLA* Color_RGBA::copyAsHSLA() const
558
+ {
559
+
560
+ // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
561
+ double r = r_ / 255.0;
562
+ double g = g_ / 255.0;
563
+ double b = b_ / 255.0;
564
+
565
+ double max = std::max(r, std::max(g, b));
566
+ double min = std::min(r, std::min(g, b));
567
+ double delta = max - min;
568
+
569
+ double h = 0;
570
+ double s;
571
+ double l = (max + min) / 2.0;
572
+
573
+ if (NEAR_EQUAL(max, min)) {
574
+ h = s = 0; // achromatic
575
+ }
576
+ else {
577
+ if (l < 0.5) s = delta / (max + min);
578
+ else s = delta / (2.0 - max - min);
579
+
580
+ if (r == max) h = (g - b) / delta + (g < b ? 6 : 0);
581
+ else if (g == max) h = (b - r) / delta + 2;
582
+ else if (b == max) h = (r - g) / delta + 4;
583
+ }
584
+
585
+ // HSL hsl_struct;
586
+ h = h * 60;
587
+ s = s * 100;
588
+ l = l * 100;
589
+
590
+ return SASS_MEMORY_NEW(Color_HSLA,
591
+ pstate(), h, s, l, a(), ""
592
+ );
593
+ }
594
+
595
+ Color_RGBA* Color_RGBA::copyAsRGBA() const
596
+ {
597
+ return SASS_MEMORY_COPY(this);
598
+ }
599
+
600
+ /////////////////////////////////////////////////////////////////////////
601
+ /////////////////////////////////////////////////////////////////////////
602
+
603
+ Color_HSLA::Color_HSLA(ParserState pstate, double h, double s, double l, double a, const std::string disp)
604
+ : Color(pstate, a, disp),
605
+ h_(absmod(h, 360.0)),
606
+ s_(clip(s, 0.0, 100.0)),
607
+ l_(clip(l, 0.0, 100.0))
608
+ // hash_(0)
609
+ { concrete_type(COLOR); }
610
+
611
+ Color_HSLA::Color_HSLA(const Color_HSLA* ptr)
612
+ : Color(ptr),
613
+ h_(ptr->h_),
614
+ s_(ptr->s_),
615
+ l_(ptr->l_)
616
+ // hash_(ptr->hash_)
617
+ { concrete_type(COLOR); }
618
+
619
+ bool Color_HSLA::operator== (const Expression& rhs) const
620
+ {
621
+ if (auto r = Cast<Color_HSLA>(&rhs)) {
622
+ return h_ == r->h() &&
623
+ s_ == r->s() &&
624
+ l_ == r->l() &&
625
+ a_ == r->a();
626
+ }
627
+ return false;
628
+ }
629
+
630
+ size_t Color_HSLA::hash() const
631
+ {
632
+ if (hash_ == 0) {
633
+ hash_ = std::hash<std::string>()("HSLA");
634
+ hash_combine(hash_, std::hash<double>()(a_));
635
+ hash_combine(hash_, std::hash<double>()(h_));
636
+ hash_combine(hash_, std::hash<double>()(s_));
637
+ hash_combine(hash_, std::hash<double>()(l_));
638
+ }
639
+ return hash_;
640
+ }
641
+
642
+ // hue to RGB helper function
643
+ double h_to_rgb(double m1, double m2, double h)
644
+ {
645
+ h = absmod(h, 1.0);
646
+ if (h*6.0 < 1) return m1 + (m2 - m1)*h*6;
647
+ if (h*2.0 < 1) return m2;
648
+ if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6;
649
+ return m1;
650
+ }
651
+
652
+ Color_RGBA* Color_HSLA::copyAsRGBA() const
653
+ {
654
+
655
+ double h = absmod(h_ / 360.0, 1.0);
656
+ double s = clip(s_ / 100.0, 0.0, 1.0);
657
+ double l = clip(l_ / 100.0, 0.0, 1.0);
658
+
659
+ // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.
660
+ double m2;
661
+ if (l <= 0.5) m2 = l*(s+1.0);
662
+ else m2 = (l+s)-(l*s);
663
+ double m1 = (l*2.0)-m2;
664
+ // round the results -- consider moving this into the Color constructor
665
+ double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0);
666
+ double g = (h_to_rgb(m1, m2, h) * 255.0);
667
+ double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0);
668
+
669
+ return SASS_MEMORY_NEW(Color_RGBA,
670
+ pstate(), r, g, b, a(), ""
671
+ );
672
+ }
673
+
674
+ Color_HSLA* Color_HSLA::copyAsHSLA() const
675
+ {
676
+ return SASS_MEMORY_COPY(this);
677
+ }
678
+
679
+ /////////////////////////////////////////////////////////////////////////
680
+ /////////////////////////////////////////////////////////////////////////
681
+
682
+ Custom_Error::Custom_Error(ParserState pstate, std::string msg)
683
+ : Value(pstate), message_(msg)
684
+ { concrete_type(C_ERROR); }
685
+
686
+ Custom_Error::Custom_Error(const Custom_Error* ptr)
687
+ : Value(ptr), message_(ptr->message_)
688
+ { concrete_type(C_ERROR); }
689
+
690
+ bool Custom_Error::operator== (const Expression& rhs) const
691
+ {
692
+ if (auto r = Cast<Custom_Error>(&rhs)) {
693
+ return message() == r->message();
694
+ }
695
+ return false;
696
+ }
697
+
698
+ /////////////////////////////////////////////////////////////////////////
699
+ /////////////////////////////////////////////////////////////////////////
700
+
701
+ Custom_Warning::Custom_Warning(ParserState pstate, std::string msg)
702
+ : Value(pstate), message_(msg)
703
+ { concrete_type(C_WARNING); }
704
+
705
+ Custom_Warning::Custom_Warning(const Custom_Warning* ptr)
706
+ : Value(ptr), message_(ptr->message_)
707
+ { concrete_type(C_WARNING); }
708
+
709
+ bool Custom_Warning::operator== (const Expression& rhs) const
710
+ {
711
+ if (auto r = Cast<Custom_Warning>(&rhs)) {
712
+ return message() == r->message();
713
+ }
714
+ return false;
715
+ }
716
+
717
+ /////////////////////////////////////////////////////////////////////////
718
+ /////////////////////////////////////////////////////////////////////////
719
+
720
+ Boolean::Boolean(ParserState pstate, bool val)
721
+ : Value(pstate), value_(val),
722
+ hash_(0)
723
+ { concrete_type(BOOLEAN); }
724
+
725
+ Boolean::Boolean(const Boolean* ptr)
726
+ : Value(ptr),
727
+ value_(ptr->value_),
728
+ hash_(ptr->hash_)
729
+ { concrete_type(BOOLEAN); }
730
+
731
+ bool Boolean::operator== (const Expression& rhs) const
732
+ {
733
+ if (auto r = Cast<Boolean>(&rhs)) {
734
+ return (value() == r->value());
735
+ }
736
+ return false;
737
+ }
738
+
739
+ size_t Boolean::hash() const
740
+ {
741
+ if (hash_ == 0) {
742
+ hash_ = std::hash<bool>()(value_);
743
+ }
744
+ return hash_;
745
+ }
746
+
747
+ /////////////////////////////////////////////////////////////////////////
748
+ /////////////////////////////////////////////////////////////////////////
749
+
750
+ String::String(ParserState pstate, bool delayed)
751
+ : Value(pstate, delayed)
752
+ { concrete_type(STRING); }
753
+ String::String(const String* ptr)
754
+ : Value(ptr)
755
+ { concrete_type(STRING); }
756
+
757
+ /////////////////////////////////////////////////////////////////////////
758
+ /////////////////////////////////////////////////////////////////////////
759
+
760
+ String_Schema::String_Schema(ParserState pstate, size_t size, bool css)
761
+ : String(pstate), Vectorized<PreValue_Obj>(size), css_(css), hash_(0)
762
+ { concrete_type(STRING); }
763
+
764
+ String_Schema::String_Schema(const String_Schema* ptr)
765
+ : String(ptr),
766
+ Vectorized<PreValue_Obj>(*ptr),
767
+ css_(ptr->css_),
768
+ hash_(ptr->hash_)
769
+ { concrete_type(STRING); }
770
+
771
+ void String_Schema::rtrim()
772
+ {
773
+ if (!empty()) {
774
+ if (String* str = Cast<String>(last())) str->rtrim();
775
+ }
776
+ }
777
+
778
+ bool String_Schema::is_left_interpolant(void) const
779
+ {
780
+ return length() && first()->is_left_interpolant();
781
+ }
782
+ bool String_Schema::is_right_interpolant(void) const
783
+ {
784
+ return length() && last()->is_right_interpolant();
785
+ }
786
+
787
+ bool String_Schema::operator== (const Expression& rhs) const
788
+ {
789
+ if (auto r = Cast<String_Schema>(&rhs)) {
790
+ if (length() != r->length()) return false;
791
+ for (size_t i = 0, L = length(); i < L; ++i) {
792
+ auto rv = (*r)[i];
793
+ auto lv = (*this)[i];
794
+ if (*lv != *rv) return false;
795
+ }
796
+ return true;
797
+ }
798
+ return false;
799
+ }
800
+
801
+ bool String_Schema::has_interpolants()
802
+ {
803
+ for (auto el : elements()) {
804
+ if (el->is_interpolant()) return true;
805
+ }
806
+ return false;
807
+ }
808
+
809
+ size_t String_Schema::hash() const
810
+ {
811
+ if (hash_ == 0) {
812
+ for (auto string : elements())
813
+ hash_combine(hash_, string->hash());
814
+ }
815
+ return hash_;
816
+ }
817
+
818
+ void String_Schema::set_delayed(bool delayed)
819
+ {
820
+ is_delayed(delayed);
821
+ }
822
+
823
+ /////////////////////////////////////////////////////////////////////////
824
+ /////////////////////////////////////////////////////////////////////////
825
+
826
+ String_Constant::String_Constant(ParserState pstate, std::string val, bool css)
827
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val, css)), hash_(0)
828
+ { }
829
+ String_Constant::String_Constant(ParserState pstate, const char* beg, bool css)
830
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg), css)), hash_(0)
831
+ { }
832
+ String_Constant::String_Constant(ParserState pstate, const char* beg, const char* end, bool css)
833
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg), css)), hash_(0)
834
+ { }
835
+ String_Constant::String_Constant(ParserState pstate, const Token& tok, bool css)
836
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end), css)), hash_(0)
837
+ { }
838
+
839
+ String_Constant::String_Constant(const String_Constant* ptr)
840
+ : String(ptr),
841
+ quote_mark_(ptr->quote_mark_),
842
+ can_compress_whitespace_(ptr->can_compress_whitespace_),
843
+ value_(ptr->value_),
844
+ hash_(ptr->hash_)
845
+ { }
846
+
847
+ bool String_Constant::is_invisible() const {
848
+ return value_.empty() && quote_mark_ == 0;
849
+ }
850
+
851
+ bool String_Constant::operator== (const Expression& rhs) const
852
+ {
853
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
854
+ return value() == qstr->value();
855
+ } else if (auto cstr = Cast<String_Constant>(&rhs)) {
856
+ return value() == cstr->value();
857
+ }
858
+ return false;
859
+ }
860
+
861
+ std::string String_Constant::inspect() const
862
+ {
863
+ return quote(value_, '*');
864
+ }
865
+
866
+ void String_Constant::rtrim()
867
+ {
868
+ str_rtrim(value_);
869
+ }
870
+
871
+ size_t String_Constant::hash() const
872
+ {
873
+ if (hash_ == 0) {
874
+ hash_ = std::hash<std::string>()(value_);
875
+ }
876
+ return hash_;
877
+ }
878
+
879
+ /////////////////////////////////////////////////////////////////////////
880
+ /////////////////////////////////////////////////////////////////////////
881
+
882
+ String_Quoted::String_Quoted(ParserState pstate, std::string val, char q,
883
+ bool keep_utf8_escapes, bool skip_unquoting,
884
+ bool strict_unquoting, bool css)
885
+ : String_Constant(pstate, val, css)
886
+ {
887
+ if (skip_unquoting == false) {
888
+ value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);
889
+ }
890
+ if (q && quote_mark_) quote_mark_ = q;
891
+ }
892
+
893
+ String_Quoted::String_Quoted(const String_Quoted* ptr)
894
+ : String_Constant(ptr)
895
+ { }
896
+
897
+ bool String_Quoted::operator== (const Expression& rhs) const
898
+ {
899
+ if (auto qstr = Cast<String_Quoted>(&rhs)) {
900
+ return value() == qstr->value();
901
+ } else if (auto cstr = Cast<String_Constant>(&rhs)) {
902
+ return value() == cstr->value();
903
+ }
904
+ return false;
905
+ }
906
+
907
+ std::string String_Quoted::inspect() const
908
+ {
909
+ return quote(value_, '*');
910
+ }
911
+
912
+ /////////////////////////////////////////////////////////////////////////
913
+ /////////////////////////////////////////////////////////////////////////
914
+
915
+ Null::Null(ParserState pstate)
916
+ : Value(pstate)
917
+ { concrete_type(NULL_VAL); }
918
+
919
+ Null::Null(const Null* ptr) : Value(ptr)
920
+ { concrete_type(NULL_VAL); }
921
+
922
+ bool Null::operator== (const Expression& rhs) const
923
+ {
924
+ return Cast<Null>(&rhs) != NULL;
925
+ }
926
+
927
+ size_t Null::hash() const
928
+ {
929
+ return -1;
930
+ }
931
+
932
+ /////////////////////////////////////////////////////////////////////////
933
+ /////////////////////////////////////////////////////////////////////////
934
+
935
+ Parent_Reference::Parent_Reference(ParserState pstate)
936
+ : Value(pstate)
937
+ { concrete_type(PARENT); }
938
+
939
+ Parent_Reference::Parent_Reference(const Parent_Reference* ptr)
940
+ : Value(ptr)
941
+ { concrete_type(PARENT); }
942
+
943
+ /////////////////////////////////////////////////////////////////////////
944
+ /////////////////////////////////////////////////////////////////////////
945
+
946
+ IMPLEMENT_AST_OPERATORS(List);
947
+ IMPLEMENT_AST_OPERATORS(Map);
948
+ IMPLEMENT_AST_OPERATORS(Binary_Expression);
949
+ IMPLEMENT_AST_OPERATORS(Function);
950
+ IMPLEMENT_AST_OPERATORS(Function_Call);
951
+ IMPLEMENT_AST_OPERATORS(Variable);
952
+ IMPLEMENT_AST_OPERATORS(Number);
953
+ IMPLEMENT_AST_OPERATORS(Color_RGBA);
954
+ IMPLEMENT_AST_OPERATORS(Color_HSLA);
955
+ IMPLEMENT_AST_OPERATORS(Custom_Error);
956
+ IMPLEMENT_AST_OPERATORS(Custom_Warning);
957
+ IMPLEMENT_AST_OPERATORS(Boolean);
958
+ IMPLEMENT_AST_OPERATORS(String_Schema);
959
+ IMPLEMENT_AST_OPERATORS(String_Constant);
960
+ IMPLEMENT_AST_OPERATORS(String_Quoted);
961
+ IMPLEMENT_AST_OPERATORS(Null);
962
+ IMPLEMENT_AST_OPERATORS(Parent_Reference);
963
+
964
+ /////////////////////////////////////////////////////////////////////////
965
+ /////////////////////////////////////////////////////////////////////////
966
+
967
+ }