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

Side by Side Diff: src/preparser.h

Issue 4576001: Move part of scanner.* into scanner-base.* for reuse in preparser scanner. (Closed)
Patch Set: Created 10 years, 1 month 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
« no previous file with comments | « src/checks.cc ('k') | src/scanner.h » ('j') | src/scanner-base.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_PREPARSER_H 28 #ifndef V8_PREPARSER_H
29 #define V8_PREPARSER_H 29 #define V8_PREPARSER_H
30 30
31 #include "unicode.h" 31 #include "unicode.h"
32 32
33 namespace v8 { 33 namespace v8 {
34 namespace internal {
35 namespace preparser { 34 namespace preparser {
36 35
37 // Preparsing checks a JavaScript program and emits preparse-data that helps 36 // Preparsing checks a JavaScript program and emits preparse-data that helps
38 // a later parsing to be faster. 37 // a later parsing to be faster.
39 // See preparser-data.h for the data. 38 // See preparser-data.h for the data.
40 39
41 // The PreParser checks that the syntax follows the grammar for JavaScript, 40 // The PreParser checks that the syntax follows the grammar for JavaScript,
42 // and collects some information about the program along the way. 41 // and collects some information about the program along the way.
43 // The grammar check is only performed in order to understand the program 42 // The grammar check is only performed in order to understand the program
44 // sufficiently to deduce some information about it, that can be used 43 // sufficiently to deduce some information about it, that can be used
45 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 44 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
46 // rather it is to speed up properly written and correct programs. 45 // rather it is to speed up properly written and correct programs.
47 // That means that contextual checks (like a label being declared where 46 // That means that contextual checks (like a label being declared where
48 // it is used) are generally omitted. 47 // it is used) are generally omitted.
49 48
49 namespace i = v8::internal;
50
50 enum StatementType { 51 enum StatementType {
51 kUnknownStatement 52 kUnknownStatement
52 }; 53 };
53 54
54 enum ExpressionType { 55 enum ExpressionType {
55 kUnknownExpression, 56 kUnknownExpression,
56 kIdentifierExpression, // Used to detect labels. 57 kIdentifierExpression, // Used to detect labels.
57 kThisExpression, 58 kThisExpression,
58 kThisPropertyExpression 59 kThisPropertyExpression
59 }; 60 };
(...skipping 25 matching lines...) Expand all
85 // captured the syntax error), and false if a stack-overflow happened 86 // captured the syntax error), and false if a stack-overflow happened
86 // during parsing. 87 // during parsing.
87 bool PreParseProgram(Scanner* scanner, 88 bool PreParseProgram(Scanner* scanner,
88 PreParserLog* log, 89 PreParserLog* log,
89 bool allow_lazy) { 90 bool allow_lazy) {
90 allow_lazy_ = allow_lazy; 91 allow_lazy_ = allow_lazy;
91 scanner_ = scanner; 92 scanner_ = scanner;
92 log_ = log; 93 log_ = log;
93 Scope top_scope(&scope_, kTopLevelScope); 94 Scope top_scope(&scope_, kTopLevelScope);
94 bool ok = true; 95 bool ok = true;
95 ParseSourceElements(Token::EOS, &ok); 96 ParseSourceElements(i::Token::EOS, &ok);
96 bool stack_overflow = scanner_->stack_overflow(); 97 bool stack_overflow = scanner_->stack_overflow();
97 if (!ok && !stack_overflow) { 98 if (!ok && !stack_overflow) {
98 ReportUnexpectedToken(scanner_->current_token()); 99 ReportUnexpectedToken(scanner_->current_token());
99 } 100 }
100 return !stack_overflow; 101 return !stack_overflow;
101 } 102 }
102 103
103 private: 104 private:
104 enum ScopeType { 105 enum ScopeType {
105 kTopLevelScope, 106 kTopLevelScope,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 }; 138 };
138 139
139 // Types that allow us to recognize simple this-property assignments. 140 // Types that allow us to recognize simple this-property assignments.
140 // A simple this-property assignment is a statement on the form 141 // A simple this-property assignment is a statement on the form
141 // "this.propertyName = {primitive constant or function parameter name);" 142 // "this.propertyName = {primitive constant or function parameter name);"
142 // where propertyName isn't "__proto__". 143 // where propertyName isn't "__proto__".
143 // The result is only relevant if the function body contains only 144 // The result is only relevant if the function body contains only
144 // simple this-property assignments. 145 // simple this-property assignments.
145 146
146 // Report syntax error 147 // Report syntax error
147 void ReportUnexpectedToken(Token::Value token); 148 void ReportUnexpectedToken(i::Token::Value token);
148 void ReportMessageAt(int start_pos, 149 void ReportMessageAt(int start_pos,
149 int end_pos, 150 int end_pos,
150 const char* type, 151 const char* type,
151 const char* name_opt) { 152 const char* name_opt) {
152 log_->LogMessage(start_pos, end_pos, type, name_opt); 153 log_->LogMessage(start_pos, end_pos, type, name_opt);
153 } 154 }
154 155
155 // All ParseXXX functions take as the last argument an *ok parameter 156 // All ParseXXX functions take as the last argument an *ok parameter
156 // which is set to false if parsing failed; it is unchanged otherwise. 157 // which is set to false if parsing failed; it is unchanged otherwise.
157 // By making the 'exception handling' explicit, we are forced to check 158 // By making the 'exception handling' explicit, we are forced to check
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 199
199 Identifier ParseIdentifier(bool* ok); 200 Identifier ParseIdentifier(bool* ok);
200 Identifier ParseIdentifierName(bool* ok); 201 Identifier ParseIdentifierName(bool* ok);
201 Identifier ParseIdentifierOrGetOrSet(bool* is_get, bool* is_set, bool* ok); 202 Identifier ParseIdentifierOrGetOrSet(bool* is_get, bool* is_set, bool* ok);
202 203
203 Identifier GetIdentifierSymbol(); 204 Identifier GetIdentifierSymbol();
204 unsigned int HexDigitValue(char digit); 205 unsigned int HexDigitValue(char digit);
205 Expression GetStringSymbol(); 206 Expression GetStringSymbol();
206 207
207 208
208 Token::Value peek() { return scanner_->peek(); } 209 i::Token::Value peek() { return scanner_->peek(); }
209 Token::Value Next() { 210 i::Token::Value Next() {
210 Token::Value next = scanner_->Next(); 211 i::Token::Value next = scanner_->Next();
211 return next; 212 return next;
212 } 213 }
213 214
214 void Consume(Token::Value token) { 215 void Consume(i::Token::Value token) {
215 Next(); 216 Next();
216 } 217 }
217 218
218 void Expect(Token::Value token, bool* ok) { 219 void Expect(i::Token::Value token, bool* ok) {
219 if (Next() != token) { 220 if (Next() != token) {
220 *ok = false; 221 *ok = false;
221 } 222 }
222 } 223 }
223 224
224 bool Check(Token::Value token) { 225 bool Check(i::Token::Value token) {
225 Token::Value next = peek(); 226 i::Token::Value next = peek();
226 if (next == token) { 227 if (next == token) {
227 Consume(next); 228 Consume(next);
228 return true; 229 return true;
229 } 230 }
230 return false; 231 return false;
231 } 232 }
232 void ExpectSemicolon(bool* ok); 233 void ExpectSemicolon(bool* ok);
233 234
234 static int Precedence(Token::Value tok, bool accept_IN); 235 static int Precedence(i::Token::Value tok, bool accept_IN);
235 236
236 Scanner* scanner_; 237 Scanner* scanner_;
237 PreParserLog* log_; 238 PreParserLog* log_;
238 Scope* scope_; 239 Scope* scope_;
239 bool allow_lazy_; 240 bool allow_lazy_;
240 }; 241 };
241 242
242 243
243 #define CHECK_OK ok); \ 244 #define CHECK_OK ok); \
244 if (!*ok) return -1; \ 245 if (!*ok) return -1; \
245 ((void)0 246 ((void)0
246 #define DUMMY ) // to make indentation work 247 #define DUMMY ) // to make indentation work
247 #undef DUMMY 248 #undef DUMMY
248 249
249 250
250 template <typename Scanner, typename Log> 251 template <typename Scanner, typename Log>
251 void PreParser<Scanner, Log>::ReportUnexpectedToken(Token::Value token) { 252 void PreParser<Scanner, Log>::ReportUnexpectedToken(i::Token::Value token) {
252 // We don't report stack overflows here, to avoid increasing the 253 // We don't report stack overflows here, to avoid increasing the
253 // stack depth even further. Instead we report it after parsing is 254 // stack depth even further. Instead we report it after parsing is
254 // over, in ParseProgram. 255 // over, in ParseProgram.
255 if (token == Token::ILLEGAL && scanner_->stack_overflow()) { 256 if (token == i::Token::ILLEGAL && scanner_->stack_overflow()) {
256 return; 257 return;
257 } 258 }
258 typename Scanner::Location source_location = scanner_->location(); 259 typename Scanner::Location source_location = scanner_->location();
259 260
260 // Four of the tokens are treated specially 261 // Four of the tokens are treated specially
261 switch (token) { 262 switch (token) {
262 case Token::EOS: 263 case i::Token::EOS:
263 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 264 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
264 "unexpected_eos", NULL); 265 "unexpected_eos", NULL);
265 case Token::NUMBER: 266 case i::Token::NUMBER:
266 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 267 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
267 "unexpected_token_number", NULL); 268 "unexpected_token_number", NULL);
268 case Token::STRING: 269 case i::Token::STRING:
269 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 270 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
270 "unexpected_token_string", NULL); 271 "unexpected_token_string", NULL);
271 case Token::IDENTIFIER: 272 case i::Token::IDENTIFIER:
272 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 273 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
273 "unexpected_token_identifier", NULL); 274 "unexpected_token_identifier", NULL);
274 default: 275 default:
275 const char* name = Token::String(token); 276 const char* name = i::Token::String(token);
276 ReportMessageAt(source_location.beg_pos, source_location.end_pos, 277 ReportMessageAt(source_location.beg_pos, source_location.end_pos,
277 "unexpected_token", name); 278 "unexpected_token", name);
278 } 279 }
279 } 280 }
280 281
281 282
282 template <typename Scanner, typename Log> 283 template <typename Scanner, typename Log>
283 SourceElements PreParser<Scanner, Log>::ParseSourceElements(int end_token, 284 SourceElements PreParser<Scanner, Log>::ParseSourceElements(int end_token,
284 bool* ok) { 285 bool* ok) {
285 // SourceElements :: 286 // SourceElements ::
(...skipping 27 matching lines...) Expand all
313 314
314 // Note: Since labels can only be used by 'break' and 'continue' 315 // Note: Since labels can only be used by 'break' and 'continue'
315 // statements, which themselves are only valid within blocks, 316 // statements, which themselves are only valid within blocks,
316 // iterations or 'switch' statements (i.e., BreakableStatements), 317 // iterations or 'switch' statements (i.e., BreakableStatements),
317 // labels can be simply ignored in all other cases; except for 318 // labels can be simply ignored in all other cases; except for
318 // trivial labeled break statements 'label: break label' which is 319 // trivial labeled break statements 'label: break label' which is
319 // parsed into an empty statement. 320 // parsed into an empty statement.
320 321
321 // Keep the source position of the statement 322 // Keep the source position of the statement
322 switch (peek()) { 323 switch (peek()) {
323 case Token::LBRACE: 324 case i::Token::LBRACE:
324 return ParseBlock(ok); 325 return ParseBlock(ok);
325 326
326 case Token::CONST: 327 case i::Token::CONST:
327 case Token::VAR: 328 case i::Token::VAR:
328 return ParseVariableStatement(ok); 329 return ParseVariableStatement(ok);
329 330
330 case Token::SEMICOLON: 331 case i::Token::SEMICOLON:
331 Next(); 332 Next();
332 return kUnknownStatement; 333 return kUnknownStatement;
333 334
334 case Token::IF: 335 case i::Token::IF:
335 return ParseIfStatement(ok); 336 return ParseIfStatement(ok);
336 337
337 case Token::DO: 338 case i::Token::DO:
338 return ParseDoWhileStatement(ok); 339 return ParseDoWhileStatement(ok);
339 340
340 case Token::WHILE: 341 case i::Token::WHILE:
341 return ParseWhileStatement(ok); 342 return ParseWhileStatement(ok);
342 343
343 case Token::FOR: 344 case i::Token::FOR:
344 return ParseForStatement(ok); 345 return ParseForStatement(ok);
345 346
346 case Token::CONTINUE: 347 case i::Token::CONTINUE:
347 return ParseContinueStatement(ok); 348 return ParseContinueStatement(ok);
348 349
349 case Token::BREAK: 350 case i::Token::BREAK:
350 return ParseBreakStatement(ok); 351 return ParseBreakStatement(ok);
351 352
352 case Token::RETURN: 353 case i::Token::RETURN:
353 return ParseReturnStatement(ok); 354 return ParseReturnStatement(ok);
354 355
355 case Token::WITH: 356 case i::Token::WITH:
356 return ParseWithStatement(ok); 357 return ParseWithStatement(ok);
357 358
358 case Token::SWITCH: 359 case i::Token::SWITCH:
359 return ParseSwitchStatement(ok); 360 return ParseSwitchStatement(ok);
360 361
361 case Token::THROW: 362 case i::Token::THROW:
362 return ParseThrowStatement(ok); 363 return ParseThrowStatement(ok);
363 364
364 case Token::TRY: 365 case i::Token::TRY:
365 return ParseTryStatement(ok); 366 return ParseTryStatement(ok);
366 367
367 case Token::FUNCTION: 368 case i::Token::FUNCTION:
368 return ParseFunctionDeclaration(ok); 369 return ParseFunctionDeclaration(ok);
369 370
370 case Token::NATIVE: 371 case i::Token::NATIVE:
371 return ParseNativeDeclaration(ok); 372 return ParseNativeDeclaration(ok);
372 373
373 case Token::DEBUGGER: 374 case i::Token::DEBUGGER:
374 return ParseDebuggerStatement(ok); 375 return ParseDebuggerStatement(ok);
375 376
376 default: 377 default:
377 return ParseExpressionOrLabelledStatement(ok); 378 return ParseExpressionOrLabelledStatement(ok);
378 } 379 }
379 } 380 }
380 381
381 382
382 template <typename Scanner, typename Log> 383 template <typename Scanner, typename Log>
383 Statement PreParser<Scanner, Log>::ParseFunctionDeclaration(bool* ok) { 384 Statement PreParser<Scanner, Log>::ParseFunctionDeclaration(bool* ok) {
384 // FunctionDeclaration :: 385 // FunctionDeclaration ::
385 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 386 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
386 Expect(Token::FUNCTION, CHECK_OK); 387 Expect(i::Token::FUNCTION, CHECK_OK);
387 ParseIdentifier(CHECK_OK); 388 ParseIdentifier(CHECK_OK);
388 ParseFunctionLiteral(CHECK_OK); 389 ParseFunctionLiteral(CHECK_OK);
389 return kUnknownStatement; 390 return kUnknownStatement;
390 } 391 }
391 392
392 393
393 // Language extension which is only enabled for source files loaded 394 // Language extension which is only enabled for source files loaded
394 // through the API's extension mechanism. A native function 395 // through the API's extension mechanism. A native function
395 // declaration is resolved by looking up the function through a 396 // declaration is resolved by looking up the function through a
396 // callback provided by the extension. 397 // callback provided by the extension.
397 template <typename Scanner, typename Log> 398 template <typename Scanner, typename Log>
398 Statement PreParser<Scanner, Log>::ParseNativeDeclaration(bool* ok) { 399 Statement PreParser<Scanner, Log>::ParseNativeDeclaration(bool* ok) {
399 Expect(Token::NATIVE, CHECK_OK); 400 Expect(i::Token::NATIVE, CHECK_OK);
400 Expect(Token::FUNCTION, CHECK_OK); 401 Expect(i::Token::FUNCTION, CHECK_OK);
401 ParseIdentifier(CHECK_OK); 402 ParseIdentifier(CHECK_OK);
402 Expect(Token::LPAREN, CHECK_OK); 403 Expect(i::Token::LPAREN, CHECK_OK);
403 bool done = (peek() == Token::RPAREN); 404 bool done = (peek() == i::Token::RPAREN);
404 while (!done) { 405 while (!done) {
405 ParseIdentifier(CHECK_OK); 406 ParseIdentifier(CHECK_OK);
406 done = (peek() == Token::RPAREN); 407 done = (peek() == i::Token::RPAREN);
407 if (!done) { 408 if (!done) {
408 Expect(Token::COMMA, CHECK_OK); 409 Expect(i::Token::COMMA, CHECK_OK);
409 } 410 }
410 } 411 }
411 Expect(Token::RPAREN, CHECK_OK); 412 Expect(i::Token::RPAREN, CHECK_OK);
412 Expect(Token::SEMICOLON, CHECK_OK); 413 Expect(i::Token::SEMICOLON, CHECK_OK);
413 return kUnknownStatement; 414 return kUnknownStatement;
414 } 415 }
415 416
416 417
417 template <typename Scanner, typename Log> 418 template <typename Scanner, typename Log>
418 Statement PreParser<Scanner, Log>::ParseBlock(bool* ok) { 419 Statement PreParser<Scanner, Log>::ParseBlock(bool* ok) {
419 // Block :: 420 // Block ::
420 // '{' Statement* '}' 421 // '{' Statement* '}'
421 422
422 // Note that a Block does not introduce a new execution scope! 423 // Note that a Block does not introduce a new execution scope!
423 // (ECMA-262, 3rd, 12.2) 424 // (ECMA-262, 3rd, 12.2)
424 // 425 //
425 Expect(Token::LBRACE, CHECK_OK); 426 Expect(i::Token::LBRACE, CHECK_OK);
426 while (peek() != Token::RBRACE) { 427 while (peek() != i::Token::RBRACE) {
427 ParseStatement(CHECK_OK); 428 ParseStatement(CHECK_OK);
428 } 429 }
429 Expect(Token::RBRACE, CHECK_OK); 430 Expect(i::Token::RBRACE, CHECK_OK);
430 return kUnknownStatement; 431 return kUnknownStatement;
431 } 432 }
432 433
433 434
434 template <typename Scanner, typename Log> 435 template <typename Scanner, typename Log>
435 Statement PreParser<Scanner, Log>::ParseVariableStatement(bool* ok) { 436 Statement PreParser<Scanner, Log>::ParseVariableStatement(bool* ok) {
436 // VariableStatement :: 437 // VariableStatement ::
437 // VariableDeclarations ';' 438 // VariableDeclarations ';'
438 439
439 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); 440 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK);
440 ExpectSemicolon(CHECK_OK); 441 ExpectSemicolon(CHECK_OK);
441 return result; 442 return result;
442 } 443 }
443 444
444 445
445 // If the variable declaration declares exactly one non-const 446 // If the variable declaration declares exactly one non-const
446 // variable, then *var is set to that variable. In all other cases, 447 // variable, then *var is set to that variable. In all other cases,
447 // *var is untouched; in particular, it is the caller's responsibility 448 // *var is untouched; in particular, it is the caller's responsibility
448 // to initialize it properly. This mechanism is also used for the parsing 449 // to initialize it properly. This mechanism is also used for the parsing
449 // of 'for-in' loops. 450 // of 'for-in' loops.
450 template <typename Scanner, typename Log> 451 template <typename Scanner, typename Log>
451 Statement PreParser<Scanner, Log>::ParseVariableDeclarations(bool accept_IN, 452 Statement PreParser<Scanner, Log>::ParseVariableDeclarations(bool accept_IN,
452 int* num_decl, 453 int* num_decl,
453 bool* ok) { 454 bool* ok) {
454 // VariableDeclarations :: 455 // VariableDeclarations ::
455 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 456 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
456 457
457 if (peek() == Token::VAR) { 458 if (peek() == i::Token::VAR) {
458 Consume(Token::VAR); 459 Consume(i::Token::VAR);
459 } else if (peek() == Token::CONST) { 460 } else if (peek() == i::Token::CONST) {
460 Consume(Token::CONST); 461 Consume(i::Token::CONST);
461 } else { 462 } else {
462 *ok = false; 463 *ok = false;
463 return 0; 464 return 0;
464 } 465 }
465 466
466 // The scope of a variable/const declared anywhere inside a function 467 // The scope of a variable/const declared anywhere inside a function
467 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). . 468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). .
468 int nvars = 0; // the number of variables declared 469 int nvars = 0; // the number of variables declared
469 do { 470 do {
470 // Parse variable name. 471 // Parse variable name.
471 if (nvars > 0) Consume(Token::COMMA); 472 if (nvars > 0) Consume(i::Token::COMMA);
472 ParseIdentifier(CHECK_OK); 473 ParseIdentifier(CHECK_OK);
473 nvars++; 474 nvars++;
474 if (peek() == Token::ASSIGN) { 475 if (peek() == i::Token::ASSIGN) {
475 Expect(Token::ASSIGN, CHECK_OK); 476 Expect(i::Token::ASSIGN, CHECK_OK);
476 ParseAssignmentExpression(accept_IN, CHECK_OK); 477 ParseAssignmentExpression(accept_IN, CHECK_OK);
477 } 478 }
478 } while (peek() == Token::COMMA); 479 } while (peek() == i::Token::COMMA);
479 480
480 if (num_decl != NULL) *num_decl = nvars; 481 if (num_decl != NULL) *num_decl = nvars;
481 return kUnknownStatement; 482 return kUnknownStatement;
482 } 483 }
483 484
484 485
485 template <typename Scanner, typename Log> 486 template <typename Scanner, typename Log>
486 Statement PreParser<Scanner, Log>::ParseExpressionOrLabelledStatement( 487 Statement PreParser<Scanner, Log>::ParseExpressionOrLabelledStatement(
487 bool* ok) { 488 bool* ok) {
488 // ExpressionStatement | LabelledStatement :: 489 // ExpressionStatement | LabelledStatement ::
489 // Expression ';' 490 // Expression ';'
490 // Identifier ':' Statement 491 // Identifier ':' Statement
491 492
492 Expression expr = ParseExpression(true, CHECK_OK); 493 Expression expr = ParseExpression(true, CHECK_OK);
493 if (peek() == Token::COLON && expr == kIdentifierExpression) { 494 if (peek() == i::Token::COLON && expr == kIdentifierExpression) {
494 Consume(Token::COLON); 495 Consume(i::Token::COLON);
495 return ParseStatement(ok); 496 return ParseStatement(ok);
496 } 497 }
497 // Parsed expression statement. 498 // Parsed expression statement.
498 ExpectSemicolon(CHECK_OK); 499 ExpectSemicolon(CHECK_OK);
499 return kUnknownStatement; 500 return kUnknownStatement;
500 } 501 }
501 502
502 503
503 template <typename Scanner, typename Log> 504 template <typename Scanner, typename Log>
504 Statement PreParser<Scanner, Log>::ParseIfStatement(bool* ok) { 505 Statement PreParser<Scanner, Log>::ParseIfStatement(bool* ok) {
505 // IfStatement :: 506 // IfStatement ::
506 // 'if' '(' Expression ')' Statement ('else' Statement)? 507 // 'if' '(' Expression ')' Statement ('else' Statement)?
507 508
508 Expect(Token::IF, CHECK_OK); 509 Expect(i::Token::IF, CHECK_OK);
509 Expect(Token::LPAREN, CHECK_OK); 510 Expect(i::Token::LPAREN, CHECK_OK);
510 ParseExpression(true, CHECK_OK); 511 ParseExpression(true, CHECK_OK);
511 Expect(Token::RPAREN, CHECK_OK); 512 Expect(i::Token::RPAREN, CHECK_OK);
512 ParseStatement(CHECK_OK); 513 ParseStatement(CHECK_OK);
513 if (peek() == Token::ELSE) { 514 if (peek() == i::Token::ELSE) {
514 Next(); 515 Next();
515 ParseStatement(CHECK_OK); 516 ParseStatement(CHECK_OK);
516 } 517 }
517 return kUnknownStatement; 518 return kUnknownStatement;
518 } 519 }
519 520
520 521
521 template <typename Scanner, typename Log> 522 template <typename Scanner, typename Log>
522 Statement PreParser<Scanner, Log>::ParseContinueStatement(bool* ok) { 523 Statement PreParser<Scanner, Log>::ParseContinueStatement(bool* ok) {
523 // ContinueStatement :: 524 // ContinueStatement ::
524 // 'continue' [no line terminator] Identifier? ';' 525 // 'continue' [no line terminator] Identifier? ';'
525 526
526 Expect(Token::CONTINUE, CHECK_OK); 527 Expect(i::Token::CONTINUE, CHECK_OK);
527 Token::Value tok = peek(); 528 i::Token::Value tok = peek();
528 if (!scanner_->has_line_terminator_before_next() && 529 if (!scanner_->has_line_terminator_before_next() &&
529 tok != Token::SEMICOLON && 530 tok != i::Token::SEMICOLON &&
530 tok != Token::RBRACE && 531 tok != i::Token::RBRACE &&
531 tok != Token::EOS) { 532 tok != i::Token::EOS) {
532 ParseIdentifier(CHECK_OK); 533 ParseIdentifier(CHECK_OK);
533 } 534 }
534 ExpectSemicolon(CHECK_OK); 535 ExpectSemicolon(CHECK_OK);
535 return kUnknownStatement; 536 return kUnknownStatement;
536 } 537 }
537 538
538 539
539 template <typename Scanner, typename Log> 540 template <typename Scanner, typename Log>
540 Statement PreParser<Scanner, Log>::ParseBreakStatement(bool* ok) { 541 Statement PreParser<Scanner, Log>::ParseBreakStatement(bool* ok) {
541 // BreakStatement :: 542 // BreakStatement ::
542 // 'break' [no line terminator] Identifier? ';' 543 // 'break' [no line terminator] Identifier? ';'
543 544
544 Expect(Token::BREAK, CHECK_OK); 545 Expect(i::Token::BREAK, CHECK_OK);
545 Token::Value tok = peek(); 546 i::Token::Value tok = peek();
546 if (!scanner_->has_line_terminator_before_next() && 547 if (!scanner_->has_line_terminator_before_next() &&
547 tok != Token::SEMICOLON && 548 tok != i::Token::SEMICOLON &&
548 tok != Token::RBRACE && 549 tok != i::Token::RBRACE &&
549 tok != Token::EOS) { 550 tok != i::Token::EOS) {
550 ParseIdentifier(CHECK_OK); 551 ParseIdentifier(CHECK_OK);
551 } 552 }
552 ExpectSemicolon(CHECK_OK); 553 ExpectSemicolon(CHECK_OK);
553 return kUnknownStatement; 554 return kUnknownStatement;
554 } 555 }
555 556
556 557
557 template <typename Scanner, typename Log> 558 template <typename Scanner, typename Log>
558 Statement PreParser<Scanner, Log>::ParseReturnStatement(bool* ok) { 559 Statement PreParser<Scanner, Log>::ParseReturnStatement(bool* ok) {
559 // ReturnStatement :: 560 // ReturnStatement ::
560 // 'return' [no line terminator] Expression? ';' 561 // 'return' [no line terminator] Expression? ';'
561 562
562 // Consume the return token. It is necessary to do the before 563 // Consume the return token. It is necessary to do the before
563 // reporting any errors on it, because of the way errors are 564 // reporting any errors on it, because of the way errors are
564 // reported (underlining). 565 // reported (underlining).
565 Expect(Token::RETURN, CHECK_OK); 566 Expect(i::Token::RETURN, CHECK_OK);
566 567
567 // An ECMAScript program is considered syntactically incorrect if it 568 // An ECMAScript program is considered syntactically incorrect if it
568 // contains a return statement that is not within the body of a 569 // contains a return statement that is not within the body of a
569 // function. See ECMA-262, section 12.9, page 67. 570 // function. See ECMA-262, section 12.9, page 67.
570 // This is not handled during preparsing. 571 // This is not handled during preparsing.
571 572
572 Token::Value tok = peek(); 573 i::Token::Value tok = peek();
573 if (!scanner_->has_line_terminator_before_next() && 574 if (!scanner_->has_line_terminator_before_next() &&
574 tok != Token::SEMICOLON && 575 tok != i::Token::SEMICOLON &&
575 tok != Token::RBRACE && 576 tok != i::Token::RBRACE &&
576 tok != Token::EOS) { 577 tok != i::Token::EOS) {
577 ParseExpression(true, CHECK_OK); 578 ParseExpression(true, CHECK_OK);
578 } 579 }
579 ExpectSemicolon(CHECK_OK); 580 ExpectSemicolon(CHECK_OK);
580 return kUnknownStatement; 581 return kUnknownStatement;
581 } 582 }
582 583
583 584
584 template <typename Scanner, typename Log> 585 template <typename Scanner, typename Log>
585 Statement PreParser<Scanner, Log>::ParseWithStatement(bool* ok) { 586 Statement PreParser<Scanner, Log>::ParseWithStatement(bool* ok) {
586 // WithStatement :: 587 // WithStatement ::
587 // 'with' '(' Expression ')' Statement 588 // 'with' '(' Expression ')' Statement
588 Expect(Token::WITH, CHECK_OK); 589 Expect(i::Token::WITH, CHECK_OK);
589 Expect(Token::LPAREN, CHECK_OK); 590 Expect(i::Token::LPAREN, CHECK_OK);
590 ParseExpression(true, CHECK_OK); 591 ParseExpression(true, CHECK_OK);
591 Expect(Token::RPAREN, CHECK_OK); 592 Expect(i::Token::RPAREN, CHECK_OK);
592 593
593 scope_->EnterWith(); 594 scope_->EnterWith();
594 ParseStatement(CHECK_OK); 595 ParseStatement(CHECK_OK);
595 scope_->LeaveWith(); 596 scope_->LeaveWith();
596 return kUnknownStatement; 597 return kUnknownStatement;
597 } 598 }
598 599
599 600
600 template <typename Scanner, typename Log> 601 template <typename Scanner, typename Log>
601 Statement PreParser<Scanner, Log>::ParseSwitchStatement(bool* ok) { 602 Statement PreParser<Scanner, Log>::ParseSwitchStatement(bool* ok) {
602 // SwitchStatement :: 603 // SwitchStatement ::
603 // 'switch' '(' Expression ')' '{' CaseClause* '}' 604 // 'switch' '(' Expression ')' '{' CaseClause* '}'
604 605
605 Expect(Token::SWITCH, CHECK_OK); 606 Expect(i::Token::SWITCH, CHECK_OK);
606 Expect(Token::LPAREN, CHECK_OK); 607 Expect(i::Token::LPAREN, CHECK_OK);
607 ParseExpression(true, CHECK_OK); 608 ParseExpression(true, CHECK_OK);
608 Expect(Token::RPAREN, CHECK_OK); 609 Expect(i::Token::RPAREN, CHECK_OK);
609 610
610 Expect(Token::LBRACE, CHECK_OK); 611 Expect(i::Token::LBRACE, CHECK_OK);
611 Token::Value token = peek(); 612 i::Token::Value token = peek();
612 while (token != Token::RBRACE) { 613 while (token != i::Token::RBRACE) {
613 if (token == Token::CASE) { 614 if (token == i::Token::CASE) {
614 Expect(Token::CASE, CHECK_OK); 615 Expect(i::Token::CASE, CHECK_OK);
615 ParseExpression(true, CHECK_OK); 616 ParseExpression(true, CHECK_OK);
616 Expect(Token::COLON, CHECK_OK); 617 Expect(i::Token::COLON, CHECK_OK);
617 } else if (token == Token::DEFAULT) { 618 } else if (token == i::Token::DEFAULT) {
618 Expect(Token::DEFAULT, CHECK_OK); 619 Expect(i::Token::DEFAULT, CHECK_OK);
619 Expect(Token::COLON, CHECK_OK); 620 Expect(i::Token::COLON, CHECK_OK);
620 } else { 621 } else {
621 ParseStatement(CHECK_OK); 622 ParseStatement(CHECK_OK);
622 } 623 }
623 token = peek(); 624 token = peek();
624 } 625 }
625 Expect(Token::RBRACE, CHECK_OK); 626 Expect(i::Token::RBRACE, CHECK_OK);
626 627
627 return kUnknownStatement; 628 return kUnknownStatement;
628 } 629 }
629 630
630 631
631 template <typename Scanner, typename Log> 632 template <typename Scanner, typename Log>
632 Statement PreParser<Scanner, Log>::ParseDoWhileStatement(bool* ok) { 633 Statement PreParser<Scanner, Log>::ParseDoWhileStatement(bool* ok) {
633 // DoStatement :: 634 // DoStatement ::
634 // 'do' Statement 'while' '(' Expression ')' ';' 635 // 'do' Statement 'while' '(' Expression ')' ';'
635 636
636 Expect(Token::DO, CHECK_OK); 637 Expect(i::Token::DO, CHECK_OK);
637 ParseStatement(CHECK_OK); 638 ParseStatement(CHECK_OK);
638 Expect(Token::WHILE, CHECK_OK); 639 Expect(i::Token::WHILE, CHECK_OK);
639 Expect(Token::LPAREN, CHECK_OK); 640 Expect(i::Token::LPAREN, CHECK_OK);
640 ParseExpression(true, CHECK_OK); 641 ParseExpression(true, CHECK_OK);
641 Expect(Token::RPAREN, CHECK_OK); 642 Expect(i::Token::RPAREN, CHECK_OK);
642 return kUnknownStatement; 643 return kUnknownStatement;
643 } 644 }
644 645
645 646
646 template <typename Scanner, typename Log> 647 template <typename Scanner, typename Log>
647 Statement PreParser<Scanner, Log>::ParseWhileStatement(bool* ok) { 648 Statement PreParser<Scanner, Log>::ParseWhileStatement(bool* ok) {
648 // WhileStatement :: 649 // WhileStatement ::
649 // 'while' '(' Expression ')' Statement 650 // 'while' '(' Expression ')' Statement
650 651
651 Expect(Token::WHILE, CHECK_OK); 652 Expect(i::Token::WHILE, CHECK_OK);
652 Expect(Token::LPAREN, CHECK_OK); 653 Expect(i::Token::LPAREN, CHECK_OK);
653 ParseExpression(true, CHECK_OK); 654 ParseExpression(true, CHECK_OK);
654 Expect(Token::RPAREN, CHECK_OK); 655 Expect(i::Token::RPAREN, CHECK_OK);
655 ParseStatement(CHECK_OK); 656 ParseStatement(CHECK_OK);
656 return kUnknownStatement; 657 return kUnknownStatement;
657 } 658 }
658 659
659 660
660 template <typename Scanner, typename Log> 661 template <typename Scanner, typename Log>
661 Statement PreParser<Scanner, Log>::ParseForStatement(bool* ok) { 662 Statement PreParser<Scanner, Log>::ParseForStatement(bool* ok) {
662 // ForStatement :: 663 // ForStatement ::
663 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 664 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
664 665
665 Expect(Token::FOR, CHECK_OK); 666 Expect(i::Token::FOR, CHECK_OK);
666 Expect(Token::LPAREN, CHECK_OK); 667 Expect(i::Token::LPAREN, CHECK_OK);
667 if (peek() != Token::SEMICOLON) { 668 if (peek() != i::Token::SEMICOLON) {
668 if (peek() == Token::VAR || peek() == Token::CONST) { 669 if (peek() == i::Token::VAR || peek() == i::Token::CONST) {
669 int decl_count; 670 int decl_count;
670 ParseVariableDeclarations(false, &decl_count, CHECK_OK); 671 ParseVariableDeclarations(false, &decl_count, CHECK_OK);
671 if (peek() == Token::IN && decl_count == 1) { 672 if (peek() == i::Token::IN && decl_count == 1) {
672 Expect(Token::IN, CHECK_OK); 673 Expect(i::Token::IN, CHECK_OK);
673 ParseExpression(true, CHECK_OK); 674 ParseExpression(true, CHECK_OK);
674 Expect(Token::RPAREN, CHECK_OK); 675 Expect(i::Token::RPAREN, CHECK_OK);
675 676
676 ParseStatement(CHECK_OK); 677 ParseStatement(CHECK_OK);
677 return kUnknownStatement; 678 return kUnknownStatement;
678 } 679 }
679 } else { 680 } else {
680 ParseExpression(false, CHECK_OK); 681 ParseExpression(false, CHECK_OK);
681 if (peek() == Token::IN) { 682 if (peek() == i::Token::IN) {
682 Expect(Token::IN, CHECK_OK); 683 Expect(i::Token::IN, CHECK_OK);
683 ParseExpression(true, CHECK_OK); 684 ParseExpression(true, CHECK_OK);
684 Expect(Token::RPAREN, CHECK_OK); 685 Expect(i::Token::RPAREN, CHECK_OK);
685 686
686 ParseStatement(CHECK_OK); 687 ParseStatement(CHECK_OK);
687 return kUnknownStatement; 688 return kUnknownStatement;
688 } 689 }
689 } 690 }
690 } 691 }
691 692
692 // Parsed initializer at this point. 693 // Parsed initializer at this point.
693 Expect(Token::SEMICOLON, CHECK_OK); 694 Expect(i::Token::SEMICOLON, CHECK_OK);
694 695
695 if (peek() != Token::SEMICOLON) { 696 if (peek() != i::Token::SEMICOLON) {
696 ParseExpression(true, CHECK_OK); 697 ParseExpression(true, CHECK_OK);
697 } 698 }
698 Expect(Token::SEMICOLON, CHECK_OK); 699 Expect(i::Token::SEMICOLON, CHECK_OK);
699 700
700 if (peek() != Token::RPAREN) { 701 if (peek() != i::Token::RPAREN) {
701 ParseExpression(true, CHECK_OK); 702 ParseExpression(true, CHECK_OK);
702 } 703 }
703 Expect(Token::RPAREN, CHECK_OK); 704 Expect(i::Token::RPAREN, CHECK_OK);
704 705
705 ParseStatement(CHECK_OK); 706 ParseStatement(CHECK_OK);
706 return kUnknownStatement; 707 return kUnknownStatement;
707 } 708 }
708 709
709 710
710 template <typename Scanner, typename Log> 711 template <typename Scanner, typename Log>
711 Statement PreParser<Scanner, Log>::ParseThrowStatement(bool* ok) { 712 Statement PreParser<Scanner, Log>::ParseThrowStatement(bool* ok) {
712 // ThrowStatement :: 713 // ThrowStatement ::
713 // 'throw' [no line terminator] Expression ';' 714 // 'throw' [no line terminator] Expression ';'
714 715
715 Expect(Token::THROW, CHECK_OK); 716 Expect(i::Token::THROW, CHECK_OK);
716 if (scanner_->has_line_terminator_before_next()) { 717 if (scanner_->has_line_terminator_before_next()) {
717 typename Scanner::Location pos = scanner_->location(); 718 typename Scanner::Location pos = scanner_->location();
718 ReportMessageAt(pos.beg_pos, pos.end_pos, 719 ReportMessageAt(pos.beg_pos, pos.end_pos,
719 "newline_after_throw", NULL); 720 "newline_after_throw", NULL);
720 *ok = false; 721 *ok = false;
721 return NULL; 722 return NULL;
722 } 723 }
723 ParseExpression(true, CHECK_OK); 724 ParseExpression(true, CHECK_OK);
724 ExpectSemicolon(CHECK_OK); 725 ExpectSemicolon(CHECK_OK);
725 726
(...skipping 10 matching lines...) Expand all
736 // 737 //
737 // Catch :: 738 // Catch ::
738 // 'catch' '(' Identifier ')' Block 739 // 'catch' '(' Identifier ')' Block
739 // 740 //
740 // Finally :: 741 // Finally ::
741 // 'finally' Block 742 // 'finally' Block
742 743
743 // In preparsing, allow any number of catch/finally blocks, including zero 744 // In preparsing, allow any number of catch/finally blocks, including zero
744 // of both. 745 // of both.
745 746
746 Expect(Token::TRY, CHECK_OK); 747 Expect(i::Token::TRY, CHECK_OK);
747 748
748 ParseBlock(CHECK_OK); 749 ParseBlock(CHECK_OK);
749 750
750 bool catch_or_finally_seen = false; 751 bool catch_or_finally_seen = false;
751 if (peek() == Token::CATCH) { 752 if (peek() == i::Token::CATCH) {
752 Expect(Token::CATCH, CHECK_OK); 753 Expect(i::Token::CATCH, CHECK_OK);
753 Expect(Token::LPAREN, CHECK_OK); 754 Expect(i::Token::LPAREN, CHECK_OK);
754 ParseIdentifier(CHECK_OK); 755 ParseIdentifier(CHECK_OK);
755 Expect(Token::RPAREN, CHECK_OK); 756 Expect(i::Token::RPAREN, CHECK_OK);
756 ParseBlock(CHECK_OK); 757 ParseBlock(CHECK_OK);
757 catch_or_finally_seen = true; 758 catch_or_finally_seen = true;
758 } 759 }
759 if (peek() == Token::FINALLY) { 760 if (peek() == i::Token::FINALLY) {
760 Expect(Token::FINALLY, CHECK_OK); 761 Expect(i::Token::FINALLY, CHECK_OK);
761 ParseBlock(CHECK_OK); 762 ParseBlock(CHECK_OK);
762 catch_or_finally_seen = true; 763 catch_or_finally_seen = true;
763 } 764 }
764 if (!catch_or_finally_seen) { 765 if (!catch_or_finally_seen) {
765 *ok = false; 766 *ok = false;
766 } 767 }
767 return kUnknownStatement; 768 return kUnknownStatement;
768 } 769 }
769 770
770 771
771 template <typename Scanner, typename Log> 772 template <typename Scanner, typename Log>
772 Statement PreParser<Scanner, Log>::ParseDebuggerStatement(bool* ok) { 773 Statement PreParser<Scanner, Log>::ParseDebuggerStatement(bool* ok) {
773 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 774 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
774 // contexts this is used as a statement which invokes the debugger as if a 775 // contexts this is used as a statement which invokes the debugger as if a
775 // break point is present. 776 // break point is present.
776 // DebuggerStatement :: 777 // DebuggerStatement ::
777 // 'debugger' ';' 778 // 'debugger' ';'
778 779
779 Expect(Token::DEBUGGER, CHECK_OK); 780 Expect(i::Token::DEBUGGER, CHECK_OK);
780 ExpectSemicolon(CHECK_OK); 781 ExpectSemicolon(CHECK_OK);
781 return kUnknownStatement; 782 return kUnknownStatement;
782 } 783 }
783 784
784 785
785 // Precedence = 1 786 // Precedence = 1
786 template <typename Scanner, typename Log> 787 template <typename Scanner, typename Log>
787 Expression PreParser<Scanner, Log>::ParseExpression(bool accept_IN, bool* ok) { 788 Expression PreParser<Scanner, Log>::ParseExpression(bool accept_IN, bool* ok) {
788 // Expression :: 789 // Expression ::
789 // AssignmentExpression 790 // AssignmentExpression
790 // Expression ',' AssignmentExpression 791 // Expression ',' AssignmentExpression
791 792
792 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); 793 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
793 while (peek() == Token::COMMA) { 794 while (peek() == i::Token::COMMA) {
794 Expect(Token::COMMA, CHECK_OK); 795 Expect(i::Token::COMMA, CHECK_OK);
795 ParseAssignmentExpression(accept_IN, CHECK_OK); 796 ParseAssignmentExpression(accept_IN, CHECK_OK);
796 result = kUnknownExpression; 797 result = kUnknownExpression;
797 } 798 }
798 return result; 799 return result;
799 } 800 }
800 801
801 802
802 // Precedence = 2 803 // Precedence = 2
803 template <typename Scanner, typename Log> 804 template <typename Scanner, typename Log>
804 Expression PreParser<Scanner, Log>::ParseAssignmentExpression(bool accept_IN, 805 Expression PreParser<Scanner, Log>::ParseAssignmentExpression(bool accept_IN,
805 bool* ok) { 806 bool* ok) {
806 // AssignmentExpression :: 807 // AssignmentExpression ::
807 // ConditionalExpression 808 // ConditionalExpression
808 // LeftHandSideExpression AssignmentOperator AssignmentExpression 809 // LeftHandSideExpression AssignmentOperator AssignmentExpression
809 810
810 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 811 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
811 812
812 if (!Token::IsAssignmentOp(peek())) { 813 if (!i::Token::IsAssignmentOp(peek())) {
813 // Parsed conditional expression only (no assignment). 814 // Parsed conditional expression only (no assignment).
814 return expression; 815 return expression;
815 } 816 }
816 817
817 Token::Value op = Next(); // Get assignment operator. 818 i::Token::Value op = Next(); // Get assignment operator.
818 ParseAssignmentExpression(accept_IN, CHECK_OK); 819 ParseAssignmentExpression(accept_IN, CHECK_OK);
819 820
820 if ((op == Token::ASSIGN) && (expression == kThisPropertyExpression)) { 821 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) {
821 scope_->AddProperty(); 822 scope_->AddProperty();
822 } 823 }
823 824
824 return kUnknownExpression; 825 return kUnknownExpression;
825 } 826 }
826 827
827 828
828 // Precedence = 3 829 // Precedence = 3
829 template <typename Scanner, typename Log> 830 template <typename Scanner, typename Log>
830 Expression PreParser<Scanner, Log>::ParseConditionalExpression(bool accept_IN, 831 Expression PreParser<Scanner, Log>::ParseConditionalExpression(bool accept_IN,
831 bool* ok) { 832 bool* ok) {
832 // ConditionalExpression :: 833 // ConditionalExpression ::
833 // LogicalOrExpression 834 // LogicalOrExpression
834 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 835 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
835 836
836 // We start using the binary expression parser for prec >= 4 only! 837 // We start using the binary expression parser for prec >= 4 only!
837 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 838 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
838 if (peek() != Token::CONDITIONAL) return expression; 839 if (peek() != i::Token::CONDITIONAL) return expression;
839 Consume(Token::CONDITIONAL); 840 Consume(i::Token::CONDITIONAL);
840 // In parsing the first assignment expression in conditional 841 // In parsing the first assignment expression in conditional
841 // expressions we always accept the 'in' keyword; see ECMA-262, 842 // expressions we always accept the 'in' keyword; see ECMA-262,
842 // section 11.12, page 58. 843 // section 11.12, page 58.
843 ParseAssignmentExpression(true, CHECK_OK); 844 ParseAssignmentExpression(true, CHECK_OK);
844 Expect(Token::COLON, CHECK_OK); 845 Expect(i::Token::COLON, CHECK_OK);
845 ParseAssignmentExpression(accept_IN, CHECK_OK); 846 ParseAssignmentExpression(accept_IN, CHECK_OK);
846 return kUnknownExpression; 847 return kUnknownExpression;
847 } 848 }
848 849
849 850
850 template <typename Scanner, typename Log> 851 template <typename Scanner, typename Log>
851 int PreParser<Scanner, Log>::Precedence(Token::Value tok, bool accept_IN) { 852 int PreParser<Scanner, Log>::Precedence(i::Token::Value tok, bool accept_IN) {
852 if (tok == Token::IN && !accept_IN) 853 if (tok == i::Token::IN && !accept_IN)
853 return 0; // 0 precedence will terminate binary expression parsing 854 return 0; // 0 precedence will terminate binary expression parsing
854 855
855 return Token::Precedence(tok); 856 return i::Token::Precedence(tok);
856 } 857 }
857 858
858 859
859 // Precedence >= 4 860 // Precedence >= 4
860 template <typename Scanner, typename Log> 861 template <typename Scanner, typename Log>
861 Expression PreParser<Scanner, Log>::ParseBinaryExpression(int prec, 862 Expression PreParser<Scanner, Log>::ParseBinaryExpression(int prec,
862 bool accept_IN, 863 bool accept_IN,
863 bool* ok) { 864 bool* ok) {
864 Expression result = ParseUnaryExpression(CHECK_OK); 865 Expression result = ParseUnaryExpression(CHECK_OK);
865 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 866 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
(...skipping 15 matching lines...) Expand all
881 // 'delete' UnaryExpression 882 // 'delete' UnaryExpression
882 // 'void' UnaryExpression 883 // 'void' UnaryExpression
883 // 'typeof' UnaryExpression 884 // 'typeof' UnaryExpression
884 // '++' UnaryExpression 885 // '++' UnaryExpression
885 // '--' UnaryExpression 886 // '--' UnaryExpression
886 // '+' UnaryExpression 887 // '+' UnaryExpression
887 // '-' UnaryExpression 888 // '-' UnaryExpression
888 // '~' UnaryExpression 889 // '~' UnaryExpression
889 // '!' UnaryExpression 890 // '!' UnaryExpression
890 891
891 Token::Value op = peek(); 892 i::Token::Value op = peek();
892 if (Token::IsUnaryOp(op) || Token::IsCountOp(op)) { 893 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) {
893 op = Next(); 894 op = Next();
894 ParseUnaryExpression(ok); 895 ParseUnaryExpression(ok);
895 return kUnknownExpression; 896 return kUnknownExpression;
896 } else { 897 } else {
897 return ParsePostfixExpression(ok); 898 return ParsePostfixExpression(ok);
898 } 899 }
899 } 900 }
900 901
901 902
902 template <typename Scanner, typename Log> 903 template <typename Scanner, typename Log>
903 Expression PreParser<Scanner, Log>::ParsePostfixExpression(bool* ok) { 904 Expression PreParser<Scanner, Log>::ParsePostfixExpression(bool* ok) {
904 // PostfixExpression :: 905 // PostfixExpression ::
905 // LeftHandSideExpression ('++' | '--')? 906 // LeftHandSideExpression ('++' | '--')?
906 907
907 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 908 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
908 if (!scanner_->has_line_terminator_before_next() && 909 if (!scanner_->has_line_terminator_before_next() &&
909 Token::IsCountOp(peek())) { 910 i::Token::IsCountOp(peek())) {
910 Next(); 911 Next();
911 return kUnknownExpression; 912 return kUnknownExpression;
912 } 913 }
913 return expression; 914 return expression;
914 } 915 }
915 916
916 917
917 template <typename Scanner, typename Log> 918 template <typename Scanner, typename Log>
918 Expression PreParser<Scanner, Log>::ParseLeftHandSideExpression(bool* ok) { 919 Expression PreParser<Scanner, Log>::ParseLeftHandSideExpression(bool* ok) {
919 // LeftHandSideExpression :: 920 // LeftHandSideExpression ::
920 // (NewExpression | MemberExpression) ... 921 // (NewExpression | MemberExpression) ...
921 922
922 Expression result; 923 Expression result;
923 if (peek() == Token::NEW) { 924 if (peek() == i::Token::NEW) {
924 result = ParseNewExpression(CHECK_OK); 925 result = ParseNewExpression(CHECK_OK);
925 } else { 926 } else {
926 result = ParseMemberExpression(CHECK_OK); 927 result = ParseMemberExpression(CHECK_OK);
927 } 928 }
928 929
929 while (true) { 930 while (true) {
930 switch (peek()) { 931 switch (peek()) {
931 case Token::LBRACK: { 932 case i::Token::LBRACK: {
932 Consume(Token::LBRACK); 933 Consume(i::Token::LBRACK);
933 ParseExpression(true, CHECK_OK); 934 ParseExpression(true, CHECK_OK);
934 Expect(Token::RBRACK, CHECK_OK); 935 Expect(i::Token::RBRACK, CHECK_OK);
935 if (result == kThisExpression) { 936 if (result == kThisExpression) {
936 result = kThisPropertyExpression; 937 result = kThisPropertyExpression;
937 } else { 938 } else {
938 result = kUnknownExpression; 939 result = kUnknownExpression;
939 } 940 }
940 break; 941 break;
941 } 942 }
942 943
943 case Token::LPAREN: { 944 case i::Token::LPAREN: {
944 ParseArguments(CHECK_OK); 945 ParseArguments(CHECK_OK);
945 result = kUnknownExpression; 946 result = kUnknownExpression;
946 break; 947 break;
947 } 948 }
948 949
949 case Token::PERIOD: { 950 case i::Token::PERIOD: {
950 Consume(Token::PERIOD); 951 Consume(i::Token::PERIOD);
951 ParseIdentifierName(CHECK_OK); 952 ParseIdentifierName(CHECK_OK);
952 if (result == kThisExpression) { 953 if (result == kThisExpression) {
953 result = kThisPropertyExpression; 954 result = kThisPropertyExpression;
954 } else { 955 } else {
955 result = kUnknownExpression; 956 result = kUnknownExpression;
956 } 957 }
957 break; 958 break;
958 } 959 }
959 960
960 default: 961 default:
(...skipping 11 matching lines...) Expand all
972 // The grammar for new expressions is pretty warped. The keyword 973 // The grammar for new expressions is pretty warped. The keyword
973 // 'new' can either be a part of the new expression (where it isn't 974 // 'new' can either be a part of the new expression (where it isn't
974 // followed by an argument list) or a part of the member expression, 975 // followed by an argument list) or a part of the member expression,
975 // where it must be followed by an argument list. To accommodate 976 // where it must be followed by an argument list. To accommodate
976 // this, we parse the 'new' keywords greedily and keep track of how 977 // this, we parse the 'new' keywords greedily and keep track of how
977 // many we have parsed. This information is then passed on to the 978 // many we have parsed. This information is then passed on to the
978 // member expression parser, which is only allowed to match argument 979 // member expression parser, which is only allowed to match argument
979 // lists as long as it has 'new' prefixes left 980 // lists as long as it has 'new' prefixes left
980 unsigned new_count = 0; 981 unsigned new_count = 0;
981 do { 982 do {
982 Consume(Token::NEW); 983 Consume(i::Token::NEW);
983 new_count++; 984 new_count++;
984 } while (peek() == Token::NEW); 985 } while (peek() == i::Token::NEW);
985 986
986 return ParseMemberWithNewPrefixesExpression(new_count, ok); 987 return ParseMemberWithNewPrefixesExpression(new_count, ok);
987 } 988 }
988 989
989 990
990 template <typename Scanner, typename Log> 991 template <typename Scanner, typename Log>
991 Expression PreParser<Scanner, Log>::ParseMemberExpression(bool* ok) { 992 Expression PreParser<Scanner, Log>::ParseMemberExpression(bool* ok) {
992 return ParseMemberWithNewPrefixesExpression(0, ok); 993 return ParseMemberWithNewPrefixesExpression(0, ok);
993 } 994 }
994 995
995 996
996 template <typename Scanner, typename Log> 997 template <typename Scanner, typename Log>
997 Expression PreParser<Scanner, Log>::ParseMemberWithNewPrefixesExpression( 998 Expression PreParser<Scanner, Log>::ParseMemberWithNewPrefixesExpression(
998 unsigned new_count, bool* ok) { 999 unsigned new_count, bool* ok) {
999 // MemberExpression :: 1000 // MemberExpression ::
1000 // (PrimaryExpression | FunctionLiteral) 1001 // (PrimaryExpression | FunctionLiteral)
1001 // ('[' Expression ']' | '.' Identifier | Arguments)* 1002 // ('[' Expression ']' | '.' Identifier | Arguments)*
1002 1003
1003 // Parse the initial primary or function expression. 1004 // Parse the initial primary or function expression.
1004 Expression result = NULL; 1005 Expression result = NULL;
1005 if (peek() == Token::FUNCTION) { 1006 if (peek() == i::Token::FUNCTION) {
1006 Consume(Token::FUNCTION); 1007 Consume(i::Token::FUNCTION);
1007 if (peek() == Token::IDENTIFIER) { 1008 if (peek() == i::Token::IDENTIFIER) {
1008 ParseIdentifier(CHECK_OK); 1009 ParseIdentifier(CHECK_OK);
1009 } 1010 }
1010 result = ParseFunctionLiteral(CHECK_OK); 1011 result = ParseFunctionLiteral(CHECK_OK);
1011 } else { 1012 } else {
1012 result = ParsePrimaryExpression(CHECK_OK); 1013 result = ParsePrimaryExpression(CHECK_OK);
1013 } 1014 }
1014 1015
1015 while (true) { 1016 while (true) {
1016 switch (peek()) { 1017 switch (peek()) {
1017 case Token::LBRACK: { 1018 case i::Token::LBRACK: {
1018 Consume(Token::LBRACK); 1019 Consume(i::Token::LBRACK);
1019 ParseExpression(true, CHECK_OK); 1020 ParseExpression(true, CHECK_OK);
1020 Expect(Token::RBRACK, CHECK_OK); 1021 Expect(i::Token::RBRACK, CHECK_OK);
1021 if (result == kThisExpression) { 1022 if (result == kThisExpression) {
1022 result = kThisPropertyExpression; 1023 result = kThisPropertyExpression;
1023 } else { 1024 } else {
1024 result = kUnknownExpression; 1025 result = kUnknownExpression;
1025 } 1026 }
1026 break; 1027 break;
1027 } 1028 }
1028 case Token::PERIOD: { 1029 case i::Token::PERIOD: {
1029 Consume(Token::PERIOD); 1030 Consume(i::Token::PERIOD);
1030 ParseIdentifierName(CHECK_OK); 1031 ParseIdentifierName(CHECK_OK);
1031 if (result == kThisExpression) { 1032 if (result == kThisExpression) {
1032 result = kThisPropertyExpression; 1033 result = kThisPropertyExpression;
1033 } else { 1034 } else {
1034 result = kUnknownExpression; 1035 result = kUnknownExpression;
1035 } 1036 }
1036 break; 1037 break;
1037 } 1038 }
1038 case Token::LPAREN: { 1039 case i::Token::LPAREN: {
1039 if (new_count == 0) return result; 1040 if (new_count == 0) return result;
1040 // Consume one of the new prefixes (already parsed). 1041 // Consume one of the new prefixes (already parsed).
1041 ParseArguments(CHECK_OK); 1042 ParseArguments(CHECK_OK);
1042 new_count--; 1043 new_count--;
1043 result = kUnknownExpression; 1044 result = kUnknownExpression;
1044 break; 1045 break;
1045 } 1046 }
1046 default: 1047 default:
1047 return result; 1048 return result;
1048 } 1049 }
(...skipping 11 matching lines...) Expand all
1060 // Identifier 1061 // Identifier
1061 // Number 1062 // Number
1062 // String 1063 // String
1063 // ArrayLiteral 1064 // ArrayLiteral
1064 // ObjectLiteral 1065 // ObjectLiteral
1065 // RegExpLiteral 1066 // RegExpLiteral
1066 // '(' Expression ')' 1067 // '(' Expression ')'
1067 1068
1068 Expression result = kUnknownExpression; 1069 Expression result = kUnknownExpression;
1069 switch (peek()) { 1070 switch (peek()) {
1070 case Token::THIS: { 1071 case i::Token::THIS: {
1071 Next(); 1072 Next();
1072 result = kThisExpression; 1073 result = kThisExpression;
1073 break; 1074 break;
1074 } 1075 }
1075 1076
1076 case Token::IDENTIFIER: { 1077 case i::Token::IDENTIFIER: {
1077 ParseIdentifier(CHECK_OK); 1078 ParseIdentifier(CHECK_OK);
1078 result = kIdentifierExpression; 1079 result = kIdentifierExpression;
1079 break; 1080 break;
1080 } 1081 }
1081 1082
1082 case Token::NULL_LITERAL: 1083 case i::Token::NULL_LITERAL:
1083 case Token::TRUE_LITERAL: 1084 case i::Token::TRUE_LITERAL:
1084 case Token::FALSE_LITERAL: 1085 case i::Token::FALSE_LITERAL:
1085 case Token::NUMBER: { 1086 case i::Token::NUMBER: {
1086 Next(); 1087 Next();
1087 break; 1088 break;
1088 } 1089 }
1089 case Token::STRING: { 1090 case i::Token::STRING: {
1090 Next(); 1091 Next();
1091 result = GetStringSymbol(); 1092 result = GetStringSymbol();
1092 break; 1093 break;
1093 } 1094 }
1094 1095
1095 case Token::ASSIGN_DIV: 1096 case i::Token::ASSIGN_DIV:
1096 result = ParseRegExpLiteral(true, CHECK_OK); 1097 result = ParseRegExpLiteral(true, CHECK_OK);
1097 break; 1098 break;
1098 1099
1099 case Token::DIV: 1100 case i::Token::DIV:
1100 result = ParseRegExpLiteral(false, CHECK_OK); 1101 result = ParseRegExpLiteral(false, CHECK_OK);
1101 break; 1102 break;
1102 1103
1103 case Token::LBRACK: 1104 case i::Token::LBRACK:
1104 result = ParseArrayLiteral(CHECK_OK); 1105 result = ParseArrayLiteral(CHECK_OK);
1105 break; 1106 break;
1106 1107
1107 case Token::LBRACE: 1108 case i::Token::LBRACE:
1108 result = ParseObjectLiteral(CHECK_OK); 1109 result = ParseObjectLiteral(CHECK_OK);
1109 break; 1110 break;
1110 1111
1111 case Token::LPAREN: 1112 case i::Token::LPAREN:
1112 Consume(Token::LPAREN); 1113 Consume(i::Token::LPAREN);
1113 result = ParseExpression(true, CHECK_OK); 1114 result = ParseExpression(true, CHECK_OK);
1114 Expect(Token::RPAREN, CHECK_OK); 1115 Expect(i::Token::RPAREN, CHECK_OK);
1115 if (result == kIdentifierExpression) result = kUnknownExpression; 1116 if (result == kIdentifierExpression) result = kUnknownExpression;
1116 break; 1117 break;
1117 1118
1118 case Token::MOD: 1119 case i::Token::MOD:
1119 result = ParseV8Intrinsic(CHECK_OK); 1120 result = ParseV8Intrinsic(CHECK_OK);
1120 break; 1121 break;
1121 1122
1122 default: { 1123 default: {
1123 Next(); 1124 Next();
1124 *ok = false; 1125 *ok = false;
1125 return kUnknownExpression; 1126 return kUnknownExpression;
1126 } 1127 }
1127 } 1128 }
1128 1129
1129 return result; 1130 return result;
1130 } 1131 }
1131 1132
1132 1133
1133 template <typename Scanner, typename Log> 1134 template <typename Scanner, typename Log>
1134 Expression PreParser<Scanner, Log>::ParseArrayLiteral(bool* ok) { 1135 Expression PreParser<Scanner, Log>::ParseArrayLiteral(bool* ok) {
1135 // ArrayLiteral :: 1136 // ArrayLiteral ::
1136 // '[' Expression? (',' Expression?)* ']' 1137 // '[' Expression? (',' Expression?)* ']'
1137 Expect(Token::LBRACK, CHECK_OK); 1138 Expect(i::Token::LBRACK, CHECK_OK);
1138 while (peek() != Token::RBRACK) { 1139 while (peek() != i::Token::RBRACK) {
1139 if (peek() != Token::COMMA) { 1140 if (peek() != i::Token::COMMA) {
1140 ParseAssignmentExpression(true, CHECK_OK); 1141 ParseAssignmentExpression(true, CHECK_OK);
1141 } 1142 }
1142 if (peek() != Token::RBRACK) { 1143 if (peek() != i::Token::RBRACK) {
1143 Expect(Token::COMMA, CHECK_OK); 1144 Expect(i::Token::COMMA, CHECK_OK);
1144 } 1145 }
1145 } 1146 }
1146 Expect(Token::RBRACK, CHECK_OK); 1147 Expect(i::Token::RBRACK, CHECK_OK);
1147 1148
1148 scope_->NextMaterializedLiteralIndex(); 1149 scope_->NextMaterializedLiteralIndex();
1149 return kUnknownExpression; 1150 return kUnknownExpression;
1150 } 1151 }
1151 1152
1152 1153
1153 template <typename Scanner, typename Log> 1154 template <typename Scanner, typename Log>
1154 Expression PreParser<Scanner, Log>::ParseObjectLiteral(bool* ok) { 1155 Expression PreParser<Scanner, Log>::ParseObjectLiteral(bool* ok) {
1155 // ObjectLiteral :: 1156 // ObjectLiteral ::
1156 // '{' ( 1157 // '{' (
1157 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1158 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1158 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1159 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1159 // )*[','] '}' 1160 // )*[','] '}'
1160 1161
1161 Expect(Token::LBRACE, CHECK_OK); 1162 Expect(i::Token::LBRACE, CHECK_OK);
1162 while (peek() != Token::RBRACE) { 1163 while (peek() != i::Token::RBRACE) {
1163 Token::Value next = peek(); 1164 i::Token::Value next = peek();
1164 switch (next) { 1165 switch (next) {
1165 case Token::IDENTIFIER: { 1166 case i::Token::IDENTIFIER: {
1166 bool is_getter = false; 1167 bool is_getter = false;
1167 bool is_setter = false; 1168 bool is_setter = false;
1168 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1169 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1169 if ((is_getter || is_setter) && peek() != Token::COLON) { 1170 if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1170 Token::Value name = Next(); 1171 i::Token::Value name = Next();
1171 if (name != Token::IDENTIFIER && 1172 if (name != i::Token::IDENTIFIER &&
1172 name != Token::NUMBER && 1173 name != i::Token::NUMBER &&
1173 name != Token::STRING && 1174 name != i::Token::STRING &&
1174 !Token::IsKeyword(name)) { 1175 !i::Token::IsKeyword(name)) {
1175 *ok = false; 1176 *ok = false;
1176 return kUnknownExpression; 1177 return kUnknownExpression;
1177 } 1178 }
1178 ParseFunctionLiteral(CHECK_OK); 1179 ParseFunctionLiteral(CHECK_OK);
1179 if (peek() != Token::RBRACE) { 1180 if (peek() != i::Token::RBRACE) {
1180 Expect(Token::COMMA, CHECK_OK); 1181 Expect(i::Token::COMMA, CHECK_OK);
1181 } 1182 }
1182 continue; // restart the while 1183 continue; // restart the while
1183 } 1184 }
1184 break; 1185 break;
1185 } 1186 }
1186 case Token::STRING: 1187 case i::Token::STRING:
1187 Consume(next); 1188 Consume(next);
1188 GetStringSymbol(); 1189 GetStringSymbol();
1189 break; 1190 break;
1190 case Token::NUMBER: 1191 case i::Token::NUMBER:
1191 Consume(next); 1192 Consume(next);
1192 break; 1193 break;
1193 default: 1194 default:
1194 if (Token::IsKeyword(next)) { 1195 if (i::Token::IsKeyword(next)) {
1195 Consume(next); 1196 Consume(next);
1196 } else { 1197 } else {
1197 // Unexpected token. 1198 // Unexpected token.
1198 *ok = false; 1199 *ok = false;
1199 return kUnknownExpression; 1200 return kUnknownExpression;
1200 } 1201 }
1201 } 1202 }
1202 1203
1203 Expect(Token::COLON, CHECK_OK); 1204 Expect(i::Token::COLON, CHECK_OK);
1204 ParseAssignmentExpression(true, CHECK_OK); 1205 ParseAssignmentExpression(true, CHECK_OK);
1205 1206
1206 // TODO(1240767): Consider allowing trailing comma. 1207 // TODO(1240767): Consider allowing trailing comma.
1207 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 1208 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
1208 } 1209 }
1209 Expect(Token::RBRACE, CHECK_OK); 1210 Expect(i::Token::RBRACE, CHECK_OK);
1210 1211
1211 scope_->NextMaterializedLiteralIndex(); 1212 scope_->NextMaterializedLiteralIndex();
1212 return kUnknownExpression; 1213 return kUnknownExpression;
1213 } 1214 }
1214 1215
1215 1216
1216 template <typename Scanner, typename Log> 1217 template <typename Scanner, typename Log>
1217 Expression PreParser<Scanner, Log>::ParseRegExpLiteral(bool seen_equal, 1218 Expression PreParser<Scanner, Log>::ParseRegExpLiteral(bool seen_equal,
1218 bool* ok) { 1219 bool* ok) {
1219 if (!scanner_->ScanRegExpPattern(seen_equal)) { 1220 if (!scanner_->ScanRegExpPattern(seen_equal)) {
(...skipping 18 matching lines...) Expand all
1238 Next(); 1239 Next();
1239 return kUnknownExpression; 1240 return kUnknownExpression;
1240 } 1241 }
1241 1242
1242 1243
1243 template <typename Scanner, typename Log> 1244 template <typename Scanner, typename Log>
1244 Arguments PreParser<Scanner, Log>::ParseArguments(bool* ok) { 1245 Arguments PreParser<Scanner, Log>::ParseArguments(bool* ok) {
1245 // Arguments :: 1246 // Arguments ::
1246 // '(' (AssignmentExpression)*[','] ')' 1247 // '(' (AssignmentExpression)*[','] ')'
1247 1248
1248 Expect(Token::LPAREN, CHECK_OK); 1249 Expect(i::Token::LPAREN, CHECK_OK);
1249 bool done = (peek() == Token::RPAREN); 1250 bool done = (peek() == i::Token::RPAREN);
1250 int argc = 0; 1251 int argc = 0;
1251 while (!done) { 1252 while (!done) {
1252 ParseAssignmentExpression(true, CHECK_OK); 1253 ParseAssignmentExpression(true, CHECK_OK);
1253 argc++; 1254 argc++;
1254 done = (peek() == Token::RPAREN); 1255 done = (peek() == i::Token::RPAREN);
1255 if (!done) Expect(Token::COMMA, CHECK_OK); 1256 if (!done) Expect(i::Token::COMMA, CHECK_OK);
1256 } 1257 }
1257 Expect(Token::RPAREN, CHECK_OK); 1258 Expect(i::Token::RPAREN, CHECK_OK);
1258 return argc; 1259 return argc;
1259 } 1260 }
1260 1261
1261 1262
1262 template <typename Scanner, typename Log> 1263 template <typename Scanner, typename Log>
1263 Expression PreParser<Scanner, Log>::ParseFunctionLiteral(bool* ok) { 1264 Expression PreParser<Scanner, Log>::ParseFunctionLiteral(bool* ok) {
1264 // Function :: 1265 // Function ::
1265 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1266 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1266 1267
1267 // Parse function body. 1268 // Parse function body.
1268 ScopeType outer_scope_type = scope_->type(); 1269 ScopeType outer_scope_type = scope_->type();
1269 bool inside_with = scope_->IsInsideWith(); 1270 bool inside_with = scope_->IsInsideWith();
1270 Scope function_scope(&scope_, kFunctionScope); 1271 Scope function_scope(&scope_, kFunctionScope);
1271 1272
1272 // FormalParameterList :: 1273 // FormalParameterList ::
1273 // '(' (Identifier)*[','] ')' 1274 // '(' (Identifier)*[','] ')'
1274 Expect(Token::LPAREN, CHECK_OK); 1275 Expect(i::Token::LPAREN, CHECK_OK);
1275 bool done = (peek() == Token::RPAREN); 1276 bool done = (peek() == i::Token::RPAREN);
1276 while (!done) { 1277 while (!done) {
1277 ParseIdentifier(CHECK_OK); 1278 ParseIdentifier(CHECK_OK);
1278 done = (peek() == Token::RPAREN); 1279 done = (peek() == i::Token::RPAREN);
1279 if (!done) { 1280 if (!done) {
1280 Expect(Token::COMMA, CHECK_OK); 1281 Expect(i::Token::COMMA, CHECK_OK);
1281 } 1282 }
1282 } 1283 }
1283 Expect(Token::RPAREN, CHECK_OK); 1284 Expect(i::Token::RPAREN, CHECK_OK);
1284 1285
1285 Expect(Token::LBRACE, CHECK_OK); 1286 Expect(i::Token::LBRACE, CHECK_OK);
1286 int function_block_pos = scanner_->location().beg_pos; 1287 int function_block_pos = scanner_->location().beg_pos;
1287 1288
1288 // Determine if the function will be lazily compiled. 1289 // Determine if the function will be lazily compiled.
1289 // Currently only happens to top-level functions. 1290 // Currently only happens to top-level functions.
1290 // Optimistically assume that all top-level functions are lazily compiled. 1291 // Optimistically assume that all top-level functions are lazily compiled.
1291 bool is_lazily_compiled = 1292 bool is_lazily_compiled =
1292 (outer_scope_type == kTopLevelScope && !inside_with && allow_lazy_); 1293 (outer_scope_type == kTopLevelScope && !inside_with && allow_lazy_);
1293 1294
1294 if (is_lazily_compiled) { 1295 if (is_lazily_compiled) {
1295 log_->PauseRecording(); 1296 log_->PauseRecording();
1296 ParseSourceElements(Token::RBRACE, ok); 1297 ParseSourceElements(i::Token::RBRACE, ok);
1297 log_->ResumeRecording(); 1298 log_->ResumeRecording();
1298 if (!*ok) return kUnknownExpression; 1299 if (!*ok) return kUnknownExpression;
1299 1300
1300 Expect(Token::RBRACE, CHECK_OK); 1301 Expect(i::Token::RBRACE, CHECK_OK);
1301 1302
1302 int end_pos = scanner_->location().end_pos; 1303 int end_pos = scanner_->location().end_pos;
1303 log_->LogFunction(function_block_pos, end_pos, 1304 log_->LogFunction(function_block_pos, end_pos,
1304 function_scope.materialized_literal_count(), 1305 function_scope.materialized_literal_count(),
1305 function_scope.expected_properties()); 1306 function_scope.expected_properties());
1306 } else { 1307 } else {
1307 ParseSourceElements(Token::RBRACE, CHECK_OK); 1308 ParseSourceElements(i::Token::RBRACE, CHECK_OK);
1308 Expect(Token::RBRACE, CHECK_OK); 1309 Expect(i::Token::RBRACE, CHECK_OK);
1309 } 1310 }
1310 return kUnknownExpression; 1311 return kUnknownExpression;
1311 } 1312 }
1312 1313
1313 1314
1314 template <typename Scanner, typename Log> 1315 template <typename Scanner, typename Log>
1315 Expression PreParser<Scanner, Log>::ParseV8Intrinsic(bool* ok) { 1316 Expression PreParser<Scanner, Log>::ParseV8Intrinsic(bool* ok) {
1316 // CallRuntime :: 1317 // CallRuntime ::
1317 // '%' Identifier Arguments 1318 // '%' Identifier Arguments
1318 1319
1319 Expect(Token::MOD, CHECK_OK); 1320 Expect(i::Token::MOD, CHECK_OK);
1320 ParseIdentifier(CHECK_OK); 1321 ParseIdentifier(CHECK_OK);
1321 ParseArguments(CHECK_OK); 1322 ParseArguments(CHECK_OK);
1322 1323
1323 return kUnknownExpression; 1324 return kUnknownExpression;
1324 } 1325 }
1325 1326
1326 1327
1327 template <typename Scanner, typename Log> 1328 template <typename Scanner, typename Log>
1328 void PreParser<Scanner, Log>::ExpectSemicolon(bool* ok) { 1329 void PreParser<Scanner, Log>::ExpectSemicolon(bool* ok) {
1329 // Check for automatic semicolon insertion according to 1330 // Check for automatic semicolon insertion according to
1330 // the rules given in ECMA-262, section 7.9, page 21. 1331 // the rules given in ECMA-262, section 7.9, page 21.
1331 Token::Value tok = peek(); 1332 i::Token::Value tok = peek();
1332 if (tok == Token::SEMICOLON) { 1333 if (tok == i::Token::SEMICOLON) {
1333 Next(); 1334 Next();
1334 return; 1335 return;
1335 } 1336 }
1336 if (scanner_->has_line_terminator_before_next() || 1337 if (scanner_->has_line_terminator_before_next() ||
1337 tok == Token::RBRACE || 1338 tok == i::Token::RBRACE ||
1338 tok == Token::EOS) { 1339 tok == i::Token::EOS) {
1339 return; 1340 return;
1340 } 1341 }
1341 Expect(Token::SEMICOLON, ok); 1342 Expect(i::Token::SEMICOLON, ok);
1342 } 1343 }
1343 1344
1344 1345
1345 template <typename Scanner, typename Log> 1346 template <typename Scanner, typename Log>
1346 Identifier PreParser<Scanner, Log>::GetIdentifierSymbol() { 1347 Identifier PreParser<Scanner, Log>::GetIdentifierSymbol() {
1347 const char* literal_chars = scanner_->literal_string(); 1348 const char* literal_chars = scanner_->literal_string();
1348 int literal_length = scanner_->literal_length(); 1349 int literal_length = scanner_->literal_length();
1349 int identifier_pos = scanner_->location().beg_pos; 1350 int identifier_pos = scanner_->location().beg_pos;
1350 1351
1351 log_->LogSymbol(identifier_pos, literal_chars, literal_length); 1352 log_->LogSymbol(identifier_pos, literal_chars, literal_length);
1352 1353
1353 return kUnknownExpression; 1354 return kUnknownExpression;
1354 } 1355 }
1355 1356
1356 1357
1357 template <typename Scanner, typename Log> 1358 template <typename Scanner, typename Log>
1358 Expression PreParser<Scanner, Log>::GetStringSymbol() { 1359 Expression PreParser<Scanner, Log>::GetStringSymbol() {
1359 const char* literal_chars = scanner_->literal_string(); 1360 const char* literal_chars = scanner_->literal_string();
1360 int literal_length = scanner_->literal_length(); 1361 int literal_length = scanner_->literal_length();
1361 1362
1362 int literal_position = scanner_->location().beg_pos; 1363 int literal_position = scanner_->location().beg_pos;
1363 log_->LogSymbol(literal_position, literal_chars, literal_length); 1364 log_->LogSymbol(literal_position, literal_chars, literal_length);
1364 1365
1365 return kUnknownExpression; 1366 return kUnknownExpression;
1366 } 1367 }
1367 1368
1368 1369
1369 template <typename Scanner, typename Log> 1370 template <typename Scanner, typename Log>
1370 Identifier PreParser<Scanner, Log>::ParseIdentifier(bool* ok) { 1371 Identifier PreParser<Scanner, Log>::ParseIdentifier(bool* ok) {
1371 Expect(Token::IDENTIFIER, ok); 1372 Expect(i::Token::IDENTIFIER, ok);
1372 return GetIdentifierSymbol(); 1373 return GetIdentifierSymbol();
1373 } 1374 }
1374 1375
1375 1376
1376 template <typename Scanner, typename Log> 1377 template <typename Scanner, typename Log>
1377 Identifier PreParser<Scanner, Log>::ParseIdentifierName(bool* ok) { 1378 Identifier PreParser<Scanner, Log>::ParseIdentifierName(bool* ok) {
1378 Token::Value next = Next(); 1379 i::Token::Value next = Next();
1379 if (Token::IsKeyword(next)) { 1380 if (i::Token::IsKeyword(next)) {
1380 int pos = scanner_->location().beg_pos; 1381 int pos = scanner_->location().beg_pos;
1381 const char* keyword = Token::String(next); 1382 const char* keyword = i::Token::String(next);
1382 log_->LogSymbol(pos, keyword, strlen(keyword)); 1383 log_->LogSymbol(pos, keyword, strlen(keyword));
1383 return kUnknownExpression; 1384 return kUnknownExpression;
1384 } 1385 }
1385 if (next == Token::IDENTIFIER) { 1386 if (next == i::Token::IDENTIFIER) {
1386 return GetIdentifierSymbol(); 1387 return GetIdentifierSymbol();
1387 } 1388 }
1388 *ok = false; 1389 *ok = false;
1389 return kUnknownIdentifier; 1390 return kUnknownIdentifier;
1390 } 1391 }
1391 1392
1392 1393
1393 // This function reads an identifier and determines whether or not it 1394 // This function reads an identifier and determines whether or not it
1394 // is 'get' or 'set'. The reason for not using ParseIdentifier and 1395 // is 'get' or 'set'. The reason for not using ParseIdentifier and
1395 // checking on the output is that this involves heap allocation which 1396 // checking on the output is that this involves heap allocation which
1396 // we can't do during preparsing. 1397 // we can't do during preparsing.
1397 template <typename Scanner, typename Log> 1398 template <typename Scanner, typename Log>
1398 Identifier PreParser<Scanner, Log>::ParseIdentifierOrGetOrSet(bool* is_get, 1399 Identifier PreParser<Scanner, Log>::ParseIdentifierOrGetOrSet(bool* is_get,
1399 bool* is_set, 1400 bool* is_set,
1400 bool* ok) { 1401 bool* ok) {
1401 Expect(Token::IDENTIFIER, CHECK_OK); 1402 Expect(i::Token::IDENTIFIER, CHECK_OK);
1402 if (scanner_->literal_length() == 3) { 1403 if (scanner_->literal_length() == 3) {
1403 const char* token = scanner_->literal_string(); 1404 const char* token = scanner_->literal_string();
1404 *is_get = strncmp(token, "get", 3) == 0; 1405 *is_get = strncmp(token, "get", 3) == 0;
1405 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 1406 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1406 } 1407 }
1407 return GetIdentifierSymbol(); 1408 return GetIdentifierSymbol();
1408 } 1409 }
1409 1410
1410 #undef CHECK_OK 1411 #undef CHECK_OK
1411 } } } // v8::internal::preparser 1412 } } // v8::preparser
1412 1413
1413 #endif // V8_PREPARSER_H 1414 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/checks.cc ('k') | src/scanner.h » ('j') | src/scanner-base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698