iv-phonic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.autotest +24 -0
  2. data/Manifest.txt +49 -0
  3. data/README.rdoc +32 -0
  4. data/Rakefile +54 -0
  5. data/ext/include/iv/algorithm.h +23 -0
  6. data/ext/include/iv/alloc.h +200 -0
  7. data/ext/include/iv/any.h +71 -0
  8. data/ext/include/iv/ast-factory.h +277 -0
  9. data/ext/include/iv/ast-fwd.h +92 -0
  10. data/ext/include/iv/ast-serializer.h +579 -0
  11. data/ext/include/iv/ast-visitor.h +121 -0
  12. data/ext/include/iv/ast.h +1127 -0
  13. data/ext/include/iv/chars.h +83 -0
  14. data/ext/include/iv/cmdline.h +830 -0
  15. data/ext/include/iv/conversions.h +308 -0
  16. data/ext/include/iv/dtoa.h +20 -0
  17. data/ext/include/iv/enable_if.h +18 -0
  18. data/ext/include/iv/errors.h +15 -0
  19. data/ext/include/iv/fixedcontainer.h +42 -0
  20. data/ext/include/iv/functor.h +29 -0
  21. data/ext/include/iv/lexer.h +1281 -0
  22. data/ext/include/iv/location.h +23 -0
  23. data/ext/include/iv/mt19937.h +175 -0
  24. data/ext/include/iv/noncopyable.h +30 -0
  25. data/ext/include/iv/none.h +10 -0
  26. data/ext/include/iv/parser.h +2150 -0
  27. data/ext/include/iv/source.h +27 -0
  28. data/ext/include/iv/space.h +178 -0
  29. data/ext/include/iv/static_assert.h +30 -0
  30. data/ext/include/iv/stringpiece.h +385 -0
  31. data/ext/include/iv/token.h +311 -0
  32. data/ext/include/iv/ucdata.h +58 -0
  33. data/ext/include/iv/uchar.h +8 -0
  34. data/ext/include/iv/ustring.h +28 -0
  35. data/ext/include/iv/ustringpiece.h +9 -0
  36. data/ext/include/iv/utils.h +83 -0
  37. data/ext/include/iv/xorshift.h +74 -0
  38. data/ext/iv/phonic/ast-fwd.h +21 -0
  39. data/ext/iv/phonic/ast.h +10 -0
  40. data/ext/iv/phonic/creator.h +530 -0
  41. data/ext/iv/phonic/encoding.h +110 -0
  42. data/ext/iv/phonic/extconf.rb +5 -0
  43. data/ext/iv/phonic/factory.h +247 -0
  44. data/ext/iv/phonic/parser.h +12 -0
  45. data/ext/iv/phonic/phonic.cc +69 -0
  46. data/ext/iv/phonic/rnode.h +15 -0
  47. data/ext/iv/phonic/rparser.h +48 -0
  48. data/ext/iv/phonic/source.h +146 -0
  49. data/test/test_iv_phonic.rb +32 -0
  50. metadata +159 -0
@@ -0,0 +1,2150 @@
1
+ #ifndef _IV_PARSER_H_
2
+ #define _IV_PARSER_H_
3
+ #include <cstdio>
4
+ #include <cstring>
5
+ #include <string>
6
+ #include <tr1/unordered_map>
7
+ #include <tr1/unordered_set>
8
+ #include <tr1/type_traits>
9
+ #include "static_assert.h"
10
+ #include "ast.h"
11
+ #include "ast-factory.h"
12
+ #include "source.h"
13
+ #include "lexer.h"
14
+ #include "noncopyable.h"
15
+ #include "utils.h"
16
+ #include "none.h"
17
+
18
+ #define IS(token)\
19
+ do {\
20
+ if (token_ != token) {\
21
+ *res = false;\
22
+ ReportUnexpectedToken(token);\
23
+ return NULL;\
24
+ }\
25
+ } while (0)
26
+
27
+ #define EXPECT(token)\
28
+ do {\
29
+ if (token_ != token) {\
30
+ *res = false;\
31
+ ReportUnexpectedToken(token);\
32
+ return NULL;\
33
+ }\
34
+ Next();\
35
+ } while (0)
36
+
37
+ #define UNEXPECT(token)\
38
+ do {\
39
+ *res = false;\
40
+ ReportUnexpectedToken(token);\
41
+ return NULL;\
42
+ } while (0)
43
+
44
+ #define RAISE(str)\
45
+ do {\
46
+ *res = false;\
47
+ SetErrorHeader(lexer_.line_number());\
48
+ error_.append(str);\
49
+ return NULL;\
50
+ } while (0)
51
+
52
+ #define RAISE_WITH_NUMBER(str, line)\
53
+ do {\
54
+ *res = false;\
55
+ SetErrorHeader(line);\
56
+ error_.append(str);\
57
+ return NULL;\
58
+ } while (0)
59
+
60
+ #define CHECK res);\
61
+ if (!*res) {\
62
+ return NULL;\
63
+ }\
64
+ ((void)0
65
+ #define DUMMY ) // to make indentation work
66
+ #undef DUMMY
67
+
68
+ namespace iv {
69
+ namespace core {
70
+ namespace detail {
71
+ template<typename T>
72
+ class ParserData {
73
+ private:
74
+ static const char* use_strict;
75
+ static const char* arguments;
76
+ static const char* eval;
77
+ static const char* get;
78
+ static const char* set;
79
+ public:
80
+ static const UString kUseStrict;
81
+ static const UString kArguments;
82
+ static const UString kEval;
83
+ static const UString kGet;
84
+ static const UString kSet;
85
+ };
86
+
87
+ template<typename T>
88
+ const char * ParserData<T>::use_strict = "use strict";
89
+
90
+ template<typename T>
91
+ const char * ParserData<T>::arguments = "arguments";
92
+
93
+ template<typename T>
94
+ const char * ParserData<T>::eval = "eval";
95
+
96
+ template<typename T>
97
+ const char * ParserData<T>::get = "get";
98
+
99
+ template<typename T>
100
+ const char * ParserData<T>::set = "set";
101
+
102
+ template<typename T>
103
+ const UString ParserData<T>::kUseStrict(
104
+ ParserData<T>::use_strict,
105
+ ParserData<T>::use_strict + std::strlen(ParserData<T>::use_strict));
106
+ template<typename T>
107
+ const UString ParserData<T>::kArguments(
108
+ ParserData<T>::arguments,
109
+ ParserData<T>::arguments + std::strlen(ParserData<T>::arguments));
110
+ template<typename T>
111
+ const UString ParserData<T>::kEval(
112
+ ParserData<T>::eval,
113
+ ParserData<T>::eval + std::strlen(ParserData<T>::eval));
114
+ template<typename T>
115
+ const UString ParserData<T>::kGet(
116
+ ParserData<T>::get,
117
+ ParserData<T>::get + std::strlen(ParserData<T>::get));
118
+ template<typename T>
119
+ const UString ParserData<T>::kSet(
120
+ ParserData<T>::set,
121
+ ParserData<T>::set + std::strlen(ParserData<T>::set));
122
+
123
+ } // namespace iv::core::detail
124
+
125
+ typedef detail::ParserData<None> ParserData;
126
+
127
+ template<typename Factory>
128
+ class Parser : private Noncopyable<Parser<Factory> >::type {
129
+ public:
130
+ typedef Parser<Factory> this_type;
131
+ typedef Parser<Factory> parser_type;
132
+ #define V(AST) typedef typename ast::AST<Factory> AST;
133
+ AST_NODE_LIST(V)
134
+ #undef V
135
+ #define V(X, XS) typedef typename SpaceVector<Factory, X *>::type XS;
136
+ AST_LIST_LIST(V)
137
+ #undef V
138
+ #define V(S) typedef typename SpaceUString<Factory>::type S;
139
+ AST_STRING(V)
140
+ #undef V
141
+ class Target : private Noncopyable<Target>::type {
142
+ public:
143
+ Target(parser_type * parser, BreakableStatement* target)
144
+ : parser_(parser),
145
+ prev_(parser->target()),
146
+ node_(target) {
147
+ parser_->set_target(this);
148
+ if (parser_->labels()) {
149
+ target->set_labels(parser_->labels());
150
+ parser_->set_labels(NULL);
151
+ }
152
+ }
153
+ ~Target() {
154
+ parser_->set_target(prev_);
155
+ }
156
+ inline Target* previous() const {
157
+ return prev_;
158
+ }
159
+ inline BreakableStatement* node() const {
160
+ return node_;
161
+ }
162
+ private:
163
+ parser_type* parser_;
164
+ Target* prev_;
165
+ BreakableStatement* node_;
166
+ };
167
+
168
+ Parser(BasicSource* source, Factory* space)
169
+ : lexer_(source),
170
+ error_(),
171
+ strict_(false),
172
+ factory_(space),
173
+ scope_(NULL),
174
+ target_(NULL),
175
+ labels_(NULL) {
176
+ }
177
+
178
+ // Program
179
+ // : SourceElements
180
+ FunctionLiteral* ParseProgram() {
181
+ FunctionLiteral* global = factory_->NewFunctionLiteral(
182
+ FunctionLiteral::GLOBAL);
183
+ assert(target_ == NULL);
184
+ bool error_flag = true;
185
+ bool *res = &error_flag;
186
+ {
187
+ const ScopeSwitcher switcher(this, global->scope());
188
+ Next();
189
+ ParseSourceElements(Token::EOS, global, CHECK);
190
+ }
191
+ return (error_flag) ? global : NULL;
192
+ }
193
+
194
+ // SourceElements
195
+ // : SourceElement
196
+ // | SourceElement SourceElements
197
+ //
198
+ // SourceElement
199
+ // : Statements
200
+ // | FunctionDeclaration
201
+ bool ParseSourceElements(Token::Type end,
202
+ FunctionLiteral* function, bool *res) {
203
+ Statement *stmt;
204
+ bool recognize_use_strict_directive = true;
205
+ const StrictSwitcher switcher(this);
206
+ while (token_ != end) {
207
+ if (token_ == Token::FUNCTION) {
208
+ // FunctionDeclaration
209
+ stmt = ParseFunctionDeclaration(CHECK);
210
+ function->AddStatement(stmt);
211
+ } else {
212
+ stmt = ParseStatement(CHECK);
213
+ // use strict directive check
214
+ if (recognize_use_strict_directive &&
215
+ !strict_ &&
216
+ stmt->AsExpressionStatement()) {
217
+ Expression* const expr = stmt->AsExpressionStatement()->expr();
218
+ if (expr->AsDirectivable()) {
219
+ if (expr->AsStringLiteral()->value().compare(
220
+ ParserData::kUseStrict.data()) == 0) {
221
+ switcher.SwitchStrictMode();
222
+ function->set_strict(true);
223
+ }
224
+ }
225
+ }
226
+ function->AddStatement(stmt);
227
+ }
228
+ recognize_use_strict_directive = false;
229
+ }
230
+ return true;
231
+ }
232
+
233
+ // Statement
234
+ // : Block
235
+ // | FunctionStatement // This is not standard.
236
+ // | VariableStatement
237
+ // | EmptyStatement
238
+ // | ExpressionStatement
239
+ // | IfStatement
240
+ // | IterationStatement
241
+ // | ContinueStatement
242
+ // | BreakStatement
243
+ // | ReturnStatement
244
+ // | WithStatement
245
+ // | LabelledStatement
246
+ // | SwitchStatement
247
+ // | ThrowStatement
248
+ // | TryStatement
249
+ // | DebuggerStatement
250
+ Statement* ParseStatement(bool *res) {
251
+ Statement *result = NULL;
252
+ switch (token_) {
253
+ case Token::LBRACE:
254
+ // Block
255
+ result = ParseBlock(CHECK);
256
+ break;
257
+
258
+ case Token::CONST:
259
+ if (strict_) {
260
+ RAISE("\"const\" not allowed in strict code");
261
+ }
262
+ case Token::VAR:
263
+ // VariableStatement
264
+ result = ParseVariableStatement(CHECK);
265
+ break;
266
+
267
+ case Token::SEMICOLON:
268
+ // EmptyStatement
269
+ result = ParseEmptyStatement();
270
+ break;
271
+
272
+ case Token::IF:
273
+ // IfStatement
274
+ result = ParseIfStatement(CHECK);
275
+ break;
276
+
277
+ case Token::DO:
278
+ // IterationStatement
279
+ // do while
280
+ result = ParseDoWhileStatement(CHECK);
281
+ break;
282
+
283
+ case Token::WHILE:
284
+ // IterationStatement
285
+ // while
286
+ result = ParseWhileStatement(CHECK);
287
+ break;
288
+
289
+ case Token::FOR:
290
+ // IterationStatement
291
+ // for
292
+ result = ParseForStatement(CHECK);
293
+ break;
294
+
295
+ case Token::CONTINUE:
296
+ // ContinueStatement
297
+ result = ParseContinueStatement(CHECK);
298
+ break;
299
+
300
+ case Token::BREAK:
301
+ // BreakStatement
302
+ result = ParseBreakStatement(CHECK);
303
+ break;
304
+
305
+ case Token::RETURN:
306
+ // ReturnStatement
307
+ result = ParseReturnStatement(CHECK);
308
+ break;
309
+
310
+ case Token::WITH:
311
+ // WithStatement
312
+ result = ParseWithStatement(CHECK);
313
+ break;
314
+
315
+ case Token::SWITCH:
316
+ // SwitchStatement
317
+ result = ParseSwitchStatement(CHECK);
318
+ break;
319
+
320
+ case Token::THROW:
321
+ // ThrowStatement
322
+ result = ParseThrowStatement(CHECK);
323
+ break;
324
+
325
+ case Token::TRY:
326
+ // TryStatement
327
+ result = ParseTryStatement(CHECK);
328
+ break;
329
+
330
+ case Token::DEBUGGER:
331
+ // DebuggerStatement
332
+ result = ParseDebuggerStatement(CHECK);
333
+ break;
334
+
335
+ case Token::FUNCTION:
336
+ // FunctionStatement (not in ECMA-262 5th)
337
+ // FunctionExpression
338
+ result = ParseFunctionStatement(CHECK);
339
+ break;
340
+
341
+ case Token::IDENTIFIER:
342
+ // LabelledStatement or ExpressionStatement
343
+ result = ParseExpressionOrLabelledStatement(CHECK);
344
+ break;
345
+
346
+ case Token::ILLEGAL:
347
+ UNEXPECT(token_);
348
+ break;
349
+
350
+ default:
351
+ // ExpressionStatement or ILLEGAL
352
+ result = ParseExpressionStatement(CHECK);
353
+ break;
354
+ }
355
+ return result;
356
+ }
357
+
358
+ // FunctionDeclaration
359
+ // : FUNCTION IDENTIFIER '(' FormalParameterList_opt ')' '{' FunctionBody '}'
360
+ //
361
+ // FunctionStatement
362
+ // : FUNCTION IDENTIFIER '(' FormalParameterList_opt ')' '{' FunctionBody '}'
363
+ //
364
+ // FunctionExpression
365
+ // : FUNCTION
366
+ // IDENTIFIER_opt '(' FormalParameterList_opt ')' '{' FunctionBody '}'
367
+ //
368
+ // FunctionStatement is not standard, but implemented in SpiderMonkey
369
+ // and this statement is very useful for not breaking FunctionDeclaration.
370
+ Statement* ParseFunctionDeclaration(bool *res) {
371
+ assert(token_ == Token::FUNCTION);
372
+ Next();
373
+ IS(Token::IDENTIFIER);
374
+ FunctionLiteral* expr = ParseFunctionLiteral(
375
+ FunctionLiteral::DECLARATION,
376
+ FunctionLiteral::GENERAL, true, CHECK);
377
+ // define named function as FunctionDeclaration
378
+ scope_->AddFunctionDeclaration(expr);
379
+ return factory_->NewFunctionStatement(expr);
380
+ }
381
+
382
+ // Block
383
+ // : '{' '}'
384
+ // | '{' StatementList '}'
385
+ //
386
+ // StatementList
387
+ // : Statement
388
+ // | StatementList Statement
389
+ Block* ParseBlock(bool *res) {
390
+ assert(token_ == Token::LBRACE);
391
+ Block *block = factory_->NewBlock();
392
+ Statement *stmt;
393
+ Target target(this, block);
394
+
395
+ Next();
396
+ while (token_ != Token::RBRACE) {
397
+ stmt = ParseStatement(CHECK);
398
+ block->AddStatement(stmt);
399
+ }
400
+ Next();
401
+ return block;
402
+ }
403
+
404
+ // VariableStatement
405
+ // : VAR VariableDeclarationList ';'
406
+ // : CONST VariableDeclarationList ';'
407
+ Statement* ParseVariableStatement(bool *res) {
408
+ assert(token_ == Token::VAR || token_ == Token::CONST);
409
+ VariableStatement* stmt = factory_->NewVariableStatement(token_);
410
+ ParseVariableDeclarations(stmt, true, CHECK);
411
+ ExpectSemicolon(CHECK);
412
+ return stmt;
413
+ }
414
+
415
+ // VariableDeclarationList
416
+ // : VariableDeclaration
417
+ // | VariableDeclarationList ',' VariableDeclaration
418
+ //
419
+ // VariableDeclaration
420
+ // : IDENTIFIER Initialiser_opt
421
+ //
422
+ // Initialiser_opt
423
+ // :
424
+ // | Initialiser
425
+ //
426
+ // Initialiser
427
+ // : '=' AssignmentExpression
428
+ Statement* ParseVariableDeclarations(VariableStatement* stmt,
429
+ bool contains_in,
430
+ bool *res) {
431
+ Identifier *name;
432
+ Expression *expr;
433
+ Declaration *decl;
434
+
435
+ do {
436
+ Next();
437
+ IS(Token::IDENTIFIER);
438
+ name = factory_->NewIdentifier(lexer_.Buffer());
439
+ // section 12.2.1
440
+ // within the strict code, Identifier must not be "eval" or "arguments"
441
+ if (strict_) {
442
+ const EvalOrArguments val = IsEvalOrArguments(name);
443
+ if (val) {
444
+ if (val == kEval) {
445
+ RAISE("assignment to \"eval\" not allowed in strict code");
446
+ } else {
447
+ assert(val == kArguments);
448
+ RAISE("assignment to \"arguments\" not allowed in strict code");
449
+ }
450
+ }
451
+ }
452
+ Next();
453
+
454
+ if (token_ == Token::ASSIGN) {
455
+ Next();
456
+ // AssignmentExpression
457
+ expr = ParseAssignmentExpression(contains_in, CHECK);
458
+ decl = factory_->NewDeclaration(name, expr);
459
+ } else {
460
+ // Undefined Expression
461
+ decl = factory_->NewDeclaration(name, factory_->NewUndefined());
462
+ }
463
+ stmt->AddDeclaration(decl);
464
+ scope_->AddUnresolved(name, stmt->IsConst());
465
+ } while (token_ == Token::COMMA);
466
+
467
+ return stmt;
468
+ }
469
+
470
+ // EmptyStatement
471
+ // : ';'
472
+ Statement* ParseEmptyStatement() {
473
+ assert(token_ == Token::SEMICOLON);
474
+ Next();
475
+ return factory_->NewEmptyStatement();
476
+ }
477
+
478
+ // IfStatement
479
+ // : IF '(' Expression ')' Statement ELSE Statement
480
+ // | IF '(' Expression ')' Statement
481
+ Statement* ParseIfStatement(bool *res) {
482
+ assert(token_ == Token::IF);
483
+ IfStatement *if_stmt = NULL;
484
+ Statement* stmt;
485
+ Next();
486
+
487
+ EXPECT(Token::LPAREN);
488
+
489
+ Expression *expr = ParseExpression(true, CHECK);
490
+
491
+ EXPECT(Token::RPAREN);
492
+
493
+ stmt = ParseStatement(CHECK);
494
+ if_stmt = factory_->NewIfStatement(expr, stmt);
495
+ if (token_ == Token::ELSE) {
496
+ Next();
497
+ stmt = ParseStatement(CHECK);
498
+ if_stmt->SetElse(stmt);
499
+ }
500
+ return if_stmt;
501
+ }
502
+
503
+ // IterationStatement
504
+ // : DO Statement WHILE '(' Expression ')' ';'
505
+ // | WHILE '(' Expression ')' Statement
506
+ // | FOR '(' ExpressionNoIn_opt ';' Expression_opt ';' Expression_opt ')'
507
+ // Statement
508
+ // | FOR '(' VAR VariableDeclarationListNoIn ';'
509
+ // Expression_opt ';'
510
+ // Expression_opt ')'
511
+ // Statement
512
+ // | FOR '(' LeftHandSideExpression IN Expression ')' Statement
513
+ // | FOR '(' VAR VariableDeclarationNoIn IN Expression ')' Statement
514
+ Statement* ParseDoWhileStatement(bool *res) {
515
+ // DO Statement WHILE '(' Expression ')' ';'
516
+ assert(token_ == Token::DO);
517
+ DoWhileStatement* dowhile = factory_->NewDoWhileStatement();
518
+ Target target(this, dowhile);
519
+ Next();
520
+
521
+ Statement *stmt = ParseStatement(CHECK);
522
+ dowhile->set_body(stmt);
523
+
524
+ EXPECT(Token::WHILE);
525
+
526
+ EXPECT(Token::LPAREN);
527
+
528
+ Expression *expr = ParseExpression(true, CHECK);
529
+ dowhile->set_cond(expr);
530
+
531
+ EXPECT(Token::RPAREN);
532
+
533
+ ExpectSemicolon(CHECK);
534
+ return dowhile;
535
+ }
536
+
537
+ // WHILE '(' Expression ')' Statement
538
+ Statement* ParseWhileStatement(bool *res) {
539
+ assert(token_ == Token::WHILE);
540
+ Next();
541
+
542
+ EXPECT(Token::LPAREN);
543
+
544
+ Expression *expr = ParseExpression(true, CHECK);
545
+ WhileStatement* whilestmt = factory_->NewWhileStatement(expr);
546
+ Target target(this, whilestmt);
547
+
548
+ EXPECT(Token::RPAREN);
549
+
550
+ Statement* stmt = ParseStatement(CHECK);
551
+ whilestmt->set_body(stmt);
552
+
553
+ return whilestmt;
554
+ }
555
+
556
+ // FOR '(' ExpressionNoIn_opt ';' Expression_opt ';' Expression_opt ')'
557
+ // Statement
558
+ // FOR '(' VAR VariableDeclarationListNoIn ';'
559
+ // Expression_opt ';'
560
+ // Expression_opt ')'
561
+ // Statement
562
+ // FOR '(' LeftHandSideExpression IN Expression ')' Statement
563
+ // FOR '(' VAR VariableDeclarationNoIn IN Expression ')' Statement
564
+ Statement* ParseForStatement(bool *res) {
565
+ assert(token_ == Token::FOR);
566
+ Next();
567
+
568
+ EXPECT(Token::LPAREN);
569
+
570
+ Statement *init = NULL;
571
+
572
+ if (token_ != Token::SEMICOLON) {
573
+ if (token_ == Token::VAR || token_ == Token::CONST) {
574
+ VariableStatement *var = factory_->NewVariableStatement(token_);
575
+ ParseVariableDeclarations(var, false, CHECK);
576
+ init = var;
577
+ if (token_ == Token::IN) {
578
+ // for in loop
579
+ Next();
580
+ const Declarations& decls = var->decls();
581
+ if (decls.size() != 1) {
582
+ // ForInStatement requests VaraibleDeclarationNoIn (not List),
583
+ // so check declarations' size is 1.
584
+ RAISE("invalid for-in left-hand-side");
585
+ }
586
+ Expression *enumerable = ParseExpression(true, CHECK);
587
+ EXPECT(Token::RPAREN);
588
+ ForInStatement* forstmt =
589
+ factory_->NewForInStatement(init, enumerable);
590
+ Target target(this, forstmt);
591
+ Statement *body = ParseStatement(CHECK);
592
+ forstmt->set_body(body);
593
+ return forstmt;
594
+ }
595
+ } else {
596
+ Expression *init_expr = ParseExpression(false, CHECK);
597
+ init = factory_->NewExpressionStatement(init_expr);
598
+ if (token_ == Token::IN) {
599
+ // for in loop
600
+ if (!init_expr->IsValidLeftHandSide()) {
601
+ RAISE("invalid for-in left-hand-side");
602
+ }
603
+ Next();
604
+ Expression *enumerable = ParseExpression(true, CHECK);
605
+ EXPECT(Token::RPAREN);
606
+ ForInStatement* forstmt =
607
+ factory_->NewForInStatement(init, enumerable);
608
+ Target target(this, forstmt);
609
+ Statement *body = ParseStatement(CHECK);
610
+ forstmt->set_body(body);
611
+ return forstmt;
612
+ }
613
+ }
614
+ }
615
+
616
+ // ordinary for loop
617
+ EXPECT(Token::SEMICOLON);
618
+
619
+ Expression *cond = NULL;
620
+ if (token_ == Token::SEMICOLON) {
621
+ // no cond expr
622
+ Next();
623
+ } else {
624
+ cond = ParseExpression(true, CHECK);
625
+ EXPECT(Token::SEMICOLON);
626
+ }
627
+
628
+ ExpressionStatement *next = NULL;
629
+ if (token_ == Token::RPAREN) {
630
+ Next();
631
+ } else {
632
+ Expression *next_expr = ParseExpression(true, CHECK);
633
+ next = factory_->NewExpressionStatement(next_expr);
634
+ EXPECT(Token::RPAREN);
635
+ }
636
+
637
+ ForStatement *for_stmt = factory_->NewForStatement();
638
+ Target target(this, for_stmt);
639
+ Statement *body = ParseStatement(CHECK);
640
+ for_stmt->set_body(body);
641
+ if (init) {
642
+ for_stmt->SetInit(init);
643
+ }
644
+ if (cond) {
645
+ for_stmt->SetCondition(cond);
646
+ }
647
+ if (next) {
648
+ for_stmt->SetNext(next);
649
+ }
650
+
651
+ return for_stmt;
652
+ }
653
+
654
+ // ContinueStatement
655
+ // : CONTINUE Identifier_opt ';'
656
+ Statement* ParseContinueStatement(bool *res) {
657
+ assert(token_ == Token::CONTINUE);
658
+ ContinueStatement *continue_stmt = factory_->NewContinueStatement();
659
+ Next();
660
+ if (!lexer_.has_line_terminator_before_next() &&
661
+ token_ != Token::SEMICOLON &&
662
+ token_ != Token::RBRACE &&
663
+ token_ != Token::EOS) {
664
+ IS(Token::IDENTIFIER);
665
+ Identifier* label = factory_->NewIdentifier(lexer_.Buffer());
666
+ continue_stmt->SetLabel(label);
667
+ IterationStatement* target = LookupContinuableTarget(label);
668
+ if (target) {
669
+ continue_stmt->SetTarget(target);
670
+ } else {
671
+ RAISE("label not found");
672
+ }
673
+ Next();
674
+ } else {
675
+ IterationStatement* target = LookupContinuableTarget();
676
+ if (target) {
677
+ continue_stmt->SetTarget(target);
678
+ } else {
679
+ RAISE("label not found");
680
+ }
681
+ }
682
+ ExpectSemicolon(CHECK);
683
+ return continue_stmt;
684
+ }
685
+
686
+ // BreakStatement
687
+ // : BREAK Identifier_opt ';'
688
+ Statement* ParseBreakStatement(bool *res) {
689
+ assert(token_ == Token::BREAK);
690
+ BreakStatement *break_stmt = factory_->NewBreakStatement();
691
+ Next();
692
+ if (!lexer_.has_line_terminator_before_next() &&
693
+ token_ != Token::SEMICOLON &&
694
+ token_ != Token::RBRACE &&
695
+ token_ != Token::EOS) {
696
+ // label
697
+ IS(Token::IDENTIFIER);
698
+ Identifier* label = factory_->NewIdentifier(lexer_.Buffer());
699
+ break_stmt->SetLabel(label);
700
+ if (ContainsLabel(labels_, label)) {
701
+ // example
702
+ //
703
+ // do {
704
+ // test: break test;
705
+ // } while (0);
706
+ //
707
+ // This BreakStatement is interpreted as EmptyStatement
708
+ // In iv, BreakStatement with label, but without target is
709
+ // interpreted as EmptyStatement
710
+ } else {
711
+ BreakableStatement* target = LookupBreakableTarget(label);
712
+ if (target) {
713
+ break_stmt->SetTarget(target);
714
+ } else {
715
+ RAISE("label not found");
716
+ }
717
+ }
718
+ Next();
719
+ } else {
720
+ BreakableStatement* target = LookupBreakableTarget();
721
+ if (target) {
722
+ break_stmt->SetTarget(target);
723
+ } else {
724
+ RAISE("label not found");
725
+ }
726
+ }
727
+ ExpectSemicolon(CHECK);
728
+ return break_stmt;
729
+ }
730
+
731
+ // ReturnStatement
732
+ // : RETURN Expression_opt ';'
733
+ Statement* ParseReturnStatement(bool *res) {
734
+ assert(token_ == Token::RETURN);
735
+ Next();
736
+ if (lexer_.has_line_terminator_before_next() ||
737
+ token_ == Token::SEMICOLON ||
738
+ token_ == Token::RBRACE ||
739
+ token_ == Token::EOS) {
740
+ ExpectSemicolon(CHECK);
741
+ return factory_->NewReturnStatement(factory_->NewUndefined());
742
+ }
743
+ Expression *expr = ParseExpression(true, CHECK);
744
+ ExpectSemicolon(CHECK);
745
+ return factory_->NewReturnStatement(expr);
746
+ }
747
+
748
+ // WithStatement
749
+ // : WITH '(' Expression ')' Statement
750
+ Statement* ParseWithStatement(bool *res) {
751
+ assert(token_ == Token::WITH);
752
+ Next();
753
+
754
+ // section 12.10.1
755
+ // when in strict mode code, WithStatement is not allowed.
756
+ if (strict_) {
757
+ RAISE("with statement not allowed in strict code");
758
+ }
759
+
760
+ EXPECT(Token::LPAREN);
761
+
762
+ Expression *expr = ParseExpression(true, CHECK);
763
+
764
+ EXPECT(Token::RPAREN);
765
+
766
+ Statement *stmt = ParseStatement(CHECK);
767
+ return factory_->NewWithStatement(expr, stmt);
768
+ }
769
+
770
+ // SwitchStatement
771
+ // : SWITCH '(' Expression ')' CaseBlock
772
+ //
773
+ // CaseBlock
774
+ // : '{' CaseClauses_opt '}'
775
+ // | '{' CaseClauses_opt DefaultClause CaseClauses_opt '}'
776
+ Statement* ParseSwitchStatement(bool *res) {
777
+ assert(token_ == Token::SWITCH);
778
+ CaseClause *case_clause;
779
+ Next();
780
+
781
+ EXPECT(Token::LPAREN);
782
+
783
+ Expression *expr = ParseExpression(true, CHECK);
784
+ SwitchStatement *switch_stmt = factory_->NewSwitchStatement(expr);
785
+ Target target(this, switch_stmt);
786
+
787
+ EXPECT(Token::RPAREN);
788
+
789
+ EXPECT(Token::LBRACE);
790
+
791
+ while (token_ != Token::RBRACE) {
792
+ case_clause = ParseCaseClause(CHECK);
793
+ switch_stmt->AddCaseClause(case_clause);
794
+ }
795
+ Next();
796
+
797
+ return switch_stmt;
798
+ }
799
+
800
+ // CaseClauses
801
+ // : CaseClause
802
+ // | CaseClauses CaseClause
803
+ //
804
+ // CaseClause
805
+ // : CASE Expression ':' StatementList_opt
806
+ //
807
+ // DefaultClause
808
+ // : DEFAULT ':' StatementList_opt
809
+ CaseClause* ParseCaseClause(bool *res) {
810
+ assert(token_ == Token::CASE || token_ == Token::DEFAULT);
811
+ CaseClause *clause = factory_->NewCaseClause();
812
+ Statement *stmt;
813
+
814
+ if (token_ == Token::CASE) {
815
+ Next();
816
+ Expression *expr = ParseExpression(true, CHECK);
817
+ clause->SetExpression(expr);
818
+ } else {
819
+ EXPECT(Token::DEFAULT);
820
+ clause->SetDefault();
821
+ }
822
+
823
+ EXPECT(Token::COLON);
824
+
825
+ while (token_ != Token::RBRACE &&
826
+ token_ != Token::CASE &&
827
+ token_ != Token::DEFAULT) {
828
+ stmt = ParseStatement(CHECK);
829
+ clause->AddStatement(stmt);
830
+ }
831
+
832
+ return clause;
833
+ }
834
+
835
+ // ThrowStatement
836
+ // : THROW Expression ';'
837
+ Statement* ParseThrowStatement(bool *res) {
838
+ assert(token_ == Token::THROW);
839
+ Expression *expr;
840
+ Next();
841
+ // Throw requires Expression
842
+ if (lexer_.has_line_terminator_before_next()) {
843
+ RAISE("missing expression between throw and newline");
844
+ }
845
+ expr = ParseExpression(true, CHECK);
846
+ ExpectSemicolon(CHECK);
847
+ return factory_->NewThrowStatement(expr);
848
+ }
849
+
850
+ // TryStatement
851
+ // : TRY Block Catch
852
+ // | TRY Block Finally
853
+ // | TRY Block Catch Finally
854
+ //
855
+ // Catch
856
+ // : CATCH '(' IDENTIFIER ')' Block
857
+ //
858
+ // Finally
859
+ // : FINALLY Block
860
+ Statement* ParseTryStatement(bool *res) {
861
+ assert(token_ == Token::TRY);
862
+ Identifier *name;
863
+ Block *block;
864
+ bool has_catch_or_finally = false;
865
+
866
+ Next();
867
+
868
+ block = ParseBlock(CHECK);
869
+ TryStatement *try_stmt = factory_->NewTryStatement(block);
870
+
871
+ if (token_ == Token::CATCH) {
872
+ // Catch
873
+ has_catch_or_finally = true;
874
+ Next();
875
+ EXPECT(Token::LPAREN);
876
+ IS(Token::IDENTIFIER);
877
+ name = factory_->NewIdentifier(lexer_.Buffer());
878
+ // section 12.14.1
879
+ // within the strict code, Identifier must not be "eval" or "arguments"
880
+ if (strict_) {
881
+ const EvalOrArguments val = IsEvalOrArguments(name);
882
+ if (val) {
883
+ if (val == kEval) {
884
+ RAISE("catch placeholder \"eval\" not allowed in strict code");
885
+ } else {
886
+ assert(val == kArguments);
887
+ RAISE(
888
+ "catch placeholder \"arguments\" not allowed in strict code");
889
+ }
890
+ }
891
+ }
892
+ Next();
893
+ EXPECT(Token::RPAREN);
894
+ block = ParseBlock(CHECK);
895
+ try_stmt->SetCatch(name, block);
896
+ }
897
+
898
+ if (token_ == Token::FINALLY) {
899
+ // Finally
900
+ has_catch_or_finally= true;
901
+ Next();
902
+ block = ParseBlock(CHECK);
903
+ try_stmt->SetFinally(block);
904
+ }
905
+
906
+ if (!has_catch_or_finally) {
907
+ RAISE("missing catch or finally after try statement");
908
+ }
909
+
910
+ return try_stmt;
911
+ }
912
+
913
+ // DebuggerStatement
914
+ // : DEBUGGER ';'
915
+ Statement* ParseDebuggerStatement(bool *res) {
916
+ assert(token_ == Token::DEBUGGER);
917
+ Next();
918
+ ExpectSemicolon(CHECK);
919
+ return factory_->NewDebuggerStatement();
920
+ }
921
+
922
+ Statement* ParseExpressionStatement(bool *res) {
923
+ Expression* expr = ParseExpression(true, CHECK);
924
+ ExpectSemicolon(CHECK);
925
+ return factory_->NewExpressionStatement(expr);
926
+ }
927
+
928
+ // LabelledStatement
929
+ // : IDENTIFIER ':' Statement
930
+ //
931
+ // ExpressionStatement
932
+ // : Expression ';'
933
+ Statement* ParseExpressionOrLabelledStatement(bool *res) {
934
+ assert(token_ == Token::IDENTIFIER);
935
+ Expression* expr = ParseExpression(true, CHECK);
936
+ if (token_ == Token::COLON &&
937
+ expr->AsIdentifier()) {
938
+ // LabelledStatement
939
+ Next();
940
+
941
+ Identifiers* labels = labels_;
942
+ Identifier* const label = expr->AsIdentifier();
943
+ const bool exist_labels = labels;
944
+ if (!exist_labels) {
945
+ labels = factory_->NewLabels();
946
+ }
947
+ if (ContainsLabel(labels, label) || TargetsContainsLabel(label)) {
948
+ // duplicate label
949
+ RAISE("duplicate label");
950
+ }
951
+ labels->push_back(label);
952
+ LabelScope scope(this, labels, exist_labels);
953
+
954
+ Statement* stmt = ParseStatement(CHECK);
955
+ return factory_->NewLabelledStatement(expr, stmt);
956
+ }
957
+ ExpectSemicolon(CHECK);
958
+ return factory_->NewExpressionStatement(expr);
959
+ }
960
+
961
+ Statement* ParseFunctionStatement(bool *res) {
962
+ assert(token_ == Token::FUNCTION);
963
+ if (strict_) {
964
+ RAISE("function statement not allowed in strict code");
965
+ }
966
+ Next();
967
+ IS(Token::IDENTIFIER);
968
+ FunctionLiteral* expr = ParseFunctionLiteral(FunctionLiteral::STATEMENT,
969
+ FunctionLiteral::GENERAL,
970
+ true, CHECK);
971
+ // define named function as variable declaration
972
+ scope_->AddUnresolved(expr->name(), false);
973
+ return factory_->NewFunctionStatement(expr);
974
+ }
975
+
976
+ // Expression
977
+ // : AssignmentExpression
978
+ // | Expression ',' AssignmentExpression
979
+ Expression* ParseExpression(bool contains_in, bool *res) {
980
+ Expression *right;
981
+ Expression *result = ParseAssignmentExpression(contains_in, CHECK);
982
+ while (token_ == Token::COMMA) {
983
+ Next();
984
+ right = ParseAssignmentExpression(contains_in, CHECK);
985
+ result = factory_->NewBinaryOperation(Token::COMMA, result, right);
986
+ }
987
+ return result;
988
+ }
989
+
990
+ // AssignmentExpression
991
+ // : ConditionalExpression
992
+ // | LeftHandSideExpression AssignmentOperator AssignmentExpression
993
+ Expression* ParseAssignmentExpression(bool contains_in, bool *res) {
994
+ Expression *result = ParseConditionalExpression(contains_in, CHECK);
995
+ if (!Token::IsAssignOp(token_)) {
996
+ return result;
997
+ }
998
+ if (!result->IsValidLeftHandSide()) {
999
+ RAISE("invalid left-hand-side in assignment");
1000
+ }
1001
+ // section 11.13.1 throwing SyntaxError
1002
+ if (strict_ &&
1003
+ result->AsIdentifier()) {
1004
+ const EvalOrArguments val = IsEvalOrArguments(result->AsIdentifier());
1005
+ if (val) {
1006
+ if (val == kEval) {
1007
+ RAISE("assignment to \"eval\" not allowed in strict code");
1008
+ } else {
1009
+ assert(val == kArguments);
1010
+ RAISE("assignment to \"arguments\" not allowed in strict code");
1011
+ }
1012
+ }
1013
+ }
1014
+ const Token::Type op = token_;
1015
+ Next();
1016
+ Expression *right = ParseAssignmentExpression(contains_in, CHECK);
1017
+ return factory_->NewAssignment(op, result, right);
1018
+ }
1019
+
1020
+ // ConditionalExpression
1021
+ // : LogicalOrExpression
1022
+ // | LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
1023
+ Expression* ParseConditionalExpression(bool contains_in, bool *res) {
1024
+ Expression *result;
1025
+ result = ParseBinaryExpression(contains_in, 9, CHECK);
1026
+ if (token_ == Token::CONDITIONAL) {
1027
+ Next();
1028
+ // see ECMA-262 section 11.12
1029
+ Expression *left = ParseAssignmentExpression(true, CHECK);
1030
+ EXPECT(Token::COLON);
1031
+ Expression *right = ParseAssignmentExpression(contains_in, CHECK);
1032
+ result = factory_->NewConditionalExpression(result, left, right);
1033
+ }
1034
+ return result;
1035
+ }
1036
+
1037
+ // LogicalOrExpression
1038
+ // : LogicalAndExpression
1039
+ // | LogicalOrExpression LOGICAL_OR LogicalAndExpression
1040
+ //
1041
+ // LogicalAndExpression
1042
+ // : BitwiseOrExpression
1043
+ // | LogicalAndExpression LOGICAL_AND BitwiseOrExpression
1044
+ //
1045
+ // BitwiseOrExpression
1046
+ // : BitwiseXorExpression
1047
+ // | BitwiseOrExpression '|' BitwiseXorExpression
1048
+ //
1049
+ // BitwiseXorExpression
1050
+ // : BitwiseAndExpression
1051
+ // | BitwiseXorExpression '^' BitwiseAndExpression
1052
+ //
1053
+ // BitwiseAndExpression
1054
+ // : EqualityExpression
1055
+ // | BitwiseAndExpression '&' EqualityExpression
1056
+ //
1057
+ // EqualityExpression
1058
+ // : RelationalExpression
1059
+ // | EqualityExpression EQ_STRICT RelationalExpression
1060
+ // | EqualityExpression NE_STRICT RelationalExpression
1061
+ // | EqualityExpression EQ RelationalExpression
1062
+ // | EqualityExpression NE RelationalExpression
1063
+ //
1064
+ // RelationalExpression
1065
+ // : ShiftExpression
1066
+ // | RelationalExpression LT ShiftExpression
1067
+ // | RelationalExpression GT ShiftExpression
1068
+ // | RelationalExpression LTE ShiftExpression
1069
+ // | RelationalExpression GTE ShiftExpression
1070
+ // | RelationalExpression INSTANCEOF ShiftExpression
1071
+ // | RelationalExpression IN ShiftExpression
1072
+ //
1073
+ // ShiftExpression
1074
+ // : AdditiveExpression
1075
+ // | ShiftExpression SHL AdditiveExpression
1076
+ // | ShiftExpression SAR AdditiveExpression
1077
+ // | ShiftExpression SHR AdditiveExpression
1078
+ //
1079
+ // AdditiveExpression
1080
+ // : MultiplicativeExpression
1081
+ // | AdditiveExpression ADD MultiplicativeExpression
1082
+ // | AdditiveExpression SUB MultiplicativeExpression
1083
+ //
1084
+ // MultiplicativeExpression
1085
+ // : UnaryExpression
1086
+ // | MultiplicativeExpression MUL UnaryExpression
1087
+ // | MultiplicativeExpression DIV UnaryExpression
1088
+ // | MultiplicativeExpression MOD UnaryExpression
1089
+ Expression* ParseBinaryExpression(bool contains_in,
1090
+ int prec, bool *res) {
1091
+ Expression *left, *right;
1092
+ Token::Type op;
1093
+ left = ParseUnaryExpression(CHECK);
1094
+ // MultiplicativeExpression
1095
+ while (token_ == Token::MUL ||
1096
+ token_ == Token::DIV ||
1097
+ token_ == Token::MOD) {
1098
+ op = token_;
1099
+ Next();
1100
+ right = ParseUnaryExpression(CHECK);
1101
+ left = ReduceBinaryOperation(op, left, right);
1102
+ }
1103
+ if (prec < 1) return left;
1104
+
1105
+ // AdditiveExpression
1106
+ while (token_ == Token::ADD ||
1107
+ token_ == Token::SUB) {
1108
+ op = token_;
1109
+ Next();
1110
+ right = ParseBinaryExpression(contains_in, 0, CHECK);
1111
+ left = ReduceBinaryOperation(op, left, right);
1112
+ }
1113
+ if (prec < 2) return left;
1114
+
1115
+ // ShiftExpression
1116
+ while (token_ == Token::SHL ||
1117
+ token_ == Token::SAR ||
1118
+ token_ == Token::SHR) {
1119
+ op = token_;
1120
+ Next();
1121
+ right = ParseBinaryExpression(contains_in, 1, CHECK);
1122
+ left = ReduceBinaryOperation(op, left, right);
1123
+ }
1124
+ if (prec < 3) return left;
1125
+
1126
+ // RelationalExpression
1127
+ while ((Token::REL_FIRST < token_ &&
1128
+ token_ < Token::REL_LAST) ||
1129
+ (contains_in && token_ == Token::IN)) {
1130
+ op = token_;
1131
+ Next();
1132
+ right = ParseBinaryExpression(contains_in, 2, CHECK);
1133
+ left = factory_->NewBinaryOperation(op, left, right);
1134
+ }
1135
+ if (prec < 4) return left;
1136
+
1137
+ // EqualityExpression
1138
+ while (token_ == Token::EQ_STRICT ||
1139
+ token_ == Token::NE_STRICT ||
1140
+ token_ == Token::EQ ||
1141
+ token_ == Token::NE) {
1142
+ op = token_;
1143
+ Next();
1144
+ right = ParseBinaryExpression(contains_in, 3, CHECK);
1145
+ left = factory_->NewBinaryOperation(op, left, right);
1146
+ }
1147
+ if (prec < 5) return left;
1148
+
1149
+ // BitwiseAndExpression
1150
+ while (token_ == Token::BIT_AND) {
1151
+ op = token_;
1152
+ Next();
1153
+ right = ParseBinaryExpression(contains_in, 4, CHECK);
1154
+ left = ReduceBinaryOperation(op, left, right);
1155
+ }
1156
+ if (prec < 6) return left;
1157
+
1158
+ // BitwiseXorExpression
1159
+ while (token_ == Token::BIT_XOR) {
1160
+ op = token_;
1161
+ Next();
1162
+ right = ParseBinaryExpression(contains_in, 5, CHECK);
1163
+ left = ReduceBinaryOperation(op, left, right);
1164
+ }
1165
+ if (prec < 7) return left;
1166
+
1167
+ // BitwiseOrExpression
1168
+ while (token_ == Token::BIT_OR) {
1169
+ op = token_;
1170
+ Next();
1171
+ right = ParseBinaryExpression(contains_in, 6, CHECK);
1172
+ left = ReduceBinaryOperation(op, left, right);
1173
+ }
1174
+ if (prec < 8) return left;
1175
+
1176
+ // LogicalAndExpression
1177
+ while (token_ == Token::LOGICAL_AND) {
1178
+ op = token_;
1179
+ Next();
1180
+ right = ParseBinaryExpression(contains_in, 7, CHECK);
1181
+ left = factory_->NewBinaryOperation(op, left, right);
1182
+ }
1183
+ if (prec < 9) return left;
1184
+
1185
+ // LogicalOrExpression
1186
+ while (token_ == Token::LOGICAL_OR) {
1187
+ op = token_;
1188
+ Next();
1189
+ right = ParseBinaryExpression(contains_in, 8, CHECK);
1190
+ left = factory_->NewBinaryOperation(op, left, right);
1191
+ }
1192
+ return left;
1193
+ }
1194
+
1195
+ Expression* ReduceBinaryOperation(Token::Type op,
1196
+ Expression* left,
1197
+ Expression* right) {
1198
+ if (left->AsNumberLiteral() &&
1199
+ right->AsNumberLiteral()) {
1200
+ const double l_val = left->AsNumberLiteral()->value();
1201
+ const double r_val = right->AsNumberLiteral()->value();
1202
+ Expression* res;
1203
+ switch (op) {
1204
+ case Token::ADD:
1205
+ res = factory_->NewNumberLiteral(l_val + r_val);
1206
+ break;
1207
+
1208
+ case Token::SUB:
1209
+ res = factory_->NewNumberLiteral(l_val - r_val);
1210
+ break;
1211
+
1212
+ case Token::MUL:
1213
+ res = factory_->NewNumberLiteral(l_val * r_val);
1214
+ break;
1215
+
1216
+ case Token::DIV:
1217
+ res = factory_->NewNumberLiteral(l_val / r_val);
1218
+ break;
1219
+
1220
+ case Token::BIT_OR:
1221
+ res = factory_->NewNumberLiteral(
1222
+ DoubleToInt32(l_val) | DoubleToInt32(r_val));
1223
+ break;
1224
+
1225
+ case Token::BIT_AND:
1226
+ res = factory_->NewNumberLiteral(
1227
+ DoubleToInt32(l_val) & DoubleToInt32(r_val));
1228
+ break;
1229
+
1230
+ case Token::BIT_XOR:
1231
+ res = factory_->NewNumberLiteral(
1232
+ DoubleToInt32(l_val) ^ DoubleToInt32(r_val));
1233
+ break;
1234
+
1235
+ // section 11.7 Bitwise Shift Operators
1236
+ case Token::SHL: {
1237
+ const int32_t value = DoubleToInt32(l_val)
1238
+ << (DoubleToInt32(r_val) & 0x1f);
1239
+ res = factory_->NewNumberLiteral(value);
1240
+ break;
1241
+ }
1242
+
1243
+ case Token::SHR: {
1244
+ const uint32_t shift = DoubleToInt32(r_val) & 0x1f;
1245
+ const uint32_t value = DoubleToUInt32(l_val) >> shift;
1246
+ res = factory_->NewNumberLiteral(value);
1247
+ break;
1248
+ }
1249
+
1250
+ case Token::SAR: {
1251
+ uint32_t shift = DoubleToInt32(r_val) & 0x1f;
1252
+ int32_t value = DoubleToInt32(l_val) >> shift;
1253
+ res = factory_->NewNumberLiteral(value);
1254
+ break;
1255
+ }
1256
+
1257
+ default:
1258
+ res = factory_->NewBinaryOperation(op, left, right);
1259
+ break;
1260
+ }
1261
+ return res;
1262
+ } else {
1263
+ return factory_->NewBinaryOperation(op, left, right);
1264
+ }
1265
+ }
1266
+
1267
+ // UnaryExpression
1268
+ // : PostfixExpression
1269
+ // | DELETE UnaryExpression
1270
+ // | VOID UnaryExpression
1271
+ // | TYPEOF UnaryExpression
1272
+ // | INC UnaryExpression
1273
+ // | DEC UnaryExpression
1274
+ // | '+' UnaryExpression
1275
+ // | '-' UnaryExpression
1276
+ // | '~' UnaryExpression
1277
+ // | '!' UnaryExpression
1278
+ Expression* ParseUnaryExpression(bool *res) {
1279
+ Expression *result, *expr;
1280
+ const Token::Type op = token_;
1281
+ switch (token_) {
1282
+ case Token::VOID:
1283
+ case Token::NOT:
1284
+ case Token::TYPEOF:
1285
+ Next();
1286
+ expr = ParseUnaryExpression(CHECK);
1287
+ result = factory_->NewUnaryOperation(op, expr);
1288
+ break;
1289
+
1290
+ case Token::DELETE:
1291
+ // a strict mode restriction in sec 11.4.1
1292
+ // raise SyntaxError when target is direct reference to a variable,
1293
+ // function argument, or function name
1294
+ Next();
1295
+ expr = ParseUnaryExpression(CHECK);
1296
+ if (strict_ &&
1297
+ expr->AsIdentifier()) {
1298
+ RAISE("delete to direct identifier not allowed in strict code");
1299
+ }
1300
+ result = factory_->NewUnaryOperation(op, expr);
1301
+ break;
1302
+
1303
+ case Token::BIT_NOT:
1304
+ Next();
1305
+ expr = ParseUnaryExpression(CHECK);
1306
+ if (expr->AsNumberLiteral()) {
1307
+ result = factory_->NewNumberLiteral(
1308
+ ~DoubleToInt32(expr->AsNumberLiteral()->value()));
1309
+ } else {
1310
+ result = factory_->NewUnaryOperation(op, expr);
1311
+ }
1312
+ break;
1313
+
1314
+ case Token::ADD:
1315
+ Next();
1316
+ expr = ParseUnaryExpression(CHECK);
1317
+ if (expr->AsNumberLiteral()) {
1318
+ result = expr;
1319
+ } else {
1320
+ result = factory_->NewUnaryOperation(op, expr);
1321
+ }
1322
+ break;
1323
+
1324
+ case Token::SUB:
1325
+ Next();
1326
+ expr = ParseUnaryExpression(CHECK);
1327
+ if (expr->AsNumberLiteral()) {
1328
+ result = factory_->NewNumberLiteral(
1329
+ -(expr->AsNumberLiteral()->value()));
1330
+ } else {
1331
+ result = factory_->NewUnaryOperation(op, expr);
1332
+ }
1333
+ break;
1334
+
1335
+ case Token::INC:
1336
+ case Token::DEC:
1337
+ Next();
1338
+ expr = ParseMemberExpression(true, CHECK);
1339
+ if (!expr->IsValidLeftHandSide()) {
1340
+ RAISE("invalid left-hand-side in prefix expression");
1341
+ }
1342
+ // section 11.4.4, 11.4.5 throwing SyntaxError
1343
+ if (strict_ &&
1344
+ expr->AsIdentifier()) {
1345
+ const EvalOrArguments val = IsEvalOrArguments(expr->AsIdentifier());
1346
+ if (val) {
1347
+ if (val == kEval) {
1348
+ RAISE("prefix expression to \"eval\" "
1349
+ "not allowed in strict code");
1350
+ } else {
1351
+ assert(val == kArguments);
1352
+ RAISE("prefix expression to \"arguments\" "
1353
+ "not allowed in strict code");
1354
+ }
1355
+ }
1356
+ }
1357
+ result = factory_->NewUnaryOperation(op, expr);
1358
+ break;
1359
+
1360
+ default:
1361
+ result = ParsePostfixExpression(CHECK);
1362
+ break;
1363
+ }
1364
+ return result;
1365
+ }
1366
+
1367
+ // PostfixExpression
1368
+ // : LeftHandSideExpression
1369
+ // | LeftHandSideExpression INCREMENT
1370
+ // | LeftHandSideExpression DECREMENT
1371
+ Expression* ParsePostfixExpression(bool *res) {
1372
+ Expression *expr;
1373
+ expr = ParseMemberExpression(true, CHECK);
1374
+ if (!lexer_.has_line_terminator_before_next() &&
1375
+ (token_ == Token::INC || token_ == Token::DEC)) {
1376
+ if (!expr->IsValidLeftHandSide()) {
1377
+ RAISE("invalid left-hand-side in postfix expression");
1378
+ }
1379
+ // section 11.3.1, 11.3.2 throwing SyntaxError
1380
+ if (strict_ &&
1381
+ expr->AsIdentifier()) {
1382
+ const EvalOrArguments val = IsEvalOrArguments(expr->AsIdentifier());
1383
+ if (val) {
1384
+ if (val == kEval) {
1385
+ RAISE("postfix expression to \"eval\" not allowed in strict code");
1386
+ } else {
1387
+ assert(val == kArguments);
1388
+ RAISE("postfix expression to \"arguments\" "
1389
+ "not allowed in strict code");
1390
+ }
1391
+ }
1392
+ }
1393
+ expr = factory_->NewPostfixExpression(token_, expr);
1394
+ Next();
1395
+ }
1396
+ return expr;
1397
+ }
1398
+
1399
+ // LeftHandSideExpression
1400
+ // : NewExpression
1401
+ // | CallExpression
1402
+ //
1403
+ // NewExpression
1404
+ // : MemberExpression
1405
+ // | NEW NewExpression
1406
+ //
1407
+ // MemberExpression
1408
+ // : PrimaryExpression
1409
+ // | FunctionExpression
1410
+ // | MemberExpression '[' Expression ']'
1411
+ // | NEW MemberExpression Arguments
1412
+ Expression* ParseMemberExpression(bool allow_call, bool *res) {
1413
+ Expression *expr;
1414
+ if (token_ != Token::NEW) {
1415
+ if (token_ == Token::FUNCTION) {
1416
+ // FunctionExpression
1417
+ Next();
1418
+ expr = ParseFunctionLiteral(FunctionLiteral::EXPRESSION,
1419
+ FunctionLiteral::GENERAL, true, CHECK);
1420
+ } else {
1421
+ expr = ParsePrimaryExpression(CHECK);
1422
+ }
1423
+ } else {
1424
+ Next();
1425
+ Expression *target = ParseMemberExpression(false, CHECK);
1426
+ ConstructorCall *con = factory_->NewConstructorCall(target);
1427
+ if (token_ == Token::LPAREN) {
1428
+ ParseArguments(con, CHECK);
1429
+ }
1430
+ expr = con;
1431
+ }
1432
+ FunctionCall *funcall;
1433
+ while (true) {
1434
+ switch (token_) {
1435
+ case Token::LBRACK: {
1436
+ Next();
1437
+ Expression* index = ParseExpression(true, CHECK);
1438
+ expr = factory_->NewIndexAccess(expr, index);
1439
+ EXPECT(Token::RBRACK);
1440
+ break;
1441
+ }
1442
+
1443
+ case Token::PERIOD: {
1444
+ Next(Lexer::kIgnoreReservedWords); // IDENTIFIERNAME
1445
+ IS(Token::IDENTIFIER);
1446
+ Identifier* ident = factory_->NewIdentifier(lexer_.Buffer());
1447
+ Next();
1448
+ expr = factory_->NewIdentifierAccess(expr, ident);
1449
+ break;
1450
+ }
1451
+
1452
+ case Token::LPAREN:
1453
+ if (allow_call) {
1454
+ funcall = factory_->NewFunctionCall(expr);
1455
+ ParseArguments(funcall, CHECK);
1456
+ expr = funcall;
1457
+ } else {
1458
+ return expr;
1459
+ }
1460
+ break;
1461
+
1462
+ default:
1463
+ return expr;
1464
+ }
1465
+ }
1466
+ }
1467
+
1468
+ // PrimaryExpression
1469
+ // : THIS
1470
+ // | IDENTIFIER
1471
+ // | Literal
1472
+ // | ArrayLiteral
1473
+ // | ObjectLiteral
1474
+ // | '(' Expression ')'
1475
+ //
1476
+ // Literal
1477
+ // : NULL_LITERAL
1478
+ // | TRUE_LITERAL
1479
+ // | FALSE_LITERAL
1480
+ // | NUMBER
1481
+ // | STRING
1482
+ // | REGEXP
1483
+ Expression* ParsePrimaryExpression(bool *res) {
1484
+ Expression *result = NULL;
1485
+ switch (token_) {
1486
+ case Token::THIS:
1487
+ result = factory_->NewThisLiteral();
1488
+ Next();
1489
+ break;
1490
+
1491
+ case Token::IDENTIFIER:
1492
+ result = factory_->NewIdentifier(lexer_.Buffer());
1493
+ Next();
1494
+ break;
1495
+
1496
+ case Token::NULL_LITERAL:
1497
+ result = factory_->NewNullLiteral();
1498
+ Next();
1499
+ break;
1500
+
1501
+ case Token::TRUE_LITERAL:
1502
+ result = factory_->NewTrueLiteral();
1503
+ Next();
1504
+ break;
1505
+
1506
+ case Token::FALSE_LITERAL:
1507
+ result = factory_->NewFalseLiteral();
1508
+ Next();
1509
+ break;
1510
+
1511
+ case Token::NUMBER:
1512
+ // section 7.8.3
1513
+ // strict mode forbids Octal Digits Literal
1514
+ if (strict_ && lexer_.NumericType() == Lexer::OCTAL) {
1515
+ RAISE("octal integer literal not allowed in strict code");
1516
+ }
1517
+ result = factory_->NewNumberLiteral(lexer_.Numeric());
1518
+ Next();
1519
+ break;
1520
+
1521
+ case Token::STRING: {
1522
+ const Lexer::State state = lexer_.StringEscapeType();
1523
+ if (strict_ && state == Lexer::OCTAL) {
1524
+ RAISE("octal excape sequence not allowed in strict code");
1525
+ }
1526
+ if (state == Lexer::NONE) {
1527
+ result = factory_->NewDirectivable(lexer_.Buffer());
1528
+ } else {
1529
+ result = factory_->NewStringLiteral(lexer_.Buffer());
1530
+ }
1531
+ Next();
1532
+ break;
1533
+ }
1534
+
1535
+ case Token::DIV:
1536
+ result = ParseRegExpLiteral(false, CHECK);
1537
+ break;
1538
+
1539
+ case Token::ASSIGN_DIV:
1540
+ result = ParseRegExpLiteral(true, CHECK);
1541
+ break;
1542
+
1543
+ case Token::LBRACK:
1544
+ result = ParseArrayLiteral(CHECK);
1545
+ break;
1546
+
1547
+ case Token::LBRACE:
1548
+ result = ParseObjectLiteral(CHECK);
1549
+ break;
1550
+
1551
+ case Token::LPAREN:
1552
+ Next();
1553
+ result = ParseExpression(true, CHECK);
1554
+ EXPECT(Token::RPAREN);
1555
+ break;
1556
+
1557
+ default:
1558
+ RAISE("invalid primary expression token");
1559
+ break;
1560
+ }
1561
+ return result;
1562
+ }
1563
+
1564
+ // Arguments
1565
+ // : '(' ')'
1566
+ // | '(' ArgumentList ')'
1567
+ //
1568
+ // ArgumentList
1569
+ // : AssignmentExpression
1570
+ // | ArgumentList ',' AssignmentExpression
1571
+ Call* ParseArguments(Call* func, bool *res) {
1572
+ Expression *expr;
1573
+ Next();
1574
+ while (token_ != Token::RPAREN) {
1575
+ expr = ParseAssignmentExpression(true, CHECK);
1576
+ func->AddArgument(expr);
1577
+ if (token_ != Token::RPAREN) {
1578
+ EXPECT(Token::COMMA);
1579
+ }
1580
+ }
1581
+ Next();
1582
+ return func;
1583
+ }
1584
+
1585
+ Expression* ParseRegExpLiteral(bool contains_eq, bool *res) {
1586
+ if (lexer_.ScanRegExpLiteral(contains_eq)) {
1587
+ RegExpLiteral* expr;
1588
+ const std::vector<uc16> content(lexer_.Buffer());
1589
+ if (!lexer_.ScanRegExpFlags()) {
1590
+ RAISE("invalid regular expression flag");
1591
+ } else {
1592
+ expr = factory_->NewRegExpLiteral(content, lexer_.Buffer());
1593
+ if (!expr) {
1594
+ RAISE("invalid regular expression");
1595
+ }
1596
+ }
1597
+ Next();
1598
+ return expr;
1599
+ } else {
1600
+ RAISE("invalid regular expression");
1601
+ }
1602
+ }
1603
+
1604
+ // ArrayLiteral
1605
+ // : '[' Elision_opt ']'
1606
+ // | '[' ElementList ']'
1607
+ // | '[' ElementList ',' Elision_opt ']'
1608
+ //
1609
+ // ElementList
1610
+ // : Elision_opt AssignmentExpression
1611
+ // | ElementList ',' Elision_opt AssignmentExpression
1612
+ //
1613
+ // Elision
1614
+ // : ','
1615
+ // | Elision ','
1616
+ Expression* ParseArrayLiteral(bool *res) {
1617
+ ArrayLiteral *array = factory_->NewArrayLiteral();
1618
+ Expression *expr;
1619
+ Next();
1620
+ while (token_ != Token::RBRACK) {
1621
+ if (token_ == Token::COMMA) {
1622
+ // when Token::COMMA, only increment length
1623
+ array->AddItem(NULL);
1624
+ } else {
1625
+ expr = ParseAssignmentExpression(true, CHECK);
1626
+ array->AddItem(expr);
1627
+ }
1628
+ if (token_ != Token::RBRACK) {
1629
+ EXPECT(Token::COMMA);
1630
+ }
1631
+ }
1632
+ Next();
1633
+ return array;
1634
+ }
1635
+
1636
+
1637
+
1638
+ // ObjectLiteral
1639
+ // : '{' PropertyNameAndValueList_opt '}'
1640
+ //
1641
+ // PropertyNameAndValueList_opt
1642
+ // :
1643
+ // | PropertyNameAndValueList
1644
+ //
1645
+ // PropertyNameAndValueList
1646
+ // : PropertyAssignment
1647
+ // | PropertyNameAndValueList ',' PropertyAssignment
1648
+ //
1649
+ // PropertyAssignment
1650
+ // : PropertyName ':' AssignmentExpression
1651
+ // | 'get' PropertyName '(' ')' '{' FunctionBody '}'
1652
+ // | 'set' PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
1653
+ //
1654
+ // PropertyName
1655
+ // : IDENTIFIER
1656
+ // | STRING
1657
+ // | NUMBER
1658
+ //
1659
+ // PropertySetParameterList
1660
+ // : IDENTIFIER
1661
+ Expression* ParseObjectLiteral(bool *res) {
1662
+ typedef std::tr1::unordered_map<IdentifierKey, int> ObjectMap;
1663
+ ObjectLiteral *object = factory_->NewObjectLiteral();
1664
+ ObjectMap map;
1665
+ Expression *expr;
1666
+ Identifier *ident;
1667
+
1668
+ // IDENTIFIERNAME
1669
+ Next(Lexer::kIgnoreReservedWordsAndIdentifyGetterOrSetter);
1670
+ while (token_ != Token::RBRACE) {
1671
+ if (token_ == Token::GET || token_ == Token::SET) {
1672
+ const bool is_get = token_ == Token::GET;
1673
+ // this is getter or setter or usual prop
1674
+ Next(Lexer::kIgnoreReservedWords); // IDENTIFIERNAME
1675
+ if (token_ == Token::COLON) {
1676
+ // property
1677
+ ident = factory_->NewIdentifier(
1678
+ is_get ? ParserData::kGet : ParserData::kSet);
1679
+ Next();
1680
+ expr = ParseAssignmentExpression(true, CHECK);
1681
+ object->AddDataProperty(ident, expr);
1682
+ typename ObjectMap::iterator it = map.find(ident);
1683
+ if (it == map.end()) {
1684
+ map.insert(std::make_pair(ident, ObjectLiteral::DATA));
1685
+ } else {
1686
+ if (it->second != ObjectLiteral::DATA) {
1687
+ RAISE("accessor property and data property "
1688
+ "exist with the same name");
1689
+ } else {
1690
+ if (strict_) {
1691
+ RAISE("multiple data property assignments "
1692
+ "with the same name not allowed in strict code");
1693
+ }
1694
+ }
1695
+ }
1696
+ } else {
1697
+ // getter or setter
1698
+ if (token_ == Token::IDENTIFIER ||
1699
+ token_ == Token::STRING ||
1700
+ token_ == Token::NUMBER) {
1701
+ if (token_ == Token::NUMBER) {
1702
+ ident = factory_->NewIdentifier(lexer_.Buffer8());
1703
+ } else {
1704
+ ident = factory_->NewIdentifier(lexer_.Buffer());
1705
+ }
1706
+ Next();
1707
+ typename ObjectLiteral::PropertyDescriptorType type =
1708
+ (is_get) ? ObjectLiteral::GET : ObjectLiteral::SET;
1709
+ expr = ParseFunctionLiteral(
1710
+ FunctionLiteral::EXPRESSION,
1711
+ (is_get) ? FunctionLiteral::GETTER : FunctionLiteral::SETTER,
1712
+ false, CHECK);
1713
+ object->AddAccessor(type, ident, expr);
1714
+ typename ObjectMap::iterator it = map.find(ident);
1715
+ if (it == map.end()) {
1716
+ map.insert(std::make_pair(ident, type));
1717
+ } else if (it->second & (ObjectLiteral::DATA | type)) {
1718
+ if (it->second & ObjectLiteral::DATA) {
1719
+ RAISE("data property and accessor property "
1720
+ "exist with the same name");
1721
+ } else {
1722
+ RAISE("multiple same accessor properties "
1723
+ "exist with the same name");
1724
+ }
1725
+ } else {
1726
+ it->second |= type;
1727
+ }
1728
+ } else {
1729
+ RAISE("invalid property name");
1730
+ }
1731
+ }
1732
+ } else if (token_ == Token::IDENTIFIER ||
1733
+ token_ == Token::STRING ||
1734
+ token_ == Token::NUMBER) {
1735
+ ident = factory_->NewIdentifier(lexer_.Buffer());
1736
+ Next();
1737
+ EXPECT(Token::COLON);
1738
+ expr = ParseAssignmentExpression(true, CHECK);
1739
+ object->AddDataProperty(ident, expr);
1740
+ typename ObjectMap::iterator it = map.find(ident);
1741
+ if (it == map.end()) {
1742
+ map.insert(std::make_pair(ident, ObjectLiteral::DATA));
1743
+ } else {
1744
+ if (it->second != ObjectLiteral::DATA) {
1745
+ RAISE("accessor property and data property "
1746
+ "exist with the same name");
1747
+ } else {
1748
+ if (strict_) {
1749
+ RAISE("multiple data property assignments "
1750
+ "with the same name not allowed in strict code");
1751
+ }
1752
+ }
1753
+ }
1754
+ } else {
1755
+ RAISE("invalid property name");
1756
+ }
1757
+
1758
+ if (token_ != Token::RBRACE) {
1759
+ IS(Token::COMMA);
1760
+ // IDENTIFIERNAME
1761
+ Next(Lexer::kIgnoreReservedWordsAndIdentifyGetterOrSetter);
1762
+ }
1763
+ }
1764
+ Next();
1765
+ return object;
1766
+ }
1767
+
1768
+ FunctionLiteral* ParseFunctionLiteral(
1769
+ typename FunctionLiteral::DeclType decl_type,
1770
+ typename FunctionLiteral::ArgType arg_type,
1771
+ bool allow_identifier,
1772
+ bool *res) {
1773
+ // IDENTIFIER
1774
+ // IDENTIFIER_opt
1775
+ std::tr1::unordered_set<IdentifierKey> param_set;
1776
+ std::size_t throw_error_if_strict_code_line = 0;
1777
+ enum {
1778
+ kDetectNone = 0,
1779
+ kDetectEvalName,
1780
+ kDetectArgumentsName,
1781
+ kDetectEvalParameter,
1782
+ kDetectArgumentsParameter,
1783
+ kDetectDuplicateParameter
1784
+ } throw_error_if_strict_code = kDetectNone;
1785
+
1786
+ FunctionLiteral *literal = factory_->NewFunctionLiteral(decl_type);
1787
+ literal->set_strict(strict_);
1788
+ if (allow_identifier && token_ == Token::IDENTIFIER) {
1789
+ Identifier* const name = factory_->NewIdentifier(lexer_.Buffer());
1790
+ literal->SetName(name);
1791
+ const EvalOrArguments val = IsEvalOrArguments(name);
1792
+ if (val) {
1793
+ throw_error_if_strict_code = (val == kEval) ?
1794
+ kDetectEvalName : kDetectArgumentsName;
1795
+ throw_error_if_strict_code_line = lexer_.line_number();
1796
+ }
1797
+ Next();
1798
+ }
1799
+ const ScopeSwitcher switcher(this, literal->scope());
1800
+ literal->set_start_position(lexer_.pos() - 2);
1801
+
1802
+ // '(' FormalParameterList_opt ')'
1803
+ EXPECT(Token::LPAREN);
1804
+
1805
+ if (arg_type == FunctionLiteral::GETTER) {
1806
+ // if getter, parameter count is 0
1807
+ EXPECT(Token::RPAREN);
1808
+ } else if (arg_type == FunctionLiteral::SETTER) {
1809
+ // if setter, parameter count is 1
1810
+ IS(Token::IDENTIFIER);
1811
+ Identifier* const ident = factory_->NewIdentifier(lexer_.Buffer());
1812
+ if (!throw_error_if_strict_code) {
1813
+ const EvalOrArguments val = IsEvalOrArguments(ident);
1814
+ if (val) {
1815
+ throw_error_if_strict_code = (val == kEval) ?
1816
+ kDetectEvalParameter : kDetectArgumentsParameter;
1817
+ throw_error_if_strict_code_line = lexer_.line_number();
1818
+ }
1819
+ }
1820
+ literal->AddParameter(ident);
1821
+ Next();
1822
+ EXPECT(Token::RPAREN);
1823
+ } else {
1824
+ while (token_ != Token::RPAREN) {
1825
+ IS(Token::IDENTIFIER);
1826
+ Identifier* const ident = factory_->NewIdentifier(lexer_.Buffer());
1827
+ if (!throw_error_if_strict_code) {
1828
+ const EvalOrArguments val = IsEvalOrArguments(ident);
1829
+ if (val) {
1830
+ throw_error_if_strict_code = (val == kEval) ?
1831
+ kDetectEvalParameter : kDetectArgumentsParameter;
1832
+ throw_error_if_strict_code_line = lexer_.line_number();
1833
+ }
1834
+ if ((!throw_error_if_strict_code) &&
1835
+ (param_set.find(ident) != param_set.end())) {
1836
+ throw_error_if_strict_code = kDetectDuplicateParameter;
1837
+ throw_error_if_strict_code_line = lexer_.line_number();
1838
+ }
1839
+ }
1840
+ literal->AddParameter(ident);
1841
+ param_set.insert(ident);
1842
+ Next();
1843
+ if (token_ != Token::RPAREN) {
1844
+ EXPECT(Token::COMMA);
1845
+ }
1846
+ }
1847
+ Next();
1848
+ }
1849
+
1850
+ // '{' FunctionBody '}'
1851
+ //
1852
+ // FunctionBody
1853
+ // :
1854
+ // | SourceElements
1855
+ EXPECT(Token::LBRACE);
1856
+
1857
+ ParseSourceElements(Token::RBRACE, literal, CHECK);
1858
+ if (strict_ || literal->strict()) {
1859
+ // section 13.1
1860
+ // Strict Mode Restrictions
1861
+ switch (throw_error_if_strict_code) {
1862
+ case kDetectNone:
1863
+ break;
1864
+ case kDetectEvalName:
1865
+ RAISE_WITH_NUMBER(
1866
+ "function name \"eval\" not allowed in strict code",
1867
+ throw_error_if_strict_code_line);
1868
+ break;
1869
+ case kDetectArgumentsName:
1870
+ RAISE_WITH_NUMBER(
1871
+ "function name \"arguments\" not allowed in strict code",
1872
+ throw_error_if_strict_code_line);
1873
+ break;
1874
+ case kDetectEvalParameter:
1875
+ RAISE_WITH_NUMBER(
1876
+ "parameter \"eval\" not allowed in strict code",
1877
+ throw_error_if_strict_code_line);
1878
+ break;
1879
+ case kDetectArgumentsParameter:
1880
+ RAISE_WITH_NUMBER(
1881
+ "parameter \"arguments\" not allowed in strict code",
1882
+ throw_error_if_strict_code_line);
1883
+ break;
1884
+ case kDetectDuplicateParameter:
1885
+ RAISE_WITH_NUMBER(
1886
+ "duplicate parameter not allowed in strict code",
1887
+ throw_error_if_strict_code_line);
1888
+ break;
1889
+ }
1890
+ }
1891
+ literal->set_end_position(lexer_.pos() - 2);
1892
+ literal->SubStringSource(lexer_.source());
1893
+ Next();
1894
+ return literal;
1895
+ }
1896
+
1897
+ bool ContainsLabel(const Identifiers* const labels,
1898
+ const Identifier * const label) const {
1899
+ assert(label != NULL);
1900
+ if (labels) {
1901
+ const SpaceUString& value = label->value();
1902
+ for (typename Identifiers::const_iterator it = labels->begin(),
1903
+ last = labels->end();
1904
+ it != last; ++it) {
1905
+ if ((*it)->value() == value) {
1906
+ return true;
1907
+ }
1908
+ }
1909
+ }
1910
+ return false;
1911
+ }
1912
+
1913
+ bool TargetsContainsLabel(const Identifier* const label) const {
1914
+ assert(label != NULL);
1915
+ for (Target* target = target_;
1916
+ target != NULL;
1917
+ target = target->previous()) {
1918
+ if (ContainsLabel(target->node()->labels(), label)) {
1919
+ return true;
1920
+ }
1921
+ }
1922
+ return false;
1923
+ }
1924
+
1925
+ BreakableStatement* LookupBreakableTarget(
1926
+ const Identifier* const label) const {
1927
+ assert(label != NULL);
1928
+ for (const Target* target = target_;
1929
+ target != NULL;
1930
+ target = target->previous()) {
1931
+ if (ContainsLabel(target->node()->labels(), label)) {
1932
+ return target->node();
1933
+ }
1934
+ }
1935
+ return NULL;
1936
+ }
1937
+
1938
+ BreakableStatement* LookupBreakableTarget() const {
1939
+ for (const Target* target = target_;
1940
+ target != NULL;
1941
+ target = target->previous()) {
1942
+ if (target->node()->AsAnonymousBreakableStatement()) {
1943
+ return target->node();
1944
+ }
1945
+ }
1946
+ return NULL;
1947
+ }
1948
+
1949
+ IterationStatement* LookupContinuableTarget(
1950
+ const Identifier* const label) const {
1951
+ assert(label != NULL);
1952
+ for (const Target* target = target_;
1953
+ target != NULL;
1954
+ target = target->previous()) {
1955
+ IterationStatement* const iter = target->node()->AsIterationStatement();
1956
+ if (iter && ContainsLabel(iter->labels(), label)) {
1957
+ return iter;
1958
+ }
1959
+ }
1960
+ return NULL;
1961
+ }
1962
+
1963
+ IterationStatement* LookupContinuableTarget() const {
1964
+ for (const Target* target = target_;
1965
+ target != NULL;
1966
+ target = target->previous()) {
1967
+ IterationStatement* const iter = target->node()->AsIterationStatement();
1968
+ if (iter) {
1969
+ return iter;
1970
+ }
1971
+ }
1972
+ return NULL;
1973
+ }
1974
+
1975
+ inline void SetErrorHeader() {
1976
+ SetErrorHeader(lexer_.line_number());
1977
+ }
1978
+
1979
+ void SetErrorHeader(std::size_t line) {
1980
+ std::tr1::array<char, 40> buf;
1981
+ error_.append(lexer_.filename());
1982
+ int num = std::snprintf(buf.data(), buf.size(),
1983
+ ":%lu: SyntaxError: ",
1984
+ static_cast<unsigned long>(line)); // NOLINT
1985
+ error_.append(buf.data(), num);
1986
+ }
1987
+
1988
+ void ReportUnexpectedToken(Token::Type expected_token) {
1989
+ SetErrorHeader();
1990
+ switch (token_) {
1991
+ case Token::STRING:
1992
+ error_.append("unexpected string");
1993
+ break;
1994
+ case Token::NUMBER:
1995
+ error_.append("unexpected number");
1996
+ break;
1997
+ case Token::IDENTIFIER:
1998
+ error_.append("unexpected identifier");
1999
+ break;
2000
+ case Token::EOS:
2001
+ error_.append("unexpected EOS");
2002
+ break;
2003
+ case Token::ILLEGAL: {
2004
+ error_.append("illegal character");
2005
+ break;
2006
+ }
2007
+ default: {
2008
+ error_.append("unexpected token ");
2009
+ error_.append(Token::ToString(token_));
2010
+ break;
2011
+ }
2012
+ }
2013
+ }
2014
+
2015
+ bool ExpectSemicolon(bool *res) {
2016
+ if (token_ == Token::SEMICOLON) {
2017
+ Next();
2018
+ return true;
2019
+ }
2020
+ if (lexer_.has_line_terminator_before_next() ||
2021
+ token_ == Token::RBRACE ||
2022
+ token_ == Token::EOS ) {
2023
+ return true;
2024
+ }
2025
+ UNEXPECT(token_);
2026
+ }
2027
+
2028
+ inline Lexer& lexer() {
2029
+ return lexer_;
2030
+ }
2031
+ inline Token::Type Next(Lexer::LexType type = Lexer::kIdentifyReservedWords) {
2032
+ return token_ = lexer_.Next(
2033
+ type | (strict_ ? Lexer::kStrict : Lexer::kClear));
2034
+ }
2035
+ inline Token::Type Peek() const {
2036
+ return token_;
2037
+ }
2038
+ inline Scope* scope() const {
2039
+ return scope_;
2040
+ }
2041
+ inline void set_scope(Scope* scope) {
2042
+ scope_ = scope;
2043
+ }
2044
+ inline const std::string& error() const {
2045
+ return error_;
2046
+ }
2047
+ inline Target* target() const {
2048
+ return target_;
2049
+ }
2050
+ inline void set_target(Target* target) {
2051
+ target_ = target;
2052
+ }
2053
+ inline Identifiers* labels() const {
2054
+ return labels_;
2055
+ }
2056
+ inline void set_labels(Identifiers* labels) {
2057
+ labels_ = labels;
2058
+ }
2059
+ inline bool strict() const {
2060
+ return strict_;
2061
+ }
2062
+ inline void set_strict(bool strict) {
2063
+ strict_ = strict;
2064
+ }
2065
+
2066
+ protected:
2067
+ class ScopeSwitcher : private Noncopyable<ScopeSwitcher>::type {
2068
+ public:
2069
+ ScopeSwitcher(parser_type* parser, Scope* scope)
2070
+ : parser_(parser) {
2071
+ scope->SetUpperScope(parser_->scope());
2072
+ parser_->set_scope(scope);
2073
+ }
2074
+ ~ScopeSwitcher() {
2075
+ assert(parser_->scope() != NULL);
2076
+ parser_->set_scope(parser_->scope()->GetUpperScope());
2077
+ }
2078
+ private:
2079
+ parser_type* parser_;
2080
+ };
2081
+
2082
+ class LabelScope : private Noncopyable<LabelScope>::type {
2083
+ public:
2084
+ LabelScope(parser_type* parser,
2085
+ Identifiers* labels, bool exist_labels)
2086
+ : parser_(parser),
2087
+ exist_labels_(exist_labels) {
2088
+ parser_->set_labels(labels);
2089
+ }
2090
+ ~LabelScope() {
2091
+ if (!exist_labels_) {
2092
+ parser_->set_labels(NULL);
2093
+ }
2094
+ }
2095
+ private:
2096
+ parser_type* parser_;
2097
+ bool exist_labels_;
2098
+ };
2099
+
2100
+ class StrictSwitcher : private Noncopyable<StrictSwitcher>::type {
2101
+ public:
2102
+ explicit StrictSwitcher(parser_type* parser)
2103
+ : parser_(parser),
2104
+ prev_(parser->strict()) {
2105
+ }
2106
+ ~StrictSwitcher() {
2107
+ parser_->set_strict(prev_);
2108
+ }
2109
+ inline void SwitchStrictMode() const {
2110
+ parser_->set_strict(true);
2111
+ }
2112
+ private:
2113
+ parser_type* parser_;
2114
+ bool prev_;
2115
+ };
2116
+
2117
+ enum EvalOrArguments {
2118
+ kNone = 0,
2119
+ kEval = 1,
2120
+ kArguments = 2
2121
+ };
2122
+
2123
+ static EvalOrArguments IsEvalOrArguments(const Identifier* ident) {
2124
+ const SpaceUString& str = ident->value();
2125
+ if (str.compare(ParserData::kEval.data()) == 0) {
2126
+ return kEval;
2127
+ } else if (str.compare(ParserData::kArguments.data()) == 0) {
2128
+ return kArguments;
2129
+ } else {
2130
+ return kNone;
2131
+ }
2132
+ }
2133
+
2134
+ Lexer lexer_;
2135
+ Token::Type token_;
2136
+ std::string error_;
2137
+ bool strict_;
2138
+ Factory* factory_;
2139
+ Scope* scope_;
2140
+ Target* target_;
2141
+ Identifiers* labels_;
2142
+ };
2143
+ #undef IS
2144
+ #undef EXPECT
2145
+ #undef UNEXPECT
2146
+ #undef RAISE
2147
+ #undef RAISE_WITH_NUMBER
2148
+ #undef CHECK
2149
+ } } // namespace iv::core
2150
+ #endif // _IV_PARSER_H_