sassc 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/libsass/.gitignore +6 -0
- data/ext/libsass/.travis.yml +5 -1
- data/ext/libsass/Makefile +12 -3
- data/ext/libsass/Makefile.am +16 -28
- data/ext/libsass/Readme.md +1 -0
- data/ext/libsass/appveyor.yml +1 -2
- data/ext/libsass/ast.cpp +9 -0
- data/ext/libsass/ast.hpp +152 -55
- data/ext/libsass/ast_factory.hpp +2 -0
- data/ext/libsass/ast_fwd_decl.hpp +1 -0
- data/ext/libsass/backtrace.hpp +2 -2
- data/ext/libsass/bind.cpp +15 -13
- data/ext/libsass/configure.ac +17 -5
- data/ext/libsass/constants.cpp +22 -2
- data/ext/libsass/constants.hpp +21 -2
- data/ext/libsass/context.cpp +79 -57
- data/ext/libsass/context.hpp +23 -9
- data/ext/libsass/contextualize.cpp +2 -28
- data/ext/libsass/contextualize.hpp +6 -10
- data/ext/libsass/contextualize_eval.cpp +93 -0
- data/ext/libsass/contextualize_eval.hpp +44 -0
- data/ext/libsass/contrib/plugin.cpp +57 -0
- data/ext/libsass/cssize.cpp +3 -1
- data/ext/libsass/debugger.hpp +242 -83
- data/ext/libsass/emitter.cpp +1 -1
- data/ext/libsass/emitter.hpp +1 -1
- data/ext/libsass/environment.hpp +109 -25
- data/ext/libsass/error_handling.cpp +3 -3
- data/ext/libsass/error_handling.hpp +0 -1
- data/ext/libsass/eval.cpp +145 -61
- data/ext/libsass/eval.hpp +9 -1
- data/ext/libsass/expand.cpp +134 -60
- data/ext/libsass/expand.hpp +5 -2
- data/ext/libsass/extend.cpp +7 -5
- data/ext/libsass/file.cpp +176 -123
- data/ext/libsass/file.hpp +44 -7
- data/ext/libsass/functions.cpp +36 -17
- data/ext/libsass/functions.hpp +2 -2
- data/ext/libsass/inspect.cpp +23 -14
- data/ext/libsass/inspect.hpp +1 -0
- data/ext/libsass/json.cpp +132 -135
- data/ext/libsass/lexer.cpp +133 -0
- data/ext/libsass/lexer.hpp +239 -0
- data/ext/libsass/listize.cpp +83 -0
- data/ext/libsass/listize.hpp +41 -0
- data/ext/libsass/operation.hpp +2 -0
- data/ext/libsass/output.cpp +5 -6
- data/ext/libsass/parser.cpp +426 -388
- data/ext/libsass/parser.hpp +97 -109
- data/ext/libsass/plugins.cpp +15 -2
- data/ext/libsass/plugins.hpp +6 -4
- data/ext/libsass/position.cpp +52 -17
- data/ext/libsass/position.hpp +19 -17
- data/ext/libsass/prelexer.cpp +202 -235
- data/ext/libsass/prelexer.hpp +73 -333
- data/ext/libsass/sass.cpp +21 -11
- data/ext/libsass/sass.h +6 -6
- data/ext/libsass/sass_context.cpp +167 -81
- data/ext/libsass/sass_context.h +26 -6
- data/ext/libsass/sass_functions.cpp +49 -40
- data/ext/libsass/sass_functions.h +55 -43
- data/ext/libsass/sass_interface.cpp +9 -8
- data/ext/libsass/sass_interface.h +3 -3
- data/ext/libsass/sass_version.h +8 -0
- data/ext/libsass/sass_version.h.in +8 -0
- data/ext/libsass/script/ci-build-libsass +3 -3
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/source_map.cpp +2 -2
- data/ext/libsass/util.cpp +60 -11
- data/ext/libsass/util.hpp +6 -1
- data/ext/libsass/win/libsass.filters +12 -0
- data/ext/libsass/win/libsass.vcxproj +10 -0
- data/lib/sassc.rb +3 -1
- data/lib/sassc/cache_stores/base.rb +2 -0
- data/lib/sassc/dependency.rb +3 -1
- data/lib/sassc/engine.rb +31 -16
- data/lib/sassc/error.rb +3 -2
- data/lib/sassc/functions_handler.rb +54 -0
- data/lib/sassc/import_handler.rb +41 -0
- data/lib/sassc/importer.rb +4 -31
- data/lib/sassc/native.rb +1 -1
- data/lib/sassc/native/native_context_api.rb +3 -2
- data/lib/sassc/script.rb +0 -51
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -0
- data/test/custom_importer_test.rb +72 -69
- data/test/engine_test.rb +53 -54
- data/test/functions_test.rb +40 -39
- data/test/native_test.rb +145 -149
- data/test/output_style_test.rb +98 -0
- data/test/test_helper.rb +21 -7
- metadata +28 -2
@@ -0,0 +1,133 @@
|
|
1
|
+
#include <cctype>
|
2
|
+
#include <cstddef>
|
3
|
+
#include <iostream>
|
4
|
+
#include <iomanip>
|
5
|
+
#include "lexer.hpp"
|
6
|
+
#include "constants.hpp"
|
7
|
+
|
8
|
+
|
9
|
+
namespace Sass {
|
10
|
+
using namespace Constants;
|
11
|
+
|
12
|
+
namespace Prelexer {
|
13
|
+
|
14
|
+
//####################################
|
15
|
+
// BASIC CHARACTER MATCHERS
|
16
|
+
//####################################
|
17
|
+
|
18
|
+
// Match standard control chars
|
19
|
+
const char* kwd_at(const char* src) { return exactly<'@'>(src); }
|
20
|
+
const char* kwd_dot(const char* src) { return exactly<'.'>(src); }
|
21
|
+
const char* kwd_comma(const char* src) { return exactly<','>(src); };
|
22
|
+
const char* kwd_colon(const char* src) { return exactly<':'>(src); };
|
23
|
+
const char* kwd_star(const char* src) { return exactly<'*'>(src); };
|
24
|
+
const char* kwd_plus(const char* src) { return exactly<'+'>(src); };
|
25
|
+
const char* kwd_minus(const char* src) { return exactly<'-'>(src); };
|
26
|
+
const char* kwd_slash(const char* src) { return exactly<'/'>(src); };
|
27
|
+
|
28
|
+
//####################################
|
29
|
+
// implement some function that do exist in the standard
|
30
|
+
// but those are locale aware which brought some trouble
|
31
|
+
// this even seems to improve performance by quite a bit
|
32
|
+
//####################################
|
33
|
+
|
34
|
+
const bool is_alpha(const char& chr)
|
35
|
+
{
|
36
|
+
return unsigned(chr - 'A') <= 'Z' - 'A' ||
|
37
|
+
unsigned(chr - 'a') <= 'z' - 'a';
|
38
|
+
}
|
39
|
+
|
40
|
+
const bool is_space(const char& chr)
|
41
|
+
{
|
42
|
+
// adapted the technique from is_alpha
|
43
|
+
return chr == ' ' || unsigned(chr - '\t') <= '\r' - '\t';
|
44
|
+
}
|
45
|
+
|
46
|
+
const bool is_digit(const char& chr)
|
47
|
+
{
|
48
|
+
// adapted the technique from is_alpha
|
49
|
+
return unsigned(chr - '0') <= '9' - '0';
|
50
|
+
}
|
51
|
+
|
52
|
+
const bool is_xdigit(const char& chr)
|
53
|
+
{
|
54
|
+
// adapted the technique from is_alpha
|
55
|
+
return unsigned(chr - '0') <= '9' - '0' ||
|
56
|
+
unsigned(chr - 'a') <= 'f' - 'a' ||
|
57
|
+
unsigned(chr - 'A') <= 'F' - 'A';
|
58
|
+
}
|
59
|
+
|
60
|
+
const bool is_punct(const char& chr)
|
61
|
+
{
|
62
|
+
// locale independent
|
63
|
+
return chr == '.';
|
64
|
+
}
|
65
|
+
|
66
|
+
const bool is_alnum(const char& chr)
|
67
|
+
{
|
68
|
+
return is_alpha(chr) || is_digit(chr);
|
69
|
+
}
|
70
|
+
|
71
|
+
// check if char is outside ascii range
|
72
|
+
const bool is_unicode(const char& chr)
|
73
|
+
{
|
74
|
+
// check for unicode range
|
75
|
+
return unsigned(chr) > 127;
|
76
|
+
}
|
77
|
+
|
78
|
+
// Match word character (look ahead)
|
79
|
+
const bool is_character(const char& chr)
|
80
|
+
{
|
81
|
+
// valid alpha, numeric or unicode char (plus hyphen)
|
82
|
+
return is_alnum(chr) || is_unicode(chr) || chr == '-';
|
83
|
+
}
|
84
|
+
|
85
|
+
//####################################
|
86
|
+
// BASIC CLASS MATCHERS
|
87
|
+
//####################################
|
88
|
+
|
89
|
+
// create matchers that advance the position
|
90
|
+
const char* space(const char* src) { return is_space(*src) ? src + 1 : 0; }
|
91
|
+
const char* alpha(const char* src) { return is_alpha(*src) ? src + 1 : 0; }
|
92
|
+
const char* unicode(const char* src) { return is_unicode(*src) ? src + 1 : 0; }
|
93
|
+
const char* digit(const char* src) { return is_digit(*src) ? src + 1 : 0; }
|
94
|
+
const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; }
|
95
|
+
const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; }
|
96
|
+
const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; }
|
97
|
+
const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; }
|
98
|
+
|
99
|
+
// Match multiple ctype characters.
|
100
|
+
const char* spaces(const char* src) { return one_plus<space>(src); }
|
101
|
+
const char* digits(const char* src) { return one_plus<digit>(src); }
|
102
|
+
|
103
|
+
// Whitespace handling.
|
104
|
+
const char* no_spaces(const char* src) { return negate< space >(src); }
|
105
|
+
const char* optional_spaces(const char* src) { return zero_plus< space >(src); }
|
106
|
+
|
107
|
+
// Match any single character.
|
108
|
+
const char* any_char(const char* src) { return *src ? src + 1 : src; }
|
109
|
+
|
110
|
+
// Match word boundary (zero-width lookahead).
|
111
|
+
const char* word_boundary(const char* src) { return is_character(*src) ? 0 : src; }
|
112
|
+
|
113
|
+
// Match linefeed /(?:\n|\r\n?)/
|
114
|
+
const char* re_linebreak(const char* src)
|
115
|
+
{
|
116
|
+
// end of file or unix linefeed return here
|
117
|
+
if (*src == 0 || *src == '\n') return src + 1;
|
118
|
+
// a carriage return may optionally be followed by a linefeed
|
119
|
+
if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1;
|
120
|
+
// no linefeed
|
121
|
+
return 0;
|
122
|
+
}
|
123
|
+
|
124
|
+
// Assert string boundaries (/\Z|\z|\A/)
|
125
|
+
// This is a zero-width positive lookahead
|
126
|
+
const char* end_of_line(const char* src)
|
127
|
+
{
|
128
|
+
// end of file or unix linefeed return here
|
129
|
+
return *src == 0 || *src == '\n' || *src == '\r' ? src : 0;
|
130
|
+
}
|
131
|
+
|
132
|
+
}
|
133
|
+
}
|
@@ -0,0 +1,239 @@
|
|
1
|
+
#ifndef SASS_LEXER_H
|
2
|
+
#define SASS_LEXER_H
|
3
|
+
|
4
|
+
#include <cstring>
|
5
|
+
|
6
|
+
namespace Sass {
|
7
|
+
namespace Prelexer {
|
8
|
+
|
9
|
+
//####################################
|
10
|
+
// BASIC CHARACTER MATCHERS
|
11
|
+
//####################################
|
12
|
+
|
13
|
+
// Match standard control chars
|
14
|
+
const char* kwd_at(const char* src);
|
15
|
+
const char* kwd_dot(const char* src);
|
16
|
+
const char* kwd_comma(const char* src);
|
17
|
+
const char* kwd_colon(const char* src);
|
18
|
+
const char* kwd_star(const char* src);
|
19
|
+
const char* kwd_plus(const char* src);
|
20
|
+
const char* kwd_minus(const char* src);
|
21
|
+
const char* kwd_slash(const char* src);
|
22
|
+
|
23
|
+
//####################################
|
24
|
+
// BASIC CLASS MATCHERS
|
25
|
+
//####################################
|
26
|
+
|
27
|
+
// These are locale independant
|
28
|
+
const bool is_space(const char& src);
|
29
|
+
const bool is_alpha(const char& src);
|
30
|
+
const bool is_punct(const char& src);
|
31
|
+
const bool is_digit(const char& src);
|
32
|
+
const bool is_alnum(const char& src);
|
33
|
+
const bool is_xdigit(const char& src);
|
34
|
+
const bool is_unicode(const char& src);
|
35
|
+
const bool is_character(const char& src);
|
36
|
+
|
37
|
+
// Match a single ctype predicate.
|
38
|
+
const char* space(const char* src);
|
39
|
+
const char* alpha(const char* src);
|
40
|
+
const char* digit(const char* src);
|
41
|
+
const char* xdigit(const char* src);
|
42
|
+
const char* alnum(const char* src);
|
43
|
+
const char* punct(const char* src);
|
44
|
+
const char* unicode(const char* src);
|
45
|
+
const char* character(const char* src);
|
46
|
+
|
47
|
+
// Match multiple ctype characters.
|
48
|
+
const char* spaces(const char* src);
|
49
|
+
const char* digits(const char* src);
|
50
|
+
|
51
|
+
// Whitespace handling.
|
52
|
+
const char* no_spaces(const char* src);
|
53
|
+
const char* optional_spaces(const char* src);
|
54
|
+
|
55
|
+
// Match any single character (/./).
|
56
|
+
const char* any_char(const char* src);
|
57
|
+
|
58
|
+
// Assert word boundary (/\b/)
|
59
|
+
// Is a zero-width positive lookaheads
|
60
|
+
const char* word_boundary(const char* src);
|
61
|
+
|
62
|
+
// Match a single linebreak (/(?:\n|\r\n?)/).
|
63
|
+
const char* re_linebreak(const char* src);
|
64
|
+
|
65
|
+
// Assert string boundaries (/\Z|\z|\A/)
|
66
|
+
// There are zero-width positive lookaheads
|
67
|
+
const char* end_of_line(const char* src);
|
68
|
+
// const char* end_of_string(const char* src);
|
69
|
+
// const char* start_of_string(const char* src);
|
70
|
+
|
71
|
+
// Type definition for prelexer functions
|
72
|
+
typedef const char* (*prelexer)(const char*);
|
73
|
+
|
74
|
+
//####################################
|
75
|
+
// BASIC "REGEX" CONSTRUCTORS
|
76
|
+
//####################################
|
77
|
+
|
78
|
+
// Match a single character literal.
|
79
|
+
// Regex equivalent: /(?:literal)/
|
80
|
+
template <char chr>
|
81
|
+
const char* exactly(const char* src) {
|
82
|
+
return *src == chr ? src + 1 : 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
// Match a string constant.
|
86
|
+
// Regex equivalent: /[axy]/
|
87
|
+
template <const char* str>
|
88
|
+
const char* exactly(const char* src) {
|
89
|
+
if (str == 0) return 0;
|
90
|
+
const char* pre = str;
|
91
|
+
if (src == 0) return 0;
|
92
|
+
// there is a small chance that the search string
|
93
|
+
// is longer than the rest of the string to look at
|
94
|
+
while (*pre && *src == *pre) {
|
95
|
+
++src, ++pre;
|
96
|
+
}
|
97
|
+
return *pre ? 0 : src;
|
98
|
+
}
|
99
|
+
|
100
|
+
// Match for members of char class.
|
101
|
+
// Regex equivalent: /[axy]/
|
102
|
+
template <const char* char_class>
|
103
|
+
const char* class_char(const char* src) {
|
104
|
+
const char* cc = char_class;
|
105
|
+
while (*cc && *src != *cc) ++cc;
|
106
|
+
return *cc ? src + 1 : 0;
|
107
|
+
}
|
108
|
+
|
109
|
+
// Match for members of char class.
|
110
|
+
// Regex equivalent: /[axy]/
|
111
|
+
template <const char* char_class>
|
112
|
+
const char* class_chars(const char* src) {
|
113
|
+
const char* p = src;
|
114
|
+
while (class_char<char_class>(p)) ++p;
|
115
|
+
return p == src ? 0 : p;
|
116
|
+
}
|
117
|
+
|
118
|
+
// Match all except the supplied one.
|
119
|
+
// Regex equivalent: /[^x]/
|
120
|
+
template <const char chr>
|
121
|
+
const char* any_char_but(const char* src) {
|
122
|
+
return (*src && *src != chr) ? src + 1 : 0;
|
123
|
+
}
|
124
|
+
|
125
|
+
// Succeeds if the matcher fails.
|
126
|
+
// Aka. zero-width negative lookahead.
|
127
|
+
// Regex equivalent: /(?!literal)/
|
128
|
+
template <prelexer mx>
|
129
|
+
const char* negate(const char* src) {
|
130
|
+
return mx(src) ? 0 : src;
|
131
|
+
}
|
132
|
+
|
133
|
+
// Succeeds if the matcher succeeds.
|
134
|
+
// Aka. zero-width positive lookahead.
|
135
|
+
// Regex equivalent: /(?=literal)/
|
136
|
+
// just hangs around until we need it
|
137
|
+
template <prelexer mx>
|
138
|
+
const char* lookahead(const char* src) {
|
139
|
+
return mx(src) ? src : 0;
|
140
|
+
}
|
141
|
+
|
142
|
+
// Tries supplied matchers in order.
|
143
|
+
// Succeeds if one of them succeeds.
|
144
|
+
// Regex equivalent: /(?:FOO|BAR)/
|
145
|
+
template <prelexer... mxs>
|
146
|
+
const char* alternatives(const char* src) {
|
147
|
+
const char* rslt;
|
148
|
+
for (prelexer mx : { mxs... }) {
|
149
|
+
if ((rslt = mx(src))) return rslt;
|
150
|
+
}
|
151
|
+
return 0;
|
152
|
+
}
|
153
|
+
|
154
|
+
// Tries supplied matchers in order.
|
155
|
+
// Succeeds if all of them succeeds.
|
156
|
+
// Regex equivalent: /(?:FOO)(?:BAR)/
|
157
|
+
template <prelexer... mxs>
|
158
|
+
const char* sequence(const char* src) {
|
159
|
+
const char* rslt = src;
|
160
|
+
for (prelexer mx : { mxs... }) {
|
161
|
+
if (!(rslt = mx(rslt))) return 0;
|
162
|
+
}
|
163
|
+
return rslt;
|
164
|
+
}
|
165
|
+
|
166
|
+
// Match a pattern or not. Always succeeds.
|
167
|
+
// Regex equivalent: /(?:literal)?/
|
168
|
+
template <prelexer mx>
|
169
|
+
const char* optional(const char* src) {
|
170
|
+
const char* p = mx(src);
|
171
|
+
return p ? p : src;
|
172
|
+
}
|
173
|
+
|
174
|
+
// Match zero or more of the patterns.
|
175
|
+
// Regex equivalent: /(?:literal)*/
|
176
|
+
template <prelexer mx>
|
177
|
+
const char* zero_plus(const char* src) {
|
178
|
+
const char* p = mx(src);
|
179
|
+
while (p) src = p, p = mx(src);
|
180
|
+
return src;
|
181
|
+
}
|
182
|
+
|
183
|
+
// Match one or more of the patterns.
|
184
|
+
// Regex equivalent: /(?:literal)+/
|
185
|
+
template <prelexer mx>
|
186
|
+
const char* one_plus(const char* src) {
|
187
|
+
const char* p = mx(src);
|
188
|
+
if (!p) return 0;
|
189
|
+
while (p) src = p, p = mx(src);
|
190
|
+
return src;
|
191
|
+
}
|
192
|
+
|
193
|
+
// Match mx non-greedy until delimiter.
|
194
|
+
// Other prelexers are greedy by default.
|
195
|
+
// Regex equivalent: /(?:$mx)*?(?=$delim)\b/
|
196
|
+
template <prelexer mx, prelexer delim>
|
197
|
+
const char* non_greedy(const char* src) {
|
198
|
+
while (!delim(src)) {
|
199
|
+
const char* p = mx(src);
|
200
|
+
if (p == src) return 0;
|
201
|
+
if (p == 0) return 0;
|
202
|
+
src = p;
|
203
|
+
}
|
204
|
+
return src;
|
205
|
+
}
|
206
|
+
|
207
|
+
//####################################
|
208
|
+
// ADVANCED "REGEX" CONSTRUCTORS
|
209
|
+
//####################################
|
210
|
+
|
211
|
+
// Match with word boundary rule.
|
212
|
+
// Regex equivalent: /(?:$mx)\b/
|
213
|
+
template <const char* str>
|
214
|
+
const char* word(const char* src) {
|
215
|
+
return sequence <
|
216
|
+
exactly < str >,
|
217
|
+
word_boundary
|
218
|
+
>(src);
|
219
|
+
}
|
220
|
+
|
221
|
+
template <char chr>
|
222
|
+
const char* loosely(const char* src) {
|
223
|
+
return sequence <
|
224
|
+
optional_spaces,
|
225
|
+
exactly < chr >
|
226
|
+
>(src);
|
227
|
+
}
|
228
|
+
template <const char* str>
|
229
|
+
const char* loosely(const char* src) {
|
230
|
+
return sequence <
|
231
|
+
optional_spaces,
|
232
|
+
exactly < str >
|
233
|
+
>(src);
|
234
|
+
}
|
235
|
+
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
#endif
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#include <iostream>
|
2
|
+
#include <typeinfo>
|
3
|
+
|
4
|
+
#include "listize.hpp"
|
5
|
+
#include "to_string.hpp"
|
6
|
+
#include "context.hpp"
|
7
|
+
#include "backtrace.hpp"
|
8
|
+
#include "error_handling.hpp"
|
9
|
+
|
10
|
+
namespace Sass {
|
11
|
+
|
12
|
+
Listize::Listize(Context& ctx)
|
13
|
+
: ctx(ctx)
|
14
|
+
{ }
|
15
|
+
|
16
|
+
Expression* Listize::operator()(Selector_List* sel)
|
17
|
+
{
|
18
|
+
List* l = new (ctx.mem) List(sel->pstate(), sel->length(), List::COMMA);
|
19
|
+
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
20
|
+
*l << (*sel)[i]->perform(this);
|
21
|
+
}
|
22
|
+
return l;
|
23
|
+
}
|
24
|
+
|
25
|
+
Expression* Listize::operator()(Compound_Selector* sel)
|
26
|
+
{
|
27
|
+
To_String to_string;
|
28
|
+
string str;
|
29
|
+
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
30
|
+
Expression* e = (*sel)[i]->perform(this);
|
31
|
+
if (e) str += e->perform(&to_string);
|
32
|
+
}
|
33
|
+
return new (ctx.mem) String_Constant(sel->pstate(), str);
|
34
|
+
}
|
35
|
+
|
36
|
+
Expression* Listize::operator()(Complex_Selector* sel)
|
37
|
+
{
|
38
|
+
List* l = new (ctx.mem) List(sel->pstate(), 2);
|
39
|
+
|
40
|
+
Compound_Selector* head = sel->head();
|
41
|
+
if (head && !head->is_empty_reference())
|
42
|
+
{
|
43
|
+
Expression* hh = head->perform(this);
|
44
|
+
if (hh) *l << hh;
|
45
|
+
}
|
46
|
+
|
47
|
+
switch(sel->combinator())
|
48
|
+
{
|
49
|
+
case Complex_Selector::PARENT_OF:
|
50
|
+
*l << new (ctx.mem) String_Constant(sel->pstate(), ">");
|
51
|
+
break;
|
52
|
+
case Complex_Selector::ADJACENT_TO:
|
53
|
+
*l << new (ctx.mem) String_Constant(sel->pstate(), "+");
|
54
|
+
break;
|
55
|
+
case Complex_Selector::PRECEDES:
|
56
|
+
*l << new (ctx.mem) String_Constant(sel->pstate(), "~");
|
57
|
+
break;
|
58
|
+
case Complex_Selector::ANCESTOR_OF:
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
|
62
|
+
Complex_Selector* tail = sel->tail();
|
63
|
+
if (tail)
|
64
|
+
{
|
65
|
+
Expression* tt = tail->perform(this);
|
66
|
+
if (tt && tt->concrete_type() == Expression::LIST)
|
67
|
+
{ *l += static_cast<List*>(tt); }
|
68
|
+
else if (tt) *l << static_cast<List*>(tt);
|
69
|
+
}
|
70
|
+
if (l->length() == 0) return 0;
|
71
|
+
return l;
|
72
|
+
}
|
73
|
+
|
74
|
+
Expression* Listize::operator()(Selector_Reference* sel)
|
75
|
+
{
|
76
|
+
return 0;
|
77
|
+
}
|
78
|
+
|
79
|
+
Expression* Listize::fallback_impl(AST_Node* n)
|
80
|
+
{
|
81
|
+
return static_cast<Expression*>(n);
|
82
|
+
}
|
83
|
+
}
|