iv-phonic 0.0.1
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.
- data/.autotest +24 -0
- data/Manifest.txt +49 -0
- data/README.rdoc +32 -0
- data/Rakefile +54 -0
- data/ext/include/iv/algorithm.h +23 -0
- data/ext/include/iv/alloc.h +200 -0
- data/ext/include/iv/any.h +71 -0
- data/ext/include/iv/ast-factory.h +277 -0
- data/ext/include/iv/ast-fwd.h +92 -0
- data/ext/include/iv/ast-serializer.h +579 -0
- data/ext/include/iv/ast-visitor.h +121 -0
- data/ext/include/iv/ast.h +1127 -0
- data/ext/include/iv/chars.h +83 -0
- data/ext/include/iv/cmdline.h +830 -0
- data/ext/include/iv/conversions.h +308 -0
- data/ext/include/iv/dtoa.h +20 -0
- data/ext/include/iv/enable_if.h +18 -0
- data/ext/include/iv/errors.h +15 -0
- data/ext/include/iv/fixedcontainer.h +42 -0
- data/ext/include/iv/functor.h +29 -0
- data/ext/include/iv/lexer.h +1281 -0
- data/ext/include/iv/location.h +23 -0
- data/ext/include/iv/mt19937.h +175 -0
- data/ext/include/iv/noncopyable.h +30 -0
- data/ext/include/iv/none.h +10 -0
- data/ext/include/iv/parser.h +2150 -0
- data/ext/include/iv/source.h +27 -0
- data/ext/include/iv/space.h +178 -0
- data/ext/include/iv/static_assert.h +30 -0
- data/ext/include/iv/stringpiece.h +385 -0
- data/ext/include/iv/token.h +311 -0
- data/ext/include/iv/ucdata.h +58 -0
- data/ext/include/iv/uchar.h +8 -0
- data/ext/include/iv/ustring.h +28 -0
- data/ext/include/iv/ustringpiece.h +9 -0
- data/ext/include/iv/utils.h +83 -0
- data/ext/include/iv/xorshift.h +74 -0
- data/ext/iv/phonic/ast-fwd.h +21 -0
- data/ext/iv/phonic/ast.h +10 -0
- data/ext/iv/phonic/creator.h +530 -0
- data/ext/iv/phonic/encoding.h +110 -0
- data/ext/iv/phonic/extconf.rb +5 -0
- data/ext/iv/phonic/factory.h +247 -0
- data/ext/iv/phonic/parser.h +12 -0
- data/ext/iv/phonic/phonic.cc +69 -0
- data/ext/iv/phonic/rnode.h +15 -0
- data/ext/iv/phonic/rparser.h +48 -0
- data/ext/iv/phonic/source.h +146 -0
- data/test/test_iv_phonic.rb +32 -0
- metadata +159 -0
@@ -0,0 +1,579 @@
|
|
1
|
+
#ifndef _IV_AST_SERIALIZER_H_
|
2
|
+
#define _IV_AST_SERIALIZER_H_
|
3
|
+
#include <cstdio>
|
4
|
+
#include <ostream> // NOLINT
|
5
|
+
#include <sstream>
|
6
|
+
#include <tr1/tuple>
|
7
|
+
#include "uchar.h"
|
8
|
+
#include "ast.h"
|
9
|
+
#include "ast-visitor.h"
|
10
|
+
#include "ustring.h"
|
11
|
+
#include "stringpiece.h"
|
12
|
+
#include "ustringpiece.h"
|
13
|
+
namespace iv {
|
14
|
+
namespace core {
|
15
|
+
namespace ast {
|
16
|
+
|
17
|
+
template<typename Factory>
|
18
|
+
class AstSerializer: public AstVisitor<Factory>::const_type {
|
19
|
+
public:
|
20
|
+
|
21
|
+
typedef void ReturnType;
|
22
|
+
|
23
|
+
#define V(AST) typedef typename iv::core::ast::AST<Factory> AST;
|
24
|
+
AST_NODE_LIST(V)
|
25
|
+
#undef V
|
26
|
+
#define V(X, XS) typedef typename core::SpaceVector<Factory, X *>::type XS;
|
27
|
+
AST_LIST_LIST(V)
|
28
|
+
#undef V
|
29
|
+
#define V(S) typedef typename core::SpaceUString<Factory>::type S;
|
30
|
+
AST_STRING(V)
|
31
|
+
#undef V
|
32
|
+
|
33
|
+
AstSerializer() : out_() { }
|
34
|
+
inline const UString& out() const {
|
35
|
+
return out_;
|
36
|
+
}
|
37
|
+
|
38
|
+
void Append(const StringPiece& str) {
|
39
|
+
out_.append(str.begin(), str.end());
|
40
|
+
}
|
41
|
+
|
42
|
+
void Append(const UStringPiece& str) {
|
43
|
+
out_.append(str.begin(), str.end());
|
44
|
+
}
|
45
|
+
|
46
|
+
void Append(uc16 c) {
|
47
|
+
out_.push_back(c);
|
48
|
+
}
|
49
|
+
|
50
|
+
void Append(char c) {
|
51
|
+
out_.push_back(c);
|
52
|
+
}
|
53
|
+
|
54
|
+
void Visit(const Block* block) {
|
55
|
+
Append("{\"type\":\"block\",\"body\":[");
|
56
|
+
typename Statements::const_iterator it = block->body().begin();
|
57
|
+
const typename Statements::const_iterator end = block->body().end();
|
58
|
+
while (it != end) {
|
59
|
+
(*it)->Accept(this);
|
60
|
+
++it;
|
61
|
+
if (it != end) {
|
62
|
+
Append(',');
|
63
|
+
}
|
64
|
+
}
|
65
|
+
Append("]}");
|
66
|
+
}
|
67
|
+
|
68
|
+
void Visit(const FunctionStatement* func) {
|
69
|
+
Append("{\"type\":\"function_statement\",\"def\":");
|
70
|
+
func->function()->Accept(this);
|
71
|
+
Append('}');
|
72
|
+
}
|
73
|
+
|
74
|
+
void Visit(const VariableStatement* var) {
|
75
|
+
Append("{\"type\":");
|
76
|
+
if (var->IsConst()) {
|
77
|
+
Append("\"const\",\"decls\":[");
|
78
|
+
} else {
|
79
|
+
Append("\"var\",\"decls\":[");
|
80
|
+
}
|
81
|
+
typename Declarations::const_iterator it = var->decls().begin();
|
82
|
+
const typename Declarations::const_iterator end = var->decls().end();
|
83
|
+
while (it != end) {
|
84
|
+
(*it)->Accept(this);
|
85
|
+
++it;
|
86
|
+
if (it != end) {
|
87
|
+
Append(',');
|
88
|
+
}
|
89
|
+
}
|
90
|
+
Append("]}");
|
91
|
+
}
|
92
|
+
|
93
|
+
void Visit(const Declaration* decl) {
|
94
|
+
Append("{\"type\":\"decl\",\"name\":");
|
95
|
+
decl->name()->Accept(this);
|
96
|
+
Append(",\"exp\":");
|
97
|
+
if (decl->expr()) {
|
98
|
+
decl->expr()->Accept(this);
|
99
|
+
}
|
100
|
+
Append('}');
|
101
|
+
}
|
102
|
+
|
103
|
+
void Visit(const EmptyStatement* empty) {
|
104
|
+
Append("{\"type\":\"empty\"}");
|
105
|
+
}
|
106
|
+
|
107
|
+
void Visit(const IfStatement* ifstmt) {
|
108
|
+
Append("{\"type\":\"if\",\"cond\":");
|
109
|
+
ifstmt->cond()->Accept(this);
|
110
|
+
Append(",\"body\":");
|
111
|
+
ifstmt->then_statement()->Accept(this);
|
112
|
+
if (ifstmt->else_statement()) {
|
113
|
+
Append(",\"else\":");
|
114
|
+
ifstmt->else_statement()->Accept(this);
|
115
|
+
}
|
116
|
+
Append('}');
|
117
|
+
}
|
118
|
+
|
119
|
+
void Visit(const DoWhileStatement* dowhile) {
|
120
|
+
Append("{\"type\":\"dowhile\",\"cond\":");
|
121
|
+
dowhile->cond()->Accept(this);
|
122
|
+
Append(",\"body\":");
|
123
|
+
dowhile->body()->Accept(this);
|
124
|
+
Append('}');
|
125
|
+
}
|
126
|
+
|
127
|
+
void Visit(const WhileStatement* whilestmt) {
|
128
|
+
Append("{\"type\":\"while\",\"cond\":");
|
129
|
+
whilestmt->cond()->Accept(this);
|
130
|
+
Append(",\"body\":");
|
131
|
+
whilestmt->body()->Accept(this);
|
132
|
+
Append('}');
|
133
|
+
}
|
134
|
+
|
135
|
+
void Visit(const ForStatement* forstmt) {
|
136
|
+
Append("{\"type\":\"for\"");
|
137
|
+
if (forstmt->init() != NULL) {
|
138
|
+
Append(",\"init\":");
|
139
|
+
forstmt->init()->Accept(this);
|
140
|
+
}
|
141
|
+
if (forstmt->cond() != NULL) {
|
142
|
+
Append(",\"cond\":");
|
143
|
+
forstmt->cond()->Accept(this);
|
144
|
+
}
|
145
|
+
if (forstmt->next() != NULL) {
|
146
|
+
Append(",\"next\":");
|
147
|
+
forstmt->next()->Accept(this);
|
148
|
+
}
|
149
|
+
Append(",\"body\":");
|
150
|
+
forstmt->body()->Accept(this);
|
151
|
+
Append('}');
|
152
|
+
}
|
153
|
+
|
154
|
+
void Visit(const ForInStatement* forstmt) {
|
155
|
+
Append("{\"type\":\"forin\",\"each\":");
|
156
|
+
forstmt->each()->Accept(this);
|
157
|
+
Append(",\"enumerable\":");
|
158
|
+
forstmt->enumerable()->Accept(this);
|
159
|
+
Append(",\"body\":");
|
160
|
+
forstmt->body()->Accept(this);
|
161
|
+
Append('}');
|
162
|
+
}
|
163
|
+
|
164
|
+
void Visit(const ContinueStatement* continuestmt) {
|
165
|
+
Append("{\"type\":\"continue\"");
|
166
|
+
if (continuestmt->label()) {
|
167
|
+
Append(",\"label\":");
|
168
|
+
continuestmt->label()->Accept(this);
|
169
|
+
}
|
170
|
+
Append('}');
|
171
|
+
}
|
172
|
+
|
173
|
+
void Visit(const BreakStatement* breakstmt) {
|
174
|
+
Append("{\"type\":\"break\"");
|
175
|
+
if (breakstmt->label()) {
|
176
|
+
Append(",\"label\":");
|
177
|
+
breakstmt->label()->Accept(this);
|
178
|
+
}
|
179
|
+
Append('}');
|
180
|
+
}
|
181
|
+
|
182
|
+
void Visit(const ReturnStatement* returnstmt) {
|
183
|
+
Append("{\"type\":\"return\",\"exp\":");
|
184
|
+
returnstmt->expr()->Accept(this);
|
185
|
+
Append('}');
|
186
|
+
}
|
187
|
+
|
188
|
+
void Visit(const WithStatement* withstmt) {
|
189
|
+
Append("{\"type\":\"with\",\"context\":");
|
190
|
+
withstmt->context()->Accept(this);
|
191
|
+
Append(",\"body\":");
|
192
|
+
withstmt->body()->Accept(this);
|
193
|
+
Append('}');
|
194
|
+
}
|
195
|
+
|
196
|
+
void Visit(const LabelledStatement* labelledstmt) {
|
197
|
+
Append("{\"type\":\"labelled\",\"label\":");
|
198
|
+
labelledstmt->label()->Accept(this);
|
199
|
+
Append(",\"body\":");
|
200
|
+
labelledstmt->body()->Accept(this);
|
201
|
+
Append('}');
|
202
|
+
}
|
203
|
+
|
204
|
+
void Visit(const CaseClause* clause) {
|
205
|
+
if (clause->IsDefault()) {
|
206
|
+
Append("{\"type\":\"default\"");
|
207
|
+
} else {
|
208
|
+
Append("{\"type\":\"case\",\"exp\":");
|
209
|
+
clause->expr()->Accept(this);
|
210
|
+
}
|
211
|
+
Append(",\"body\"[");
|
212
|
+
typename Statements::const_iterator it = clause->body().begin();
|
213
|
+
const typename Statements::const_iterator end = clause->body().end();
|
214
|
+
while (it != end) {
|
215
|
+
(*it)->Accept(this);
|
216
|
+
++it;
|
217
|
+
if (it != end) {
|
218
|
+
Append(',');
|
219
|
+
}
|
220
|
+
}
|
221
|
+
Append("]}");
|
222
|
+
}
|
223
|
+
|
224
|
+
void Visit(const SwitchStatement* switchstmt) {
|
225
|
+
Append("{\"type\":\"switch\",\"exp\":");
|
226
|
+
switchstmt->expr()->Accept(this);
|
227
|
+
Append(",\"clauses\":[");
|
228
|
+
typename CaseClauses::const_iterator
|
229
|
+
it = switchstmt->clauses().begin();
|
230
|
+
const typename CaseClauses::const_iterator
|
231
|
+
end = switchstmt->clauses().end();
|
232
|
+
while (it != end) {
|
233
|
+
(*it)->Accept(this);
|
234
|
+
++it;
|
235
|
+
if (it != end) {
|
236
|
+
Append(',');
|
237
|
+
}
|
238
|
+
}
|
239
|
+
Append("]}");
|
240
|
+
}
|
241
|
+
|
242
|
+
void Visit(const ThrowStatement* throwstmt) {
|
243
|
+
Append("{\"type\":\"throw\",\"exp\":");
|
244
|
+
throwstmt->expr()->Accept(this);
|
245
|
+
Append('}');
|
246
|
+
}
|
247
|
+
|
248
|
+
void Visit(const TryStatement* trystmt) {
|
249
|
+
Append("{\"type\":\"try\",\"body\":");
|
250
|
+
trystmt->body()->Accept(this);
|
251
|
+
if (trystmt->catch_name()) {
|
252
|
+
Append(",\"catch\":{\"type\":\"catch\",\"name\":");
|
253
|
+
trystmt->catch_name()->Accept(this);
|
254
|
+
Append(",\"body\":");
|
255
|
+
trystmt->catch_block()->Accept(this);
|
256
|
+
Append('}');
|
257
|
+
}
|
258
|
+
if (trystmt->finally_block()) {
|
259
|
+
Append(",\"finally\":{\"type\":\"finally\",\"body\":");
|
260
|
+
trystmt->finally_block()->Accept(this);
|
261
|
+
Append('}');
|
262
|
+
}
|
263
|
+
Append('}');
|
264
|
+
}
|
265
|
+
|
266
|
+
void Visit(const DebuggerStatement* debuggerstmt) {
|
267
|
+
Append("{\"type\":\"debugger\"}");
|
268
|
+
}
|
269
|
+
|
270
|
+
void Visit(const ExpressionStatement* exprstmt) {
|
271
|
+
Append("{\"type\":\"expstatement\",\"exp\":");
|
272
|
+
exprstmt->expr()->Accept(this);
|
273
|
+
Append('}');
|
274
|
+
}
|
275
|
+
|
276
|
+
void Visit(const Assignment* assign) {
|
277
|
+
Append("{\"type\":\"assign\",\"op\":\"");
|
278
|
+
Append(Token::ToString(assign->op()));
|
279
|
+
Append("\",\"left\":");
|
280
|
+
assign->left()->Accept(this);
|
281
|
+
Append(",\"right\":");
|
282
|
+
assign->right()->Accept(this);
|
283
|
+
Append('}');
|
284
|
+
}
|
285
|
+
|
286
|
+
void Visit(const BinaryOperation* binary) {
|
287
|
+
Append("{\"type\":\"binary\",\"op\":\"");
|
288
|
+
Append(Token::ToString(binary->op()));
|
289
|
+
Append("\",\"left\":");
|
290
|
+
binary->left()->Accept(this);
|
291
|
+
Append(",\"right\":");
|
292
|
+
binary->right()->Accept(this);
|
293
|
+
Append('}');
|
294
|
+
}
|
295
|
+
|
296
|
+
void Visit(const ConditionalExpression* cond) {
|
297
|
+
Append("{\"type\":\"conditional\",\"cond\":");
|
298
|
+
cond->cond()->Accept(this);
|
299
|
+
Append(",\"left\":");
|
300
|
+
cond->left()->Accept(this);
|
301
|
+
Append(",\"right\":");
|
302
|
+
cond->right()->Accept(this);
|
303
|
+
Append('}');
|
304
|
+
}
|
305
|
+
|
306
|
+
void Visit(const UnaryOperation* unary) {
|
307
|
+
Append("{\"type\":\"unary\",\"op\":\"");
|
308
|
+
Append(Token::ToString(unary->op()));
|
309
|
+
Append("\",\"exp\":");
|
310
|
+
unary->expr()->Accept(this);
|
311
|
+
Append('}');
|
312
|
+
}
|
313
|
+
|
314
|
+
void Visit(const PostfixExpression* postfix) {
|
315
|
+
Append("{\"type\":\"postfix\",\"op\":\"");
|
316
|
+
Append(Token::ToString(postfix->op()));
|
317
|
+
Append("\",\"exp\":");
|
318
|
+
postfix->expr()->Accept(this);
|
319
|
+
Append('}');
|
320
|
+
}
|
321
|
+
|
322
|
+
void Visit(const StringLiteral* literal) {
|
323
|
+
Append("{\"type\":\"string\",\"value\":\"");
|
324
|
+
DecodeString(literal->value().begin(), literal->value().end());
|
325
|
+
Append("\"}");
|
326
|
+
}
|
327
|
+
|
328
|
+
void Visit(const NumberLiteral* literal) {
|
329
|
+
std::ostringstream sout;
|
330
|
+
sout << literal->value();
|
331
|
+
Append("{\"type\":\"number\",\"value\":\"");
|
332
|
+
Append(sout.str());
|
333
|
+
Append("\"}");
|
334
|
+
}
|
335
|
+
|
336
|
+
void Visit(const Identifier* literal) {
|
337
|
+
Append("{\"type\":\"identifier\",\"value\":\"");
|
338
|
+
Append(literal->value());
|
339
|
+
Append("\"}");
|
340
|
+
}
|
341
|
+
|
342
|
+
void Visit(const ThisLiteral* literal) {
|
343
|
+
Append("{\"type\":\"this\"}");
|
344
|
+
}
|
345
|
+
|
346
|
+
void Visit(const NullLiteral* literal) {
|
347
|
+
Append("{\"type\":\"null\"}");
|
348
|
+
}
|
349
|
+
|
350
|
+
void Visit(const TrueLiteral* literal) {
|
351
|
+
Append("{\"type\":\"true\"}");
|
352
|
+
}
|
353
|
+
|
354
|
+
void Visit(const FalseLiteral* literal) {
|
355
|
+
Append("{\"type\":\"false\"}");
|
356
|
+
}
|
357
|
+
|
358
|
+
void Visit(const Undefined* literal) {
|
359
|
+
Append("{\"type\":\"undefined\"}");
|
360
|
+
}
|
361
|
+
|
362
|
+
void Visit(const RegExpLiteral* literal) {
|
363
|
+
Append("{\"type\":\"regexp\",\"value\":\"");
|
364
|
+
DecodeString(literal->value().begin(), literal->value().end());
|
365
|
+
Append("\",\"flags\":\"");
|
366
|
+
Append(literal->flags());
|
367
|
+
Append("\"}");
|
368
|
+
}
|
369
|
+
|
370
|
+
void Visit(const ArrayLiteral* literal) {
|
371
|
+
Append("{\"type\":\"array\",\"value\":[");
|
372
|
+
typename Expressions::const_iterator it = literal->items().begin();
|
373
|
+
const typename Expressions::const_iterator end = literal->items().end();
|
374
|
+
bool previous_is_elision = false;
|
375
|
+
while (it != end) {
|
376
|
+
if ((*it)) {
|
377
|
+
(*it)->Accept(this);
|
378
|
+
previous_is_elision = false;
|
379
|
+
} else {
|
380
|
+
previous_is_elision = true;
|
381
|
+
}
|
382
|
+
++it;
|
383
|
+
if (it != end) {
|
384
|
+
Append(',');
|
385
|
+
}
|
386
|
+
}
|
387
|
+
if (previous_is_elision) {
|
388
|
+
Append(',');
|
389
|
+
}
|
390
|
+
Append("]}");
|
391
|
+
}
|
392
|
+
|
393
|
+
void Visit(const ObjectLiteral* literal) {
|
394
|
+
using std::tr1::get;
|
395
|
+
Append("{\"type\":\"object\",\"value\":[");
|
396
|
+
typename ObjectLiteral::Properties::const_iterator
|
397
|
+
it = literal->properties().begin();
|
398
|
+
const typename ObjectLiteral::Properties::const_iterator
|
399
|
+
end = literal->properties().end();
|
400
|
+
while (it != end) {
|
401
|
+
Append("{\"type\":");
|
402
|
+
const typename ObjectLiteral::PropertyDescriptorType type(get<0>(*it));
|
403
|
+
if (type == ObjectLiteral::DATA) {
|
404
|
+
Append("\"data\"");
|
405
|
+
} else if (type == ObjectLiteral::SET) {
|
406
|
+
Append("\"setter\"");
|
407
|
+
} else {
|
408
|
+
Append("\"getter\"");
|
409
|
+
}
|
410
|
+
Append(",\"key\":");
|
411
|
+
get<1>(*it)->Accept(this);
|
412
|
+
Append(",\"val\":");
|
413
|
+
get<2>(*it)->Accept(this);
|
414
|
+
Append('}');
|
415
|
+
++it;
|
416
|
+
if (it == end) {
|
417
|
+
break;
|
418
|
+
}
|
419
|
+
Append(',');
|
420
|
+
}
|
421
|
+
Append("]}");
|
422
|
+
}
|
423
|
+
|
424
|
+
void Visit(const FunctionLiteral* literal) {
|
425
|
+
Append("{\"type\":\"function\",\"name\":");
|
426
|
+
if (literal->name()) {
|
427
|
+
literal->name()->Accept(this);
|
428
|
+
}
|
429
|
+
Append(",\"params\":[");
|
430
|
+
typename Identifiers::const_iterator it = literal->params().begin();
|
431
|
+
const typename Identifiers::const_iterator end = literal->params().end();
|
432
|
+
while (it != end) {
|
433
|
+
(*it)->Accept(this);
|
434
|
+
++it;
|
435
|
+
if (it == end) {
|
436
|
+
break;
|
437
|
+
}
|
438
|
+
Append(',');
|
439
|
+
}
|
440
|
+
Append("],\"body\":[");
|
441
|
+
typename Statements::const_iterator it_body = literal->body().begin();
|
442
|
+
const typename Statements::const_iterator end_body = literal->body().end();
|
443
|
+
while (it_body != end_body) {
|
444
|
+
(*it_body)->Accept(this);
|
445
|
+
++it_body;
|
446
|
+
if (it_body == end_body) {
|
447
|
+
break;
|
448
|
+
}
|
449
|
+
Append(',');
|
450
|
+
}
|
451
|
+
Append("]}");
|
452
|
+
}
|
453
|
+
|
454
|
+
void Visit(const IndexAccess* prop) {
|
455
|
+
Append("{\"type\":\"property\",\"target\":");
|
456
|
+
prop->target()->Accept(this);
|
457
|
+
Append(",\"key\":");
|
458
|
+
prop->key()->Accept(this);
|
459
|
+
Append('}');
|
460
|
+
}
|
461
|
+
|
462
|
+
void Visit(const IdentifierAccess* prop) {
|
463
|
+
Append("{\"type\":\"property\",\"target\":");
|
464
|
+
prop->target()->Accept(this);
|
465
|
+
Append(",\"key\":");
|
466
|
+
prop->key()->Accept(this);
|
467
|
+
Append('}');
|
468
|
+
}
|
469
|
+
|
470
|
+
void Visit(const FunctionCall* call) {
|
471
|
+
Append("{\"type\":\"funcall\",\"target\":");
|
472
|
+
call->target()->Accept(this);
|
473
|
+
Append(",\"args\":[");
|
474
|
+
typename Expressions::const_iterator it = call->args().begin();
|
475
|
+
const typename Expressions::const_iterator end = call->args().end();
|
476
|
+
while (it != end) {
|
477
|
+
(*it)->Accept(this);
|
478
|
+
++it;
|
479
|
+
if (it == end) {
|
480
|
+
break;
|
481
|
+
}
|
482
|
+
Append(',');
|
483
|
+
}
|
484
|
+
Append("]}");
|
485
|
+
}
|
486
|
+
|
487
|
+
void Visit(const ConstructorCall* call) {
|
488
|
+
Append("{\"type\":\"new\",\"target\":");
|
489
|
+
call->target()->Accept(this);
|
490
|
+
Append(",\"args\":[");
|
491
|
+
typename Expressions::const_iterator it = call->args().begin();
|
492
|
+
const typename Expressions::const_iterator end = call->args().end();
|
493
|
+
while (it != end) {
|
494
|
+
(*it)->Accept(this);
|
495
|
+
++it;
|
496
|
+
if (it == end) {
|
497
|
+
break;
|
498
|
+
}
|
499
|
+
Append(',');
|
500
|
+
}
|
501
|
+
Append("]}");
|
502
|
+
}
|
503
|
+
|
504
|
+
private:
|
505
|
+
template <class Iter>
|
506
|
+
void DecodeString(Iter it, const Iter last) {
|
507
|
+
char buf[5];
|
508
|
+
for (;it != last; ++it) {
|
509
|
+
const uc16 val = *it;
|
510
|
+
switch (val) {
|
511
|
+
case '"':
|
512
|
+
Append("\\\"");
|
513
|
+
break;
|
514
|
+
|
515
|
+
case '\\':
|
516
|
+
Append("\\\\");
|
517
|
+
break;
|
518
|
+
|
519
|
+
case '/':
|
520
|
+
Append("\\/");
|
521
|
+
break;
|
522
|
+
|
523
|
+
case '\b':
|
524
|
+
Append("\\b");
|
525
|
+
break;
|
526
|
+
|
527
|
+
case '\f':
|
528
|
+
Append("\\f");
|
529
|
+
break;
|
530
|
+
|
531
|
+
case '\n':
|
532
|
+
Append("\\n");
|
533
|
+
break;
|
534
|
+
|
535
|
+
case '\r':
|
536
|
+
Append("\\r");
|
537
|
+
break;
|
538
|
+
|
539
|
+
case '\t':
|
540
|
+
Append("\\t");
|
541
|
+
break;
|
542
|
+
|
543
|
+
case '\x0B': // \v
|
544
|
+
Append("\\u000b");
|
545
|
+
break;
|
546
|
+
|
547
|
+
default:
|
548
|
+
if (val < 0x20) {
|
549
|
+
if (val < 0x10) {
|
550
|
+
Append("\\u000");
|
551
|
+
std::snprintf(buf, sizeof(buf), "%x", val);
|
552
|
+
Append(buf);
|
553
|
+
} else if (0x10 <= val && val < 0x20) {
|
554
|
+
Append("\\u00");
|
555
|
+
std::snprintf(buf, sizeof(buf), "%x", val);
|
556
|
+
Append(buf);
|
557
|
+
}
|
558
|
+
} else if (0x80 <= val) {
|
559
|
+
if (0x80 <= val && val < 0x1000) {
|
560
|
+
Append("\\u0");
|
561
|
+
std::snprintf(buf, sizeof(buf), "%x", val);
|
562
|
+
Append(buf);
|
563
|
+
} else if (0x1000 <= val) {
|
564
|
+
Append("\\u");
|
565
|
+
std::snprintf(buf, sizeof(buf), "%x", val);
|
566
|
+
Append(buf);
|
567
|
+
}
|
568
|
+
} else {
|
569
|
+
Append(val);
|
570
|
+
}
|
571
|
+
break;
|
572
|
+
}
|
573
|
+
}
|
574
|
+
}
|
575
|
+
UString out_;
|
576
|
+
};
|
577
|
+
|
578
|
+
} } } // namespace iv::core::ast
|
579
|
+
#endif // _IV_AST_SERIALIZER_H_
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#ifndef _IV_AST_VISITOR_H_
|
2
|
+
#define _IV_AST_VISITOR_H_
|
3
|
+
#include <tr1/type_traits>
|
4
|
+
#include "noncopyable.h"
|
5
|
+
#include "ast-fwd.h"
|
6
|
+
|
7
|
+
namespace iv {
|
8
|
+
namespace core {
|
9
|
+
namespace ast {
|
10
|
+
namespace detail {
|
11
|
+
|
12
|
+
template<bool IsConst, typename T>
|
13
|
+
struct AstVisitorTraits {
|
14
|
+
};
|
15
|
+
|
16
|
+
template<typename T>
|
17
|
+
struct AstVisitorTraits<true, T> {
|
18
|
+
typedef typename std::tr1::add_pointer<
|
19
|
+
typename std::tr1::add_const<T>::type>::type type;
|
20
|
+
};
|
21
|
+
|
22
|
+
template<typename T>
|
23
|
+
struct AstVisitorTraits<false, T> {
|
24
|
+
typedef typename std::tr1::add_pointer<
|
25
|
+
typename std::tr1::add_const<T>::type>::type type;
|
26
|
+
};
|
27
|
+
|
28
|
+
} // namespace iv::core::ast::detail
|
29
|
+
|
30
|
+
template<bool IsConst, typename Factory>
|
31
|
+
class BasicAstVisitor
|
32
|
+
: private Noncopyable<BasicAstVisitor<IsConst, Factory> >::type {
|
33
|
+
private:
|
34
|
+
template<typename T>
|
35
|
+
struct add {
|
36
|
+
typedef typename detail::AstVisitorTraits<IsConst, T>::type type;
|
37
|
+
};
|
38
|
+
public:
|
39
|
+
virtual ~BasicAstVisitor() = 0;
|
40
|
+
virtual void Visit(typename add<Block<Factory> >::type block) = 0; //NOLINT
|
41
|
+
virtual void Visit(typename add<FunctionStatement<Factory> >::type func) = 0; //NOLINT
|
42
|
+
virtual void Visit(typename add<VariableStatement<Factory> >::type var) = 0; //NOLINT
|
43
|
+
virtual void Visit(typename add<Declaration<Factory> >::type decl) = 0; //NOLINT
|
44
|
+
virtual void Visit(typename add<EmptyStatement<Factory> >::type empty) = 0; //NOLINT
|
45
|
+
virtual void Visit(typename add<IfStatement<Factory> >::type ifstmt) = 0; //NOLINT
|
46
|
+
virtual void Visit(typename add<DoWhileStatement<Factory> >::type dowhile) = 0; //NOLINT
|
47
|
+
virtual void Visit(typename add<WhileStatement<Factory> >::type whilestmt) = 0; //NOLINT
|
48
|
+
virtual void Visit(typename add<ForStatement<Factory> >::type forstmt) = 0; //NOLINT
|
49
|
+
virtual void Visit(typename add<ForInStatement<Factory> >::type forstmt) = 0; //NOLINT
|
50
|
+
virtual void Visit(typename add<ContinueStatement<Factory> >::type continuestmt) = 0; //NOLINT
|
51
|
+
virtual void Visit(typename add<BreakStatement<Factory> >::type breakstmt) = 0; //NOLINT
|
52
|
+
virtual void Visit(typename add<ReturnStatement<Factory> >::type returnstmt) = 0; //NOLINT
|
53
|
+
virtual void Visit(typename add<WithStatement<Factory> >::type withstmt) = 0; //NOLINT
|
54
|
+
virtual void Visit(typename add<LabelledStatement<Factory> >::type labelledstmt) = 0; //NOLINT
|
55
|
+
virtual void Visit(typename add<CaseClause<Factory> >::type clause) = 0; //NOLINT
|
56
|
+
virtual void Visit(typename add<SwitchStatement<Factory> >::type switchstmt) = 0; //NOLINT
|
57
|
+
virtual void Visit(typename add<ThrowStatement<Factory> >::type throwstmt) = 0; //NOLINT
|
58
|
+
virtual void Visit(typename add<TryStatement<Factory> >::type trystmt) = 0; //NOLINT
|
59
|
+
virtual void Visit(typename add<DebuggerStatement<Factory> >::type debuggerstmt) = 0; //NOLINT
|
60
|
+
virtual void Visit(typename add<ExpressionStatement<Factory> >::type exprstmt) = 0; //NOLINT
|
61
|
+
|
62
|
+
virtual void Visit(typename add<Assignment<Factory> >::type assign) = 0; //NOLINT
|
63
|
+
virtual void Visit(typename add<BinaryOperation<Factory> >::type binary) = 0; //NOLINT
|
64
|
+
virtual void Visit(typename add<ConditionalExpression<Factory> >::type cond) = 0; //NOLINT
|
65
|
+
virtual void Visit(typename add<UnaryOperation<Factory> >::type unary) = 0; //NOLINT
|
66
|
+
virtual void Visit(typename add<PostfixExpression<Factory> >::type postfix) = 0; //NOLINT
|
67
|
+
|
68
|
+
virtual void Visit(typename add<StringLiteral<Factory> >::type literal) = 0; //NOLINT
|
69
|
+
virtual void Visit(typename add<NumberLiteral<Factory> >::type literal) = 0; //NOLINT
|
70
|
+
virtual void Visit(typename add<Identifier<Factory> >::type literal) = 0; //NOLINT
|
71
|
+
virtual void Visit(typename add<ThisLiteral<Factory> >::type literal) = 0; //NOLINT
|
72
|
+
virtual void Visit(typename add<NullLiteral<Factory> >::type literal) = 0; //NOLINT
|
73
|
+
virtual void Visit(typename add<TrueLiteral<Factory> >::type literal) = 0; //NOLINT
|
74
|
+
virtual void Visit(typename add<FalseLiteral<Factory> >::type literal) = 0; //NOLINT
|
75
|
+
virtual void Visit(typename add<Undefined<Factory> >::type literal) = 0; //NOLINT
|
76
|
+
virtual void Visit(typename add<RegExpLiteral<Factory> >::type literal) = 0; //NOLINT
|
77
|
+
virtual void Visit(typename add<ArrayLiteral<Factory> >::type literal) = 0; //NOLINT
|
78
|
+
virtual void Visit(typename add<ObjectLiteral<Factory> >::type literal) = 0; //NOLINT
|
79
|
+
virtual void Visit(typename add<FunctionLiteral<Factory> >::type literal) = 0; //NOLINT
|
80
|
+
|
81
|
+
virtual void Visit(typename add<IdentifierAccess<Factory> >::type prop) = 0; //NOLINT
|
82
|
+
virtual void Visit(typename add<IndexAccess<Factory> >::type prop) = 0; //NOLINT
|
83
|
+
virtual void Visit(typename add<FunctionCall<Factory> >::type call) = 0; //NOLINT
|
84
|
+
virtual void Visit(typename add<ConstructorCall<Factory> >::type call) = 0; //NOLINT
|
85
|
+
protected:
|
86
|
+
template<typename T>
|
87
|
+
class Acceptor {
|
88
|
+
public:
|
89
|
+
explicit Acceptor(T* visitor) : visitor_(visitor) { }
|
90
|
+
template<typename U>
|
91
|
+
void operator()(U* p) const {
|
92
|
+
p->Accept(visitor_);
|
93
|
+
}
|
94
|
+
private:
|
95
|
+
T* const visitor_;
|
96
|
+
};
|
97
|
+
|
98
|
+
template<typename T>
|
99
|
+
class Visitor {
|
100
|
+
public:
|
101
|
+
explicit Visitor(T* visitor) : visitor_(visitor) { }
|
102
|
+
template<typename U>
|
103
|
+
void operator()(U* p) const {
|
104
|
+
visitor_->Visit(p);
|
105
|
+
}
|
106
|
+
private:
|
107
|
+
T* const visitor_;
|
108
|
+
};
|
109
|
+
};
|
110
|
+
|
111
|
+
template<bool IsConst, typename Factory>
|
112
|
+
inline BasicAstVisitor<IsConst, Factory>::~BasicAstVisitor() { }
|
113
|
+
|
114
|
+
template<typename Factory>
|
115
|
+
struct AstVisitor {
|
116
|
+
typedef BasicAstVisitor<false, Factory> type;
|
117
|
+
typedef BasicAstVisitor<true, Factory> const_type;
|
118
|
+
};
|
119
|
+
|
120
|
+
} } } // namespace iv::core::ast
|
121
|
+
#endif // _IV_AST_VISITOR_H_
|