iv-phonic 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/include/iv/ast.h +27 -39
- data/ext/include/iv/ast_factory.h +148 -51
- data/ext/include/iv/ast_fwd.h +8 -4
- data/ext/include/iv/ast_serializer.h +9 -0
- data/ext/include/iv/ast_visitor.h +3 -0
- data/ext/include/iv/lexer.h +37 -4
- data/ext/include/iv/parser.h +219 -109
- data/ext/iv/phonic/ast_fwd.h +6 -0
- data/ext/iv/phonic/creator.h +83 -24
- data/ext/iv/phonic/factory.h +258 -104
- data/test/test_iv_phonic.rb +8 -1
- metadata +2 -2
data/ext/include/iv/parser.h
CHANGED
@@ -218,16 +218,16 @@ class Parser
|
|
218
218
|
int type_;
|
219
219
|
};
|
220
220
|
|
221
|
-
class
|
221
|
+
class TargetSwitcher : private Noncopyable<TargetSwitcher>::type {
|
222
222
|
public:
|
223
|
-
explicit
|
223
|
+
explicit TargetSwitcher(parser_type* parser)
|
224
224
|
: parser_(parser),
|
225
225
|
target_(parser->target()),
|
226
226
|
labels_(parser->labels()) {
|
227
227
|
parser_->set_target(NULL);
|
228
228
|
parser_->set_labels(NULL);
|
229
229
|
}
|
230
|
-
~
|
230
|
+
~TargetSwitcher() {
|
231
231
|
parser_->set_target(target_);
|
232
232
|
parser_->set_labels(labels_);
|
233
233
|
}
|
@@ -237,12 +237,12 @@ class Parser
|
|
237
237
|
Identifiers* labels_;
|
238
238
|
};
|
239
239
|
|
240
|
-
Parser(Factory*
|
240
|
+
Parser(Factory* factory, const Source* source)
|
241
241
|
: lexer_(source),
|
242
242
|
error_(),
|
243
243
|
strict_(false),
|
244
244
|
error_state_(0),
|
245
|
-
factory_(
|
245
|
+
factory_(factory),
|
246
246
|
scope_(NULL),
|
247
247
|
target_(NULL),
|
248
248
|
labels_(NULL) {
|
@@ -251,18 +251,27 @@ class Parser
|
|
251
251
|
// Program
|
252
252
|
// : SourceElements
|
253
253
|
FunctionLiteral* ParseProgram() {
|
254
|
-
|
255
|
-
|
256
|
-
|
254
|
+
Identifiers* params = factory_->template NewVector<Identifier*>();
|
255
|
+
Statements* body = factory_->template NewVector<Statement*>();
|
256
|
+
Scope* const scope = factory_->NewScope(FunctionLiteral::GLOBAL);
|
257
257
|
assert(target_ == NULL);
|
258
258
|
bool error_flag = true;
|
259
259
|
bool *res = &error_flag;
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
260
|
+
const ScopeSwitcher scope_switcher(this, scope);
|
261
|
+
Next();
|
262
|
+
const bool strict = ParseSourceElements(Token::EOS, body, CHECK);
|
263
|
+
const std::size_t end_position = lexer_.end_position();
|
264
|
+
return (error_flag) ?
|
265
|
+
factory_->NewFunctionLiteral(FunctionLiteral::GLOBAL,
|
266
|
+
NULL,
|
267
|
+
params,
|
268
|
+
body,
|
269
|
+
scope,
|
270
|
+
strict,
|
271
|
+
0,
|
272
|
+
end_position,
|
273
|
+
0,
|
274
|
+
end_position) : NULL;
|
266
275
|
}
|
267
276
|
|
268
277
|
// SourceElements
|
@@ -273,16 +282,16 @@ class Parser
|
|
273
282
|
// : Statements
|
274
283
|
// | FunctionDeclaration
|
275
284
|
bool ParseSourceElements(Token::Type end,
|
276
|
-
|
285
|
+
Statements* body,
|
277
286
|
bool *res) {
|
278
287
|
Statement* stmt;
|
279
288
|
bool recognize_directive = true;
|
280
|
-
const StrictSwitcher
|
289
|
+
const StrictSwitcher strict_switcher(this);
|
281
290
|
while (token_ != end) {
|
282
291
|
if (token_ == Token::FUNCTION) {
|
283
292
|
// FunctionDeclaration
|
284
293
|
stmt = ParseFunctionDeclaration(CHECK);
|
285
|
-
|
294
|
+
body->push_back(stmt);
|
286
295
|
recognize_directive = false;
|
287
296
|
} else {
|
288
297
|
stmt = ParseStatement(CHECK);
|
@@ -294,8 +303,7 @@ class Parser
|
|
294
303
|
// expression is directive
|
295
304
|
if (expr->AsStringLiteral()->value().compare(
|
296
305
|
ParserData::kUseStrict.data()) == 0) {
|
297
|
-
|
298
|
-
function->set_strict(true);
|
306
|
+
strict_switcher.SwitchStrictMode();
|
299
307
|
}
|
300
308
|
} else {
|
301
309
|
recognize_directive = false;
|
@@ -304,10 +312,10 @@ class Parser
|
|
304
312
|
recognize_directive = false;
|
305
313
|
}
|
306
314
|
}
|
307
|
-
|
315
|
+
body->push_back(stmt);
|
308
316
|
}
|
309
317
|
}
|
310
|
-
return
|
318
|
+
return strict_switcher.IsStrict();
|
311
319
|
}
|
312
320
|
|
313
321
|
// Statement
|
@@ -466,17 +474,19 @@ class Parser
|
|
466
474
|
// | StatementList Statement
|
467
475
|
Block* ParseBlock(bool *res) {
|
468
476
|
assert(token_ == Token::LBRACE);
|
477
|
+
const std::size_t begin = lexer_.begin_position();
|
469
478
|
Statements* const body = factory_->template NewVector<Statement*>();
|
470
|
-
Statement* stmt;
|
471
479
|
Target target(this, Target::kNamedOnlyStatement);
|
472
480
|
|
473
481
|
Next();
|
474
482
|
while (token_ != Token::RBRACE) {
|
475
|
-
stmt = ParseStatement(CHECK);
|
483
|
+
Statement* const stmt = ParseStatement(CHECK);
|
476
484
|
body->push_back(stmt);
|
477
485
|
}
|
478
486
|
Next();
|
479
|
-
Block* const block = factory_->NewBlock(body
|
487
|
+
Block* const block = factory_->NewBlock(body,
|
488
|
+
begin,
|
489
|
+
lexer_.previous_end_position());
|
480
490
|
target.set_node(block);
|
481
491
|
return block;
|
482
492
|
}
|
@@ -486,10 +496,15 @@ class Parser
|
|
486
496
|
// : CONST VariableDeclarationList ';'
|
487
497
|
Statement* ParseVariableStatement(bool *res) {
|
488
498
|
assert(token_ == Token::VAR || token_ == Token::CONST);
|
499
|
+
const Token::Type op = token_;
|
500
|
+
const std::size_t begin = lexer_.begin_position();
|
489
501
|
Declarations* const decls = factory_->template NewVector<Declaration*>();
|
490
502
|
ParseVariableDeclarations(decls, token_ == Token::CONST, true, CHECK);
|
491
503
|
ExpectSemicolon(CHECK);
|
492
|
-
return factory_->NewVariableStatement(
|
504
|
+
return factory_->NewVariableStatement(op,
|
505
|
+
decls,
|
506
|
+
begin,
|
507
|
+
lexer_.previous_end_position());
|
493
508
|
}
|
494
509
|
|
495
510
|
// VariableDeclarationList
|
@@ -552,7 +567,8 @@ class Parser
|
|
552
567
|
Statement* ParseEmptyStatement() {
|
553
568
|
assert(token_ == Token::SEMICOLON);
|
554
569
|
Next();
|
555
|
-
return factory_->NewEmptyStatement()
|
570
|
+
return factory_->NewEmptyStatement(lexer_.previous_begin_position(),
|
571
|
+
lexer_.previous_end_position());
|
556
572
|
}
|
557
573
|
|
558
574
|
// IfStatement
|
@@ -560,6 +576,7 @@ class Parser
|
|
560
576
|
// | IF '(' Expression ')' Statement
|
561
577
|
Statement* ParseIfStatement(bool *res) {
|
562
578
|
assert(token_ == Token::IF);
|
579
|
+
const std::size_t begin = lexer_.begin_position();
|
563
580
|
Statement* else_statement = NULL;
|
564
581
|
Next();
|
565
582
|
|
@@ -576,7 +593,8 @@ class Parser
|
|
576
593
|
}
|
577
594
|
return factory_->NewIfStatement(expr,
|
578
595
|
then_statement,
|
579
|
-
else_statement
|
596
|
+
else_statement,
|
597
|
+
begin);
|
580
598
|
}
|
581
599
|
|
582
600
|
// IterationStatement
|
@@ -593,6 +611,7 @@ class Parser
|
|
593
611
|
Statement* ParseDoWhileStatement(bool *res) {
|
594
612
|
// DO Statement WHILE '(' Expression ')' ';'
|
595
613
|
assert(token_ == Token::DO);
|
614
|
+
const std::size_t begin = lexer_.begin_position();
|
596
615
|
Target target(this, Target::kIterationStatement);
|
597
616
|
Next();
|
598
617
|
|
@@ -614,7 +633,8 @@ class Parser
|
|
614
633
|
if (token_ == Token::SEMICOLON) {
|
615
634
|
Next();
|
616
635
|
}
|
617
|
-
DoWhileStatement* const dowhile = factory_->NewDoWhileStatement(
|
636
|
+
DoWhileStatement* const dowhile = factory_->NewDoWhileStatement(
|
637
|
+
stmt, expr, begin, lexer_.previous_end_position());
|
618
638
|
target.set_node(dowhile);
|
619
639
|
return dowhile;
|
620
640
|
}
|
@@ -622,6 +642,7 @@ class Parser
|
|
622
642
|
// WHILE '(' Expression ')' Statement
|
623
643
|
Statement* ParseWhileStatement(bool *res) {
|
624
644
|
assert(token_ == Token::WHILE);
|
645
|
+
const std::size_t begin = lexer_.begin_position();
|
625
646
|
Next();
|
626
647
|
|
627
648
|
EXPECT(Token::LPAREN);
|
@@ -632,7 +653,8 @@ class Parser
|
|
632
653
|
EXPECT(Token::RPAREN);
|
633
654
|
|
634
655
|
Statement* const stmt = ParseStatement(CHECK);
|
635
|
-
WhileStatement* const whilestmt = factory_->NewWhileStatement(stmt,
|
656
|
+
WhileStatement* const whilestmt = factory_->NewWhileStatement(stmt,
|
657
|
+
expr, begin);
|
636
658
|
|
637
659
|
target.set_node(whilestmt);
|
638
660
|
return whilestmt;
|
@@ -648,6 +670,7 @@ class Parser
|
|
648
670
|
// FOR '(' VAR VariableDeclarationNoIn IN Expression ')' Statement
|
649
671
|
Statement* ParseForStatement(bool *res) {
|
650
672
|
assert(token_ == Token::FOR);
|
673
|
+
const std::size_t for_stmt_begin = lexer_.begin_position();
|
651
674
|
Next();
|
652
675
|
|
653
676
|
EXPECT(Token::LPAREN);
|
@@ -656,13 +679,18 @@ class Parser
|
|
656
679
|
|
657
680
|
if (token_ != Token::SEMICOLON) {
|
658
681
|
if (token_ == Token::VAR || token_ == Token::CONST) {
|
682
|
+
const std::size_t begin = lexer_.begin_position();
|
683
|
+
const Token::Type op = token_;
|
659
684
|
Declarations* const decls =
|
660
685
|
factory_->template NewVector<Declaration*>();
|
661
686
|
ParseVariableDeclarations(decls, token_ == Token::CONST, false, CHECK);
|
662
|
-
VariableStatement* const var =
|
663
|
-
factory_->NewVariableStatement(token_, decls);
|
664
|
-
init = var;
|
665
687
|
if (token_ == Token::IN) {
|
688
|
+
VariableStatement* const var =
|
689
|
+
factory_->NewVariableStatement(op,
|
690
|
+
decls,
|
691
|
+
begin,
|
692
|
+
lexer_.previous_end_position());
|
693
|
+
init = var;
|
666
694
|
// for in loop
|
667
695
|
Next();
|
668
696
|
const Declarations& decls = var->decls();
|
@@ -676,15 +704,21 @@ class Parser
|
|
676
704
|
Target target(this, Target::kIterationStatement);
|
677
705
|
Statement* const body = ParseStatement(CHECK);
|
678
706
|
ForInStatement* const forstmt =
|
679
|
-
factory_->NewForInStatement(body, init, enumerable
|
707
|
+
factory_->NewForInStatement(body, init, enumerable,
|
708
|
+
for_stmt_begin);
|
680
709
|
target.set_node(forstmt);
|
681
710
|
return forstmt;
|
711
|
+
} else {
|
712
|
+
init = factory_->NewVariableStatement(op, decls,
|
713
|
+
begin,
|
714
|
+
lexer_.end_position());
|
682
715
|
}
|
683
716
|
} else {
|
684
717
|
Expression* const init_expr = ParseExpression(false, CHECK);
|
685
|
-
init = factory_->NewExpressionStatement(init_expr);
|
686
718
|
if (token_ == Token::IN) {
|
687
719
|
// for in loop
|
720
|
+
init = factory_->NewExpressionStatement(init_expr,
|
721
|
+
lexer_.previous_end_position());
|
688
722
|
if (!init_expr->IsValidLeftHandSide()) {
|
689
723
|
RAISE("invalid for-in left-hand-side");
|
690
724
|
}
|
@@ -694,9 +728,13 @@ class Parser
|
|
694
728
|
Target target(this, Target::kIterationStatement);
|
695
729
|
Statement* const body = ParseStatement(CHECK);
|
696
730
|
ForInStatement* const forstmt =
|
697
|
-
factory_->NewForInStatement(body, init, enumerable
|
731
|
+
factory_->NewForInStatement(body, init, enumerable,
|
732
|
+
for_stmt_begin);
|
698
733
|
target.set_node(forstmt);
|
699
734
|
return forstmt;
|
735
|
+
} else {
|
736
|
+
init = factory_->NewExpressionStatement(init_expr,
|
737
|
+
lexer_.end_position());
|
700
738
|
}
|
701
739
|
}
|
702
740
|
}
|
@@ -717,15 +755,16 @@ class Parser
|
|
717
755
|
if (token_ == Token::RPAREN) {
|
718
756
|
Next();
|
719
757
|
} else {
|
720
|
-
Expression
|
721
|
-
next = factory_->NewExpressionStatement(next_expr
|
758
|
+
Expression* next_expr = ParseExpression(true, CHECK);
|
759
|
+
next = factory_->NewExpressionStatement(next_expr,
|
760
|
+
lexer_.previous_end_position());
|
722
761
|
EXPECT(Token::RPAREN);
|
723
762
|
}
|
724
763
|
|
725
764
|
Target target(this, Target::kIterationStatement);
|
726
765
|
Statement* const body = ParseStatement(CHECK);
|
727
766
|
ForStatement* const forstmt =
|
728
|
-
factory_->NewForStatement(body, init, cond, next);
|
767
|
+
factory_->NewForStatement(body, init, cond, next, for_stmt_begin);
|
729
768
|
target.set_node(forstmt);
|
730
769
|
return forstmt;
|
731
770
|
}
|
@@ -734,6 +773,7 @@ class Parser
|
|
734
773
|
// : CONTINUE Identifier_opt ';'
|
735
774
|
Statement* ParseContinueStatement(bool *res) {
|
736
775
|
assert(token_ == Token::CONTINUE);
|
776
|
+
const std::size_t begin = lexer_.begin_position();
|
737
777
|
Identifier* label = NULL;
|
738
778
|
IterationStatement** target;
|
739
779
|
Next();
|
@@ -754,13 +794,15 @@ class Parser
|
|
754
794
|
}
|
755
795
|
}
|
756
796
|
ExpectSemicolon(CHECK);
|
757
|
-
return factory_->NewContinueStatement(label, target
|
797
|
+
return factory_->NewContinueStatement(label, target, begin,
|
798
|
+
lexer_.previous_end_position());
|
758
799
|
}
|
759
800
|
|
760
801
|
// BreakStatement
|
761
802
|
// : BREAK Identifier_opt ';'
|
762
803
|
Statement* ParseBreakStatement(bool *res) {
|
763
804
|
assert(token_ == Token::BREAK);
|
805
|
+
const std::size_t begin = lexer_.begin_position();
|
764
806
|
Identifier* label = NULL;
|
765
807
|
BreakableStatement** target = NULL;
|
766
808
|
Next();
|
@@ -794,13 +836,16 @@ class Parser
|
|
794
836
|
}
|
795
837
|
}
|
796
838
|
ExpectSemicolon(CHECK);
|
797
|
-
return factory_->NewBreakStatement(label, target
|
839
|
+
return factory_->NewBreakStatement(label, target, begin,
|
840
|
+
lexer_.previous_end_position());
|
798
841
|
}
|
799
842
|
|
800
843
|
// ReturnStatement
|
801
844
|
// : RETURN Expression_opt ';'
|
802
845
|
Statement* ParseReturnStatement(bool *res) {
|
846
|
+
// TODO(Constellation) NewUndefined -> NULL
|
803
847
|
assert(token_ == Token::RETURN);
|
848
|
+
const std::size_t begin = lexer_.begin_position();
|
804
849
|
Next();
|
805
850
|
|
806
851
|
if (scope_->IsGlobal()) {
|
@@ -814,17 +859,21 @@ class Parser
|
|
814
859
|
token_ == Token::RBRACE ||
|
815
860
|
token_ == Token::EOS) {
|
816
861
|
ExpectSemicolon(CHECK);
|
817
|
-
return factory_->NewReturnStatement(factory_->NewUndefined()
|
862
|
+
return factory_->NewReturnStatement(factory_->NewUndefined(),
|
863
|
+
begin,
|
864
|
+
lexer_.previous_end_position());
|
818
865
|
}
|
819
866
|
Expression *expr = ParseExpression(true, CHECK);
|
820
867
|
ExpectSemicolon(CHECK);
|
821
|
-
return factory_->NewReturnStatement(expr
|
868
|
+
return factory_->NewReturnStatement(expr, begin,
|
869
|
+
lexer_.previous_end_position());
|
822
870
|
}
|
823
871
|
|
824
872
|
// WithStatement
|
825
873
|
// : WITH '(' Expression ')' Statement
|
826
874
|
Statement* ParseWithStatement(bool *res) {
|
827
875
|
assert(token_ == Token::WITH);
|
876
|
+
const std::size_t begin = lexer_.begin_position();
|
828
877
|
Next();
|
829
878
|
|
830
879
|
// section 12.10.1
|
@@ -840,7 +889,7 @@ class Parser
|
|
840
889
|
EXPECT(Token::RPAREN);
|
841
890
|
|
842
891
|
Statement *stmt = ParseStatement(CHECK);
|
843
|
-
return factory_->NewWithStatement(expr, stmt);
|
892
|
+
return factory_->NewWithStatement(expr, stmt, begin);
|
844
893
|
}
|
845
894
|
|
846
895
|
// SwitchStatement
|
@@ -851,6 +900,7 @@ class Parser
|
|
851
900
|
// | '{' CaseClauses_opt DefaultClause CaseClauses_opt '}'
|
852
901
|
Statement* ParseSwitchStatement(bool *res) {
|
853
902
|
assert(token_ == Token::SWITCH);
|
903
|
+
const std::size_t begin = lexer_.begin_position();
|
854
904
|
CaseClause* case_clause;
|
855
905
|
Next();
|
856
906
|
|
@@ -882,9 +932,10 @@ class Parser
|
|
882
932
|
clauses->push_back(case_clause);
|
883
933
|
}
|
884
934
|
Next();
|
885
|
-
|
886
935
|
SwitchStatement* const switch_stmt =
|
887
|
-
factory_->NewSwitchStatement(expr, clauses
|
936
|
+
factory_->NewSwitchStatement(expr, clauses,
|
937
|
+
begin,
|
938
|
+
lexer_.previous_end_position());
|
888
939
|
target.set_node(switch_stmt);
|
889
940
|
return switch_stmt;
|
890
941
|
}
|
@@ -900,6 +951,7 @@ class Parser
|
|
900
951
|
// : DEFAULT ':' StatementList_opt
|
901
952
|
CaseClause* ParseCaseClause(bool *res) {
|
902
953
|
assert(token_ == Token::CASE || token_ == Token::DEFAULT);
|
954
|
+
const std::size_t begin = lexer_.begin_position();
|
903
955
|
Expression* expr = NULL;
|
904
956
|
Statements* const body = factory_->template NewVector<Statement*>();
|
905
957
|
|
@@ -919,22 +971,25 @@ class Parser
|
|
919
971
|
body->push_back(stmt);
|
920
972
|
}
|
921
973
|
|
922
|
-
return factory_->NewCaseClause(expr == NULL,
|
974
|
+
return factory_->NewCaseClause(expr == NULL,
|
975
|
+
expr, body,
|
976
|
+
begin, lexer_.previous_end_position());
|
923
977
|
}
|
924
978
|
|
925
979
|
// ThrowStatement
|
926
980
|
// : THROW Expression ';'
|
927
981
|
Statement* ParseThrowStatement(bool *res) {
|
928
982
|
assert(token_ == Token::THROW);
|
983
|
+
const std::size_t begin = lexer_.begin_position();
|
929
984
|
Next();
|
930
985
|
// Throw requires Expression
|
931
986
|
if (lexer_.has_line_terminator_before_next()) {
|
932
|
-
// TODO(Constellation) more refined parse error system
|
933
987
|
RAISE("missing expression between throw and newline");
|
934
988
|
}
|
935
989
|
Expression* const expr = ParseExpression(true, CHECK);
|
936
990
|
ExpectSemicolon(CHECK);
|
937
|
-
return factory_->NewThrowStatement(expr
|
991
|
+
return factory_->NewThrowStatement(expr,
|
992
|
+
begin, lexer_.previous_end_position());
|
938
993
|
}
|
939
994
|
|
940
995
|
// TryStatement
|
@@ -949,6 +1004,7 @@ class Parser
|
|
949
1004
|
// : FINALLY Block
|
950
1005
|
Statement* ParseTryStatement(bool *res) {
|
951
1006
|
assert(token_ == Token::TRY);
|
1007
|
+
const std::size_t begin = lexer_.begin_position();
|
952
1008
|
Identifier* name = NULL;
|
953
1009
|
Block* catch_block = NULL;
|
954
1010
|
Block* finally_block = NULL;
|
@@ -998,22 +1054,26 @@ class Parser
|
|
998
1054
|
}
|
999
1055
|
|
1000
1056
|
return factory_->NewTryStatement(try_block,
|
1001
|
-
name, catch_block,
|
1057
|
+
name, catch_block,
|
1058
|
+
finally_block, begin);
|
1002
1059
|
}
|
1003
1060
|
|
1004
1061
|
// DebuggerStatement
|
1005
1062
|
// : DEBUGGER ';'
|
1006
1063
|
Statement* ParseDebuggerStatement(bool *res) {
|
1007
1064
|
assert(token_ == Token::DEBUGGER);
|
1065
|
+
const std::size_t begin = lexer_.begin_position();
|
1008
1066
|
Next();
|
1009
1067
|
ExpectSemicolon(CHECK);
|
1010
|
-
return factory_->NewDebuggerStatement(
|
1068
|
+
return factory_->NewDebuggerStatement(begin,
|
1069
|
+
lexer_.previous_end_position());
|
1011
1070
|
}
|
1012
1071
|
|
1013
1072
|
Statement* ParseExpressionStatement(bool *res) {
|
1014
1073
|
Expression* const expr = ParseExpression(true, CHECK);
|
1015
1074
|
ExpectSemicolon(CHECK);
|
1016
|
-
return factory_->NewExpressionStatement(expr
|
1075
|
+
return factory_->NewExpressionStatement(expr,
|
1076
|
+
lexer_.previous_end_position());
|
1017
1077
|
}
|
1018
1078
|
|
1019
1079
|
// LabelledStatement
|
@@ -1040,13 +1100,14 @@ class Parser
|
|
1040
1100
|
RAISE("duplicate label");
|
1041
1101
|
}
|
1042
1102
|
labels->push_back(label);
|
1043
|
-
const
|
1103
|
+
const LabelSwitcher label_switcher(this, labels, exist_labels);
|
1044
1104
|
|
1045
1105
|
Statement* const stmt = ParseStatement(CHECK);
|
1046
1106
|
return factory_->NewLabelledStatement(expr, stmt);
|
1047
1107
|
}
|
1048
1108
|
ExpectSemicolon(CHECK);
|
1049
|
-
return factory_->NewExpressionStatement(expr
|
1109
|
+
return factory_->NewExpressionStatement(expr,
|
1110
|
+
lexer_.previous_end_position());
|
1050
1111
|
}
|
1051
1112
|
|
1052
1113
|
template<bool Use>
|
@@ -1304,33 +1365,33 @@ class Parser
|
|
1304
1365
|
Expression* res;
|
1305
1366
|
switch (op) {
|
1306
1367
|
case Token::ADD:
|
1307
|
-
res = factory_->
|
1368
|
+
res = factory_->NewReducedNumberLiteral(l_val + r_val);
|
1308
1369
|
break;
|
1309
1370
|
|
1310
1371
|
case Token::SUB:
|
1311
|
-
res = factory_->
|
1372
|
+
res = factory_->NewReducedNumberLiteral(l_val - r_val);
|
1312
1373
|
break;
|
1313
1374
|
|
1314
1375
|
case Token::MUL:
|
1315
|
-
res = factory_->
|
1376
|
+
res = factory_->NewReducedNumberLiteral(l_val * r_val);
|
1316
1377
|
break;
|
1317
1378
|
|
1318
1379
|
case Token::DIV:
|
1319
|
-
res = factory_->
|
1380
|
+
res = factory_->NewReducedNumberLiteral(l_val / r_val);
|
1320
1381
|
break;
|
1321
1382
|
|
1322
1383
|
case Token::BIT_OR:
|
1323
|
-
res = factory_->
|
1384
|
+
res = factory_->NewReducedNumberLiteral(
|
1324
1385
|
DoubleToInt32(l_val) | DoubleToInt32(r_val));
|
1325
1386
|
break;
|
1326
1387
|
|
1327
1388
|
case Token::BIT_AND:
|
1328
|
-
res = factory_->
|
1389
|
+
res = factory_->NewReducedNumberLiteral(
|
1329
1390
|
DoubleToInt32(l_val) & DoubleToInt32(r_val));
|
1330
1391
|
break;
|
1331
1392
|
|
1332
1393
|
case Token::BIT_XOR:
|
1333
|
-
res = factory_->
|
1394
|
+
res = factory_->NewReducedNumberLiteral(
|
1334
1395
|
DoubleToInt32(l_val) ^ DoubleToInt32(r_val));
|
1335
1396
|
break;
|
1336
1397
|
|
@@ -1338,21 +1399,21 @@ class Parser
|
|
1338
1399
|
case Token::SHL: {
|
1339
1400
|
const int32_t value = DoubleToInt32(l_val)
|
1340
1401
|
<< (DoubleToInt32(r_val) & 0x1f);
|
1341
|
-
res = factory_->
|
1402
|
+
res = factory_->NewReducedNumberLiteral(value);
|
1342
1403
|
break;
|
1343
1404
|
}
|
1344
1405
|
|
1345
1406
|
case Token::SHR: {
|
1346
1407
|
const uint32_t shift = DoubleToInt32(r_val) & 0x1f;
|
1347
1408
|
const uint32_t value = DoubleToUInt32(l_val) >> shift;
|
1348
|
-
res = factory_->
|
1409
|
+
res = factory_->NewReducedNumberLiteral(value);
|
1349
1410
|
break;
|
1350
1411
|
}
|
1351
1412
|
|
1352
1413
|
case Token::SAR: {
|
1353
1414
|
uint32_t shift = DoubleToInt32(r_val) & 0x1f;
|
1354
1415
|
int32_t value = DoubleToInt32(l_val) >> shift;
|
1355
|
-
res = factory_->
|
1416
|
+
res = factory_->NewReducedNumberLiteral(value);
|
1356
1417
|
break;
|
1357
1418
|
}
|
1358
1419
|
|
@@ -1388,13 +1449,14 @@ class Parser
|
|
1388
1449
|
Expression* ParseUnaryExpression(bool *res) {
|
1389
1450
|
Expression *result, *expr;
|
1390
1451
|
const Token::Type op = token_;
|
1452
|
+
const std::size_t begin = lexer_.begin_position();
|
1391
1453
|
switch (token_) {
|
1392
1454
|
case Token::VOID:
|
1393
1455
|
case Token::NOT:
|
1394
1456
|
case Token::TYPEOF:
|
1395
1457
|
Next();
|
1396
1458
|
expr = ParseUnaryExpression(CHECK);
|
1397
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1459
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1398
1460
|
break;
|
1399
1461
|
|
1400
1462
|
case Token::DELETE:
|
@@ -1407,17 +1469,17 @@ class Parser
|
|
1407
1469
|
expr->AsIdentifier()) {
|
1408
1470
|
RAISE("delete to direct identifier not allowed in strict code");
|
1409
1471
|
}
|
1410
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1472
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1411
1473
|
break;
|
1412
1474
|
|
1413
1475
|
case Token::BIT_NOT:
|
1414
1476
|
Next();
|
1415
1477
|
expr = ParseUnaryExpression(CHECK);
|
1416
|
-
if (expr->AsNumberLiteral()) {
|
1417
|
-
result = factory_->
|
1478
|
+
if (ReduceExpressions && expr->AsNumberLiteral()) {
|
1479
|
+
result = factory_->NewReducedNumberLiteral(
|
1418
1480
|
~DoubleToInt32(expr->AsNumberLiteral()->value()));
|
1419
1481
|
} else {
|
1420
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1482
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1421
1483
|
}
|
1422
1484
|
break;
|
1423
1485
|
|
@@ -1427,18 +1489,18 @@ class Parser
|
|
1427
1489
|
if (expr->AsNumberLiteral()) {
|
1428
1490
|
result = expr;
|
1429
1491
|
} else {
|
1430
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1492
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1431
1493
|
}
|
1432
1494
|
break;
|
1433
1495
|
|
1434
1496
|
case Token::SUB:
|
1435
1497
|
Next();
|
1436
1498
|
expr = ParseUnaryExpression(CHECK);
|
1437
|
-
if (expr->AsNumberLiteral()) {
|
1438
|
-
result = factory_->
|
1499
|
+
if (ReduceExpressions && expr->AsNumberLiteral()) {
|
1500
|
+
result = factory_->NewReducedNumberLiteral(
|
1439
1501
|
-(expr->AsNumberLiteral()->value()));
|
1440
1502
|
} else {
|
1441
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1503
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1442
1504
|
}
|
1443
1505
|
break;
|
1444
1506
|
|
@@ -1464,7 +1526,7 @@ class Parser
|
|
1464
1526
|
}
|
1465
1527
|
}
|
1466
1528
|
}
|
1467
|
-
result = factory_->NewUnaryOperation(op, expr);
|
1529
|
+
result = factory_->NewUnaryOperation(op, expr, begin);
|
1468
1530
|
break;
|
1469
1531
|
|
1470
1532
|
default:
|
@@ -1499,7 +1561,8 @@ class Parser
|
|
1499
1561
|
}
|
1500
1562
|
}
|
1501
1563
|
}
|
1502
|
-
expr = factory_->NewPostfixExpression(token_, expr
|
1564
|
+
expr = factory_->NewPostfixExpression(token_, expr,
|
1565
|
+
lexer_.end_position());
|
1503
1566
|
Next();
|
1504
1567
|
}
|
1505
1568
|
return expr;
|
@@ -1535,7 +1598,7 @@ class Parser
|
|
1535
1598
|
if (token_ == Token::LPAREN) {
|
1536
1599
|
ParseArguments(args, CHECK);
|
1537
1600
|
}
|
1538
|
-
expr = factory_->NewConstructorCall(target, args);
|
1601
|
+
expr = factory_->NewConstructorCall(target, args, lexer_.previous_end_position());
|
1539
1602
|
}
|
1540
1603
|
while (true) {
|
1541
1604
|
switch (token_) {
|
@@ -1560,7 +1623,8 @@ class Parser
|
|
1560
1623
|
Expressions* const args =
|
1561
1624
|
factory_->template NewVector<Expression*>();
|
1562
1625
|
ParseArguments(args, CHECK);
|
1563
|
-
expr = factory_->NewFunctionCall(expr, args
|
1626
|
+
expr = factory_->NewFunctionCall(expr, args,
|
1627
|
+
lexer_.previous_end_position());
|
1564
1628
|
} else {
|
1565
1629
|
return expr;
|
1566
1630
|
}
|
@@ -1591,7 +1655,8 @@ class Parser
|
|
1591
1655
|
Expression* result = NULL;
|
1592
1656
|
switch (token_) {
|
1593
1657
|
case Token::THIS:
|
1594
|
-
result = factory_->NewThisLiteral()
|
1658
|
+
result = factory_->NewThisLiteral(lexer_.begin_position(),
|
1659
|
+
lexer_.end_position());
|
1595
1660
|
Next();
|
1596
1661
|
break;
|
1597
1662
|
|
@@ -1600,17 +1665,20 @@ class Parser
|
|
1600
1665
|
break;
|
1601
1666
|
|
1602
1667
|
case Token::NULL_LITERAL:
|
1603
|
-
result = factory_->NewNullLiteral()
|
1668
|
+
result = factory_->NewNullLiteral(lexer_.begin_position(),
|
1669
|
+
lexer_.end_position());
|
1604
1670
|
Next();
|
1605
1671
|
break;
|
1606
1672
|
|
1607
1673
|
case Token::TRUE_LITERAL:
|
1608
|
-
result = factory_->NewTrueLiteral()
|
1674
|
+
result = factory_->NewTrueLiteral(lexer_.begin_position(),
|
1675
|
+
lexer_.end_position());
|
1609
1676
|
Next();
|
1610
1677
|
break;
|
1611
1678
|
|
1612
1679
|
case Token::FALSE_LITERAL:
|
1613
|
-
result = factory_->NewFalseLiteral()
|
1680
|
+
result = factory_->NewFalseLiteral(lexer_.begin_position(),
|
1681
|
+
lexer_.end_position());
|
1614
1682
|
Next();
|
1615
1683
|
break;
|
1616
1684
|
|
@@ -1620,7 +1688,9 @@ class Parser
|
|
1620
1688
|
if (strict_ && lexer_.NumericType() == lexer_type::OCTAL) {
|
1621
1689
|
RAISE("octal integer literal not allowed in strict code");
|
1622
1690
|
}
|
1623
|
-
result = factory_->NewNumberLiteral(lexer_.Numeric()
|
1691
|
+
result = factory_->NewNumberLiteral(lexer_.Numeric(),
|
1692
|
+
lexer_.begin_position(),
|
1693
|
+
lexer_.end_position());
|
1624
1694
|
Next();
|
1625
1695
|
break;
|
1626
1696
|
|
@@ -1630,9 +1700,13 @@ class Parser
|
|
1630
1700
|
RAISE("octal excape sequence not allowed in strict code");
|
1631
1701
|
}
|
1632
1702
|
if (state == lexer_type::NONE) {
|
1633
|
-
result = factory_->NewDirectivable(lexer_.Buffer()
|
1703
|
+
result = factory_->NewDirectivable(lexer_.Buffer(),
|
1704
|
+
lexer_.begin_position(),
|
1705
|
+
lexer_.end_position());
|
1634
1706
|
} else {
|
1635
|
-
result = factory_->NewStringLiteral(lexer_.Buffer()
|
1707
|
+
result = factory_->NewStringLiteral(lexer_.Buffer(),
|
1708
|
+
lexer_.begin_position(),
|
1709
|
+
lexer_.end_position());
|
1636
1710
|
}
|
1637
1711
|
Next();
|
1638
1712
|
break;
|
@@ -1696,8 +1770,10 @@ class Parser
|
|
1696
1770
|
if (!lexer_.ScanRegExpFlags()) {
|
1697
1771
|
RAISE("invalid regular expression flag");
|
1698
1772
|
}
|
1699
|
-
RegExpLiteral* const expr =
|
1700
|
-
|
1773
|
+
RegExpLiteral* const expr = factory_->NewRegExpLiteral(
|
1774
|
+
content, lexer_.Buffer(),
|
1775
|
+
lexer_.begin_position(),
|
1776
|
+
lexer_.end_position());
|
1701
1777
|
if (!expr) {
|
1702
1778
|
RAISE("invalid regular expression");
|
1703
1779
|
}
|
@@ -1721,6 +1797,7 @@ class Parser
|
|
1721
1797
|
// : ','
|
1722
1798
|
// | Elision ','
|
1723
1799
|
Expression* ParseArrayLiteral(bool *res) {
|
1800
|
+
const std::size_t begin = lexer_.begin_position();
|
1724
1801
|
Expressions* const items = factory_->template NewVector<Expression*>();
|
1725
1802
|
Next();
|
1726
1803
|
while (token_ != Token::RBRACK) {
|
@@ -1736,7 +1813,8 @@ class Parser
|
|
1736
1813
|
}
|
1737
1814
|
}
|
1738
1815
|
Next();
|
1739
|
-
return factory_->NewArrayLiteral(items
|
1816
|
+
return factory_->NewArrayLiteral(items,
|
1817
|
+
begin, lexer_.previous_end_position());
|
1740
1818
|
}
|
1741
1819
|
|
1742
1820
|
|
@@ -1768,6 +1846,7 @@ class Parser
|
|
1768
1846
|
typedef std::tr1::unordered_map<IdentifierKey, int> ObjectMap;
|
1769
1847
|
typedef typename ObjectLiteral::Property Property;
|
1770
1848
|
typedef typename ObjectLiteral::Properties Properties;
|
1849
|
+
const std::size_t begin = lexer_.begin_position();
|
1771
1850
|
Properties* const prop = factory_->template NewVector<Property>();
|
1772
1851
|
ObjectMap map;
|
1773
1852
|
Expression* expr;
|
@@ -1782,8 +1861,10 @@ class Parser
|
|
1782
1861
|
Next<IgnoreReservedWords>(); // IDENTIFIERNAME
|
1783
1862
|
if (token_ == Token::COLON) {
|
1784
1863
|
// property
|
1785
|
-
ident =
|
1786
|
-
is_get ? ParserData::kGet : ParserData::kSet
|
1864
|
+
ident = ParseIdentifierWithPosition(
|
1865
|
+
is_get ? ParserData::kGet : ParserData::kSet,
|
1866
|
+
lexer_.previous_begin_position(),
|
1867
|
+
lexer_.previous_end_position());
|
1787
1868
|
expr = ParseAssignmentExpression(true, CHECK);
|
1788
1869
|
ObjectLiteral::AddDataProperty(prop, ident, expr);
|
1789
1870
|
typename ObjectMap::iterator it = map.find(ident);
|
@@ -1870,8 +1951,9 @@ class Parser
|
|
1870
1951
|
Next<IgnoreReservedWordsAndIdentifyGetterOrSetter>();
|
1871
1952
|
}
|
1872
1953
|
}
|
1954
|
+
const std::size_t end = lexer_.begin_position();
|
1873
1955
|
Next();
|
1874
|
-
return factory_->NewObjectLiteral(prop);
|
1956
|
+
return factory_->NewObjectLiteral(prop, begin, end);
|
1875
1957
|
}
|
1876
1958
|
|
1877
1959
|
FunctionLiteral* ParseFunctionLiteral(
|
@@ -1882,6 +1964,7 @@ class Parser
|
|
1882
1964
|
// IDENTIFIER_opt
|
1883
1965
|
std::tr1::unordered_set<IdentifierKey> param_set;
|
1884
1966
|
std::size_t throw_error_if_strict_code_line = 0;
|
1967
|
+
const std::size_t begin_position = lexer_.begin_position();
|
1885
1968
|
enum {
|
1886
1969
|
kDetectNone = 0,
|
1887
1970
|
kDetectEvalName,
|
@@ -1892,8 +1975,8 @@ class Parser
|
|
1892
1975
|
kDetectFutureReservedWords
|
1893
1976
|
} throw_error_if_strict_code = kDetectNone;
|
1894
1977
|
|
1895
|
-
|
1896
|
-
|
1978
|
+
Identifiers* const params = factory_->template NewVector<Identifier*>();
|
1979
|
+
Identifier* name = NULL;
|
1897
1980
|
|
1898
1981
|
if (arg_type == FunctionLiteral::GENERAL) {
|
1899
1982
|
assert(token_ == Token::FUNCTION);
|
@@ -1901,8 +1984,7 @@ class Parser
|
|
1901
1984
|
const Token::Type current = token_;
|
1902
1985
|
if (current == Token::IDENTIFIER ||
|
1903
1986
|
Token::IsAddedFutureReservedWordInStrictCode(current)) {
|
1904
|
-
|
1905
|
-
literal->SetName(name);
|
1987
|
+
name = ParseIdentifier(lexer_.Buffer());
|
1906
1988
|
if (Token::IsAddedFutureReservedWordInStrictCode(current)) {
|
1907
1989
|
throw_error_if_strict_code = kDetectFutureReservedWords;
|
1908
1990
|
throw_error_if_strict_code_line = lexer_.line_number();
|
@@ -1921,9 +2003,7 @@ class Parser
|
|
1921
2003
|
}
|
1922
2004
|
}
|
1923
2005
|
|
1924
|
-
const
|
1925
|
-
const TargetScope scope(this);
|
1926
|
-
literal->set_start_position(lexer_.begin_position());
|
2006
|
+
const std::size_t begin_block_position = lexer_.begin_position();
|
1927
2007
|
|
1928
2008
|
// '(' FormalParameterList_opt ')'
|
1929
2009
|
IS(Token::LPAREN);
|
@@ -1954,7 +2034,7 @@ class Parser
|
|
1954
2034
|
}
|
1955
2035
|
}
|
1956
2036
|
}
|
1957
|
-
|
2037
|
+
params->push_back(ident);
|
1958
2038
|
EXPECT(Token::RPAREN);
|
1959
2039
|
} else {
|
1960
2040
|
if (token_ != Token::RPAREN) {
|
@@ -1984,7 +2064,7 @@ class Parser
|
|
1984
2064
|
throw_error_if_strict_code_line = lexer_.line_number();
|
1985
2065
|
}
|
1986
2066
|
}
|
1987
|
-
|
2067
|
+
params->push_back(ident);
|
1988
2068
|
param_set.insert(ident);
|
1989
2069
|
if (token_ == Token::COMMA) {
|
1990
2070
|
Next(true);
|
@@ -2003,8 +2083,13 @@ class Parser
|
|
2003
2083
|
// | SourceElements
|
2004
2084
|
EXPECT(Token::LBRACE);
|
2005
2085
|
|
2006
|
-
|
2007
|
-
|
2086
|
+
Statements* const body = factory_->template NewVector<Statement*>();
|
2087
|
+
Scope* const scope = factory_->NewScope(decl_type);
|
2088
|
+
const ScopeSwitcher scope_switcher(this, scope);
|
2089
|
+
const TargetSwitcher target_switcher(this);
|
2090
|
+
const bool function_is_strict =
|
2091
|
+
ParseSourceElements(Token::RBRACE, body, CHECK);
|
2092
|
+
if (strict_ || function_is_strict) {
|
2008
2093
|
// section 13.1
|
2009
2094
|
// Strict Mode Restrictions
|
2010
2095
|
switch (throw_error_if_strict_code) {
|
@@ -2042,14 +2127,36 @@ class Parser
|
|
2042
2127
|
break;
|
2043
2128
|
}
|
2044
2129
|
}
|
2045
|
-
literal->set_end_position(lexer_.end_position());
|
2046
2130
|
Next();
|
2047
|
-
|
2131
|
+
const std::size_t end_block_position = lexer_.previous_end_position();
|
2132
|
+
return factory_->NewFunctionLiteral(decl_type,
|
2133
|
+
name,
|
2134
|
+
params,
|
2135
|
+
body,
|
2136
|
+
scope,
|
2137
|
+
function_is_strict,
|
2138
|
+
begin_block_position,
|
2139
|
+
end_block_position,
|
2140
|
+
begin_position,
|
2141
|
+
end_block_position);
|
2048
2142
|
}
|
2049
2143
|
|
2050
2144
|
template<typename Range>
|
2051
2145
|
Identifier* ParseIdentifier(const Range& range) {
|
2052
|
-
Identifier* const ident = factory_->NewIdentifier(range
|
2146
|
+
Identifier* const ident = factory_->NewIdentifier(range,
|
2147
|
+
lexer_.begin_position(),
|
2148
|
+
lexer_.end_position());
|
2149
|
+
Next();
|
2150
|
+
return ident;
|
2151
|
+
}
|
2152
|
+
|
2153
|
+
template<typename Range>
|
2154
|
+
Identifier* ParseIdentifierWithPosition(const Range& range,
|
2155
|
+
std::size_t begin,
|
2156
|
+
std::size_t end) {
|
2157
|
+
Identifier* const ident = factory_->NewIdentifier(range,
|
2158
|
+
begin,
|
2159
|
+
end);
|
2053
2160
|
Next();
|
2054
2161
|
return ident;
|
2055
2162
|
}
|
@@ -2183,8 +2290,8 @@ class Parser
|
|
2183
2290
|
UNEXPECT(token_);
|
2184
2291
|
}
|
2185
2292
|
|
2186
|
-
inline lexer_type
|
2187
|
-
return lexer_;
|
2293
|
+
inline lexer_type* lexer() const {
|
2294
|
+
return &lexer_;
|
2188
2295
|
}
|
2189
2296
|
template<typename LexType>
|
2190
2297
|
inline Token::Type Next() {
|
@@ -2249,15 +2356,15 @@ class Parser
|
|
2249
2356
|
parser_type* parser_;
|
2250
2357
|
};
|
2251
2358
|
|
2252
|
-
class
|
2359
|
+
class LabelSwitcher : private Noncopyable<LabelSwitcher>::type {
|
2253
2360
|
public:
|
2254
|
-
|
2255
|
-
|
2361
|
+
LabelSwitcher(parser_type* parser,
|
2362
|
+
Identifiers* labels, bool exist_labels)
|
2256
2363
|
: parser_(parser),
|
2257
2364
|
exist_labels_(exist_labels) {
|
2258
2365
|
parser_->set_labels(labels);
|
2259
2366
|
}
|
2260
|
-
~
|
2367
|
+
~LabelSwitcher() {
|
2261
2368
|
if (!exist_labels_) {
|
2262
2369
|
parser_->set_labels(NULL);
|
2263
2370
|
}
|
@@ -2279,6 +2386,9 @@ class Parser
|
|
2279
2386
|
inline void SwitchStrictMode() const {
|
2280
2387
|
parser_->set_strict(true);
|
2281
2388
|
}
|
2389
|
+
inline bool IsStrict() const {
|
2390
|
+
return parser_->strict();
|
2391
|
+
}
|
2282
2392
|
private:
|
2283
2393
|
parser_type* parser_;
|
2284
2394
|
bool prev_;
|