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.
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_