1 | #ifndef SASS_AST_VALUES_H |
2 | #define SASS_AST_VALUES_H |
3 | |
4 | // sass.hpp must go before all system headers to get the |
5 | // __EXTENSIONS__ fix on Solaris. |
6 | #include "sass.hpp" |
7 | #include "ast.hpp" |
8 | |
9 | namespace Sass { |
10 | |
11 | ////////////////////////////////////////////////////////////////////// |
12 | // Still just an expression, but with a to_string method |
13 | ////////////////////////////////////////////////////////////////////// |
14 | class PreValue : public Expression { |
15 | public: |
16 | PreValue(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE); |
17 | ATTACH_VIRTUAL_AST_OPERATIONS(PreValue); |
18 | virtual ~PreValue() { } |
19 | }; |
20 | |
21 | ////////////////////////////////////////////////////////////////////// |
22 | // base class for values that support operations |
23 | ////////////////////////////////////////////////////////////////////// |
24 | class Value : public PreValue { |
25 | public: |
26 | Value(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE); |
27 | |
28 | // Some obects are not meant to be compared |
29 | // ToDo: maybe fallback to pointer comparison? |
30 | virtual bool operator< (const Expression& rhs) const override = 0; |
31 | virtual bool operator== (const Expression& rhs) const override = 0; |
32 | |
33 | // We can give some reasonable implementations by using |
34 | // inverst operators on the specialized implementations |
35 | virtual bool operator> (const Expression& rhs) const { |
36 | return rhs < *this; |
37 | } |
38 | virtual bool operator!= (const Expression& rhs) const { |
39 | return !(*this == rhs); |
40 | } |
41 | |
42 | ATTACH_VIRTUAL_AST_OPERATIONS(Value); |
43 | |
44 | }; |
45 | |
46 | /////////////////////////////////////////////////////////////////////// |
47 | // Lists of values, both comma- and space-separated (distinguished by a |
48 | // type-tag.) Also used to represent variable-length argument lists. |
49 | /////////////////////////////////////////////////////////////////////// |
50 | class List : public Value, public Vectorized<ExpressionObj> { |
51 | void adjust_after_pushing(ExpressionObj e) override { is_expanded(is_expanded__: false); } |
52 | private: |
53 | ADD_PROPERTY(enum Sass_Separator, separator) |
54 | ADD_PROPERTY(bool, is_arglist) |
55 | ADD_PROPERTY(bool, is_bracketed) |
56 | ADD_PROPERTY(bool, from_selector) |
57 | public: |
58 | List(SourceSpan pstate, size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false); |
59 | sass::string type() const override { return is_arglist_ ? "arglist" : "list" ; } |
60 | static sass::string type_name() { return "list" ; } |
61 | const char* sep_string(bool compressed = false) const { |
62 | return separator() == SASS_SPACE ? |
63 | " " : (compressed ? "," : ", " ); |
64 | } |
65 | bool is_invisible() const override { return empty() && !is_bracketed(); } |
66 | ExpressionObj value_at_index(size_t i); |
67 | |
68 | virtual size_t hash() const override; |
69 | virtual size_t size() const; |
70 | virtual void set_delayed(bool delayed) override; |
71 | |
72 | virtual bool operator< (const Expression& rhs) const override; |
73 | virtual bool operator== (const Expression& rhs) const override; |
74 | |
75 | ATTACH_AST_OPERATIONS(List) |
76 | ATTACH_CRTP_PERFORM_METHODS() |
77 | }; |
78 | |
79 | /////////////////////////////////////////////////////////////////////// |
80 | // Key value paris. |
81 | /////////////////////////////////////////////////////////////////////// |
82 | class Map : public Value, public Hashed<ExpressionObj, ExpressionObj, Map_Obj> { |
83 | void adjust_after_pushing(std::pair<ExpressionObj, ExpressionObj> p) override { is_expanded(is_expanded__: false); } |
84 | public: |
85 | Map(SourceSpan pstate, size_t size = 0); |
86 | sass::string type() const override { return "map" ; } |
87 | static sass::string type_name() { return "map" ; } |
88 | bool is_invisible() const override { return empty(); } |
89 | List_Obj to_list(SourceSpan& pstate); |
90 | |
91 | virtual size_t hash() const override; |
92 | |
93 | virtual bool operator< (const Expression& rhs) const override; |
94 | virtual bool operator== (const Expression& rhs) const override; |
95 | |
96 | ATTACH_AST_OPERATIONS(Map) |
97 | ATTACH_CRTP_PERFORM_METHODS() |
98 | }; |
99 | |
100 | |
101 | ////////////////////////////////////////////////////////////////////////// |
102 | // Binary expressions. Represents logical, relational, and arithmetic |
103 | // operations. Templatized to avoid large switch statements and repetitive |
104 | // subclassing. |
105 | ////////////////////////////////////////////////////////////////////////// |
106 | class Binary_Expression : public PreValue { |
107 | private: |
108 | HASH_PROPERTY(Operand, op) |
109 | HASH_PROPERTY(ExpressionObj, left) |
110 | HASH_PROPERTY(ExpressionObj, right) |
111 | mutable size_t hash_; |
112 | public: |
113 | Binary_Expression(SourceSpan pstate, |
114 | Operand op, ExpressionObj lhs, ExpressionObj rhs); |
115 | |
116 | const sass::string type_name(); |
117 | const sass::string separator(); |
118 | bool is_left_interpolant(void) const override; |
119 | bool is_right_interpolant(void) const override; |
120 | bool has_interpolant() const override; |
121 | |
122 | virtual void set_delayed(bool delayed) override; |
123 | |
124 | virtual bool operator< (const Expression& rhs) const override; |
125 | virtual bool operator==(const Expression& rhs) const override; |
126 | |
127 | virtual size_t hash() const override; |
128 | enum Sass_OP optype() const { return op_.operand; } |
129 | ATTACH_AST_OPERATIONS(Binary_Expression) |
130 | ATTACH_CRTP_PERFORM_METHODS() |
131 | }; |
132 | |
133 | //////////////////////////////////////////////////// |
134 | // Function reference. |
135 | //////////////////////////////////////////////////// |
136 | class Function final : public Value { |
137 | public: |
138 | ADD_PROPERTY(Definition_Obj, definition) |
139 | ADD_PROPERTY(bool, is_css) |
140 | public: |
141 | Function(SourceSpan pstate, Definition_Obj def, bool css); |
142 | |
143 | sass::string type() const override { return "function" ; } |
144 | static sass::string type_name() { return "function" ; } |
145 | bool is_invisible() const override { return true; } |
146 | |
147 | sass::string name(); |
148 | |
149 | bool operator< (const Expression& rhs) const override; |
150 | bool operator== (const Expression& rhs) const override; |
151 | |
152 | ATTACH_AST_OPERATIONS(Function) |
153 | ATTACH_CRTP_PERFORM_METHODS() |
154 | }; |
155 | |
156 | ////////////////// |
157 | // Function calls. |
158 | ////////////////// |
159 | class Function_Call final : public PreValue { |
160 | HASH_CONSTREF(String_Obj, sname) |
161 | HASH_PROPERTY(Arguments_Obj, arguments) |
162 | HASH_PROPERTY(Function_Obj, func) |
163 | ADD_PROPERTY(bool, via_call) |
164 | ADD_PROPERTY(void*, cookie) |
165 | mutable size_t hash_; |
166 | public: |
167 | Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie); |
168 | Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func); |
169 | Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args); |
170 | |
171 | Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie); |
172 | Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func); |
173 | Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args); |
174 | |
175 | sass::string name() const; |
176 | bool is_css(); |
177 | |
178 | bool operator==(const Expression& rhs) const override; |
179 | |
180 | size_t hash() const override; |
181 | |
182 | ATTACH_AST_OPERATIONS(Function_Call) |
183 | ATTACH_CRTP_PERFORM_METHODS() |
184 | }; |
185 | |
186 | /////////////////////// |
187 | // Variable references. |
188 | /////////////////////// |
189 | class Variable final : public PreValue { |
190 | ADD_CONSTREF(sass::string, name) |
191 | public: |
192 | Variable(SourceSpan pstate, sass::string n); |
193 | virtual bool operator==(const Expression& rhs) const override; |
194 | virtual size_t hash() const override; |
195 | ATTACH_AST_OPERATIONS(Variable) |
196 | ATTACH_CRTP_PERFORM_METHODS() |
197 | }; |
198 | |
199 | //////////////////////////////////////////////// |
200 | // Numbers, percentages, dimensions, and colors. |
201 | //////////////////////////////////////////////// |
202 | class Number final : public Value, public Units { |
203 | HASH_PROPERTY(double, value) |
204 | ADD_PROPERTY(bool, zero) |
205 | mutable size_t hash_; |
206 | public: |
207 | Number(SourceSpan pstate, double val, sass::string u = "" , bool zero = true); |
208 | |
209 | bool zero() { return zero_; } |
210 | |
211 | sass::string type() const override { return "number" ; } |
212 | static sass::string type_name() { return "number" ; } |
213 | |
214 | // cancel out unnecessary units |
215 | // result will be in input units |
216 | void reduce(); |
217 | |
218 | // normalize units to defaults |
219 | // needed to compare two numbers |
220 | void normalize(); |
221 | |
222 | size_t hash() const override; |
223 | |
224 | bool operator< (const Number& rhs) const; |
225 | bool operator== (const Number& rhs) const; |
226 | bool operator< (const Expression& rhs) const override; |
227 | bool operator== (const Expression& rhs) const override; |
228 | ATTACH_AST_OPERATIONS(Number) |
229 | ATTACH_CRTP_PERFORM_METHODS() |
230 | }; |
231 | |
232 | ////////// |
233 | // Colors. |
234 | ////////// |
235 | class Color : public Value { |
236 | ADD_CONSTREF(sass::string, disp) |
237 | HASH_PROPERTY(double, a) |
238 | protected: |
239 | mutable size_t hash_; |
240 | public: |
241 | Color(SourceSpan pstate, double a = 1, const sass::string disp = "" ); |
242 | |
243 | sass::string type() const override { return "color" ; } |
244 | static sass::string type_name() { return "color" ; } |
245 | |
246 | virtual size_t hash() const override = 0; |
247 | |
248 | bool operator< (const Expression& rhs) const override; |
249 | bool operator== (const Expression& rhs) const override; |
250 | |
251 | virtual Color_RGBA* copyAsRGBA() const = 0; |
252 | virtual Color_RGBA* toRGBA() = 0; |
253 | |
254 | virtual Color_HSLA* copyAsHSLA() const = 0; |
255 | virtual Color_HSLA* toHSLA() = 0; |
256 | |
257 | ATTACH_VIRTUAL_AST_OPERATIONS(Color) |
258 | }; |
259 | |
260 | ////////// |
261 | // Colors. |
262 | ////////// |
263 | class Color_RGBA final : public Color { |
264 | HASH_PROPERTY(double, r) |
265 | HASH_PROPERTY(double, g) |
266 | HASH_PROPERTY(double, b) |
267 | public: |
268 | Color_RGBA(SourceSpan pstate, double r, double g, double b, double a = 1, const sass::string disp = "" ); |
269 | |
270 | sass::string type() const override { return "color" ; } |
271 | static sass::string type_name() { return "color" ; } |
272 | |
273 | size_t hash() const override; |
274 | |
275 | Color_RGBA* copyAsRGBA() const override; |
276 | Color_RGBA* toRGBA() override { return this; } |
277 | |
278 | Color_HSLA* copyAsHSLA() const override; |
279 | Color_HSLA* toHSLA() override { return copyAsHSLA(); } |
280 | |
281 | bool operator< (const Expression& rhs) const override; |
282 | bool operator== (const Expression& rhs) const override; |
283 | |
284 | ATTACH_AST_OPERATIONS(Color_RGBA) |
285 | ATTACH_CRTP_PERFORM_METHODS() |
286 | }; |
287 | |
288 | |
289 | ////////// |
290 | // Colors. |
291 | ////////// |
292 | class Color_HSLA final : public Color { |
293 | HASH_PROPERTY(double, h) |
294 | HASH_PROPERTY(double, s) |
295 | HASH_PROPERTY(double, l) |
296 | public: |
297 | Color_HSLA(SourceSpan pstate, double h, double s, double l, double a = 1, const sass::string disp = "" ); |
298 | |
299 | sass::string type() const override { return "color" ; } |
300 | static sass::string type_name() { return "color" ; } |
301 | |
302 | size_t hash() const override; |
303 | |
304 | Color_RGBA* copyAsRGBA() const override; |
305 | Color_RGBA* toRGBA() override { return copyAsRGBA(); } |
306 | |
307 | Color_HSLA* copyAsHSLA() const override; |
308 | Color_HSLA* toHSLA() override { return this; } |
309 | |
310 | bool operator< (const Expression& rhs) const override; |
311 | bool operator== (const Expression& rhs) const override; |
312 | |
313 | ATTACH_AST_OPERATIONS(Color_HSLA) |
314 | ATTACH_CRTP_PERFORM_METHODS() |
315 | }; |
316 | |
317 | ////////////////////////////// |
318 | // Errors from Sass_Values. |
319 | ////////////////////////////// |
320 | class Custom_Error final : public Value { |
321 | ADD_CONSTREF(sass::string, message) |
322 | public: |
323 | Custom_Error(SourceSpan pstate, sass::string msg); |
324 | bool operator< (const Expression& rhs) const override; |
325 | bool operator== (const Expression& rhs) const override; |
326 | ATTACH_AST_OPERATIONS(Custom_Error) |
327 | ATTACH_CRTP_PERFORM_METHODS() |
328 | }; |
329 | |
330 | ////////////////////////////// |
331 | // Warnings from Sass_Values. |
332 | ////////////////////////////// |
333 | class Custom_Warning final : public Value { |
334 | ADD_CONSTREF(sass::string, message) |
335 | public: |
336 | Custom_Warning(SourceSpan pstate, sass::string msg); |
337 | bool operator< (const Expression& rhs) const override; |
338 | bool operator== (const Expression& rhs) const override; |
339 | ATTACH_AST_OPERATIONS(Custom_Warning) |
340 | ATTACH_CRTP_PERFORM_METHODS() |
341 | }; |
342 | |
343 | //////////// |
344 | // Booleans. |
345 | //////////// |
346 | class Boolean final : public Value { |
347 | HASH_PROPERTY(bool, value) |
348 | mutable size_t hash_; |
349 | public: |
350 | Boolean(SourceSpan pstate, bool val); |
351 | operator bool() override { return value_; } |
352 | |
353 | sass::string type() const override { return "bool" ; } |
354 | static sass::string type_name() { return "bool" ; } |
355 | |
356 | size_t hash() const override; |
357 | |
358 | bool is_false() override { return !value_; } |
359 | |
360 | bool operator< (const Expression& rhs) const override; |
361 | bool operator== (const Expression& rhs) const override; |
362 | |
363 | ATTACH_AST_OPERATIONS(Boolean) |
364 | ATTACH_CRTP_PERFORM_METHODS() |
365 | }; |
366 | |
367 | //////////////////////////////////////////////////////////////////////// |
368 | // Abstract base class for Sass string values. Includes interpolated and |
369 | // "flat" strings. |
370 | //////////////////////////////////////////////////////////////////////// |
371 | class String : public Value { |
372 | public: |
373 | String(SourceSpan pstate, bool delayed = false); |
374 | static sass::string type_name() { return "string" ; } |
375 | virtual ~String() = 0; |
376 | virtual void rtrim() = 0; |
377 | virtual bool operator<(const Expression& rhs) const override { |
378 | return this->to_string() < rhs.to_string(); |
379 | }; |
380 | virtual bool operator==(const Expression& rhs) const override { |
381 | return this->to_string() == rhs.to_string(); |
382 | }; |
383 | ATTACH_VIRTUAL_AST_OPERATIONS(String); |
384 | ATTACH_CRTP_PERFORM_METHODS() |
385 | }; |
386 | inline String::~String() { }; |
387 | |
388 | /////////////////////////////////////////////////////////////////////// |
389 | // Interpolated strings. Meant to be reduced to flat strings during the |
390 | // evaluation phase. |
391 | /////////////////////////////////////////////////////////////////////// |
392 | class String_Schema final : public String, public Vectorized<PreValueObj> { |
393 | ADD_PROPERTY(bool, css) |
394 | mutable size_t hash_; |
395 | public: |
396 | String_Schema(SourceSpan pstate, size_t size = 0, bool css = true); |
397 | |
398 | sass::string type() const override { return "string" ; } |
399 | static sass::string type_name() { return "string" ; } |
400 | |
401 | bool is_left_interpolant(void) const override; |
402 | bool is_right_interpolant(void) const override; |
403 | |
404 | bool has_interpolants(); |
405 | void rtrim() override; |
406 | size_t hash() const override; |
407 | virtual void set_delayed(bool delayed) override; |
408 | |
409 | bool operator< (const Expression& rhs) const override; |
410 | bool operator==(const Expression& rhs) const override; |
411 | ATTACH_AST_OPERATIONS(String_Schema) |
412 | ATTACH_CRTP_PERFORM_METHODS() |
413 | }; |
414 | |
415 | //////////////////////////////////////////////////////// |
416 | // Flat strings -- the lowest level of raw textual data. |
417 | //////////////////////////////////////////////////////// |
418 | class String_Constant : public String { |
419 | ADD_PROPERTY(char, quote_mark) |
420 | HASH_CONSTREF(sass::string, value) |
421 | protected: |
422 | mutable size_t hash_; |
423 | public: |
424 | String_Constant(SourceSpan pstate, sass::string val, bool css = true); |
425 | String_Constant(SourceSpan pstate, const char* beg, bool css = true); |
426 | String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css = true); |
427 | String_Constant(SourceSpan pstate, const Token& tok, bool css = true); |
428 | sass::string type() const override { return "string" ; } |
429 | static sass::string type_name() { return "string" ; } |
430 | bool is_invisible() const override; |
431 | virtual void rtrim() override; |
432 | size_t hash() const override; |
433 | bool operator< (const Expression& rhs) const override; |
434 | bool operator==(const Expression& rhs) const override; |
435 | // quotes are forced on inspection |
436 | virtual sass::string inspect() const override; |
437 | ATTACH_AST_OPERATIONS(String_Constant) |
438 | ATTACH_CRTP_PERFORM_METHODS() |
439 | }; |
440 | |
441 | //////////////////////////////////////////////////////// |
442 | // Possibly quoted string (unquote on instantiation) |
443 | //////////////////////////////////////////////////////// |
444 | class String_Quoted final : public String_Constant { |
445 | public: |
446 | String_Quoted(SourceSpan pstate, sass::string val, char q = 0, |
447 | bool keep_utf8_escapes = false, bool skip_unquoting = false, |
448 | bool strict_unquoting = true, bool css = true); |
449 | bool operator< (const Expression& rhs) const override; |
450 | bool operator==(const Expression& rhs) const override; |
451 | // quotes are forced on inspection |
452 | sass::string inspect() const override; |
453 | ATTACH_AST_OPERATIONS(String_Quoted) |
454 | ATTACH_CRTP_PERFORM_METHODS() |
455 | }; |
456 | |
457 | ////////////////// |
458 | // The null value. |
459 | ////////////////// |
460 | class Null final : public Value { |
461 | public: |
462 | Null(SourceSpan pstate); |
463 | sass::string type() const override { return "null" ; } |
464 | static sass::string type_name() { return "null" ; } |
465 | bool is_invisible() const override { return true; } |
466 | operator bool() override { return false; } |
467 | bool is_false() override { return true; } |
468 | |
469 | size_t hash() const override; |
470 | |
471 | bool operator< (const Expression& rhs) const override; |
472 | bool operator== (const Expression& rhs) const override; |
473 | |
474 | ATTACH_AST_OPERATIONS(Null) |
475 | ATTACH_CRTP_PERFORM_METHODS() |
476 | }; |
477 | |
478 | ////////////////////////////////// |
479 | // The Parent Reference Expression. |
480 | ////////////////////////////////// |
481 | class Parent_Reference final : public Value { |
482 | public: |
483 | Parent_Reference(SourceSpan pstate); |
484 | sass::string type() const override { return "parent" ; } |
485 | static sass::string type_name() { return "parent" ; } |
486 | bool operator< (const Expression& rhs) const override { |
487 | return false; // they are always equal |
488 | } |
489 | bool operator==(const Expression& rhs) const override { |
490 | return true; // they are always equal |
491 | }; |
492 | ATTACH_AST_OPERATIONS(Parent_Reference) |
493 | ATTACH_CRTP_PERFORM_METHODS() |
494 | }; |
495 | |
496 | } |
497 | |
498 | #endif |
499 | |