Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/preparser.cc

Issue 252423007: Parser: Introduce StatementList + NewStatementList() (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/preparser.h ('K') | « src/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 // it is used) are generally omitted. 176 // it is used) are generally omitted.
177 177
178 178
179 #define CHECK_OK ok); \ 179 #define CHECK_OK ok); \
180 if (!*ok) return kUnknownSourceElements; \ 180 if (!*ok) return kUnknownSourceElements; \
181 ((void)0 181 ((void)0
182 #define DUMMY ) // to make indentation work 182 #define DUMMY ) // to make indentation work
183 #undef DUMMY 183 #undef DUMMY
184 184
185 185
186 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 186 PreParserStatement PreParser::ParseSourceElement(bool* ok) {
marja 2014/04/24 15:31:10 The same here.
187 // (Ecma 262 5th Edition, clause 14): 187 // (Ecma 262 5th Edition, clause 14):
188 // SourceElement: 188 // SourceElement:
189 // Statement 189 // Statement
190 // FunctionDeclaration 190 // FunctionDeclaration
191 // 191 //
192 // In harmony mode we allow additionally the following productions 192 // In harmony mode we allow additionally the following productions
193 // SourceElement: 193 // SourceElement:
194 // LetDeclaration 194 // LetDeclaration
195 // ConstDeclaration 195 // ConstDeclaration
196 // GeneratorDeclaration 196 // GeneratorDeclaration
(...skipping 13 matching lines...) Expand all
210 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 210 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
211 bool* ok) { 211 bool* ok) {
212 // SourceElements :: 212 // SourceElements ::
213 // (Statement)* <end_token> 213 // (Statement)* <end_token>
214 214
215 bool directive_prologue = true; 215 bool directive_prologue = true;
216 while (peek() != end_token) { 216 while (peek() != end_token) {
217 if (directive_prologue && peek() != Token::STRING) { 217 if (directive_prologue && peek() != Token::STRING) {
218 directive_prologue = false; 218 directive_prologue = false;
219 } 219 }
220 Statement statement = ParseSourceElement(CHECK_OK); 220 PreParserStatement statement = ParseSourceElement(CHECK_OK);
marja 2014/04/24 15:31:10 ... and overall.
221 if (directive_prologue) { 221 if (directive_prologue) {
222 if (statement.IsUseStrictLiteral()) { 222 if (statement.IsUseStrictLiteral()) {
223 scope_->SetStrictMode(STRICT); 223 scope_->SetStrictMode(STRICT);
224 } else if (!statement.IsStringLiteral()) { 224 } else if (!statement.IsStringLiteral()) {
225 directive_prologue = false; 225 directive_prologue = false;
226 } 226 }
227 } 227 }
228 } 228 }
229 return kUnknownSourceElements; 229 return kUnknownSourceElements;
230 } 230 }
231 231
232 232
233 #undef CHECK_OK 233 #undef CHECK_OK
234 #define CHECK_OK ok); \ 234 #define CHECK_OK ok); \
235 if (!*ok) return Statement::Default(); \ 235 if (!*ok) return PreParserStatement::Default(); \
236 ((void)0 236 ((void)0
237 #define DUMMY ) // to make indentation work 237 #define DUMMY ) // to make indentation work
238 #undef DUMMY 238 #undef DUMMY
239 239
240 240
241 PreParser::Statement PreParser::ParseStatement(bool* ok) { 241 PreParserStatement PreParser::ParseStatement(bool* ok) {
242 // Statement :: 242 // Statement ::
243 // Block 243 // Block
244 // VariableStatement 244 // VariableStatement
245 // EmptyStatement 245 // EmptyStatement
246 // ExpressionStatement 246 // ExpressionStatement
247 // IfStatement 247 // IfStatement
248 // IterationStatement 248 // IterationStatement
249 // ContinueStatement 249 // ContinueStatement
250 // BreakStatement 250 // BreakStatement
251 // ReturnStatement 251 // ReturnStatement
(...skipping 16 matching lines...) Expand all
268 case Token::LBRACE: 268 case Token::LBRACE:
269 return ParseBlock(ok); 269 return ParseBlock(ok);
270 270
271 case Token::CONST: 271 case Token::CONST:
272 case Token::LET: 272 case Token::LET:
273 case Token::VAR: 273 case Token::VAR:
274 return ParseVariableStatement(kStatement, ok); 274 return ParseVariableStatement(kStatement, ok);
275 275
276 case Token::SEMICOLON: 276 case Token::SEMICOLON:
277 Next(); 277 Next();
278 return Statement::Default(); 278 return PreParserStatement::Default();
279 279
280 case Token::IF: 280 case Token::IF:
281 return ParseIfStatement(ok); 281 return ParseIfStatement(ok);
282 282
283 case Token::DO: 283 case Token::DO:
284 return ParseDoWhileStatement(ok); 284 return ParseDoWhileStatement(ok);
285 285
286 case Token::WHILE: 286 case Token::WHILE:
287 return ParseWhileStatement(ok); 287 return ParseWhileStatement(ok);
288 288
(...skipping 16 matching lines...) Expand all
305 return ParseSwitchStatement(ok); 305 return ParseSwitchStatement(ok);
306 306
307 case Token::THROW: 307 case Token::THROW:
308 return ParseThrowStatement(ok); 308 return ParseThrowStatement(ok);
309 309
310 case Token::TRY: 310 case Token::TRY:
311 return ParseTryStatement(ok); 311 return ParseTryStatement(ok);
312 312
313 case Token::FUNCTION: { 313 case Token::FUNCTION: {
314 Scanner::Location start_location = scanner()->peek_location(); 314 Scanner::Location start_location = scanner()->peek_location();
315 Statement statement = ParseFunctionDeclaration(CHECK_OK); 315 PreParserStatement statement = ParseFunctionDeclaration(CHECK_OK);
316 Scanner::Location end_location = scanner()->location(); 316 Scanner::Location end_location = scanner()->location();
317 if (strict_mode() == STRICT) { 317 if (strict_mode() == STRICT) {
318 PreParserTraits::ReportMessageAt(start_location.beg_pos, 318 PreParserTraits::ReportMessageAt(start_location.beg_pos,
319 end_location.end_pos, 319 end_location.end_pos,
320 "strict_function", 320 "strict_function",
321 NULL); 321 NULL);
322 *ok = false; 322 *ok = false;
323 return Statement::Default(); 323 return PreParserStatement::Default();
324 } else { 324 } else {
325 return statement; 325 return statement;
326 } 326 }
327 } 327 }
328 328
329 case Token::DEBUGGER: 329 case Token::DEBUGGER:
330 return ParseDebuggerStatement(ok); 330 return ParseDebuggerStatement(ok);
331 331
332 default: 332 default:
333 return ParseExpressionOrLabelledStatement(ok); 333 return ParseExpressionOrLabelledStatement(ok);
334 } 334 }
335 } 335 }
336 336
337 337
338 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 338 PreParserStatement PreParser::ParseFunctionDeclaration(bool* ok) {
339 // FunctionDeclaration :: 339 // FunctionDeclaration ::
340 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 340 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
341 // GeneratorDeclaration :: 341 // GeneratorDeclaration ::
342 // 'function' '*' Identifier '(' FormalParameterListopt ')' 342 // 'function' '*' Identifier '(' FormalParameterListopt ')'
343 // '{' FunctionBody '}' 343 // '{' FunctionBody '}'
344 Expect(Token::FUNCTION, CHECK_OK); 344 Expect(Token::FUNCTION, CHECK_OK);
345 int pos = position(); 345 int pos = position();
346 bool is_generator = allow_generators() && Check(Token::MUL); 346 bool is_generator = allow_generators() && Check(Token::MUL);
347 bool is_strict_reserved = false; 347 bool is_strict_reserved = false;
348 Identifier name = ParseIdentifierOrStrictReservedWord( 348 Identifier name = ParseIdentifierOrStrictReservedWord(
349 &is_strict_reserved, CHECK_OK); 349 &is_strict_reserved, CHECK_OK);
350 ParseFunctionLiteral(name, 350 ParseFunctionLiteral(name,
351 scanner()->location(), 351 scanner()->location(),
352 is_strict_reserved, 352 is_strict_reserved,
353 is_generator, 353 is_generator,
354 pos, 354 pos,
355 FunctionLiteral::DECLARATION, 355 FunctionLiteral::DECLARATION,
356 CHECK_OK); 356 CHECK_OK);
357 return Statement::FunctionDeclaration(); 357 return PreParserStatement::FunctionDeclaration();
358 } 358 }
359 359
360 360
361 PreParser::Statement PreParser::ParseBlock(bool* ok) { 361 PreParserStatement PreParser::ParseBlock(bool* ok) {
362 // Block :: 362 // Block ::
363 // '{' Statement* '}' 363 // '{' Statement* '}'
364 364
365 // Note that a Block does not introduce a new execution scope! 365 // Note that a Block does not introduce a new execution scope!
366 // (ECMA-262, 3rd, 12.2) 366 // (ECMA-262, 3rd, 12.2)
367 // 367 //
368 Expect(Token::LBRACE, CHECK_OK); 368 Expect(Token::LBRACE, CHECK_OK);
369 while (peek() != Token::RBRACE) { 369 while (peek() != Token::RBRACE) {
370 if (allow_harmony_scoping() && strict_mode() == STRICT) { 370 if (allow_harmony_scoping() && strict_mode() == STRICT) {
371 ParseSourceElement(CHECK_OK); 371 ParseSourceElement(CHECK_OK);
372 } else { 372 } else {
373 ParseStatement(CHECK_OK); 373 ParseStatement(CHECK_OK);
374 } 374 }
375 } 375 }
376 Expect(Token::RBRACE, ok); 376 Expect(Token::RBRACE, ok);
377 return Statement::Default(); 377 return PreParserStatement::Default();
378 } 378 }
379 379
380 380
381 PreParser::Statement PreParser::ParseVariableStatement( 381 PreParserStatement PreParser::ParseVariableStatement(
382 VariableDeclarationContext var_context, 382 VariableDeclarationContext var_context,
383 bool* ok) { 383 bool* ok) {
384 // VariableStatement :: 384 // VariableStatement ::
385 // VariableDeclarations ';' 385 // VariableDeclarations ';'
386 386
387 Statement result = ParseVariableDeclarations(var_context, 387 PreParserStatement result = ParseVariableDeclarations(var_context,
388 NULL, 388 NULL,
389 NULL, 389 NULL,
390 CHECK_OK); 390 CHECK_OK);
391 ExpectSemicolon(CHECK_OK); 391 ExpectSemicolon(CHECK_OK);
392 return result; 392 return result;
393 } 393 }
394 394
395 395
396 // If the variable declaration declares exactly one non-const 396 // If the variable declaration declares exactly one non-const
397 // variable, then *var is set to that variable. In all other cases, 397 // variable, then *var is set to that variable. In all other cases,
398 // *var is untouched; in particular, it is the caller's responsibility 398 // *var is untouched; in particular, it is the caller's responsibility
399 // to initialize it properly. This mechanism is also used for the parsing 399 // to initialize it properly. This mechanism is also used for the parsing
400 // of 'for-in' loops. 400 // of 'for-in' loops.
401 PreParser::Statement PreParser::ParseVariableDeclarations( 401 PreParserStatement PreParser::ParseVariableDeclarations(
402 VariableDeclarationContext var_context, 402 VariableDeclarationContext var_context,
403 VariableDeclarationProperties* decl_props, 403 VariableDeclarationProperties* decl_props,
404 int* num_decl, 404 int* num_decl,
405 bool* ok) { 405 bool* ok) {
406 // VariableDeclarations :: 406 // VariableDeclarations ::
407 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 407 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
408 // 408 //
409 // The ES6 Draft Rev3 specifies the following grammar for const declarations 409 // The ES6 Draft Rev3 specifies the following grammar for const declarations
410 // 410 //
411 // ConstDeclaration :: 411 // ConstDeclaration ::
(...skipping 17 matching lines...) Expand all
429 // 429 //
430 // However disallowing const in sloppy mode will break compatibility with 430 // However disallowing const in sloppy mode will break compatibility with
431 // existing pages. Therefore we keep allowing const with the old 431 // existing pages. Therefore we keep allowing const with the old
432 // non-harmony semantics in sloppy mode. 432 // non-harmony semantics in sloppy mode.
433 Consume(Token::CONST); 433 Consume(Token::CONST);
434 if (strict_mode() == STRICT) { 434 if (strict_mode() == STRICT) {
435 if (allow_harmony_scoping()) { 435 if (allow_harmony_scoping()) {
436 if (var_context != kSourceElement && var_context != kForStatement) { 436 if (var_context != kSourceElement && var_context != kForStatement) {
437 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); 437 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
438 *ok = false; 438 *ok = false;
439 return Statement::Default(); 439 return PreParserStatement::Default();
440 } 440 }
441 require_initializer = true; 441 require_initializer = true;
442 } else { 442 } else {
443 Scanner::Location location = scanner()->peek_location(); 443 Scanner::Location location = scanner()->peek_location();
444 ReportMessageAt(location, "strict_const"); 444 ReportMessageAt(location, "strict_const");
445 *ok = false; 445 *ok = false;
446 return Statement::Default(); 446 return PreParserStatement::Default();
447 } 447 }
448 } 448 }
449 } else if (peek() == Token::LET) { 449 } else if (peek() == Token::LET) {
450 // ES6 Draft Rev4 section 12.2.1: 450 // ES6 Draft Rev4 section 12.2.1:
451 // 451 //
452 // LetDeclaration : let LetBindingList ; 452 // LetDeclaration : let LetBindingList ;
453 // 453 //
454 // * It is a Syntax Error if the code that matches this production is not 454 // * It is a Syntax Error if the code that matches this production is not
455 // contained in extended code. 455 // contained in extended code.
456 // 456 //
457 // TODO(rossberg): make 'let' a legal identifier in sloppy mode. 457 // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
458 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) { 458 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) {
459 ReportMessageAt(scanner()->peek_location(), "illegal_let"); 459 ReportMessageAt(scanner()->peek_location(), "illegal_let");
460 *ok = false; 460 *ok = false;
461 return Statement::Default(); 461 return PreParserStatement::Default();
462 } 462 }
463 Consume(Token::LET); 463 Consume(Token::LET);
464 if (var_context != kSourceElement && 464 if (var_context != kSourceElement &&
465 var_context != kForStatement) { 465 var_context != kForStatement) {
466 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 466 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
467 *ok = false; 467 *ok = false;
468 return Statement::Default(); 468 return PreParserStatement::Default();
469 } 469 }
470 } else { 470 } else {
471 *ok = false; 471 *ok = false;
472 return Statement::Default(); 472 return PreParserStatement::Default();
473 } 473 }
474 474
475 // The scope of a var/const declared variable anywhere inside a function 475 // The scope of a var/const declared variable anywhere inside a function
476 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 476 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
477 // of a let declared variable is the scope of the immediately enclosing 477 // of a let declared variable is the scope of the immediately enclosing
478 // block. 478 // block.
479 int nvars = 0; // the number of variables declared 479 int nvars = 0; // the number of variables declared
480 do { 480 do {
481 // Parse variable name. 481 // Parse variable name.
482 if (nvars > 0) Consume(Token::COMMA); 482 if (nvars > 0) Consume(Token::COMMA);
483 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 483 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
484 nvars++; 484 nvars++;
485 if (peek() == Token::ASSIGN || require_initializer) { 485 if (peek() == Token::ASSIGN || require_initializer) {
486 Expect(Token::ASSIGN, CHECK_OK); 486 Expect(Token::ASSIGN, CHECK_OK);
487 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 487 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
488 if (decl_props != NULL) *decl_props = kHasInitializers; 488 if (decl_props != NULL) *decl_props = kHasInitializers;
489 } 489 }
490 } while (peek() == Token::COMMA); 490 } while (peek() == Token::COMMA);
491 491
492 if (num_decl != NULL) *num_decl = nvars; 492 if (num_decl != NULL) *num_decl = nvars;
493 return Statement::Default(); 493 return PreParserStatement::Default();
494 } 494 }
495 495
496 496
497 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 497 PreParserStatement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
498 // ExpressionStatement | LabelledStatement :: 498 // ExpressionStatement | LabelledStatement ::
499 // Expression ';' 499 // Expression ';'
500 // Identifier ':' Statement 500 // Identifier ':' Statement
501 501
502 bool starts_with_identifier = peek_any_identifier(); 502 bool starts_with_identifier = peek_any_identifier();
503 Expression expr = ParseExpression(true, CHECK_OK); 503 Expression expr = ParseExpression(true, CHECK_OK);
504 // Even if the expression starts with an identifier, it is not necessarily an 504 // Even if the expression starts with an identifier, it is not necessarily an
505 // identifier. For example, "foo + bar" starts with an identifier but is not 505 // identifier. For example, "foo + bar" starts with an identifier but is not
506 // an identifier. 506 // an identifier.
507 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 507 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
508 // Expression is a single identifier, and not, e.g., a parenthesized 508 // Expression is a single identifier, and not, e.g., a parenthesized
509 // identifier. 509 // identifier.
510 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 510 ASSERT(!expr.AsIdentifier().IsFutureReserved());
511 ASSERT(strict_mode() == SLOPPY || 511 ASSERT(strict_mode() == SLOPPY ||
512 (!expr.AsIdentifier().IsFutureStrictReserved() && 512 (!expr.AsIdentifier().IsFutureStrictReserved() &&
513 !expr.AsIdentifier().IsYield())); 513 !expr.AsIdentifier().IsYield()));
514 Consume(Token::COLON); 514 Consume(Token::COLON);
515 return ParseStatement(ok); 515 return ParseStatement(ok);
516 // Preparsing is disabled for extensions (because the extension details 516 // Preparsing is disabled for extensions (because the extension details
517 // aren't passed to lazily compiled functions), so we don't 517 // aren't passed to lazily compiled functions), so we don't
518 // accept "native function" in the preparser. 518 // accept "native function" in the preparser.
519 } 519 }
520 // Parsed expression statement. 520 // Parsed expression statement.
521 ExpectSemicolon(CHECK_OK); 521 ExpectSemicolon(CHECK_OK);
522 return Statement::ExpressionStatement(expr); 522 return PreParserStatement::ExpressionStatement(expr);
523 } 523 }
524 524
525 525
526 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 526 PreParserStatement PreParser::ParseIfStatement(bool* ok) {
527 // IfStatement :: 527 // IfStatement ::
528 // 'if' '(' Expression ')' Statement ('else' Statement)? 528 // 'if' '(' Expression ')' Statement ('else' Statement)?
529 529
530 Expect(Token::IF, CHECK_OK); 530 Expect(Token::IF, CHECK_OK);
531 Expect(Token::LPAREN, CHECK_OK); 531 Expect(Token::LPAREN, CHECK_OK);
532 ParseExpression(true, CHECK_OK); 532 ParseExpression(true, CHECK_OK);
533 Expect(Token::RPAREN, CHECK_OK); 533 Expect(Token::RPAREN, CHECK_OK);
534 ParseStatement(CHECK_OK); 534 ParseStatement(CHECK_OK);
535 if (peek() == Token::ELSE) { 535 if (peek() == Token::ELSE) {
536 Next(); 536 Next();
537 ParseStatement(CHECK_OK); 537 ParseStatement(CHECK_OK);
538 } 538 }
539 return Statement::Default(); 539 return PreParserStatement::Default();
540 } 540 }
541 541
542 542
543 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 543 PreParserStatement PreParser::ParseContinueStatement(bool* ok) {
544 // ContinueStatement :: 544 // ContinueStatement ::
545 // 'continue' [no line terminator] Identifier? ';' 545 // 'continue' [no line terminator] Identifier? ';'
546 546
547 Expect(Token::CONTINUE, CHECK_OK); 547 Expect(Token::CONTINUE, CHECK_OK);
548 Token::Value tok = peek(); 548 Token::Value tok = peek();
549 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 549 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
550 tok != Token::SEMICOLON && 550 tok != Token::SEMICOLON &&
551 tok != Token::RBRACE && 551 tok != Token::RBRACE &&
552 tok != Token::EOS) { 552 tok != Token::EOS) {
553 // ECMA allows "eval" or "arguments" as labels even in strict mode. 553 // ECMA allows "eval" or "arguments" as labels even in strict mode.
554 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 554 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
555 } 555 }
556 ExpectSemicolon(CHECK_OK); 556 ExpectSemicolon(CHECK_OK);
557 return Statement::Default(); 557 return PreParserStatement::Default();
558 } 558 }
559 559
560 560
561 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 561 PreParserStatement PreParser::ParseBreakStatement(bool* ok) {
562 // BreakStatement :: 562 // BreakStatement ::
563 // 'break' [no line terminator] Identifier? ';' 563 // 'break' [no line terminator] Identifier? ';'
564 564
565 Expect(Token::BREAK, CHECK_OK); 565 Expect(Token::BREAK, CHECK_OK);
566 Token::Value tok = peek(); 566 Token::Value tok = peek();
567 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 567 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
568 tok != Token::SEMICOLON && 568 tok != Token::SEMICOLON &&
569 tok != Token::RBRACE && 569 tok != Token::RBRACE &&
570 tok != Token::EOS) { 570 tok != Token::EOS) {
571 // ECMA allows "eval" or "arguments" as labels even in strict mode. 571 // ECMA allows "eval" or "arguments" as labels even in strict mode.
572 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 572 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
573 } 573 }
574 ExpectSemicolon(CHECK_OK); 574 ExpectSemicolon(CHECK_OK);
575 return Statement::Default(); 575 return PreParserStatement::Default();
576 } 576 }
577 577
578 578
579 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 579 PreParserStatement PreParser::ParseReturnStatement(bool* ok) {
580 // ReturnStatement :: 580 // ReturnStatement ::
581 // 'return' [no line terminator] Expression? ';' 581 // 'return' [no line terminator] Expression? ';'
582 582
583 // Consume the return token. It is necessary to do before 583 // Consume the return token. It is necessary to do before
584 // reporting any errors on it, because of the way errors are 584 // reporting any errors on it, because of the way errors are
585 // reported (underlining). 585 // reported (underlining).
586 Expect(Token::RETURN, CHECK_OK); 586 Expect(Token::RETURN, CHECK_OK);
587 587
588 // An ECMAScript program is considered syntactically incorrect if it 588 // An ECMAScript program is considered syntactically incorrect if it
589 // contains a return statement that is not within the body of a 589 // contains a return statement that is not within the body of a
590 // function. See ECMA-262, section 12.9, page 67. 590 // function. See ECMA-262, section 12.9, page 67.
591 // This is not handled during preparsing. 591 // This is not handled during preparsing.
592 592
593 Token::Value tok = peek(); 593 Token::Value tok = peek();
594 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 594 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
595 tok != Token::SEMICOLON && 595 tok != Token::SEMICOLON &&
596 tok != Token::RBRACE && 596 tok != Token::RBRACE &&
597 tok != Token::EOS) { 597 tok != Token::EOS) {
598 ParseExpression(true, CHECK_OK); 598 ParseExpression(true, CHECK_OK);
599 } 599 }
600 ExpectSemicolon(CHECK_OK); 600 ExpectSemicolon(CHECK_OK);
601 return Statement::Default(); 601 return PreParserStatement::Default();
602 } 602 }
603 603
604 604
605 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 605 PreParserStatement PreParser::ParseWithStatement(bool* ok) {
606 // WithStatement :: 606 // WithStatement ::
607 // 'with' '(' Expression ')' Statement 607 // 'with' '(' Expression ')' Statement
608 Expect(Token::WITH, CHECK_OK); 608 Expect(Token::WITH, CHECK_OK);
609 if (strict_mode() == STRICT) { 609 if (strict_mode() == STRICT) {
610 ReportMessageAt(scanner()->location(), "strict_mode_with"); 610 ReportMessageAt(scanner()->location(), "strict_mode_with");
611 *ok = false; 611 *ok = false;
612 return Statement::Default(); 612 return PreParserStatement::Default();
613 } 613 }
614 Expect(Token::LPAREN, CHECK_OK); 614 Expect(Token::LPAREN, CHECK_OK);
615 ParseExpression(true, CHECK_OK); 615 ParseExpression(true, CHECK_OK);
616 Expect(Token::RPAREN, CHECK_OK); 616 Expect(Token::RPAREN, CHECK_OK);
617 617
618 PreParserScope with_scope(scope_, WITH_SCOPE); 618 PreParserScope with_scope(scope_, WITH_SCOPE);
619 BlockState block_state(&scope_, &with_scope); 619 BlockState block_state(&scope_, &with_scope);
620 ParseStatement(CHECK_OK); 620 ParseStatement(CHECK_OK);
621 return Statement::Default(); 621 return PreParserStatement::Default();
622 } 622 }
623 623
624 624
625 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 625 PreParserStatement PreParser::ParseSwitchStatement(bool* ok) {
626 // SwitchStatement :: 626 // SwitchStatement ::
627 // 'switch' '(' Expression ')' '{' CaseClause* '}' 627 // 'switch' '(' Expression ')' '{' CaseClause* '}'
628 628
629 Expect(Token::SWITCH, CHECK_OK); 629 Expect(Token::SWITCH, CHECK_OK);
630 Expect(Token::LPAREN, CHECK_OK); 630 Expect(Token::LPAREN, CHECK_OK);
631 ParseExpression(true, CHECK_OK); 631 ParseExpression(true, CHECK_OK);
632 Expect(Token::RPAREN, CHECK_OK); 632 Expect(Token::RPAREN, CHECK_OK);
633 633
634 Expect(Token::LBRACE, CHECK_OK); 634 Expect(Token::LBRACE, CHECK_OK);
635 Token::Value token = peek(); 635 Token::Value token = peek();
636 while (token != Token::RBRACE) { 636 while (token != Token::RBRACE) {
637 if (token == Token::CASE) { 637 if (token == Token::CASE) {
638 Expect(Token::CASE, CHECK_OK); 638 Expect(Token::CASE, CHECK_OK);
639 ParseExpression(true, CHECK_OK); 639 ParseExpression(true, CHECK_OK);
640 } else { 640 } else {
641 Expect(Token::DEFAULT, CHECK_OK); 641 Expect(Token::DEFAULT, CHECK_OK);
642 } 642 }
643 Expect(Token::COLON, CHECK_OK); 643 Expect(Token::COLON, CHECK_OK);
644 token = peek(); 644 token = peek();
645 while (token != Token::CASE && 645 while (token != Token::CASE &&
646 token != Token::DEFAULT && 646 token != Token::DEFAULT &&
647 token != Token::RBRACE) { 647 token != Token::RBRACE) {
648 ParseStatement(CHECK_OK); 648 ParseStatement(CHECK_OK);
649 token = peek(); 649 token = peek();
650 } 650 }
651 } 651 }
652 Expect(Token::RBRACE, ok); 652 Expect(Token::RBRACE, ok);
653 return Statement::Default(); 653 return PreParserStatement::Default();
654 } 654 }
655 655
656 656
657 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 657 PreParserStatement PreParser::ParseDoWhileStatement(bool* ok) {
658 // DoStatement :: 658 // DoStatement ::
659 // 'do' Statement 'while' '(' Expression ')' ';' 659 // 'do' Statement 'while' '(' Expression ')' ';'
660 660
661 Expect(Token::DO, CHECK_OK); 661 Expect(Token::DO, CHECK_OK);
662 ParseStatement(CHECK_OK); 662 ParseStatement(CHECK_OK);
663 Expect(Token::WHILE, CHECK_OK); 663 Expect(Token::WHILE, CHECK_OK);
664 Expect(Token::LPAREN, CHECK_OK); 664 Expect(Token::LPAREN, CHECK_OK);
665 ParseExpression(true, CHECK_OK); 665 ParseExpression(true, CHECK_OK);
666 Expect(Token::RPAREN, ok); 666 Expect(Token::RPAREN, ok);
667 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 667 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
668 return Statement::Default(); 668 return PreParserStatement::Default();
669 } 669 }
670 670
671 671
672 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { 672 PreParserStatement PreParser::ParseWhileStatement(bool* ok) {
673 // WhileStatement :: 673 // WhileStatement ::
674 // 'while' '(' Expression ')' Statement 674 // 'while' '(' Expression ')' Statement
675 675
676 Expect(Token::WHILE, CHECK_OK); 676 Expect(Token::WHILE, CHECK_OK);
677 Expect(Token::LPAREN, CHECK_OK); 677 Expect(Token::LPAREN, CHECK_OK);
678 ParseExpression(true, CHECK_OK); 678 ParseExpression(true, CHECK_OK);
679 Expect(Token::RPAREN, CHECK_OK); 679 Expect(Token::RPAREN, CHECK_OK);
680 ParseStatement(ok); 680 ParseStatement(ok);
681 return Statement::Default(); 681 return PreParserStatement::Default();
682 } 682 }
683 683
684 684
685 bool PreParser::CheckInOrOf(bool accept_OF) { 685 bool PreParser::CheckInOrOf(bool accept_OF) {
686 if (Check(Token::IN) || 686 if (Check(Token::IN) ||
687 (allow_for_of() && accept_OF && 687 (allow_for_of() && accept_OF &&
688 CheckContextualKeyword(CStrVector("of")))) { 688 CheckContextualKeyword(CStrVector("of")))) {
689 return true; 689 return true;
690 } 690 }
691 return false; 691 return false;
692 } 692 }
693 693
694 694
695 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 695 PreParserStatement PreParser::ParseForStatement(bool* ok) {
696 // ForStatement :: 696 // ForStatement ::
697 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 697 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
698 698
699 Expect(Token::FOR, CHECK_OK); 699 Expect(Token::FOR, CHECK_OK);
700 Expect(Token::LPAREN, CHECK_OK); 700 Expect(Token::LPAREN, CHECK_OK);
701 if (peek() != Token::SEMICOLON) { 701 if (peek() != Token::SEMICOLON) {
702 if (peek() == Token::VAR || peek() == Token::CONST || 702 if (peek() == Token::VAR || peek() == Token::CONST ||
703 peek() == Token::LET) { 703 peek() == Token::LET) {
704 bool is_let = peek() == Token::LET; 704 bool is_let = peek() == Token::LET;
705 int decl_count; 705 int decl_count;
706 VariableDeclarationProperties decl_props = kHasNoInitializers; 706 VariableDeclarationProperties decl_props = kHasNoInitializers;
707 ParseVariableDeclarations( 707 ParseVariableDeclarations(
708 kForStatement, &decl_props, &decl_count, CHECK_OK); 708 kForStatement, &decl_props, &decl_count, CHECK_OK);
709 bool has_initializers = decl_props == kHasInitializers; 709 bool has_initializers = decl_props == kHasInitializers;
710 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 710 bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
711 bool accept_OF = !has_initializers; 711 bool accept_OF = !has_initializers;
712 if (accept_IN && CheckInOrOf(accept_OF)) { 712 if (accept_IN && CheckInOrOf(accept_OF)) {
713 ParseExpression(true, CHECK_OK); 713 ParseExpression(true, CHECK_OK);
714 Expect(Token::RPAREN, CHECK_OK); 714 Expect(Token::RPAREN, CHECK_OK);
715 715
716 ParseStatement(CHECK_OK); 716 ParseStatement(CHECK_OK);
717 return Statement::Default(); 717 return PreParserStatement::Default();
718 } 718 }
719 } else { 719 } else {
720 Expression lhs = ParseExpression(false, CHECK_OK); 720 Expression lhs = ParseExpression(false, CHECK_OK);
721 if (CheckInOrOf(lhs.IsIdentifier())) { 721 if (CheckInOrOf(lhs.IsIdentifier())) {
722 ParseExpression(true, CHECK_OK); 722 ParseExpression(true, CHECK_OK);
723 Expect(Token::RPAREN, CHECK_OK); 723 Expect(Token::RPAREN, CHECK_OK);
724 724
725 ParseStatement(CHECK_OK); 725 ParseStatement(CHECK_OK);
726 return Statement::Default(); 726 return PreParserStatement::Default();
727 } 727 }
728 } 728 }
729 } 729 }
730 730
731 // Parsed initializer at this point. 731 // Parsed initializer at this point.
732 Expect(Token::SEMICOLON, CHECK_OK); 732 Expect(Token::SEMICOLON, CHECK_OK);
733 733
734 if (peek() != Token::SEMICOLON) { 734 if (peek() != Token::SEMICOLON) {
735 ParseExpression(true, CHECK_OK); 735 ParseExpression(true, CHECK_OK);
736 } 736 }
737 Expect(Token::SEMICOLON, CHECK_OK); 737 Expect(Token::SEMICOLON, CHECK_OK);
738 738
739 if (peek() != Token::RPAREN) { 739 if (peek() != Token::RPAREN) {
740 ParseExpression(true, CHECK_OK); 740 ParseExpression(true, CHECK_OK);
741 } 741 }
742 Expect(Token::RPAREN, CHECK_OK); 742 Expect(Token::RPAREN, CHECK_OK);
743 743
744 ParseStatement(ok); 744 ParseStatement(ok);
745 return Statement::Default(); 745 return PreParserStatement::Default();
746 } 746 }
747 747
748 748
749 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 749 PreParserStatement PreParser::ParseThrowStatement(bool* ok) {
750 // ThrowStatement :: 750 // ThrowStatement ::
751 // 'throw' [no line terminator] Expression ';' 751 // 'throw' [no line terminator] Expression ';'
752 752
753 Expect(Token::THROW, CHECK_OK); 753 Expect(Token::THROW, CHECK_OK);
754 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 754 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
755 ReportMessageAt(scanner()->location(), "newline_after_throw"); 755 ReportMessageAt(scanner()->location(), "newline_after_throw");
756 *ok = false; 756 *ok = false;
757 return Statement::Default(); 757 return PreParserStatement::Default();
758 } 758 }
759 ParseExpression(true, CHECK_OK); 759 ParseExpression(true, CHECK_OK);
760 ExpectSemicolon(ok); 760 ExpectSemicolon(ok);
761 return Statement::Default(); 761 return PreParserStatement::Default();
762 } 762 }
763 763
764 764
765 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { 765 PreParserStatement PreParser::ParseTryStatement(bool* ok) {
766 // TryStatement :: 766 // TryStatement ::
767 // 'try' Block Catch 767 // 'try' Block Catch
768 // 'try' Block Finally 768 // 'try' Block Finally
769 // 'try' Block Catch Finally 769 // 'try' Block Catch Finally
770 // 770 //
771 // Catch :: 771 // Catch ::
772 // 'catch' '(' Identifier ')' Block 772 // 'catch' '(' Identifier ')' Block
773 // 773 //
774 // Finally :: 774 // Finally ::
775 // 'finally' Block 775 // 'finally' Block
776 776
777 Expect(Token::TRY, CHECK_OK); 777 Expect(Token::TRY, CHECK_OK);
778 778
779 ParseBlock(CHECK_OK); 779 ParseBlock(CHECK_OK);
780 780
781 Token::Value tok = peek(); 781 Token::Value tok = peek();
782 if (tok != Token::CATCH && tok != Token::FINALLY) { 782 if (tok != Token::CATCH && tok != Token::FINALLY) {
783 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); 783 ReportMessageAt(scanner()->location(), "no_catch_or_finally");
784 *ok = false; 784 *ok = false;
785 return Statement::Default(); 785 return PreParserStatement::Default();
786 } 786 }
787 if (tok == Token::CATCH) { 787 if (tok == Token::CATCH) {
788 Consume(Token::CATCH); 788 Consume(Token::CATCH);
789 Expect(Token::LPAREN, CHECK_OK); 789 Expect(Token::LPAREN, CHECK_OK);
790 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 790 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
791 Expect(Token::RPAREN, CHECK_OK); 791 Expect(Token::RPAREN, CHECK_OK);
792 { 792 {
793 PreParserScope with_scope(scope_, WITH_SCOPE); 793 PreParserScope with_scope(scope_, WITH_SCOPE);
794 BlockState block_state(&scope_, &with_scope); 794 BlockState block_state(&scope_, &with_scope);
795 ParseBlock(CHECK_OK); 795 ParseBlock(CHECK_OK);
796 } 796 }
797 tok = peek(); 797 tok = peek();
798 } 798 }
799 if (tok == Token::FINALLY) { 799 if (tok == Token::FINALLY) {
800 Consume(Token::FINALLY); 800 Consume(Token::FINALLY);
801 ParseBlock(CHECK_OK); 801 ParseBlock(CHECK_OK);
802 } 802 }
803 return Statement::Default(); 803 return PreParserStatement::Default();
804 } 804 }
805 805
806 806
807 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 807 PreParserStatement PreParser::ParseDebuggerStatement(bool* ok) {
808 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 808 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
809 // contexts this is used as a statement which invokes the debugger as if a 809 // contexts this is used as a statement which invokes the debugger as if a
810 // break point is present. 810 // break point is present.
811 // DebuggerStatement :: 811 // DebuggerStatement ::
812 // 'debugger' ';' 812 // 'debugger' ';'
813 813
814 Expect(Token::DEBUGGER, CHECK_OK); 814 Expect(Token::DEBUGGER, CHECK_OK);
815 ExpectSemicolon(ok); 815 ExpectSemicolon(ok);
816 return Statement::Default(); 816 return PreParserStatement::Default();
817 } 817 }
818 818
819 819
820 #undef CHECK_OK 820 #undef CHECK_OK
821 #define CHECK_OK ok); \ 821 #define CHECK_OK ok); \
822 if (!*ok) return Expression::Default(); \ 822 if (!*ok) return Expression::Default(); \
823 ((void)0 823 ((void)0
824 #define DUMMY ) // to make indentation work 824 #define DUMMY ) // to make indentation work
825 #undef DUMMY 825 #undef DUMMY
826 826
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 955 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
956 ParseArguments(ok); 956 ParseArguments(ok);
957 957
958 return Expression::Default(); 958 return Expression::Default();
959 } 959 }
960 960
961 #undef CHECK_OK 961 #undef CHECK_OK
962 962
963 963
964 } } // v8::internal 964 } } // v8::internal
OLDNEW
« src/preparser.h ('K') | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698