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

Side by Side Diff: src/preparser.cc

Issue 5295004: Preparser extracted into separate files that can be compiled to a library. (Closed)
Patch Set: Cleanup of preparse class. Created 10 years 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/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 if (!*ok) return -1; \ 58 if (!*ok) return -1; \
59 ((void)0 59 ((void)0
60 #define DUMMY ) // to make indentation work 60 #define DUMMY ) // to make indentation work
61 #undef DUMMY 61 #undef DUMMY
62 62
63 63
64 void PreParser::ReportUnexpectedToken(i::Token::Value token) { 64 void PreParser::ReportUnexpectedToken(i::Token::Value token) {
65 // We don't report stack overflows here, to avoid increasing the 65 // We don't report stack overflows here, to avoid increasing the
66 // stack depth even further. Instead we report it after parsing is 66 // stack depth even further. Instead we report it after parsing is
67 // over, in ParseProgram. 67 // over, in ParseProgram.
68 if (token == i::Token::ILLEGAL && scanner_->stack_overflow()) { 68 if (token == i::Token::ILLEGAL && stack_overflow_) {
69 return; 69 return;
70 } 70 }
71 i::JavaScriptScanner::Location source_location = scanner_->location(); 71 i::JavaScriptScanner::Location source_location = scanner_->location();
72 72
73 // Four of the tokens are treated specially 73 // Four of the tokens are treated specially
74 switch (token) { 74 switch (token) {
75 case i::Token::EOS: 75 case i::Token::EOS:
76 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 76 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
77 "unexpected_eos", NULL); 77 "unexpected_eos", NULL);
78 case i::Token::NUMBER: 78 case i::Token::NUMBER:
79 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 79 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
80 "unexpected_token_number", NULL); 80 "unexpected_token_number", NULL);
81 case i::Token::STRING: 81 case i::Token::STRING:
82 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 82 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
83 "unexpected_token_string", NULL); 83 "unexpected_token_string", NULL);
84 case i::Token::IDENTIFIER: 84 case i::Token::IDENTIFIER:
85 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 85 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
86 "unexpected_token_identifier", NULL); 86 "unexpected_token_identifier", NULL);
87 default: 87 default:
88 const char* name = i::Token::String(token); 88 const char* name = i::Token::String(token);
89 ReportMessageAt(source_location.beg_pos, source_location.end_pos, 89 ReportMessageAt(source_location.beg_pos, source_location.end_pos,
90 "unexpected_token", name); 90 "unexpected_token", name);
91 } 91 }
92 } 92 }
93 93
94 94
95 SourceElements PreParser::ParseSourceElements(int end_token, 95 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
96 bool* ok) { 96 bool* ok) {
97 // SourceElements :: 97 // SourceElements ::
98 // (Statement)* <end_token> 98 // (Statement)* <end_token>
99 99
100 while (peek() != end_token) { 100 while (peek() != end_token) {
101 ParseStatement(CHECK_OK); 101 ParseStatement(CHECK_OK);
102 } 102 }
103 return kUnknownSourceElements; 103 return kUnknownSourceElements;
104 } 104 }
105 105
106 106
107 Statement PreParser::ParseStatement(bool* ok) { 107 PreParser::PreParser::Statement PreParser::ParseStatement(bool* ok) {
108 // Statement :: 108 // Statement ::
109 // Block 109 // Block
110 // VariableStatement 110 // VariableStatement
111 // EmptyStatement 111 // EmptyStatement
112 // ExpressionStatement 112 // ExpressionStatement
113 // IfStatement 113 // IfStatement
114 // IterationStatement 114 // IterationStatement
115 // ContinueStatement 115 // ContinueStatement
116 // BreakStatement 116 // BreakStatement
117 // ReturnStatement 117 // ReturnStatement
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 183
184 case i::Token::DEBUGGER: 184 case i::Token::DEBUGGER:
185 return ParseDebuggerStatement(ok); 185 return ParseDebuggerStatement(ok);
186 186
187 default: 187 default:
188 return ParseExpressionOrLabelledStatement(ok); 188 return ParseExpressionOrLabelledStatement(ok);
189 } 189 }
190 } 190 }
191 191
192 192
193 Statement PreParser::ParseFunctionDeclaration(bool* ok) { 193 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
194 // FunctionDeclaration :: 194 // FunctionDeclaration ::
195 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 195 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
196 Expect(i::Token::FUNCTION, CHECK_OK); 196 Expect(i::Token::FUNCTION, CHECK_OK);
197 ParseIdentifier(CHECK_OK); 197 ParseIdentifier(CHECK_OK);
198 ParseFunctionLiteral(CHECK_OK); 198 ParseFunctionLiteral(CHECK_OK);
199 return kUnknownStatement; 199 return kUnknownStatement;
200 } 200 }
201 201
202 202
203 // Language extension which is only enabled for source files loaded 203 // Language extension which is only enabled for source files loaded
204 // through the API's extension mechanism. A native function 204 // through the API's extension mechanism. A native function
205 // declaration is resolved by looking up the function through a 205 // declaration is resolved by looking up the function through a
206 // callback provided by the extension. 206 // callback provided by the extension.
207 Statement PreParser::ParseNativeDeclaration(bool* ok) { 207 PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) {
208 Expect(i::Token::NATIVE, CHECK_OK); 208 Expect(i::Token::NATIVE, CHECK_OK);
209 Expect(i::Token::FUNCTION, CHECK_OK); 209 Expect(i::Token::FUNCTION, CHECK_OK);
210 ParseIdentifier(CHECK_OK); 210 ParseIdentifier(CHECK_OK);
211 Expect(i::Token::LPAREN, CHECK_OK); 211 Expect(i::Token::LPAREN, CHECK_OK);
212 bool done = (peek() == i::Token::RPAREN); 212 bool done = (peek() == i::Token::RPAREN);
213 while (!done) { 213 while (!done) {
214 ParseIdentifier(CHECK_OK); 214 ParseIdentifier(CHECK_OK);
215 done = (peek() == i::Token::RPAREN); 215 done = (peek() == i::Token::RPAREN);
216 if (!done) { 216 if (!done) {
217 Expect(i::Token::COMMA, CHECK_OK); 217 Expect(i::Token::COMMA, CHECK_OK);
218 } 218 }
219 } 219 }
220 Expect(i::Token::RPAREN, CHECK_OK); 220 Expect(i::Token::RPAREN, CHECK_OK);
221 Expect(i::Token::SEMICOLON, CHECK_OK); 221 Expect(i::Token::SEMICOLON, CHECK_OK);
222 return kUnknownStatement; 222 return kUnknownStatement;
223 } 223 }
224 224
225 225
226 Statement PreParser::ParseBlock(bool* ok) { 226 PreParser::Statement PreParser::ParseBlock(bool* ok) {
227 // Block :: 227 // Block ::
228 // '{' Statement* '}' 228 // '{' Statement* '}'
229 229
230 // Note that a Block does not introduce a new execution scope! 230 // Note that a Block does not introduce a new execution scope!
231 // (ECMA-262, 3rd, 12.2) 231 // (ECMA-262, 3rd, 12.2)
232 // 232 //
233 Expect(i::Token::LBRACE, CHECK_OK); 233 Expect(i::Token::LBRACE, CHECK_OK);
234 while (peek() != i::Token::RBRACE) { 234 while (peek() != i::Token::RBRACE) {
235 ParseStatement(CHECK_OK); 235 ParseStatement(CHECK_OK);
236 } 236 }
237 Expect(i::Token::RBRACE, CHECK_OK); 237 Expect(i::Token::RBRACE, CHECK_OK);
238 return kUnknownStatement; 238 return kUnknownStatement;
239 } 239 }
240 240
241 241
242 Statement PreParser::ParseVariableStatement(bool* ok) { 242 PreParser::Statement PreParser::ParseVariableStatement(bool* ok) {
243 // VariableStatement :: 243 // VariableStatement ::
244 // VariableDeclarations ';' 244 // VariableDeclarations ';'
245 245
246 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); 246 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK);
247 ExpectSemicolon(CHECK_OK); 247 ExpectSemicolon(CHECK_OK);
248 return result; 248 return result;
249 } 249 }
250 250
251 251
252 // If the variable declaration declares exactly one non-const 252 // If the variable declaration declares exactly one non-const
253 // variable, then *var is set to that variable. In all other cases, 253 // variable, then *var is set to that variable. In all other cases,
254 // *var is untouched; in particular, it is the caller's responsibility 254 // *var is untouched; in particular, it is the caller's responsibility
255 // to initialize it properly. This mechanism is also used for the parsing 255 // to initialize it properly. This mechanism is also used for the parsing
256 // of 'for-in' loops. 256 // of 'for-in' loops.
257 Statement PreParser::ParseVariableDeclarations(bool accept_IN, 257 PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN,
258 int* num_decl, 258 int* num_decl,
259 bool* ok) { 259 bool* ok) {
260 // VariableDeclarations :: 260 // VariableDeclarations ::
261 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 261 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
262 262
263 if (peek() == i::Token::VAR) { 263 if (peek() == i::Token::VAR) {
264 Consume(i::Token::VAR); 264 Consume(i::Token::VAR);
265 } else if (peek() == i::Token::CONST) { 265 } else if (peek() == i::Token::CONST) {
266 Consume(i::Token::CONST); 266 Consume(i::Token::CONST);
267 } else { 267 } else {
268 *ok = false; 268 *ok = false;
269 return 0; 269 return 0;
(...skipping 11 matching lines...) Expand all
281 Expect(i::Token::ASSIGN, CHECK_OK); 281 Expect(i::Token::ASSIGN, CHECK_OK);
282 ParseAssignmentExpression(accept_IN, CHECK_OK); 282 ParseAssignmentExpression(accept_IN, CHECK_OK);
283 } 283 }
284 } while (peek() == i::Token::COMMA); 284 } while (peek() == i::Token::COMMA);
285 285
286 if (num_decl != NULL) *num_decl = nvars; 286 if (num_decl != NULL) *num_decl = nvars;
287 return kUnknownStatement; 287 return kUnknownStatement;
288 } 288 }
289 289
290 290
291 Statement PreParser::ParseExpressionOrLabelledStatement( 291 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
292 bool* ok) { 292 bool* ok) {
293 // ExpressionStatement | LabelledStatement :: 293 // ExpressionStatement | LabelledStatement ::
294 // Expression ';' 294 // Expression ';'
295 // Identifier ':' Statement 295 // Identifier ':' Statement
296 296
297 Expression expr = ParseExpression(true, CHECK_OK); 297 Expression expr = ParseExpression(true, CHECK_OK);
298 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { 298 if (peek() == i::Token::COLON && expr == kIdentifierExpression) {
299 Consume(i::Token::COLON); 299 Consume(i::Token::COLON);
300 return ParseStatement(ok); 300 return ParseStatement(ok);
301 } 301 }
302 // Parsed expression statement. 302 // Parsed expression statement.
303 ExpectSemicolon(CHECK_OK); 303 ExpectSemicolon(CHECK_OK);
304 return kUnknownStatement; 304 return kUnknownStatement;
305 } 305 }
306 306
307 307
308 Statement PreParser::ParseIfStatement(bool* ok) { 308 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
309 // IfStatement :: 309 // IfStatement ::
310 // 'if' '(' Expression ')' Statement ('else' Statement)? 310 // 'if' '(' Expression ')' Statement ('else' Statement)?
311 311
312 Expect(i::Token::IF, CHECK_OK); 312 Expect(i::Token::IF, CHECK_OK);
313 Expect(i::Token::LPAREN, CHECK_OK); 313 Expect(i::Token::LPAREN, CHECK_OK);
314 ParseExpression(true, CHECK_OK); 314 ParseExpression(true, CHECK_OK);
315 Expect(i::Token::RPAREN, CHECK_OK); 315 Expect(i::Token::RPAREN, CHECK_OK);
316 ParseStatement(CHECK_OK); 316 ParseStatement(CHECK_OK);
317 if (peek() == i::Token::ELSE) { 317 if (peek() == i::Token::ELSE) {
318 Next(); 318 Next();
319 ParseStatement(CHECK_OK); 319 ParseStatement(CHECK_OK);
320 } 320 }
321 return kUnknownStatement; 321 return kUnknownStatement;
322 } 322 }
323 323
324 324
325 Statement PreParser::ParseContinueStatement(bool* ok) { 325 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
326 // ContinueStatement :: 326 // ContinueStatement ::
327 // 'continue' [no line terminator] Identifier? ';' 327 // 'continue' [no line terminator] Identifier? ';'
328 328
329 Expect(i::Token::CONTINUE, CHECK_OK); 329 Expect(i::Token::CONTINUE, CHECK_OK);
330 i::Token::Value tok = peek(); 330 i::Token::Value tok = peek();
331 if (!scanner_->has_line_terminator_before_next() && 331 if (!scanner_->has_line_terminator_before_next() &&
332 tok != i::Token::SEMICOLON && 332 tok != i::Token::SEMICOLON &&
333 tok != i::Token::RBRACE && 333 tok != i::Token::RBRACE &&
334 tok != i::Token::EOS) { 334 tok != i::Token::EOS) {
335 ParseIdentifier(CHECK_OK); 335 ParseIdentifier(CHECK_OK);
336 } 336 }
337 ExpectSemicolon(CHECK_OK); 337 ExpectSemicolon(CHECK_OK);
338 return kUnknownStatement; 338 return kUnknownStatement;
339 } 339 }
340 340
341 341
342 Statement PreParser::ParseBreakStatement(bool* ok) { 342 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
343 // BreakStatement :: 343 // BreakStatement ::
344 // 'break' [no line terminator] Identifier? ';' 344 // 'break' [no line terminator] Identifier? ';'
345 345
346 Expect(i::Token::BREAK, CHECK_OK); 346 Expect(i::Token::BREAK, CHECK_OK);
347 i::Token::Value tok = peek(); 347 i::Token::Value tok = peek();
348 if (!scanner_->has_line_terminator_before_next() && 348 if (!scanner_->has_line_terminator_before_next() &&
349 tok != i::Token::SEMICOLON && 349 tok != i::Token::SEMICOLON &&
350 tok != i::Token::RBRACE && 350 tok != i::Token::RBRACE &&
351 tok != i::Token::EOS) { 351 tok != i::Token::EOS) {
352 ParseIdentifier(CHECK_OK); 352 ParseIdentifier(CHECK_OK);
353 } 353 }
354 ExpectSemicolon(CHECK_OK); 354 ExpectSemicolon(CHECK_OK);
355 return kUnknownStatement; 355 return kUnknownStatement;
356 } 356 }
357 357
358 358
359 Statement PreParser::ParseReturnStatement(bool* ok) { 359 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
360 // ReturnStatement :: 360 // ReturnStatement ::
361 // 'return' [no line terminator] Expression? ';' 361 // 'return' [no line terminator] Expression? ';'
362 362
363 // Consume the return token. It is necessary to do the before 363 // Consume the return token. It is necessary to do the before
364 // reporting any errors on it, because of the way errors are 364 // reporting any errors on it, because of the way errors are
365 // reported (underlining). 365 // reported (underlining).
366 Expect(i::Token::RETURN, CHECK_OK); 366 Expect(i::Token::RETURN, CHECK_OK);
367 367
368 // An ECMAScript program is considered syntactically incorrect if it 368 // An ECMAScript program is considered syntactically incorrect if it
369 // contains a return statement that is not within the body of a 369 // contains a return statement that is not within the body of a
370 // function. See ECMA-262, section 12.9, page 67. 370 // function. See ECMA-262, section 12.9, page 67.
371 // This is not handled during preparsing. 371 // This is not handled during preparsing.
372 372
373 i::Token::Value tok = peek(); 373 i::Token::Value tok = peek();
374 if (!scanner_->has_line_terminator_before_next() && 374 if (!scanner_->has_line_terminator_before_next() &&
375 tok != i::Token::SEMICOLON && 375 tok != i::Token::SEMICOLON &&
376 tok != i::Token::RBRACE && 376 tok != i::Token::RBRACE &&
377 tok != i::Token::EOS) { 377 tok != i::Token::EOS) {
378 ParseExpression(true, CHECK_OK); 378 ParseExpression(true, CHECK_OK);
379 } 379 }
380 ExpectSemicolon(CHECK_OK); 380 ExpectSemicolon(CHECK_OK);
381 return kUnknownStatement; 381 return kUnknownStatement;
382 } 382 }
383 383
384 384
385 Statement PreParser::ParseWithStatement(bool* ok) { 385 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
386 // WithStatement :: 386 // WithStatement ::
387 // 'with' '(' Expression ')' Statement 387 // 'with' '(' Expression ')' Statement
388 Expect(i::Token::WITH, CHECK_OK); 388 Expect(i::Token::WITH, CHECK_OK);
389 Expect(i::Token::LPAREN, CHECK_OK); 389 Expect(i::Token::LPAREN, CHECK_OK);
390 ParseExpression(true, CHECK_OK); 390 ParseExpression(true, CHECK_OK);
391 Expect(i::Token::RPAREN, CHECK_OK); 391 Expect(i::Token::RPAREN, CHECK_OK);
392 392
393 scope_->EnterWith(); 393 scope_->EnterWith();
394 ParseStatement(CHECK_OK); 394 ParseStatement(CHECK_OK);
395 scope_->LeaveWith(); 395 scope_->LeaveWith();
396 return kUnknownStatement; 396 return kUnknownStatement;
397 } 397 }
398 398
399 399
400 Statement PreParser::ParseSwitchStatement(bool* ok) { 400 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
401 // SwitchStatement :: 401 // SwitchStatement ::
402 // 'switch' '(' Expression ')' '{' CaseClause* '}' 402 // 'switch' '(' Expression ')' '{' CaseClause* '}'
403 403
404 Expect(i::Token::SWITCH, CHECK_OK); 404 Expect(i::Token::SWITCH, CHECK_OK);
405 Expect(i::Token::LPAREN, CHECK_OK); 405 Expect(i::Token::LPAREN, CHECK_OK);
406 ParseExpression(true, CHECK_OK); 406 ParseExpression(true, CHECK_OK);
407 Expect(i::Token::RPAREN, CHECK_OK); 407 Expect(i::Token::RPAREN, CHECK_OK);
408 408
409 Expect(i::Token::LBRACE, CHECK_OK); 409 Expect(i::Token::LBRACE, CHECK_OK);
410 i::Token::Value token = peek(); 410 i::Token::Value token = peek();
411 while (token != i::Token::RBRACE) { 411 while (token != i::Token::RBRACE) {
412 if (token == i::Token::CASE) { 412 if (token == i::Token::CASE) {
413 Expect(i::Token::CASE, CHECK_OK); 413 Expect(i::Token::CASE, CHECK_OK);
414 ParseExpression(true, CHECK_OK); 414 ParseExpression(true, CHECK_OK);
415 Expect(i::Token::COLON, CHECK_OK); 415 Expect(i::Token::COLON, CHECK_OK);
416 } else if (token == i::Token::DEFAULT) { 416 } else if (token == i::Token::DEFAULT) {
417 Expect(i::Token::DEFAULT, CHECK_OK); 417 Expect(i::Token::DEFAULT, CHECK_OK);
418 Expect(i::Token::COLON, CHECK_OK); 418 Expect(i::Token::COLON, CHECK_OK);
419 } else { 419 } else {
420 ParseStatement(CHECK_OK); 420 ParseStatement(CHECK_OK);
421 } 421 }
422 token = peek(); 422 token = peek();
423 } 423 }
424 Expect(i::Token::RBRACE, CHECK_OK); 424 Expect(i::Token::RBRACE, CHECK_OK);
425 425
426 return kUnknownStatement; 426 return kUnknownStatement;
427 } 427 }
428 428
429 429
430 Statement PreParser::ParseDoWhileStatement(bool* ok) { 430 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
431 // DoStatement :: 431 // DoStatement ::
432 // 'do' Statement 'while' '(' Expression ')' ';' 432 // 'do' Statement 'while' '(' Expression ')' ';'
433 433
434 Expect(i::Token::DO, CHECK_OK); 434 Expect(i::Token::DO, CHECK_OK);
435 ParseStatement(CHECK_OK); 435 ParseStatement(CHECK_OK);
436 Expect(i::Token::WHILE, CHECK_OK); 436 Expect(i::Token::WHILE, CHECK_OK);
437 Expect(i::Token::LPAREN, CHECK_OK); 437 Expect(i::Token::LPAREN, CHECK_OK);
438 ParseExpression(true, CHECK_OK); 438 ParseExpression(true, CHECK_OK);
439 Expect(i::Token::RPAREN, CHECK_OK); 439 Expect(i::Token::RPAREN, CHECK_OK);
440 return kUnknownStatement; 440 return kUnknownStatement;
441 } 441 }
442 442
443 443
444 Statement PreParser::ParseWhileStatement(bool* ok) { 444 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
445 // WhileStatement :: 445 // WhileStatement ::
446 // 'while' '(' Expression ')' Statement 446 // 'while' '(' Expression ')' Statement
447 447
448 Expect(i::Token::WHILE, CHECK_OK); 448 Expect(i::Token::WHILE, CHECK_OK);
449 Expect(i::Token::LPAREN, CHECK_OK); 449 Expect(i::Token::LPAREN, CHECK_OK);
450 ParseExpression(true, CHECK_OK); 450 ParseExpression(true, CHECK_OK);
451 Expect(i::Token::RPAREN, CHECK_OK); 451 Expect(i::Token::RPAREN, CHECK_OK);
452 ParseStatement(CHECK_OK); 452 ParseStatement(CHECK_OK);
453 return kUnknownStatement; 453 return kUnknownStatement;
454 } 454 }
455 455
456 456
457 Statement PreParser::ParseForStatement(bool* ok) { 457 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
458 // ForStatement :: 458 // ForStatement ::
459 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 459 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
460 460
461 Expect(i::Token::FOR, CHECK_OK); 461 Expect(i::Token::FOR, CHECK_OK);
462 Expect(i::Token::LPAREN, CHECK_OK); 462 Expect(i::Token::LPAREN, CHECK_OK);
463 if (peek() != i::Token::SEMICOLON) { 463 if (peek() != i::Token::SEMICOLON) {
464 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { 464 if (peek() == i::Token::VAR || peek() == i::Token::CONST) {
465 int decl_count; 465 int decl_count;
466 ParseVariableDeclarations(false, &decl_count, CHECK_OK); 466 ParseVariableDeclarations(false, &decl_count, CHECK_OK);
467 if (peek() == i::Token::IN && decl_count == 1) { 467 if (peek() == i::Token::IN && decl_count == 1) {
(...skipping 28 matching lines...) Expand all
496 if (peek() != i::Token::RPAREN) { 496 if (peek() != i::Token::RPAREN) {
497 ParseExpression(true, CHECK_OK); 497 ParseExpression(true, CHECK_OK);
498 } 498 }
499 Expect(i::Token::RPAREN, CHECK_OK); 499 Expect(i::Token::RPAREN, CHECK_OK);
500 500
501 ParseStatement(CHECK_OK); 501 ParseStatement(CHECK_OK);
502 return kUnknownStatement; 502 return kUnknownStatement;
503 } 503 }
504 504
505 505
506 Statement PreParser::ParseThrowStatement(bool* ok) { 506 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
507 // ThrowStatement :: 507 // ThrowStatement ::
508 // 'throw' [no line terminator] Expression ';' 508 // 'throw' [no line terminator] Expression ';'
509 509
510 Expect(i::Token::THROW, CHECK_OK); 510 Expect(i::Token::THROW, CHECK_OK);
511 if (scanner_->has_line_terminator_before_next()) { 511 if (scanner_->has_line_terminator_before_next()) {
512 i::JavaScriptScanner::Location pos = scanner_->location(); 512 i::JavaScriptScanner::Location pos = scanner_->location();
513 ReportMessageAt(pos.beg_pos, pos.end_pos, 513 ReportMessageAt(pos.beg_pos, pos.end_pos,
514 "newline_after_throw", NULL); 514 "newline_after_throw", NULL);
515 *ok = false; 515 *ok = false;
516 return kUnknownStatement; 516 return kUnknownStatement;
517 } 517 }
518 ParseExpression(true, CHECK_OK); 518 ParseExpression(true, CHECK_OK);
519 ExpectSemicolon(CHECK_OK); 519 ExpectSemicolon(CHECK_OK);
520 520
521 return kUnknownStatement; 521 return kUnknownStatement;
522 } 522 }
523 523
524 524
525 Statement PreParser::ParseTryStatement(bool* ok) { 525 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
526 // TryStatement :: 526 // TryStatement ::
527 // 'try' Block Catch 527 // 'try' Block Catch
528 // 'try' Block Finally 528 // 'try' Block Finally
529 // 'try' Block Catch Finally 529 // 'try' Block Catch Finally
530 // 530 //
531 // Catch :: 531 // Catch ::
532 // 'catch' '(' Identifier ')' Block 532 // 'catch' '(' Identifier ')' Block
533 // 533 //
534 // Finally :: 534 // Finally ::
535 // 'finally' Block 535 // 'finally' Block
(...skipping 22 matching lines...) Expand all
558 ParseBlock(CHECK_OK); 558 ParseBlock(CHECK_OK);
559 catch_or_finally_seen = true; 559 catch_or_finally_seen = true;
560 } 560 }
561 if (!catch_or_finally_seen) { 561 if (!catch_or_finally_seen) {
562 *ok = false; 562 *ok = false;
563 } 563 }
564 return kUnknownStatement; 564 return kUnknownStatement;
565 } 565 }
566 566
567 567
568 Statement PreParser::ParseDebuggerStatement(bool* ok) { 568 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
569 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 569 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
570 // contexts this is used as a statement which invokes the debugger as if a 570 // contexts this is used as a statement which invokes the debugger as if a
571 // break point is present. 571 // break point is present.
572 // DebuggerStatement :: 572 // DebuggerStatement ::
573 // 'debugger' ';' 573 // 'debugger' ';'
574 574
575 Expect(i::Token::DEBUGGER, CHECK_OK); 575 Expect(i::Token::DEBUGGER, CHECK_OK);
576 ExpectSemicolon(CHECK_OK); 576 ExpectSemicolon(CHECK_OK);
577 return kUnknownStatement; 577 return kUnknownStatement;
578 } 578 }
579 579
580 580
581 // Precedence = 1 581 // Precedence = 1
582 Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { 582 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
583 // Expression :: 583 // Expression ::
584 // AssignmentExpression 584 // AssignmentExpression
585 // Expression ',' AssignmentExpression 585 // Expression ',' AssignmentExpression
586 586
587 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); 587 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
588 while (peek() == i::Token::COMMA) { 588 while (peek() == i::Token::COMMA) {
589 Expect(i::Token::COMMA, CHECK_OK); 589 Expect(i::Token::COMMA, CHECK_OK);
590 ParseAssignmentExpression(accept_IN, CHECK_OK); 590 ParseAssignmentExpression(accept_IN, CHECK_OK);
591 result = kUnknownExpression; 591 result = kUnknownExpression;
592 } 592 }
593 return result; 593 return result;
594 } 594 }
595 595
596 596
597 // Precedence = 2 597 // Precedence = 2
598 Expression PreParser::ParseAssignmentExpression(bool accept_IN, 598 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
599 bool* ok) { 599 bool* ok) {
600 // AssignmentExpression :: 600 // AssignmentExpression ::
601 // ConditionalExpression 601 // ConditionalExpression
602 // LeftHandSideExpression AssignmentOperator AssignmentExpression 602 // LeftHandSideExpression AssignmentOperator AssignmentExpression
603 603
604 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 604 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
605 605
606 if (!i::Token::IsAssignmentOp(peek())) { 606 if (!i::Token::IsAssignmentOp(peek())) {
607 // Parsed conditional expression only (no assignment). 607 // Parsed conditional expression only (no assignment).
608 return expression; 608 return expression;
609 } 609 }
610 610
611 i::Token::Value op = Next(); // Get assignment operator. 611 i::Token::Value op = Next(); // Get assignment operator.
612 ParseAssignmentExpression(accept_IN, CHECK_OK); 612 ParseAssignmentExpression(accept_IN, CHECK_OK);
613 613
614 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) { 614 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) {
615 scope_->AddProperty(); 615 scope_->AddProperty();
616 } 616 }
617 617
618 return kUnknownExpression; 618 return kUnknownExpression;
619 } 619 }
620 620
621 621
622 // Precedence = 3 622 // Precedence = 3
623 Expression PreParser::ParseConditionalExpression(bool accept_IN, 623 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
624 bool* ok) { 624 bool* ok) {
625 // ConditionalExpression :: 625 // ConditionalExpression ::
626 // LogicalOrExpression 626 // LogicalOrExpression
627 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 627 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
628 628
629 // We start using the binary expression parser for prec >= 4 only! 629 // We start using the binary expression parser for prec >= 4 only!
630 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 630 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
631 if (peek() != i::Token::CONDITIONAL) return expression; 631 if (peek() != i::Token::CONDITIONAL) return expression;
632 Consume(i::Token::CONDITIONAL); 632 Consume(i::Token::CONDITIONAL);
633 // In parsing the first assignment expression in conditional 633 // In parsing the first assignment expression in conditional
634 // expressions we always accept the 'in' keyword; see ECMA-262, 634 // expressions we always accept the 'in' keyword; see ECMA-262,
635 // section 11.12, page 58. 635 // section 11.12, page 58.
636 ParseAssignmentExpression(true, CHECK_OK); 636 ParseAssignmentExpression(true, CHECK_OK);
637 Expect(i::Token::COLON, CHECK_OK); 637 Expect(i::Token::COLON, CHECK_OK);
638 ParseAssignmentExpression(accept_IN, CHECK_OK); 638 ParseAssignmentExpression(accept_IN, CHECK_OK);
639 return kUnknownExpression; 639 return kUnknownExpression;
640 } 640 }
641 641
642 642
643 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { 643 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) {
644 if (tok == i::Token::IN && !accept_IN) 644 if (tok == i::Token::IN && !accept_IN)
645 return 0; // 0 precedence will terminate binary expression parsing 645 return 0; // 0 precedence will terminate binary expression parsing
646 646
647 return i::Token::Precedence(tok); 647 return i::Token::Precedence(tok);
648 } 648 }
649 649
650 650
651 // Precedence >= 4 651 // Precedence >= 4
652 Expression PreParser::ParseBinaryExpression(int prec, 652 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
653 bool accept_IN, 653 bool accept_IN,
654 bool* ok) { 654 bool* ok) {
655 Expression result = ParseUnaryExpression(CHECK_OK); 655 Expression result = ParseUnaryExpression(CHECK_OK);
656 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 656 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
657 // prec1 >= 4 657 // prec1 >= 4
658 while (Precedence(peek(), accept_IN) == prec1) { 658 while (Precedence(peek(), accept_IN) == prec1) {
659 Next(); 659 Next();
660 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 660 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
661 result = kUnknownExpression; 661 result = kUnknownExpression;
662 } 662 }
663 } 663 }
664 return result; 664 return result;
665 } 665 }
666 666
667 667
668 Expression PreParser::ParseUnaryExpression(bool* ok) { 668 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
669 // UnaryExpression :: 669 // UnaryExpression ::
670 // PostfixExpression 670 // PostfixExpression
671 // 'delete' UnaryExpression 671 // 'delete' UnaryExpression
672 // 'void' UnaryExpression 672 // 'void' UnaryExpression
673 // 'typeof' UnaryExpression 673 // 'typeof' UnaryExpression
674 // '++' UnaryExpression 674 // '++' UnaryExpression
675 // '--' UnaryExpression 675 // '--' UnaryExpression
676 // '+' UnaryExpression 676 // '+' UnaryExpression
677 // '-' UnaryExpression 677 // '-' UnaryExpression
678 // '~' UnaryExpression 678 // '~' UnaryExpression
679 // '!' UnaryExpression 679 // '!' UnaryExpression
680 680
681 i::Token::Value op = peek(); 681 i::Token::Value op = peek();
682 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) { 682 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) {
683 op = Next(); 683 op = Next();
684 ParseUnaryExpression(ok); 684 ParseUnaryExpression(ok);
685 return kUnknownExpression; 685 return kUnknownExpression;
686 } else { 686 } else {
687 return ParsePostfixExpression(ok); 687 return ParsePostfixExpression(ok);
688 } 688 }
689 } 689 }
690 690
691 691
692 Expression PreParser::ParsePostfixExpression(bool* ok) { 692 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
693 // PostfixExpression :: 693 // PostfixExpression ::
694 // LeftHandSideExpression ('++' | '--')? 694 // LeftHandSideExpression ('++' | '--')?
695 695
696 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 696 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
697 if (!scanner_->has_line_terminator_before_next() && 697 if (!scanner_->has_line_terminator_before_next() &&
698 i::Token::IsCountOp(peek())) { 698 i::Token::IsCountOp(peek())) {
699 Next(); 699 Next();
700 return kUnknownExpression; 700 return kUnknownExpression;
701 } 701 }
702 return expression; 702 return expression;
703 } 703 }
704 704
705 705
706 Expression PreParser::ParseLeftHandSideExpression(bool* ok) { 706 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
707 // LeftHandSideExpression :: 707 // LeftHandSideExpression ::
708 // (NewExpression | MemberExpression) ... 708 // (NewExpression | MemberExpression) ...
709 709
710 Expression result; 710 Expression result;
711 if (peek() == i::Token::NEW) { 711 if (peek() == i::Token::NEW) {
712 result = ParseNewExpression(CHECK_OK); 712 result = ParseNewExpression(CHECK_OK);
713 } else { 713 } else {
714 result = ParseMemberExpression(CHECK_OK); 714 result = ParseMemberExpression(CHECK_OK);
715 } 715 }
716 716
(...skipping 28 matching lines...) Expand all
745 break; 745 break;
746 } 746 }
747 747
748 default: 748 default:
749 return result; 749 return result;
750 } 750 }
751 } 751 }
752 } 752 }
753 753
754 754
755 Expression PreParser::ParseNewExpression(bool* ok) { 755 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
756 // NewExpression :: 756 // NewExpression ::
757 // ('new')+ MemberExpression 757 // ('new')+ MemberExpression
758 758
759 // The grammar for new expressions is pretty warped. The keyword 759 // The grammar for new expressions is pretty warped. The keyword
760 // 'new' can either be a part of the new expression (where it isn't 760 // 'new' can either be a part of the new expression (where it isn't
761 // followed by an argument list) or a part of the member expression, 761 // followed by an argument list) or a part of the member expression,
762 // where it must be followed by an argument list. To accommodate 762 // where it must be followed by an argument list. To accommodate
763 // this, we parse the 'new' keywords greedily and keep track of how 763 // this, we parse the 'new' keywords greedily and keep track of how
764 // many we have parsed. This information is then passed on to the 764 // many we have parsed. This information is then passed on to the
765 // member expression parser, which is only allowed to match argument 765 // member expression parser, which is only allowed to match argument
766 // lists as long as it has 'new' prefixes left 766 // lists as long as it has 'new' prefixes left
767 unsigned new_count = 0; 767 unsigned new_count = 0;
768 do { 768 do {
769 Consume(i::Token::NEW); 769 Consume(i::Token::NEW);
770 new_count++; 770 new_count++;
771 } while (peek() == i::Token::NEW); 771 } while (peek() == i::Token::NEW);
772 772
773 return ParseMemberWithNewPrefixesExpression(new_count, ok); 773 return ParseMemberWithNewPrefixesExpression(new_count, ok);
774 } 774 }
775 775
776 776
777 Expression PreParser::ParseMemberExpression(bool* ok) { 777 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
778 return ParseMemberWithNewPrefixesExpression(0, ok); 778 return ParseMemberWithNewPrefixesExpression(0, ok);
779 } 779 }
780 780
781 781
782 Expression PreParser::ParseMemberWithNewPrefixesExpression( 782 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
783 unsigned new_count, bool* ok) { 783 unsigned new_count, bool* ok) {
784 // MemberExpression :: 784 // MemberExpression ::
785 // (PrimaryExpression | FunctionLiteral) 785 // (PrimaryExpression | FunctionLiteral)
786 // ('[' Expression ']' | '.' Identifier | Arguments)* 786 // ('[' Expression ']' | '.' Identifier | Arguments)*
787 787
788 // Parse the initial primary or function expression. 788 // Parse the initial primary or function expression.
789 Expression result = kUnknownExpression; 789 Expression result = kUnknownExpression;
790 if (peek() == i::Token::FUNCTION) { 790 if (peek() == i::Token::FUNCTION) {
791 Consume(i::Token::FUNCTION); 791 Consume(i::Token::FUNCTION);
792 if (peek() == i::Token::IDENTIFIER) { 792 if (peek() == i::Token::IDENTIFIER) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 result = kUnknownExpression; 828 result = kUnknownExpression;
829 break; 829 break;
830 } 830 }
831 default: 831 default:
832 return result; 832 return result;
833 } 833 }
834 } 834 }
835 } 835 }
836 836
837 837
838 Expression PreParser::ParsePrimaryExpression(bool* ok) { 838 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
839 // PrimaryExpression :: 839 // PrimaryExpression ::
840 // 'this' 840 // 'this'
841 // 'null' 841 // 'null'
842 // 'true' 842 // 'true'
843 // 'false' 843 // 'false'
844 // Identifier 844 // Identifier
845 // Number 845 // Number
846 // String 846 // String
847 // ArrayLiteral 847 // ArrayLiteral
848 // ObjectLiteral 848 // ObjectLiteral
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 Next(); 907 Next();
908 *ok = false; 908 *ok = false;
909 return kUnknownExpression; 909 return kUnknownExpression;
910 } 910 }
911 } 911 }
912 912
913 return result; 913 return result;
914 } 914 }
915 915
916 916
917 Expression PreParser::ParseArrayLiteral(bool* ok) { 917 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
918 // ArrayLiteral :: 918 // ArrayLiteral ::
919 // '[' Expression? (',' Expression?)* ']' 919 // '[' Expression? (',' Expression?)* ']'
920 Expect(i::Token::LBRACK, CHECK_OK); 920 Expect(i::Token::LBRACK, CHECK_OK);
921 while (peek() != i::Token::RBRACK) { 921 while (peek() != i::Token::RBRACK) {
922 if (peek() != i::Token::COMMA) { 922 if (peek() != i::Token::COMMA) {
923 ParseAssignmentExpression(true, CHECK_OK); 923 ParseAssignmentExpression(true, CHECK_OK);
924 } 924 }
925 if (peek() != i::Token::RBRACK) { 925 if (peek() != i::Token::RBRACK) {
926 Expect(i::Token::COMMA, CHECK_OK); 926 Expect(i::Token::COMMA, CHECK_OK);
927 } 927 }
928 } 928 }
929 Expect(i::Token::RBRACK, CHECK_OK); 929 Expect(i::Token::RBRACK, CHECK_OK);
930 930
931 scope_->NextMaterializedLiteralIndex(); 931 scope_->NextMaterializedLiteralIndex();
932 return kUnknownExpression; 932 return kUnknownExpression;
933 } 933 }
934 934
935 935
936 Expression PreParser::ParseObjectLiteral(bool* ok) { 936 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
937 // ObjectLiteral :: 937 // ObjectLiteral ::
938 // '{' ( 938 // '{' (
939 // ((IdentifierName | String | Number) ':' AssignmentExpression) 939 // ((IdentifierName | String | Number) ':' AssignmentExpression)
940 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 940 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
941 // )*[','] '}' 941 // )*[','] '}'
942 942
943 Expect(i::Token::LBRACE, CHECK_OK); 943 Expect(i::Token::LBRACE, CHECK_OK);
944 while (peek() != i::Token::RBRACE) { 944 while (peek() != i::Token::RBRACE) {
945 i::Token::Value next = peek(); 945 i::Token::Value next = peek();
946 switch (next) { 946 switch (next) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 // TODO(1240767): Consider allowing trailing comma. 988 // TODO(1240767): Consider allowing trailing comma.
989 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); 989 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
990 } 990 }
991 Expect(i::Token::RBRACE, CHECK_OK); 991 Expect(i::Token::RBRACE, CHECK_OK);
992 992
993 scope_->NextMaterializedLiteralIndex(); 993 scope_->NextMaterializedLiteralIndex();
994 return kUnknownExpression; 994 return kUnknownExpression;
995 } 995 }
996 996
997 997
998 Expression PreParser::ParseRegExpLiteral(bool seen_equal, 998 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
999 bool* ok) { 999 bool* ok) {
1000 if (!scanner_->ScanRegExpPattern(seen_equal)) { 1000 if (!scanner_->ScanRegExpPattern(seen_equal)) {
1001 Next(); 1001 Next();
1002 i::JavaScriptScanner::Location location = scanner_->location(); 1002 i::JavaScriptScanner::Location location = scanner_->location();
1003 ReportMessageAt(location.beg_pos, location.end_pos, 1003 ReportMessageAt(location.beg_pos, location.end_pos,
1004 "unterminated_regexp", NULL); 1004 "unterminated_regexp", NULL);
1005 *ok = false; 1005 *ok = false;
1006 return kUnknownExpression; 1006 return kUnknownExpression;
1007 } 1007 }
1008 1008
1009 scope_->NextMaterializedLiteralIndex(); 1009 scope_->NextMaterializedLiteralIndex();
1010 1010
1011 if (!scanner_->ScanRegExpFlags()) { 1011 if (!scanner_->ScanRegExpFlags()) {
1012 Next(); 1012 Next();
1013 i::JavaScriptScanner::Location location = scanner_->location(); 1013 i::JavaScriptScanner::Location location = scanner_->location();
1014 ReportMessageAt(location.beg_pos, location.end_pos, 1014 ReportMessageAt(location.beg_pos, location.end_pos,
1015 "invalid_regexp_flags", NULL); 1015 "invalid_regexp_flags", NULL);
1016 *ok = false; 1016 *ok = false;
1017 return kUnknownExpression; 1017 return kUnknownExpression;
1018 } 1018 }
1019 Next(); 1019 Next();
1020 return kUnknownExpression; 1020 return kUnknownExpression;
1021 } 1021 }
1022 1022
1023 1023
1024 Arguments PreParser::ParseArguments(bool* ok) { 1024 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1025 // Arguments :: 1025 // Arguments ::
1026 // '(' (AssignmentExpression)*[','] ')' 1026 // '(' (AssignmentExpression)*[','] ')'
1027 1027
1028 Expect(i::Token::LPAREN, CHECK_OK); 1028 Expect(i::Token::LPAREN, CHECK_OK);
1029 bool done = (peek() == i::Token::RPAREN); 1029 bool done = (peek() == i::Token::RPAREN);
1030 int argc = 0; 1030 int argc = 0;
1031 while (!done) { 1031 while (!done) {
1032 ParseAssignmentExpression(true, CHECK_OK); 1032 ParseAssignmentExpression(true, CHECK_OK);
1033 argc++; 1033 argc++;
1034 done = (peek() == i::Token::RPAREN); 1034 done = (peek() == i::Token::RPAREN);
1035 if (!done) Expect(i::Token::COMMA, CHECK_OK); 1035 if (!done) Expect(i::Token::COMMA, CHECK_OK);
1036 } 1036 }
1037 Expect(i::Token::RPAREN, CHECK_OK); 1037 Expect(i::Token::RPAREN, CHECK_OK);
1038 return argc; 1038 return argc;
1039 } 1039 }
1040 1040
1041 1041
1042 Expression PreParser::ParseFunctionLiteral(bool* ok) { 1042 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
1043 // Function :: 1043 // Function ::
1044 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1044 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1045 1045
1046 // Parse function body. 1046 // Parse function body.
1047 ScopeType outer_scope_type = scope_->type(); 1047 ScopeType outer_scope_type = scope_->type();
1048 bool inside_with = scope_->IsInsideWith(); 1048 bool inside_with = scope_->IsInsideWith();
1049 Scope function_scope(&scope_, kFunctionScope); 1049 Scope function_scope(&scope_, kFunctionScope);
1050 1050
1051 // FormalParameterList :: 1051 // FormalParameterList ::
1052 // '(' (Identifier)*[','] ')' 1052 // '(' (Identifier)*[','] ')'
(...skipping 30 matching lines...) Expand all
1083 function_scope.materialized_literal_count(), 1083 function_scope.materialized_literal_count(),
1084 function_scope.expected_properties()); 1084 function_scope.expected_properties());
1085 } else { 1085 } else {
1086 ParseSourceElements(i::Token::RBRACE, CHECK_OK); 1086 ParseSourceElements(i::Token::RBRACE, CHECK_OK);
1087 Expect(i::Token::RBRACE, CHECK_OK); 1087 Expect(i::Token::RBRACE, CHECK_OK);
1088 } 1088 }
1089 return kUnknownExpression; 1089 return kUnknownExpression;
1090 } 1090 }
1091 1091
1092 1092
1093 Expression PreParser::ParseV8Intrinsic(bool* ok) { 1093 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1094 // CallRuntime :: 1094 // CallRuntime ::
1095 // '%' Identifier Arguments 1095 // '%' Identifier Arguments
1096 1096
1097 Expect(i::Token::MOD, CHECK_OK); 1097 Expect(i::Token::MOD, CHECK_OK);
1098 ParseIdentifier(CHECK_OK); 1098 ParseIdentifier(CHECK_OK);
1099 ParseArguments(CHECK_OK); 1099 ParseArguments(CHECK_OK);
1100 1100
1101 return kUnknownExpression; 1101 return kUnknownExpression;
1102 } 1102 }
1103 1103
1104 1104
1105 void PreParser::ExpectSemicolon(bool* ok) { 1105 void PreParser::ExpectSemicolon(bool* ok) {
1106 // Check for automatic semicolon insertion according to 1106 // Check for automatic semicolon insertion according to
1107 // the rules given in ECMA-262, section 7.9, page 21. 1107 // the rules given in ECMA-262, section 7.9, page 21.
1108 i::Token::Value tok = peek(); 1108 i::Token::Value tok = peek();
1109 if (tok == i::Token::SEMICOLON) { 1109 if (tok == i::Token::SEMICOLON) {
1110 Next(); 1110 Next();
1111 return; 1111 return;
1112 } 1112 }
1113 if (scanner_->has_line_terminator_before_next() || 1113 if (scanner_->has_line_terminator_before_next() ||
1114 tok == i::Token::RBRACE || 1114 tok == i::Token::RBRACE ||
1115 tok == i::Token::EOS) { 1115 tok == i::Token::EOS) {
1116 return; 1116 return;
1117 } 1117 }
1118 Expect(i::Token::SEMICOLON, ok); 1118 Expect(i::Token::SEMICOLON, ok);
1119 } 1119 }
1120 1120
1121 1121
1122 Identifier PreParser::GetIdentifierSymbol() { 1122 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1123 const char* literal_chars = scanner_->literal_string(); 1123 const char* literal_chars = scanner_->literal_string();
1124 int literal_length = scanner_->literal_length(); 1124 int literal_length = scanner_->literal_length();
1125 int identifier_pos = scanner_->location().beg_pos; 1125 int identifier_pos = scanner_->location().beg_pos;
1126 1126
1127 log_->LogSymbol(identifier_pos, literal_chars, literal_length); 1127 log_->LogSymbol(identifier_pos, literal_chars, literal_length);
1128 1128
1129 return kUnknownExpression; 1129 return kUnknownExpression;
1130 } 1130 }
1131 1131
1132 1132
1133 Expression PreParser::GetStringSymbol() { 1133 PreParser::Expression PreParser::GetStringSymbol() {
1134 const char* literal_chars = scanner_->literal_string(); 1134 const char* literal_chars = scanner_->literal_string();
1135 int literal_length = scanner_->literal_length(); 1135 int literal_length = scanner_->literal_length();
1136 1136
1137 int literal_position = scanner_->location().beg_pos; 1137 int literal_position = scanner_->location().beg_pos;
1138 log_->LogSymbol(literal_position, literal_chars, literal_length); 1138 log_->LogSymbol(literal_position, literal_chars, literal_length);
1139 1139
1140 return kUnknownExpression; 1140 return kUnknownExpression;
1141 } 1141 }
1142 1142
1143 1143
1144 Identifier PreParser::ParseIdentifier(bool* ok) { 1144 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1145 Expect(i::Token::IDENTIFIER, ok); 1145 Expect(i::Token::IDENTIFIER, ok);
1146 if (!*ok) return kUnknownIdentifier; 1146 if (!*ok) return kUnknownIdentifier;
1147 return GetIdentifierSymbol(); 1147 return GetIdentifierSymbol();
1148 } 1148 }
1149 1149
1150 1150
1151 Identifier PreParser::ParseIdentifierName(bool* ok) { 1151 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1152 i::Token::Value next = Next(); 1152 i::Token::Value next = Next();
1153 if (i::Token::IsKeyword(next)) { 1153 if (i::Token::IsKeyword(next)) {
1154 int pos = scanner_->location().beg_pos; 1154 int pos = scanner_->location().beg_pos;
1155 const char* keyword = i::Token::String(next); 1155 const char* keyword = i::Token::String(next);
1156 log_->LogSymbol(pos, keyword, i::StrLength(keyword)); 1156 log_->LogSymbol(pos, keyword, i::StrLength(keyword));
1157 return kUnknownExpression; 1157 return kUnknownExpression;
1158 } 1158 }
1159 if (next == i::Token::IDENTIFIER) { 1159 if (next == i::Token::IDENTIFIER) {
1160 return GetIdentifierSymbol(); 1160 return GetIdentifierSymbol();
1161 } 1161 }
1162 *ok = false; 1162 *ok = false;
1163 return kUnknownIdentifier; 1163 return kUnknownIdentifier;
1164 } 1164 }
1165 1165
1166 1166
1167 // This function reads an identifier and determines whether or not it 1167 // This function reads an identifier and determines whether or not it
1168 // is 'get' or 'set'. The reason for not using ParseIdentifier and 1168 // is 'get' or 'set'. The reason for not using ParseIdentifier and
1169 // checking on the output is that this involves heap allocation which 1169 // checking on the output is that this involves heap allocation which
1170 // we can't do during preparsing. 1170 // we can't do during preparsing.
1171 Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, 1171 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get,
1172 bool* is_set, 1172 bool* is_set,
1173 bool* ok) { 1173 bool* ok) {
1174 Expect(i::Token::IDENTIFIER, CHECK_OK); 1174 Expect(i::Token::IDENTIFIER, CHECK_OK);
1175 if (scanner_->literal_length() == 3) { 1175 if (scanner_->literal_length() == 3) {
1176 const char* token = scanner_->literal_string(); 1176 const char* token = scanner_->literal_string();
1177 *is_get = strncmp(token, "get", 3) == 0; 1177 *is_get = strncmp(token, "get", 3) == 0;
1178 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 1178 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1179 } 1179 }
1180 return GetIdentifierSymbol(); 1180 return GetIdentifierSymbol();
1181 } 1181 }
1182 1182
1183 #undef CHECK_OK 1183 #undef CHECK_OK
1184 } } // v8::preparser 1184 } } // v8::preparser
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698