iv-phonic 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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_;
|