sassc 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|