iv-phonic 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/ext/include/iv/ast-factory.h +42 -30
- data/ext/include/iv/ast-fwd.h +22 -12
- data/ext/include/iv/ast-serializer.h +26 -32
- data/ext/include/iv/ast-visitor.h +0 -2
- data/ext/include/iv/ast.h +122 -244
- data/ext/include/iv/lexer.h +1 -1
- data/ext/include/iv/parser.h +199 -193
- data/ext/iv/phonic/creator.h +0 -8
- data/ext/iv/phonic/factory.h +45 -32
- data/ext/iv/phonic/phonic.cc +0 -47
- metadata +3 -3
data/ext/include/iv/parser.h
CHANGED
@@ -140,15 +140,20 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
140
140
|
#undef V
|
141
141
|
class Target : private Noncopyable<Target>::type {
|
142
142
|
public:
|
143
|
-
|
143
|
+
typedef typename SpaceVector<Factory, Identifier*>::type Identifiers;
|
144
|
+
enum Type {
|
145
|
+
kNamedOnlyStatement = 0, // (00)2
|
146
|
+
kIterationStatement = 2, // (10)2
|
147
|
+
kSwitchStatement = 3 // (11)2
|
148
|
+
};
|
149
|
+
Target(parser_type* parser, Type type)
|
144
150
|
: parser_(parser),
|
145
151
|
prev_(parser->target()),
|
146
|
-
|
152
|
+
labels_(parser->labels()),
|
153
|
+
node_(NULL),
|
154
|
+
type_(type) {
|
147
155
|
parser_->set_target(this);
|
148
|
-
|
149
|
-
target->set_labels(parser_->labels());
|
150
|
-
parser_->set_labels(NULL);
|
151
|
-
}
|
156
|
+
parser_->set_labels(NULL);
|
152
157
|
}
|
153
158
|
~Target() {
|
154
159
|
parser_->set_target(prev_);
|
@@ -156,13 +161,36 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
156
161
|
inline Target* previous() const {
|
157
162
|
return prev_;
|
158
163
|
}
|
159
|
-
inline
|
164
|
+
inline bool IsAnonymous() const {
|
165
|
+
return type_ & 2;
|
166
|
+
}
|
167
|
+
inline bool IsIteration() const {
|
168
|
+
return type_ == kIterationStatement;
|
169
|
+
}
|
170
|
+
inline bool IsSwitch() const {
|
171
|
+
return type_ == kSwitchStatement;
|
172
|
+
}
|
173
|
+
inline bool IsNamedOnly() const {
|
174
|
+
return !IsAnonymous();
|
175
|
+
}
|
176
|
+
inline BreakableStatement** node() {
|
177
|
+
node_ = new(parser_->factory())BreakableStatement*();
|
160
178
|
return node_;
|
161
179
|
}
|
180
|
+
inline Identifiers* labels() const {
|
181
|
+
return labels_;
|
182
|
+
}
|
183
|
+
inline void set_node(BreakableStatement* node) {
|
184
|
+
if (node_) {
|
185
|
+
*node_ = node;
|
186
|
+
}
|
187
|
+
}
|
162
188
|
private:
|
163
189
|
parser_type* parser_;
|
164
190
|
Target* prev_;
|
165
|
-
|
191
|
+
Identifiers* labels_;
|
192
|
+
BreakableStatement** node_;
|
193
|
+
int type_;
|
166
194
|
};
|
167
195
|
|
168
196
|
Parser(BasicSource* source, Factory* space)
|
@@ -200,7 +228,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
200
228
|
// | FunctionDeclaration
|
201
229
|
bool ParseSourceElements(Token::Type end,
|
202
230
|
FunctionLiteral* function, bool *res) {
|
203
|
-
Statement
|
231
|
+
Statement* stmt;
|
204
232
|
bool recognize_use_strict_directive = true;
|
205
233
|
const StrictSwitcher switcher(this);
|
206
234
|
while (token_ != end) {
|
@@ -369,11 +397,9 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
369
397
|
// and this statement is very useful for not breaking FunctionDeclaration.
|
370
398
|
Statement* ParseFunctionDeclaration(bool *res) {
|
371
399
|
assert(token_ == Token::FUNCTION);
|
372
|
-
|
373
|
-
IS(Token::IDENTIFIER);
|
374
|
-
FunctionLiteral* expr = ParseFunctionLiteral(
|
400
|
+
FunctionLiteral* const expr = ParseFunctionLiteral(
|
375
401
|
FunctionLiteral::DECLARATION,
|
376
|
-
FunctionLiteral::GENERAL,
|
402
|
+
FunctionLiteral::GENERAL, CHECK);
|
377
403
|
// define named function as FunctionDeclaration
|
378
404
|
scope_->AddFunctionDeclaration(expr);
|
379
405
|
return factory_->NewFunctionStatement(expr);
|
@@ -388,9 +414,9 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
388
414
|
// | StatementList Statement
|
389
415
|
Block* ParseBlock(bool *res) {
|
390
416
|
assert(token_ == Token::LBRACE);
|
391
|
-
Block
|
392
|
-
Statement
|
393
|
-
Target target(this,
|
417
|
+
Block* const block = factory_->NewBlock();
|
418
|
+
Statement* stmt;
|
419
|
+
Target target(this, Target::kNamedOnlyStatement);
|
394
420
|
|
395
421
|
Next();
|
396
422
|
while (token_ != Token::RBRACE) {
|
@@ -398,6 +424,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
398
424
|
block->AddStatement(stmt);
|
399
425
|
}
|
400
426
|
Next();
|
427
|
+
target.set_node(block);
|
401
428
|
return block;
|
402
429
|
}
|
403
430
|
|
@@ -406,7 +433,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
406
433
|
// : CONST VariableDeclarationList ';'
|
407
434
|
Statement* ParseVariableStatement(bool *res) {
|
408
435
|
assert(token_ == Token::VAR || token_ == Token::CONST);
|
409
|
-
VariableStatement* stmt = factory_->NewVariableStatement(token_);
|
436
|
+
VariableStatement* const stmt = factory_->NewVariableStatement(token_);
|
410
437
|
ParseVariableDeclarations(stmt, true, CHECK);
|
411
438
|
ExpectSemicolon(CHECK);
|
412
439
|
return stmt;
|
@@ -428,14 +455,14 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
428
455
|
Statement* ParseVariableDeclarations(VariableStatement* stmt,
|
429
456
|
bool contains_in,
|
430
457
|
bool *res) {
|
431
|
-
Identifier
|
432
|
-
Expression
|
433
|
-
Declaration
|
458
|
+
Identifier* name;
|
459
|
+
Expression* expr;
|
460
|
+
Declaration* decl;
|
434
461
|
|
435
462
|
do {
|
436
463
|
Next();
|
437
464
|
IS(Token::IDENTIFIER);
|
438
|
-
name =
|
465
|
+
name = ParseIdentifier(lexer_.Buffer());
|
439
466
|
// section 12.2.1
|
440
467
|
// within the strict code, Identifier must not be "eval" or "arguments"
|
441
468
|
if (strict_) {
|
@@ -449,7 +476,6 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
449
476
|
}
|
450
477
|
}
|
451
478
|
}
|
452
|
-
Next();
|
453
479
|
|
454
480
|
if (token_ == Token::ASSIGN) {
|
455
481
|
Next();
|
@@ -480,24 +506,23 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
480
506
|
// | IF '(' Expression ')' Statement
|
481
507
|
Statement* ParseIfStatement(bool *res) {
|
482
508
|
assert(token_ == Token::IF);
|
483
|
-
|
484
|
-
Statement* stmt;
|
509
|
+
Statement* else_statement = NULL;
|
485
510
|
Next();
|
486
511
|
|
487
512
|
EXPECT(Token::LPAREN);
|
488
513
|
|
489
|
-
Expression
|
514
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
490
515
|
|
491
516
|
EXPECT(Token::RPAREN);
|
492
517
|
|
493
|
-
|
494
|
-
if_stmt = factory_->NewIfStatement(expr, stmt);
|
518
|
+
Statement* const then_statement = ParseStatement(CHECK);
|
495
519
|
if (token_ == Token::ELSE) {
|
496
520
|
Next();
|
497
|
-
|
498
|
-
if_stmt->SetElse(stmt);
|
521
|
+
else_statement = ParseStatement(CHECK);
|
499
522
|
}
|
500
|
-
return
|
523
|
+
return factory_->NewIfStatement(expr,
|
524
|
+
then_statement,
|
525
|
+
else_statement);
|
501
526
|
}
|
502
527
|
|
503
528
|
// IterationStatement
|
@@ -514,23 +539,22 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
514
539
|
Statement* ParseDoWhileStatement(bool *res) {
|
515
540
|
// DO Statement WHILE '(' Expression ')' ';'
|
516
541
|
assert(token_ == Token::DO);
|
517
|
-
|
518
|
-
Target target(this, dowhile);
|
542
|
+
Target target(this, Target::kIterationStatement);
|
519
543
|
Next();
|
520
544
|
|
521
|
-
Statement
|
522
|
-
dowhile->set_body(stmt);
|
545
|
+
Statement* const stmt = ParseStatement(CHECK);
|
523
546
|
|
524
547
|
EXPECT(Token::WHILE);
|
525
548
|
|
526
549
|
EXPECT(Token::LPAREN);
|
527
550
|
|
528
|
-
Expression
|
529
|
-
dowhile->set_cond(expr);
|
551
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
530
552
|
|
531
553
|
EXPECT(Token::RPAREN);
|
532
554
|
|
533
555
|
ExpectSemicolon(CHECK);
|
556
|
+
DoWhileStatement* const dowhile = factory_->NewDoWhileStatement(stmt, expr);
|
557
|
+
target.set_node(dowhile);
|
534
558
|
return dowhile;
|
535
559
|
}
|
536
560
|
|
@@ -541,15 +565,15 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
541
565
|
|
542
566
|
EXPECT(Token::LPAREN);
|
543
567
|
|
544
|
-
Expression
|
545
|
-
|
546
|
-
Target target(this, whilestmt);
|
568
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
569
|
+
Target target(this, Target::kIterationStatement);
|
547
570
|
|
548
571
|
EXPECT(Token::RPAREN);
|
549
572
|
|
550
|
-
Statement* stmt = ParseStatement(CHECK);
|
551
|
-
whilestmt->
|
573
|
+
Statement* const stmt = ParseStatement(CHECK);
|
574
|
+
WhileStatement* const whilestmt = factory_->NewWhileStatement(stmt, expr);
|
552
575
|
|
576
|
+
target.set_node(whilestmt);
|
553
577
|
return whilestmt;
|
554
578
|
}
|
555
579
|
|
@@ -571,7 +595,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
571
595
|
|
572
596
|
if (token_ != Token::SEMICOLON) {
|
573
597
|
if (token_ == Token::VAR || token_ == Token::CONST) {
|
574
|
-
VariableStatement
|
598
|
+
VariableStatement* const var = factory_->NewVariableStatement(token_);
|
575
599
|
ParseVariableDeclarations(var, false, CHECK);
|
576
600
|
init = var;
|
577
601
|
if (token_ == Token::IN) {
|
@@ -583,17 +607,17 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
583
607
|
// so check declarations' size is 1.
|
584
608
|
RAISE("invalid for-in left-hand-side");
|
585
609
|
}
|
586
|
-
Expression
|
610
|
+
Expression* const enumerable = ParseExpression(true, CHECK);
|
587
611
|
EXPECT(Token::RPAREN);
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
forstmt
|
612
|
+
Target target(this, Target::kIterationStatement);
|
613
|
+
Statement* const body = ParseStatement(CHECK);
|
614
|
+
ForInStatement* const forstmt =
|
615
|
+
factory_->NewForInStatement(body, init, enumerable);
|
616
|
+
target.set_node(forstmt);
|
593
617
|
return forstmt;
|
594
618
|
}
|
595
619
|
} else {
|
596
|
-
Expression
|
620
|
+
Expression* const init_expr = ParseExpression(false, CHECK);
|
597
621
|
init = factory_->NewExpressionStatement(init_expr);
|
598
622
|
if (token_ == Token::IN) {
|
599
623
|
// for in loop
|
@@ -601,13 +625,13 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
601
625
|
RAISE("invalid for-in left-hand-side");
|
602
626
|
}
|
603
627
|
Next();
|
604
|
-
Expression
|
628
|
+
Expression* const enumerable = ParseExpression(true, CHECK);
|
605
629
|
EXPECT(Token::RPAREN);
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
forstmt
|
630
|
+
Target target(this, Target::kIterationStatement);
|
631
|
+
Statement* const body = ParseStatement(CHECK);
|
632
|
+
ForInStatement* const forstmt =
|
633
|
+
factory_->NewForInStatement(body, init, enumerable);
|
634
|
+
target.set_node(forstmt);
|
611
635
|
return forstmt;
|
612
636
|
}
|
613
637
|
}
|
@@ -616,7 +640,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
616
640
|
// ordinary for loop
|
617
641
|
EXPECT(Token::SEMICOLON);
|
618
642
|
|
619
|
-
Expression
|
643
|
+
Expression* cond = NULL;
|
620
644
|
if (token_ == Token::SEMICOLON) {
|
621
645
|
// no cond expr
|
622
646
|
Next();
|
@@ -625,7 +649,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
625
649
|
EXPECT(Token::SEMICOLON);
|
626
650
|
}
|
627
651
|
|
628
|
-
ExpressionStatement
|
652
|
+
ExpressionStatement* next = NULL;
|
629
653
|
if (token_ == Token::RPAREN) {
|
630
654
|
Next();
|
631
655
|
} else {
|
@@ -634,60 +658,47 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
634
658
|
EXPECT(Token::RPAREN);
|
635
659
|
}
|
636
660
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
}
|
644
|
-
if (cond) {
|
645
|
-
for_stmt->SetCondition(cond);
|
646
|
-
}
|
647
|
-
if (next) {
|
648
|
-
for_stmt->SetNext(next);
|
649
|
-
}
|
650
|
-
|
651
|
-
return for_stmt;
|
661
|
+
Target target(this, Target::kIterationStatement);
|
662
|
+
Statement* const body = ParseStatement(CHECK);
|
663
|
+
ForStatement* const forstmt =
|
664
|
+
factory_->NewForStatement(body, init, cond, next);
|
665
|
+
target.set_node(forstmt);
|
666
|
+
return forstmt;
|
652
667
|
}
|
653
668
|
|
654
669
|
// ContinueStatement
|
655
670
|
// : CONTINUE Identifier_opt ';'
|
656
671
|
Statement* ParseContinueStatement(bool *res) {
|
657
672
|
assert(token_ == Token::CONTINUE);
|
658
|
-
|
673
|
+
Identifier* label = NULL;
|
674
|
+
IterationStatement** target;
|
659
675
|
Next();
|
660
676
|
if (!lexer_.has_line_terminator_before_next() &&
|
661
677
|
token_ != Token::SEMICOLON &&
|
662
678
|
token_ != Token::RBRACE &&
|
663
679
|
token_ != Token::EOS) {
|
664
680
|
IS(Token::IDENTIFIER);
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
if (target) {
|
669
|
-
continue_stmt->SetTarget(target);
|
670
|
-
} else {
|
681
|
+
label = ParseIdentifier(lexer_.Buffer());
|
682
|
+
target = LookupContinuableTarget(label);
|
683
|
+
if (!target) {
|
671
684
|
RAISE("label not found");
|
672
685
|
}
|
673
|
-
Next();
|
674
686
|
} else {
|
675
|
-
|
676
|
-
if (target) {
|
677
|
-
continue_stmt->SetTarget(target);
|
678
|
-
} else {
|
687
|
+
target = LookupContinuableTarget();
|
688
|
+
if (!target) {
|
679
689
|
RAISE("label not found");
|
680
690
|
}
|
681
691
|
}
|
682
692
|
ExpectSemicolon(CHECK);
|
683
|
-
return
|
693
|
+
return factory_->NewContinueStatement(label, target);
|
684
694
|
}
|
685
695
|
|
686
696
|
// BreakStatement
|
687
697
|
// : BREAK Identifier_opt ';'
|
688
698
|
Statement* ParseBreakStatement(bool *res) {
|
689
699
|
assert(token_ == Token::BREAK);
|
690
|
-
|
700
|
+
Identifier* label = NULL;
|
701
|
+
BreakableStatement** target = NULL;
|
691
702
|
Next();
|
692
703
|
if (!lexer_.has_line_terminator_before_next() &&
|
693
704
|
token_ != Token::SEMICOLON &&
|
@@ -695,8 +706,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
695
706
|
token_ != Token::EOS) {
|
696
707
|
// label
|
697
708
|
IS(Token::IDENTIFIER);
|
698
|
-
|
699
|
-
break_stmt->SetLabel(label);
|
709
|
+
label = ParseIdentifier(lexer_.Buffer());
|
700
710
|
if (ContainsLabel(labels_, label)) {
|
701
711
|
// example
|
702
712
|
//
|
@@ -708,24 +718,19 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
708
718
|
// In iv, BreakStatement with label, but without target is
|
709
719
|
// interpreted as EmptyStatement
|
710
720
|
} else {
|
711
|
-
|
712
|
-
if (target) {
|
713
|
-
break_stmt->SetTarget(target);
|
714
|
-
} else {
|
721
|
+
target = LookupBreakableTarget(label);
|
722
|
+
if (!target) {
|
715
723
|
RAISE("label not found");
|
716
724
|
}
|
717
725
|
}
|
718
|
-
Next();
|
719
726
|
} else {
|
720
|
-
|
721
|
-
if (target) {
|
722
|
-
break_stmt->SetTarget(target);
|
723
|
-
} else {
|
727
|
+
target = LookupBreakableTarget();
|
728
|
+
if (!target) {
|
724
729
|
RAISE("label not found");
|
725
730
|
}
|
726
731
|
}
|
727
732
|
ExpectSemicolon(CHECK);
|
728
|
-
return
|
733
|
+
return factory_->NewBreakStatement(label, target);
|
729
734
|
}
|
730
735
|
|
731
736
|
// ReturnStatement
|
@@ -782,7 +787,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
782
787
|
|
783
788
|
Expression *expr = ParseExpression(true, CHECK);
|
784
789
|
SwitchStatement *switch_stmt = factory_->NewSwitchStatement(expr);
|
785
|
-
Target target(this,
|
790
|
+
Target target(this, Target::kSwitchStatement);
|
786
791
|
|
787
792
|
EXPECT(Token::RPAREN);
|
788
793
|
|
@@ -794,6 +799,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
794
799
|
}
|
795
800
|
Next();
|
796
801
|
|
802
|
+
target.set_node(switch_stmt);
|
797
803
|
return switch_stmt;
|
798
804
|
}
|
799
805
|
|
@@ -808,16 +814,16 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
808
814
|
// : DEFAULT ':' StatementList_opt
|
809
815
|
CaseClause* ParseCaseClause(bool *res) {
|
810
816
|
assert(token_ == Token::CASE || token_ == Token::DEFAULT);
|
811
|
-
CaseClause
|
812
|
-
Statement
|
817
|
+
CaseClause* clause;
|
818
|
+
Statement* stmt;
|
813
819
|
|
814
820
|
if (token_ == Token::CASE) {
|
815
821
|
Next();
|
816
|
-
Expression
|
817
|
-
clause->
|
822
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
823
|
+
clause = factory_->NewCaseClause(false, expr);
|
818
824
|
} else {
|
819
825
|
EXPECT(Token::DEFAULT);
|
820
|
-
clause->
|
826
|
+
clause = factory_->NewCaseClause(true, NULL);
|
821
827
|
}
|
822
828
|
|
823
829
|
EXPECT(Token::COLON);
|
@@ -836,13 +842,12 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
836
842
|
// : THROW Expression ';'
|
837
843
|
Statement* ParseThrowStatement(bool *res) {
|
838
844
|
assert(token_ == Token::THROW);
|
839
|
-
Expression *expr;
|
840
845
|
Next();
|
841
846
|
// Throw requires Expression
|
842
847
|
if (lexer_.has_line_terminator_before_next()) {
|
843
848
|
RAISE("missing expression between throw and newline");
|
844
849
|
}
|
845
|
-
expr = ParseExpression(true, CHECK);
|
850
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
846
851
|
ExpectSemicolon(CHECK);
|
847
852
|
return factory_->NewThrowStatement(expr);
|
848
853
|
}
|
@@ -859,14 +864,14 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
859
864
|
// : FINALLY Block
|
860
865
|
Statement* ParseTryStatement(bool *res) {
|
861
866
|
assert(token_ == Token::TRY);
|
862
|
-
Identifier
|
863
|
-
Block
|
867
|
+
Identifier* name = NULL;
|
868
|
+
Block* catch_block = NULL;
|
869
|
+
Block* finally_block = NULL;
|
864
870
|
bool has_catch_or_finally = false;
|
865
871
|
|
866
872
|
Next();
|
867
873
|
|
868
|
-
|
869
|
-
TryStatement *try_stmt = factory_->NewTryStatement(block);
|
874
|
+
Block* const try_block = ParseBlock(CHECK);
|
870
875
|
|
871
876
|
if (token_ == Token::CATCH) {
|
872
877
|
// Catch
|
@@ -874,7 +879,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
874
879
|
Next();
|
875
880
|
EXPECT(Token::LPAREN);
|
876
881
|
IS(Token::IDENTIFIER);
|
877
|
-
name =
|
882
|
+
name = ParseIdentifier(lexer_.Buffer());
|
878
883
|
// section 12.14.1
|
879
884
|
// within the strict code, Identifier must not be "eval" or "arguments"
|
880
885
|
if (strict_) {
|
@@ -889,25 +894,23 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
889
894
|
}
|
890
895
|
}
|
891
896
|
}
|
892
|
-
Next();
|
893
897
|
EXPECT(Token::RPAREN);
|
894
|
-
|
895
|
-
try_stmt->SetCatch(name, block);
|
898
|
+
catch_block = ParseBlock(CHECK);
|
896
899
|
}
|
897
900
|
|
898
901
|
if (token_ == Token::FINALLY) {
|
899
902
|
// Finally
|
900
903
|
has_catch_or_finally= true;
|
901
904
|
Next();
|
902
|
-
|
903
|
-
try_stmt->SetFinally(block);
|
905
|
+
finally_block = ParseBlock(CHECK);
|
904
906
|
}
|
905
907
|
|
906
908
|
if (!has_catch_or_finally) {
|
907
909
|
RAISE("missing catch or finally after try statement");
|
908
910
|
}
|
909
911
|
|
910
|
-
return
|
912
|
+
return factory_->NewTryStatement(try_block,
|
913
|
+
name, catch_block, finally_block);
|
911
914
|
}
|
912
915
|
|
913
916
|
// DebuggerStatement
|
@@ -920,7 +923,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
920
923
|
}
|
921
924
|
|
922
925
|
Statement* ParseExpressionStatement(bool *res) {
|
923
|
-
Expression* expr = ParseExpression(true, CHECK);
|
926
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
924
927
|
ExpectSemicolon(CHECK);
|
925
928
|
return factory_->NewExpressionStatement(expr);
|
926
929
|
}
|
@@ -932,7 +935,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
932
935
|
// : Expression ';'
|
933
936
|
Statement* ParseExpressionOrLabelledStatement(bool *res) {
|
934
937
|
assert(token_ == Token::IDENTIFIER);
|
935
|
-
Expression* expr = ParseExpression(true, CHECK);
|
938
|
+
Expression* const expr = ParseExpression(true, CHECK);
|
936
939
|
if (token_ == Token::COLON &&
|
937
940
|
expr->AsIdentifier()) {
|
938
941
|
// LabelledStatement
|
@@ -949,9 +952,9 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
949
952
|
RAISE("duplicate label");
|
950
953
|
}
|
951
954
|
labels->push_back(label);
|
952
|
-
LabelScope scope(this, labels, exist_labels);
|
955
|
+
const LabelScope scope(this, labels, exist_labels);
|
953
956
|
|
954
|
-
Statement* stmt = ParseStatement(CHECK);
|
957
|
+
Statement* const stmt = ParseStatement(CHECK);
|
955
958
|
return factory_->NewLabelledStatement(expr, stmt);
|
956
959
|
}
|
957
960
|
ExpectSemicolon(CHECK);
|
@@ -963,11 +966,10 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
963
966
|
if (strict_) {
|
964
967
|
RAISE("function statement not allowed in strict code");
|
965
968
|
}
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
true, CHECK);
|
969
|
+
FunctionLiteral* const expr = ParseFunctionLiteral(
|
970
|
+
FunctionLiteral::STATEMENT,
|
971
|
+
FunctionLiteral::GENERAL,
|
972
|
+
CHECK);
|
971
973
|
// define named function as variable declaration
|
972
974
|
scope_->AddUnresolved(expr->name(), false);
|
973
975
|
return factory_->NewFunctionStatement(expr);
|
@@ -977,8 +979,8 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
977
979
|
// : AssignmentExpression
|
978
980
|
// | Expression ',' AssignmentExpression
|
979
981
|
Expression* ParseExpression(bool contains_in, bool *res) {
|
980
|
-
Expression
|
981
|
-
Expression
|
982
|
+
Expression* right;
|
983
|
+
Expression* result = ParseAssignmentExpression(contains_in, CHECK);
|
982
984
|
while (token_ == Token::COMMA) {
|
983
985
|
Next();
|
984
986
|
right = ParseAssignmentExpression(contains_in, CHECK);
|
@@ -991,7 +993,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
991
993
|
// : ConditionalExpression
|
992
994
|
// | LeftHandSideExpression AssignmentOperator AssignmentExpression
|
993
995
|
Expression* ParseAssignmentExpression(bool contains_in, bool *res) {
|
994
|
-
Expression
|
996
|
+
Expression* const result = ParseConditionalExpression(contains_in, CHECK);
|
995
997
|
if (!Token::IsAssignOp(token_)) {
|
996
998
|
return result;
|
997
999
|
}
|
@@ -1013,7 +1015,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1013
1015
|
}
|
1014
1016
|
const Token::Type op = token_;
|
1015
1017
|
Next();
|
1016
|
-
Expression
|
1018
|
+
Expression* const right = ParseAssignmentExpression(contains_in, CHECK);
|
1017
1019
|
return factory_->NewAssignment(op, result, right);
|
1018
1020
|
}
|
1019
1021
|
|
@@ -1021,14 +1023,13 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1021
1023
|
// : LogicalOrExpression
|
1022
1024
|
// | LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
|
1023
1025
|
Expression* ParseConditionalExpression(bool contains_in, bool *res) {
|
1024
|
-
Expression
|
1025
|
-
result = ParseBinaryExpression(contains_in, 9, CHECK);
|
1026
|
+
Expression* result = ParseBinaryExpression(contains_in, 9, CHECK);
|
1026
1027
|
if (token_ == Token::CONDITIONAL) {
|
1027
1028
|
Next();
|
1028
1029
|
// see ECMA-262 section 11.12
|
1029
|
-
Expression
|
1030
|
+
Expression* const left = ParseAssignmentExpression(true, CHECK);
|
1030
1031
|
EXPECT(Token::COLON);
|
1031
|
-
Expression
|
1032
|
+
Expression* const right = ParseAssignmentExpression(contains_in, CHECK);
|
1032
1033
|
result = factory_->NewConditionalExpression(result, left, right);
|
1033
1034
|
}
|
1034
1035
|
return result;
|
@@ -1369,8 +1370,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1369
1370
|
// | LeftHandSideExpression INCREMENT
|
1370
1371
|
// | LeftHandSideExpression DECREMENT
|
1371
1372
|
Expression* ParsePostfixExpression(bool *res) {
|
1372
|
-
Expression
|
1373
|
-
expr = ParseMemberExpression(true, CHECK);
|
1373
|
+
Expression* expr = ParseMemberExpression(true, CHECK);
|
1374
1374
|
if (!lexer_.has_line_terminator_before_next() &&
|
1375
1375
|
(token_ == Token::INC || token_ == Token::DEC)) {
|
1376
1376
|
if (!expr->IsValidLeftHandSide()) {
|
@@ -1414,9 +1414,8 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1414
1414
|
if (token_ != Token::NEW) {
|
1415
1415
|
if (token_ == Token::FUNCTION) {
|
1416
1416
|
// FunctionExpression
|
1417
|
-
Next();
|
1418
1417
|
expr = ParseFunctionLiteral(FunctionLiteral::EXPRESSION,
|
1419
|
-
FunctionLiteral::GENERAL,
|
1418
|
+
FunctionLiteral::GENERAL, CHECK);
|
1420
1419
|
} else {
|
1421
1420
|
expr = ParsePrimaryExpression(CHECK);
|
1422
1421
|
}
|
@@ -1429,7 +1428,6 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1429
1428
|
}
|
1430
1429
|
expr = con;
|
1431
1430
|
}
|
1432
|
-
FunctionCall *funcall;
|
1433
1431
|
while (true) {
|
1434
1432
|
switch (token_) {
|
1435
1433
|
case Token::LBRACK: {
|
@@ -1443,15 +1441,14 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1443
1441
|
case Token::PERIOD: {
|
1444
1442
|
Next(Lexer::kIgnoreReservedWords); // IDENTIFIERNAME
|
1445
1443
|
IS(Token::IDENTIFIER);
|
1446
|
-
Identifier* ident =
|
1447
|
-
Next();
|
1444
|
+
Identifier* const ident = ParseIdentifier(lexer_.Buffer());
|
1448
1445
|
expr = factory_->NewIdentifierAccess(expr, ident);
|
1449
1446
|
break;
|
1450
1447
|
}
|
1451
1448
|
|
1452
1449
|
case Token::LPAREN:
|
1453
1450
|
if (allow_call) {
|
1454
|
-
funcall = factory_->NewFunctionCall(expr);
|
1451
|
+
FunctionCall* const funcall = factory_->NewFunctionCall(expr);
|
1455
1452
|
ParseArguments(funcall, CHECK);
|
1456
1453
|
expr = funcall;
|
1457
1454
|
} else {
|
@@ -1481,7 +1478,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1481
1478
|
// | STRING
|
1482
1479
|
// | REGEXP
|
1483
1480
|
Expression* ParsePrimaryExpression(bool *res) {
|
1484
|
-
Expression
|
1481
|
+
Expression* result = NULL;
|
1485
1482
|
switch (token_) {
|
1486
1483
|
case Token::THIS:
|
1487
1484
|
result = factory_->NewThisLiteral();
|
@@ -1489,8 +1486,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1489
1486
|
break;
|
1490
1487
|
|
1491
1488
|
case Token::IDENTIFIER:
|
1492
|
-
result =
|
1493
|
-
Next();
|
1489
|
+
result = ParseIdentifier(lexer_.Buffer());
|
1494
1490
|
break;
|
1495
1491
|
|
1496
1492
|
case Token::NULL_LITERAL:
|
@@ -1569,7 +1565,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1569
1565
|
// : AssignmentExpression
|
1570
1566
|
// | ArgumentList ',' AssignmentExpression
|
1571
1567
|
Call* ParseArguments(Call* func, bool *res) {
|
1572
|
-
Expression
|
1568
|
+
Expression* expr;
|
1573
1569
|
Next();
|
1574
1570
|
while (token_ != Token::RPAREN) {
|
1575
1571
|
expr = ParseAssignmentExpression(true, CHECK);
|
@@ -1614,8 +1610,8 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1614
1610
|
// : ','
|
1615
1611
|
// | Elision ','
|
1616
1612
|
Expression* ParseArrayLiteral(bool *res) {
|
1617
|
-
ArrayLiteral
|
1618
|
-
Expression
|
1613
|
+
ArrayLiteral* const array = factory_->NewArrayLiteral();
|
1614
|
+
Expression* expr;
|
1619
1615
|
Next();
|
1620
1616
|
while (token_ != Token::RBRACK) {
|
1621
1617
|
if (token_ == Token::COMMA) {
|
@@ -1660,10 +1656,10 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1660
1656
|
// : IDENTIFIER
|
1661
1657
|
Expression* ParseObjectLiteral(bool *res) {
|
1662
1658
|
typedef std::tr1::unordered_map<IdentifierKey, int> ObjectMap;
|
1663
|
-
ObjectLiteral
|
1659
|
+
ObjectLiteral* const object = factory_->NewObjectLiteral();
|
1664
1660
|
ObjectMap map;
|
1665
|
-
Expression
|
1666
|
-
Identifier
|
1661
|
+
Expression* expr;
|
1662
|
+
Identifier* ident;
|
1667
1663
|
|
1668
1664
|
// IDENTIFIERNAME
|
1669
1665
|
Next(Lexer::kIgnoreReservedWordsAndIdentifyGetterOrSetter);
|
@@ -1674,9 +1670,8 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1674
1670
|
Next(Lexer::kIgnoreReservedWords); // IDENTIFIERNAME
|
1675
1671
|
if (token_ == Token::COLON) {
|
1676
1672
|
// property
|
1677
|
-
ident =
|
1673
|
+
ident = ParseIdentifier(
|
1678
1674
|
is_get ? ParserData::kGet : ParserData::kSet);
|
1679
|
-
Next();
|
1680
1675
|
expr = ParseAssignmentExpression(true, CHECK);
|
1681
1676
|
object->AddDataProperty(ident, expr);
|
1682
1677
|
typename ObjectMap::iterator it = map.find(ident);
|
@@ -1699,17 +1694,16 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1699
1694
|
token_ == Token::STRING ||
|
1700
1695
|
token_ == Token::NUMBER) {
|
1701
1696
|
if (token_ == Token::NUMBER) {
|
1702
|
-
ident =
|
1697
|
+
ident = ParseIdentifier(lexer_.Buffer8());
|
1703
1698
|
} else {
|
1704
|
-
ident =
|
1699
|
+
ident = ParseIdentifier(lexer_.Buffer());
|
1705
1700
|
}
|
1706
|
-
Next();
|
1707
1701
|
typename ObjectLiteral::PropertyDescriptorType type =
|
1708
1702
|
(is_get) ? ObjectLiteral::GET : ObjectLiteral::SET;
|
1709
1703
|
expr = ParseFunctionLiteral(
|
1710
1704
|
FunctionLiteral::EXPRESSION,
|
1711
1705
|
(is_get) ? FunctionLiteral::GETTER : FunctionLiteral::SETTER,
|
1712
|
-
|
1706
|
+
CHECK);
|
1713
1707
|
object->AddAccessor(type, ident, expr);
|
1714
1708
|
typename ObjectMap::iterator it = map.find(ident);
|
1715
1709
|
if (it == map.end()) {
|
@@ -1732,8 +1726,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1732
1726
|
} else if (token_ == Token::IDENTIFIER ||
|
1733
1727
|
token_ == Token::STRING ||
|
1734
1728
|
token_ == Token::NUMBER) {
|
1735
|
-
ident =
|
1736
|
-
Next();
|
1729
|
+
ident = ParseIdentifier(lexer_.Buffer());
|
1737
1730
|
EXPECT(Token::COLON);
|
1738
1731
|
expr = ParseAssignmentExpression(true, CHECK);
|
1739
1732
|
object->AddDataProperty(ident, expr);
|
@@ -1768,7 +1761,6 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1768
1761
|
FunctionLiteral* ParseFunctionLiteral(
|
1769
1762
|
typename FunctionLiteral::DeclType decl_type,
|
1770
1763
|
typename FunctionLiteral::ArgType arg_type,
|
1771
|
-
bool allow_identifier,
|
1772
1764
|
bool *res) {
|
1773
1765
|
// IDENTIFIER
|
1774
1766
|
// IDENTIFIER_opt
|
@@ -1783,19 +1775,27 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1783
1775
|
kDetectDuplicateParameter
|
1784
1776
|
} throw_error_if_strict_code = kDetectNone;
|
1785
1777
|
|
1786
|
-
FunctionLiteral
|
1778
|
+
FunctionLiteral* const literal = factory_->NewFunctionLiteral(decl_type);
|
1787
1779
|
literal->set_strict(strict_);
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
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
|
-
}
|
1780
|
+
|
1781
|
+
if (arg_type == FunctionLiteral::GENERAL) {
|
1782
|
+
assert(token_ == Token::FUNCTION);
|
1797
1783
|
Next();
|
1784
|
+
if (token_ == Token::IDENTIFIER) {
|
1785
|
+
Identifier* const name = ParseIdentifier(lexer_.Buffer());
|
1786
|
+
literal->SetName(name);
|
1787
|
+
const EvalOrArguments val = IsEvalOrArguments(name);
|
1788
|
+
if (val) {
|
1789
|
+
throw_error_if_strict_code = (val == kEval) ?
|
1790
|
+
kDetectEvalName : kDetectArgumentsName;
|
1791
|
+
throw_error_if_strict_code_line = lexer_.line_number();
|
1792
|
+
}
|
1793
|
+
} else if (decl_type == FunctionLiteral::DECLARATION ||
|
1794
|
+
decl_type == FunctionLiteral::STATEMENT) {
|
1795
|
+
IS(Token::IDENTIFIER);
|
1796
|
+
}
|
1798
1797
|
}
|
1798
|
+
|
1799
1799
|
const ScopeSwitcher switcher(this, literal->scope());
|
1800
1800
|
literal->set_start_position(lexer_.pos() - 2);
|
1801
1801
|
|
@@ -1808,7 +1808,7 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1808
1808
|
} else if (arg_type == FunctionLiteral::SETTER) {
|
1809
1809
|
// if setter, parameter count is 1
|
1810
1810
|
IS(Token::IDENTIFIER);
|
1811
|
-
Identifier* const ident =
|
1811
|
+
Identifier* const ident = ParseIdentifier(lexer_.Buffer());
|
1812
1812
|
if (!throw_error_if_strict_code) {
|
1813
1813
|
const EvalOrArguments val = IsEvalOrArguments(ident);
|
1814
1814
|
if (val) {
|
@@ -1818,12 +1818,11 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1818
1818
|
}
|
1819
1819
|
}
|
1820
1820
|
literal->AddParameter(ident);
|
1821
|
-
Next();
|
1822
1821
|
EXPECT(Token::RPAREN);
|
1823
1822
|
} else {
|
1824
1823
|
while (token_ != Token::RPAREN) {
|
1825
1824
|
IS(Token::IDENTIFIER);
|
1826
|
-
Identifier* const ident =
|
1825
|
+
Identifier* const ident = ParseIdentifier(lexer_.Buffer());
|
1827
1826
|
if (!throw_error_if_strict_code) {
|
1828
1827
|
const EvalOrArguments val = IsEvalOrArguments(ident);
|
1829
1828
|
if (val) {
|
@@ -1839,7 +1838,6 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1839
1838
|
}
|
1840
1839
|
literal->AddParameter(ident);
|
1841
1840
|
param_set.insert(ident);
|
1842
|
-
Next();
|
1843
1841
|
if (token_ != Token::RPAREN) {
|
1844
1842
|
EXPECT(Token::COMMA);
|
1845
1843
|
}
|
@@ -1894,11 +1892,18 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1894
1892
|
return literal;
|
1895
1893
|
}
|
1896
1894
|
|
1895
|
+
template<typename Range>
|
1896
|
+
Identifier* ParseIdentifier(const Range& range) {
|
1897
|
+
Identifier* const ident = factory_->NewIdentifier(range);
|
1898
|
+
Next();
|
1899
|
+
return ident;
|
1900
|
+
}
|
1901
|
+
|
1897
1902
|
bool ContainsLabel(const Identifiers* const labels,
|
1898
1903
|
const Identifier * const label) const {
|
1899
1904
|
assert(label != NULL);
|
1900
1905
|
if (labels) {
|
1901
|
-
const
|
1906
|
+
const typename Identifier::value_type& value = label->value();
|
1902
1907
|
for (typename Identifiers::const_iterator it = labels->begin(),
|
1903
1908
|
last = labels->end();
|
1904
1909
|
it != last; ++it) {
|
@@ -1912,61 +1917,59 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
1912
1917
|
|
1913
1918
|
bool TargetsContainsLabel(const Identifier* const label) const {
|
1914
1919
|
assert(label != NULL);
|
1915
|
-
for (Target* target = target_;
|
1920
|
+
for (const Target* target = target_;
|
1916
1921
|
target != NULL;
|
1917
1922
|
target = target->previous()) {
|
1918
|
-
if (ContainsLabel(target->
|
1923
|
+
if (ContainsLabel(target->labels(), label)) {
|
1919
1924
|
return true;
|
1920
1925
|
}
|
1921
1926
|
}
|
1922
1927
|
return false;
|
1923
1928
|
}
|
1924
1929
|
|
1925
|
-
BreakableStatement
|
1930
|
+
BreakableStatement** LookupBreakableTarget(
|
1926
1931
|
const Identifier* const label) const {
|
1927
1932
|
assert(label != NULL);
|
1928
|
-
for (
|
1933
|
+
for (Target* target = target_;
|
1929
1934
|
target != NULL;
|
1930
1935
|
target = target->previous()) {
|
1931
|
-
if (ContainsLabel(target->
|
1936
|
+
if (ContainsLabel(target->labels(), label)) {
|
1932
1937
|
return target->node();
|
1933
1938
|
}
|
1934
1939
|
}
|
1935
1940
|
return NULL;
|
1936
1941
|
}
|
1937
1942
|
|
1938
|
-
BreakableStatement
|
1939
|
-
for (
|
1943
|
+
BreakableStatement** LookupBreakableTarget() const {
|
1944
|
+
for (Target* target = target_;
|
1940
1945
|
target != NULL;
|
1941
1946
|
target = target->previous()) {
|
1942
|
-
if (target->
|
1947
|
+
if (target->IsAnonymous()) {
|
1943
1948
|
return target->node();
|
1944
1949
|
}
|
1945
1950
|
}
|
1946
1951
|
return NULL;
|
1947
1952
|
}
|
1948
1953
|
|
1949
|
-
IterationStatement
|
1954
|
+
IterationStatement** LookupContinuableTarget(
|
1950
1955
|
const Identifier* const label) const {
|
1951
1956
|
assert(label != NULL);
|
1952
|
-
for (
|
1957
|
+
for (Target* target = target_;
|
1953
1958
|
target != NULL;
|
1954
1959
|
target = target->previous()) {
|
1955
|
-
|
1956
|
-
|
1957
|
-
return iter;
|
1960
|
+
if (target->IsIteration() && ContainsLabel(target->labels(), label)) {
|
1961
|
+
return reinterpret_cast<IterationStatement**>(target->node());
|
1958
1962
|
}
|
1959
1963
|
}
|
1960
1964
|
return NULL;
|
1961
1965
|
}
|
1962
1966
|
|
1963
|
-
IterationStatement
|
1964
|
-
for (
|
1967
|
+
IterationStatement** LookupContinuableTarget() const {
|
1968
|
+
for (Target* target = target_;
|
1965
1969
|
target != NULL;
|
1966
1970
|
target = target->previous()) {
|
1967
|
-
|
1968
|
-
|
1969
|
-
return iter;
|
1971
|
+
if (target->IsIteration()) {
|
1972
|
+
return reinterpret_cast<IterationStatement**>(target->node());
|
1970
1973
|
}
|
1971
1974
|
}
|
1972
1975
|
return NULL;
|
@@ -2050,6 +2053,9 @@ class Parser : private Noncopyable<Parser<Factory> >::type {
|
|
2050
2053
|
inline void set_target(Target* target) {
|
2051
2054
|
target_ = target;
|
2052
2055
|
}
|
2056
|
+
inline Factory* factory() const {
|
2057
|
+
return factory_;
|
2058
|
+
}
|
2053
2059
|
inline Identifiers* labels() const {
|
2054
2060
|
return labels_;
|
2055
2061
|
}
|