Serenity Operating System
at hosted 1030 lines 36 kB view raw
1/* 2 * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@gmx.de> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "Parser.h" 28#include <AK/HashMap.h> 29#include <AK/StdLibExtras.h> 30#include <stdio.h> 31 32namespace JS { 33 34static HashMap<TokenType, int> g_operator_precedence; 35Parser::ParserState::ParserState(Lexer lexer) 36 : m_lexer(move(lexer)) 37 , m_current_token(m_lexer.next()) 38{ 39} 40 41Parser::Parser(Lexer lexer) 42 : m_parser_state(move(lexer)) 43{ 44 if (g_operator_precedence.is_empty()) { 45 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence 46 g_operator_precedence.set(TokenType::Period, 20); 47 g_operator_precedence.set(TokenType::BracketOpen, 20); 48 g_operator_precedence.set(TokenType::ParenOpen, 20); 49 g_operator_precedence.set(TokenType::QuestionMarkPeriod, 20); 50 51 g_operator_precedence.set(TokenType::New, 19); 52 53 g_operator_precedence.set(TokenType::PlusPlus, 18); 54 g_operator_precedence.set(TokenType::MinusMinus, 18); 55 56 g_operator_precedence.set(TokenType::ExclamationMark, 17); 57 g_operator_precedence.set(TokenType::Tilde, 17); 58 g_operator_precedence.set(TokenType::Typeof, 17); 59 g_operator_precedence.set(TokenType::Void, 17); 60 g_operator_precedence.set(TokenType::Delete, 17); 61 g_operator_precedence.set(TokenType::Await, 17); 62 63 g_operator_precedence.set(TokenType::DoubleAsterisk, 16); 64 65 g_operator_precedence.set(TokenType::Asterisk, 15); 66 g_operator_precedence.set(TokenType::Slash, 15); 67 g_operator_precedence.set(TokenType::Percent, 15); 68 69 g_operator_precedence.set(TokenType::Plus, 14); 70 g_operator_precedence.set(TokenType::Minus, 14); 71 72 g_operator_precedence.set(TokenType::ShiftLeft, 13); 73 g_operator_precedence.set(TokenType::ShiftRight, 13); 74 g_operator_precedence.set(TokenType::UnsignedShiftRight, 13); 75 76 g_operator_precedence.set(TokenType::LessThan, 12); 77 g_operator_precedence.set(TokenType::LessThanEquals, 12); 78 g_operator_precedence.set(TokenType::GreaterThan, 12); 79 g_operator_precedence.set(TokenType::GreaterThanEquals, 12); 80 g_operator_precedence.set(TokenType::In, 12); 81 g_operator_precedence.set(TokenType::Instanceof, 12); 82 83 g_operator_precedence.set(TokenType::EqualsEquals, 11); 84 g_operator_precedence.set(TokenType::ExclamationMarkEquals, 11); 85 g_operator_precedence.set(TokenType::EqualsEqualsEquals, 11); 86 g_operator_precedence.set(TokenType::ExclamationMarkEqualsEquals, 11); 87 88 g_operator_precedence.set(TokenType::Ampersand, 10); 89 90 g_operator_precedence.set(TokenType::Caret, 9); 91 92 g_operator_precedence.set(TokenType::Pipe, 8); 93 94 g_operator_precedence.set(TokenType::DoubleQuestionMark, 7); 95 96 g_operator_precedence.set(TokenType::DoubleAmpersand, 6); 97 98 g_operator_precedence.set(TokenType::DoublePipe, 5); 99 100 g_operator_precedence.set(TokenType::QuestionMark, 4); 101 102 g_operator_precedence.set(TokenType::Equals, 3); 103 g_operator_precedence.set(TokenType::PlusEquals, 3); 104 g_operator_precedence.set(TokenType::MinusEquals, 3); 105 g_operator_precedence.set(TokenType::AsteriskAsteriskEquals, 3); 106 g_operator_precedence.set(TokenType::AsteriskEquals, 3); 107 g_operator_precedence.set(TokenType::SlashEquals, 3); 108 g_operator_precedence.set(TokenType::PercentEquals, 3); 109 g_operator_precedence.set(TokenType::ShiftLeftEquals, 3); 110 g_operator_precedence.set(TokenType::ShiftRightEquals, 3); 111 g_operator_precedence.set(TokenType::UnsignedShiftRightEquals, 3); 112 g_operator_precedence.set(TokenType::PipeEquals, 3); 113 114 g_operator_precedence.set(TokenType::Yield, 2); 115 116 g_operator_precedence.set(TokenType::Comma, 1); 117 } 118} 119 120int Parser::operator_precedence(TokenType type) const 121{ 122 auto it = g_operator_precedence.find(type); 123 if (it == g_operator_precedence.end()) { 124 fprintf(stderr, "No precedence for operator %s\n", Token::name(type)); 125 ASSERT_NOT_REACHED(); 126 return -1; 127 } 128 129 return it->value; 130} 131 132Associativity Parser::operator_associativity(TokenType type) const 133{ 134 switch (type) { 135 case TokenType::Period: 136 case TokenType::BracketOpen: 137 case TokenType::ParenOpen: 138 case TokenType::QuestionMarkPeriod: 139 case TokenType::Asterisk: 140 case TokenType::Slash: 141 case TokenType::Percent: 142 case TokenType::Plus: 143 case TokenType::Minus: 144 case TokenType::ShiftLeft: 145 case TokenType::ShiftRight: 146 case TokenType::UnsignedShiftRight: 147 case TokenType::LessThan: 148 case TokenType::LessThanEquals: 149 case TokenType::GreaterThan: 150 case TokenType::GreaterThanEquals: 151 case TokenType::In: 152 case TokenType::Instanceof: 153 case TokenType::EqualsEquals: 154 case TokenType::ExclamationMarkEquals: 155 case TokenType::EqualsEqualsEquals: 156 case TokenType::ExclamationMarkEqualsEquals: 157 case TokenType::Typeof: 158 case TokenType::Ampersand: 159 case TokenType::Caret: 160 case TokenType::Pipe: 161 case TokenType::DoubleQuestionMark: 162 case TokenType::DoubleAmpersand: 163 case TokenType::DoublePipe: 164 case TokenType::Comma: 165 return Associativity::Left; 166 default: 167 return Associativity::Right; 168 } 169} 170 171NonnullRefPtr<Program> Parser::parse_program() 172{ 173 auto program = adopt(*new Program); 174 while (!done()) { 175 if (match(TokenType::Semicolon)) { 176 consume(); 177 } else if (match_statement()) { 178 program->append(parse_statement()); 179 } else { 180 expected("statement"); 181 consume(); 182 } 183 } 184 return program; 185} 186 187NonnullRefPtr<Statement> Parser::parse_statement() 188{ 189 auto statement = [this]() -> NonnullRefPtr<Statement> { 190 switch (m_parser_state.m_current_token.type()) { 191 case TokenType::Function: 192 return parse_function_node<FunctionDeclaration>(); 193 case TokenType::CurlyOpen: 194 return parse_block_statement(); 195 case TokenType::Return: 196 return parse_return_statement(); 197 case TokenType::Var: 198 case TokenType::Let: 199 case TokenType::Const: 200 return parse_variable_declaration(); 201 case TokenType::For: 202 return parse_for_statement(); 203 case TokenType::If: 204 return parse_if_statement(); 205 case TokenType::Throw: 206 return parse_throw_statement(); 207 case TokenType::Try: 208 return parse_try_statement(); 209 case TokenType::Break: 210 return parse_break_statement(); 211 case TokenType::Continue: 212 return parse_continue_statement(); 213 case TokenType::Switch: 214 return parse_switch_statement(); 215 case TokenType::Do: 216 return parse_do_while_statement(); 217 default: 218 if (match_expression()) 219 return adopt(*new ExpressionStatement(parse_expression(0))); 220 m_parser_state.m_has_errors = true; 221 expected("statement (missing switch case)"); 222 consume(); 223 return create_ast_node<ErrorStatement>(); 224 } }(); 225 if (match(TokenType::Semicolon)) 226 consume(); 227 return statement; 228} 229 230RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expect_parens) 231{ 232 save_state(); 233 234 Vector<FlyString> parameters; 235 bool parse_failed = false; 236 while (true) { 237 if (match(TokenType::Comma)) { 238 consume(TokenType::Comma); 239 } else if (match(TokenType::Identifier)) { 240 auto token = consume(TokenType::Identifier); 241 parameters.append(token.value()); 242 } else if (match(TokenType::ParenClose)) { 243 if (expect_parens) { 244 consume(TokenType::ParenClose); 245 if (match(TokenType::Arrow)) { 246 consume(TokenType::Arrow); 247 } else { 248 parse_failed = true; 249 } 250 break; 251 } 252 parse_failed = true; 253 break; 254 } else if (match(TokenType::Arrow)) { 255 if (!expect_parens) { 256 consume(TokenType::Arrow); 257 break; 258 } 259 parse_failed = true; 260 break; 261 } else { 262 parse_failed = true; 263 break; 264 } 265 } 266 267 if (parse_failed) { 268 load_state(); 269 return nullptr; 270 } 271 272 auto function_body_result = [this]() -> RefPtr<BlockStatement> { 273 if (match(TokenType::CurlyOpen)) { 274 // Parse a function body with statements 275 return parse_block_statement(); 276 } 277 if (match_expression()) { 278 // Parse a function body which returns a single expression 279 280 // FIXME: We synthesize a block with a return statement 281 // for arrow function bodies which are a single expression. 282 // Esprima generates a single "ArrowFunctionExpression" 283 // with a "body" property. 284 auto return_expression = parse_expression(0); 285 auto return_block = create_ast_node<BlockStatement>(); 286 return_block->append<ReturnStatement>(move(return_expression)); 287 return return_block; 288 } 289 // Invalid arrow function body 290 return nullptr; 291 }(); 292 293 if (!function_body_result.is_null()) { 294 auto body = function_body_result.release_nonnull(); 295 return create_ast_node<FunctionExpression>("", move(body), move(parameters)); 296 } 297 298 load_state(); 299 return nullptr; 300} 301 302NonnullRefPtr<Expression> Parser::parse_primary_expression() 303{ 304 if (match_unary_prefixed_expression()) 305 return parse_unary_prefixed_expression(); 306 307 switch (m_parser_state.m_current_token.type()) { 308 case TokenType::ParenOpen: { 309 consume(TokenType::ParenOpen); 310 if (match(TokenType::ParenClose) || match(TokenType::Identifier)) { 311 auto arrow_function_result = try_parse_arrow_function_expression(true); 312 if (!arrow_function_result.is_null()) { 313 return arrow_function_result.release_nonnull(); 314 } 315 } 316 auto expression = parse_expression(0); 317 consume(TokenType::ParenClose); 318 return expression; 319 } 320 case TokenType::Identifier: { 321 auto arrow_function_result = try_parse_arrow_function_expression(false); 322 if (!arrow_function_result.is_null()) { 323 return arrow_function_result.release_nonnull(); 324 } 325 return create_ast_node<Identifier>(consume().value()); 326 } 327 case TokenType::NumericLiteral: 328 return create_ast_node<NumericLiteral>(consume().double_value()); 329 case TokenType::BoolLiteral: 330 return create_ast_node<BooleanLiteral>(consume().bool_value()); 331 case TokenType::StringLiteral: 332 return create_ast_node<StringLiteral>(consume().string_value()); 333 case TokenType::NullLiteral: 334 consume(); 335 return create_ast_node<NullLiteral>(); 336 case TokenType::CurlyOpen: 337 return parse_object_expression(); 338 case TokenType::Function: 339 return parse_function_node<FunctionExpression>(); 340 case TokenType::BracketOpen: 341 return parse_array_expression(); 342 case TokenType::New: 343 return parse_new_expression(); 344 default: 345 m_parser_state.m_has_errors = true; 346 expected("primary expression (missing switch case)"); 347 consume(); 348 return create_ast_node<ErrorExpression>(); 349 } 350} 351 352NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression() 353{ 354 auto precedence = operator_precedence(m_parser_state.m_current_token.type()); 355 auto associativity = operator_associativity(m_parser_state.m_current_token.type()); 356 switch (m_parser_state.m_current_token.type()) { 357 case TokenType::PlusPlus: 358 consume(); 359 return create_ast_node<UpdateExpression>(UpdateOp::Increment, parse_expression(precedence, associativity), true); 360 case TokenType::MinusMinus: 361 consume(); 362 return create_ast_node<UpdateExpression>(UpdateOp::Decrement, parse_expression(precedence, associativity), true); 363 case TokenType::ExclamationMark: 364 consume(); 365 return create_ast_node<UnaryExpression>(UnaryOp::Not, parse_expression(precedence, associativity)); 366 case TokenType::Tilde: 367 consume(); 368 return create_ast_node<UnaryExpression>(UnaryOp::BitwiseNot, parse_expression(precedence, associativity)); 369 case TokenType::Plus: 370 consume(); 371 return create_ast_node<UnaryExpression>(UnaryOp::Plus, parse_expression(precedence, associativity)); 372 case TokenType::Minus: 373 consume(); 374 return create_ast_node<UnaryExpression>(UnaryOp::Minus, parse_expression(precedence, associativity)); 375 case TokenType::Typeof: 376 consume(); 377 return create_ast_node<UnaryExpression>(UnaryOp::Typeof, parse_expression(precedence, associativity)); 378 default: 379 m_parser_state.m_has_errors = true; 380 expected("primary expression (missing switch case)"); 381 consume(); 382 return create_ast_node<ErrorExpression>(); 383 } 384} 385 386NonnullRefPtr<ObjectExpression> Parser::parse_object_expression() 387{ 388 HashMap<FlyString, NonnullRefPtr<Expression>> properties; 389 consume(TokenType::CurlyOpen); 390 391 while (!done() && !match(TokenType::CurlyClose)) { 392 FlyString property_name; 393 if (match(TokenType::Identifier)) { 394 property_name = consume(TokenType::Identifier).value(); 395 } else if (match(TokenType::StringLiteral)) { 396 property_name = consume(TokenType::StringLiteral).string_value(); 397 } else if (match(TokenType::NumericLiteral)) { 398 property_name = consume(TokenType::NumericLiteral).value(); 399 } else { 400 m_parser_state.m_has_errors = true; 401 auto& current_token = m_parser_state.m_current_token; 402 fprintf(stderr, "Error: Unexpected token %s as member in object initialization. Expected a numeric literal, string literal or identifier (line: %zu, column: %zu))\n", 403 current_token.name(), 404 current_token.line_number(), 405 current_token.line_column()); 406 consume(); 407 continue; 408 } 409 410 411 if (match(TokenType::Colon)) { 412 consume(TokenType::Colon); 413 properties.set(property_name, parse_expression(0)); 414 } else { 415 properties.set(property_name, create_ast_node<Identifier>(property_name)); 416 } 417 418 if (!match(TokenType::Comma)) 419 break; 420 421 consume(TokenType::Comma); 422 } 423 424 consume(TokenType::CurlyClose); 425 return create_ast_node<ObjectExpression>(properties); 426} 427 428NonnullRefPtr<ArrayExpression> Parser::parse_array_expression() 429{ 430 consume(TokenType::BracketOpen); 431 432 NonnullRefPtrVector<Expression> elements; 433 while (match_expression()) { 434 elements.append(parse_expression(0)); 435 if (!match(TokenType::Comma)) 436 break; 437 consume(TokenType::Comma); 438 } 439 440 consume(TokenType::BracketClose); 441 return create_ast_node<ArrayExpression>(move(elements)); 442} 443 444NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associativity associativity) 445{ 446 auto expression = parse_primary_expression(); 447 while (match_secondary_expression()) { 448 int new_precedence = operator_precedence(m_parser_state.m_current_token.type()); 449 if (new_precedence < min_precedence) 450 break; 451 if (new_precedence == min_precedence && associativity == Associativity::Left) 452 break; 453 454 Associativity new_associativity = operator_associativity(m_parser_state.m_current_token.type()); 455 expression = parse_secondary_expression(move(expression), new_precedence, new_associativity); 456 } 457 return expression; 458} 459 460NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expression> lhs, int min_precedence, Associativity associativity) 461{ 462 switch (m_parser_state.m_current_token.type()) { 463 case TokenType::Plus: 464 consume(); 465 return create_ast_node<BinaryExpression>(BinaryOp::Addition, move(lhs), parse_expression(min_precedence, associativity)); 466 case TokenType::PlusEquals: 467 consume(); 468 return create_ast_node<AssignmentExpression>(AssignmentOp::AdditionAssignment, move(lhs), parse_expression(min_precedence, associativity)); 469 case TokenType::Minus: 470 consume(); 471 return create_ast_node<BinaryExpression>(BinaryOp::Subtraction, move(lhs), parse_expression(min_precedence, associativity)); 472 case TokenType::MinusEquals: 473 consume(); 474 return create_ast_node<AssignmentExpression>(AssignmentOp::SubtractionAssignment, move(lhs), parse_expression(min_precedence, associativity)); 475 case TokenType::Asterisk: 476 consume(); 477 return create_ast_node<BinaryExpression>(BinaryOp::Multiplication, move(lhs), parse_expression(min_precedence, associativity)); 478 case TokenType::AsteriskEquals: 479 consume(); 480 return create_ast_node<AssignmentExpression>(AssignmentOp::MultiplicationAssignment, move(lhs), parse_expression(min_precedence, associativity)); 481 case TokenType::Slash: 482 consume(); 483 return create_ast_node<BinaryExpression>(BinaryOp::Division, move(lhs), parse_expression(min_precedence, associativity)); 484 case TokenType::SlashEquals: 485 consume(); 486 return create_ast_node<AssignmentExpression>(AssignmentOp::DivisionAssignment, move(lhs), parse_expression(min_precedence, associativity)); 487 case TokenType::Percent: 488 consume(); 489 return create_ast_node<BinaryExpression>(BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity)); 490 case TokenType::DoubleAsterisk: 491 consume(); 492 return create_ast_node<BinaryExpression>(BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity)); 493 case TokenType::GreaterThan: 494 consume(); 495 return create_ast_node<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity)); 496 case TokenType::GreaterThanEquals: 497 consume(); 498 return create_ast_node<BinaryExpression>(BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity)); 499 case TokenType::LessThan: 500 consume(); 501 return create_ast_node<BinaryExpression>(BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity)); 502 case TokenType::LessThanEquals: 503 consume(); 504 return create_ast_node<BinaryExpression>(BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity)); 505 case TokenType::EqualsEqualsEquals: 506 consume(); 507 return create_ast_node<BinaryExpression>(BinaryOp::TypedEquals, move(lhs), parse_expression(min_precedence, associativity)); 508 case TokenType::ExclamationMarkEqualsEquals: 509 consume(); 510 return create_ast_node<BinaryExpression>(BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity)); 511 case TokenType::EqualsEquals: 512 consume(); 513 return create_ast_node<BinaryExpression>(BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity)); 514 case TokenType::ExclamationMarkEquals: 515 consume(); 516 return create_ast_node<BinaryExpression>(BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity)); 517 case TokenType::Instanceof: 518 consume(); 519 return create_ast_node<BinaryExpression>(BinaryOp::InstanceOf, move(lhs), parse_expression(min_precedence, associativity)); 520 case TokenType::Ampersand: 521 consume(); 522 return create_ast_node<BinaryExpression>(BinaryOp::BitwiseAnd, move(lhs), parse_expression(min_precedence, associativity)); 523 case TokenType::Pipe: 524 consume(); 525 return create_ast_node<BinaryExpression>(BinaryOp::BitwiseOr, move(lhs), parse_expression(min_precedence, associativity)); 526 case TokenType::Caret: 527 consume(); 528 return create_ast_node<BinaryExpression>(BinaryOp::BitwiseXor, move(lhs), parse_expression(min_precedence, associativity)); 529 case TokenType::ParenOpen: 530 return parse_call_expression(move(lhs)); 531 case TokenType::Equals: 532 consume(); 533 return create_ast_node<AssignmentExpression>(AssignmentOp::Assignment, move(lhs), parse_expression(min_precedence, associativity)); 534 case TokenType::Period: 535 consume(); 536 return create_ast_node<MemberExpression>(move(lhs), parse_expression(min_precedence, associativity)); 537 case TokenType::BracketOpen: { 538 consume(TokenType::BracketOpen); 539 auto expression = create_ast_node<MemberExpression>(move(lhs), parse_expression(0), true); 540 consume(TokenType::BracketClose); 541 return expression; 542 } 543 case TokenType::PlusPlus: 544 consume(); 545 return create_ast_node<UpdateExpression>(UpdateOp::Increment, move(lhs)); 546 case TokenType::MinusMinus: 547 consume(); 548 return create_ast_node<UpdateExpression>(UpdateOp::Decrement, move(lhs)); 549 case TokenType::DoubleAmpersand: 550 consume(); 551 return create_ast_node<LogicalExpression>(LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity)); 552 case TokenType::DoublePipe: 553 consume(); 554 return create_ast_node<LogicalExpression>(LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity)); 555 case TokenType::QuestionMark: 556 return parse_conditional_expression(move(lhs)); 557 default: 558 m_parser_state.m_has_errors = true; 559 expected("secondary expression (missing switch case)"); 560 consume(); 561 return create_ast_node<ErrorExpression>(); 562 } 563} 564 565NonnullRefPtr<CallExpression> Parser::parse_call_expression(NonnullRefPtr<Expression> lhs) 566{ 567 consume(TokenType::ParenOpen); 568 569 NonnullRefPtrVector<Expression> arguments; 570 571 while (match_expression()) { 572 arguments.append(parse_expression(0)); 573 if (!match(TokenType::Comma)) 574 break; 575 consume(); 576 } 577 578 consume(TokenType::ParenClose); 579 580 return create_ast_node<CallExpression>(move(lhs), move(arguments)); 581} 582 583NonnullRefPtr<NewExpression> Parser::parse_new_expression() 584{ 585 consume(TokenType::New); 586 587 // FIXME: Support full expressions as the callee as well. 588 auto callee = create_ast_node<Identifier>(consume(TokenType::Identifier).value()); 589 590 NonnullRefPtrVector<Expression> arguments; 591 592 if (match(TokenType::ParenOpen)) { 593 consume(TokenType::ParenOpen); 594 while (match_expression()) { 595 arguments.append(parse_expression(0)); 596 if (!match(TokenType::Comma)) 597 break; 598 consume(); 599 } 600 consume(TokenType::ParenClose); 601 } 602 603 return create_ast_node<NewExpression>(move(callee), move(arguments)); 604} 605 606NonnullRefPtr<ReturnStatement> Parser::parse_return_statement() 607{ 608 consume(TokenType::Return); 609 if (match_expression()) { 610 return create_ast_node<ReturnStatement>(parse_expression(0)); 611 } 612 return create_ast_node<ReturnStatement>(nullptr); 613} 614 615NonnullRefPtr<BlockStatement> Parser::parse_block_statement() 616{ 617 auto block = create_ast_node<BlockStatement>(); 618 consume(TokenType::CurlyOpen); 619 while (!done() && !match(TokenType::CurlyClose)) { 620 if (match(TokenType::Semicolon)) { 621 consume(); 622 } else if (match_statement()) { 623 block->append(parse_statement()); 624 } else { 625 expected("statement"); 626 consume(); 627 } 628 } 629 consume(TokenType::CurlyClose); 630 return block; 631} 632 633template<typename FunctionNodeType> 634NonnullRefPtr<FunctionNodeType> Parser::parse_function_node() 635{ 636 consume(TokenType::Function); 637 String name; 638 if (FunctionNodeType::must_have_name()) { 639 name = consume(TokenType::Identifier).value(); 640 } else { 641 if (match(TokenType::Identifier)) 642 name = consume(TokenType::Identifier).value(); 643 } 644 consume(TokenType::ParenOpen); 645 Vector<FlyString> parameters; 646 while (match(TokenType::Identifier)) { 647 auto parameter = consume(TokenType::Identifier).value(); 648 parameters.append(parameter); 649 if (match(TokenType::ParenClose)) { 650 break; 651 } 652 consume(TokenType::Comma); 653 } 654 consume(TokenType::ParenClose); 655 auto body = parse_block_statement(); 656 return create_ast_node<FunctionNodeType>(name, move(body), move(parameters)); 657} 658 659NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration() 660{ 661 DeclarationKind declaration_kind; 662 663 switch (m_parser_state.m_current_token.type()) { 664 case TokenType::Var: 665 declaration_kind = DeclarationKind::Var; 666 consume(TokenType::Var); 667 break; 668 case TokenType::Let: 669 declaration_kind = DeclarationKind::Let; 670 consume(TokenType::Let); 671 break; 672 case TokenType::Const: 673 declaration_kind = DeclarationKind::Const; 674 consume(TokenType::Const); 675 break; 676 default: 677 ASSERT_NOT_REACHED(); 678 } 679 680 NonnullRefPtrVector<VariableDeclarator> declarations; 681 for (;;) { 682 auto id = consume(TokenType::Identifier).value(); 683 RefPtr<Expression> init; 684 if (match(TokenType::Equals)) { 685 consume(); 686 init = parse_expression(0); 687 } 688 declarations.append(create_ast_node<VariableDeclarator>(create_ast_node<Identifier>(move(id)), move(init))); 689 if (match(TokenType::Comma)) { 690 consume(); 691 continue; 692 } 693 break; 694 } 695 return create_ast_node<VariableDeclaration>(declaration_kind, move(declarations)); 696} 697 698NonnullRefPtr<ThrowStatement> Parser::parse_throw_statement() 699{ 700 consume(TokenType::Throw); 701 return create_ast_node<ThrowStatement>(parse_expression(0)); 702} 703 704NonnullRefPtr<BreakStatement> Parser::parse_break_statement() 705{ 706 consume(TokenType::Break); 707 // FIXME: Handle labels. 708 return create_ast_node<BreakStatement>(); 709} 710 711NonnullRefPtr<ContinueStatement> Parser::parse_continue_statement() 712{ 713 consume(TokenType::Continue); 714 // FIXME: Handle labels. 715 return create_ast_node<ContinueStatement>(); 716} 717 718NonnullRefPtr<ConditionalExpression> Parser::parse_conditional_expression(NonnullRefPtr<Expression> test) 719{ 720 consume(TokenType::QuestionMark); 721 auto consequent = parse_expression(0); 722 consume(TokenType::Colon); 723 auto alternate = parse_expression(0); 724 return create_ast_node<ConditionalExpression>(move(test), move(consequent), move(alternate)); 725} 726 727NonnullRefPtr<TryStatement> Parser::parse_try_statement() 728{ 729 consume(TokenType::Try); 730 731 auto block = parse_block_statement(); 732 733 RefPtr<CatchClause> handler; 734 if (match(TokenType::Catch)) 735 handler = parse_catch_clause(); 736 737 RefPtr<BlockStatement> finalizer; 738 if (match(TokenType::Finally)) { 739 consume(); 740 finalizer = parse_block_statement(); 741 } 742 743 return create_ast_node<TryStatement>(move(block), move(handler), move(finalizer)); 744} 745 746NonnullRefPtr<DoWhileStatement> Parser::parse_do_while_statement() 747{ 748 consume(TokenType::Do); 749 750 auto body = parse_statement(); 751 752 consume(TokenType::While); 753 consume(TokenType::ParenOpen); 754 755 auto test = parse_expression(0); 756 757 consume(TokenType::ParenClose); 758 759 return create_ast_node<DoWhileStatement>(move(test), move(body)); 760} 761 762NonnullRefPtr<SwitchStatement> Parser::parse_switch_statement() 763{ 764 consume(TokenType::Switch); 765 766 consume(TokenType::ParenOpen); 767 auto determinant = parse_expression(0); 768 consume(TokenType::ParenClose); 769 770 consume(TokenType::CurlyOpen); 771 772 NonnullRefPtrVector<SwitchCase> cases; 773 774 while (match(TokenType::Case) || match(TokenType::Default)) 775 cases.append(parse_switch_case()); 776 777 consume(TokenType::CurlyClose); 778 779 return create_ast_node<SwitchStatement>(move(determinant), move(cases)); 780} 781 782NonnullRefPtr<SwitchCase> Parser::parse_switch_case() 783{ 784 RefPtr<Expression> test; 785 786 if (consume().type() == TokenType::Case) { 787 test = parse_expression(0); 788 } 789 790 consume(TokenType::Colon); 791 792 NonnullRefPtrVector<Statement> consequent; 793 while (match_statement()) 794 consequent.append(parse_statement()); 795 796 return create_ast_node<SwitchCase>(move(test), move(consequent)); 797} 798 799NonnullRefPtr<CatchClause> Parser::parse_catch_clause() 800{ 801 consume(TokenType::Catch); 802 803 String parameter; 804 if (match(TokenType::ParenOpen)) { 805 consume(); 806 parameter = consume(TokenType::Identifier).value(); 807 consume(TokenType::ParenClose); 808 } 809 810 auto body = parse_block_statement(); 811 return create_ast_node<CatchClause>(parameter, move(body)); 812} 813 814NonnullRefPtr<IfStatement> Parser::parse_if_statement() 815{ 816 consume(TokenType::If); 817 consume(TokenType::ParenOpen); 818 auto predicate = parse_expression(0); 819 consume(TokenType::ParenClose); 820 auto consequent = parse_statement(); 821 RefPtr<Statement> alternate; 822 if (match(TokenType::Else)) { 823 consume(TokenType::Else); 824 alternate = parse_statement(); 825 } 826 return create_ast_node<IfStatement>(move(predicate), move(consequent), move(alternate)); 827} 828 829NonnullRefPtr<ForStatement> Parser::parse_for_statement() 830{ 831 consume(TokenType::For); 832 833 consume(TokenType::ParenOpen); 834 835 RefPtr<ASTNode> init; 836 switch (m_parser_state.m_current_token.type()) { 837 case TokenType::Semicolon: 838 break; 839 default: 840 if (match_expression()) 841 init = parse_expression(0); 842 else if (match_variable_declaration()) 843 init = parse_variable_declaration(); 844 else 845 ASSERT_NOT_REACHED(); 846 break; 847 } 848 849 consume(TokenType::Semicolon); 850 851 RefPtr<Expression> test; 852 switch (m_parser_state.m_current_token.type()) { 853 case TokenType::Semicolon: 854 break; 855 default: 856 test = parse_expression(0); 857 break; 858 } 859 860 consume(TokenType::Semicolon); 861 862 RefPtr<Expression> update; 863 switch (m_parser_state.m_current_token.type()) { 864 case TokenType::ParenClose: 865 break; 866 default: 867 update = parse_expression(0); 868 break; 869 } 870 871 consume(TokenType::ParenClose); 872 873 auto body = parse_statement(); 874 875 return create_ast_node<ForStatement>(move(init), move(test), move(update), move(body)); 876} 877 878bool Parser::match(TokenType type) const 879{ 880 return m_parser_state.m_current_token.type() == type; 881} 882 883bool Parser::match_variable_declaration() const 884{ 885 switch (m_parser_state.m_current_token.type()) { 886 case TokenType::Var: 887 case TokenType::Let: 888 case TokenType::Const: 889 return true; 890 default: 891 return false; 892 } 893} 894 895bool Parser::match_expression() const 896{ 897 auto type = m_parser_state.m_current_token.type(); 898 return type == TokenType::BoolLiteral 899 || type == TokenType::NumericLiteral 900 || type == TokenType::StringLiteral 901 || type == TokenType::NullLiteral 902 || type == TokenType::Identifier 903 || type == TokenType::New 904 || type == TokenType::CurlyOpen 905 || type == TokenType::BracketOpen 906 || type == TokenType::ParenOpen 907 || type == TokenType::Function 908 || match_unary_prefixed_expression(); 909} 910 911bool Parser::match_unary_prefixed_expression() const 912{ 913 auto type = m_parser_state.m_current_token.type(); 914 return type == TokenType::PlusPlus 915 || type == TokenType::MinusMinus 916 || type == TokenType::ExclamationMark 917 || type == TokenType::Tilde 918 || type == TokenType::Plus 919 || type == TokenType::Minus 920 || type == TokenType::Typeof; 921} 922 923bool Parser::match_secondary_expression() const 924{ 925 auto type = m_parser_state.m_current_token.type(); 926 return type == TokenType::Plus 927 || type == TokenType::PlusEquals 928 || type == TokenType::Minus 929 || type == TokenType::MinusEquals 930 || type == TokenType::Asterisk 931 || type == TokenType::AsteriskEquals 932 || type == TokenType::Slash 933 || type == TokenType::SlashEquals 934 || type == TokenType::Percent 935 || type == TokenType::DoubleAsterisk 936 || type == TokenType::Equals 937 || type == TokenType::EqualsEqualsEquals 938 || type == TokenType::ExclamationMarkEqualsEquals 939 || type == TokenType::EqualsEquals 940 || type == TokenType::ExclamationMarkEquals 941 || type == TokenType::GreaterThan 942 || type == TokenType::GreaterThanEquals 943 || type == TokenType::LessThan 944 || type == TokenType::LessThanEquals 945 || type == TokenType::ParenOpen 946 || type == TokenType::Period 947 || type == TokenType::BracketOpen 948 || type == TokenType::PlusPlus 949 || type == TokenType::MinusMinus 950 || type == TokenType::Instanceof 951 || type == TokenType::QuestionMark 952 || type == TokenType::Ampersand 953 || type == TokenType::Pipe 954 || type == TokenType::Caret 955 || type == TokenType::DoubleAmpersand 956 || type == TokenType::DoublePipe; 957} 958 959bool Parser::match_statement() const 960{ 961 auto type = m_parser_state.m_current_token.type(); 962 return match_expression() 963 || type == TokenType::Function 964 || type == TokenType::Return 965 || type == TokenType::Let 966 || type == TokenType::Class 967 || type == TokenType::Delete 968 || type == TokenType::Do 969 || type == TokenType::If 970 || type == TokenType::Throw 971 || type == TokenType::Try 972 || type == TokenType::While 973 || type == TokenType::For 974 || type == TokenType::Const 975 || type == TokenType::CurlyOpen 976 || type == TokenType::Switch 977 || type == TokenType::Break 978 || type == TokenType::Continue 979 || type == TokenType::Var; 980} 981 982bool Parser::done() const 983{ 984 return match(TokenType::Eof); 985} 986 987Token Parser::consume() 988{ 989 auto old_token = m_parser_state.m_current_token; 990 m_parser_state.m_current_token = m_parser_state.m_lexer.next(); 991 return old_token; 992} 993 994Token Parser::consume(TokenType type) 995{ 996 if (m_parser_state.m_current_token.type() != type) { 997 m_parser_state.m_has_errors = true; 998 auto& current_token = m_parser_state.m_current_token; 999 fprintf(stderr, "Error: Unexpected token %s. Expected %s (line: %zu, column: %zu))\n", 1000 current_token.name(), 1001 Token::name(type), 1002 current_token.line_number(), 1003 current_token.line_column()); 1004 } 1005 return consume(); 1006} 1007 1008void Parser::expected(const char* what) 1009{ 1010 m_parser_state.m_has_errors = true; 1011 auto& current_token = m_parser_state.m_current_token; 1012 fprintf(stderr, "Error: Unexpected token %s. Expected %s (line: %zu, column: %zu)\n", 1013 current_token.name(), 1014 what, 1015 current_token.line_number(), 1016 current_token.line_column()); 1017} 1018 1019void Parser::save_state() 1020{ 1021 m_saved_state = m_parser_state; 1022} 1023 1024void Parser::load_state() 1025{ 1026 ASSERT(m_saved_state.has_value()); 1027 m_parser_state = m_saved_state.value(); 1028 m_saved_state.clear(); 1029} 1030}