Serenity Operating System
at hosted 845 lines 24 kB view raw
1/* 2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> 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#pragma once 28 29#include <AK/FlyString.h> 30#include <AK/HashMap.h> 31#include <AK/NonnullRefPtrVector.h> 32#include <AK/RefPtr.h> 33#include <AK/String.h> 34#include <AK/Vector.h> 35#include <LibJS/Forward.h> 36#include <LibJS/Runtime/PropertyName.h> 37#include <LibJS/Runtime/Value.h> 38 39namespace JS { 40 41template<class T, class... Args> 42static inline NonnullRefPtr<T> 43create_ast_node(Args&&... args) 44{ 45 return adopt(*new T(forward<Args>(args)...)); 46} 47 48class ASTNode : public RefCounted<ASTNode> { 49public: 50 virtual ~ASTNode() {} 51 virtual const char* class_name() const = 0; 52 virtual Value execute(Interpreter&) const = 0; 53 virtual void dump(int indent) const; 54 virtual bool is_identifier() const { return false; } 55 virtual bool is_member_expression() const { return false; } 56 virtual bool is_scope_node() const { return false; } 57 virtual bool is_variable_declaration() const { return false; } 58 virtual bool is_new_expression() const { return false; } 59 60protected: 61 ASTNode() {} 62 63private: 64}; 65 66class Statement : public ASTNode { 67}; 68 69class ErrorStatement final : public Statement { 70public: 71 Value execute(Interpreter&) const override { return js_undefined(); } 72 const char* class_name() const override { return "ErrorStatement"; } 73}; 74 75class ExpressionStatement final : public Statement { 76public: 77 ExpressionStatement(NonnullRefPtr<Expression> expression) 78 : m_expression(move(expression)) 79 { 80 } 81 82 Value execute(Interpreter&) const override; 83 const char* class_name() const override { return "ExpressionStatement"; } 84 virtual void dump(int indent) const override; 85 86private: 87 NonnullRefPtr<Expression> m_expression; 88}; 89 90class ScopeNode : public Statement { 91public: 92 template<typename T, typename... Args> 93 T& append(Args&&... args) 94 { 95 auto child = create_ast_node<T>(forward<Args>(args)...); 96 m_children.append(move(child)); 97 return static_cast<T&>(m_children.last()); 98 } 99 void append(NonnullRefPtr<Statement> child) 100 { 101 m_children.append(move(child)); 102 } 103 104 const NonnullRefPtrVector<Statement>& children() const { return m_children; } 105 virtual Value execute(Interpreter&) const override; 106 virtual void dump(int indent) const override; 107 108protected: 109 ScopeNode() {} 110 111private: 112 virtual bool is_scope_node() const final { return true; } 113 NonnullRefPtrVector<Statement> m_children; 114}; 115 116class Program : public ScopeNode { 117public: 118 Program() {} 119 120private: 121 virtual const char* class_name() const override { return "Program"; } 122}; 123 124class BlockStatement : public ScopeNode { 125public: 126 BlockStatement() {} 127 128private: 129 virtual const char* class_name() const override { return "BlockStatement"; } 130}; 131 132class Expression : public ASTNode { 133}; 134 135class Declaration : public Statement { 136}; 137 138class FunctionNode { 139public: 140 const FlyString& name() const { return m_name; } 141 const Statement& body() const { return *m_body; } 142 const Vector<FlyString>& parameters() const { return m_parameters; }; 143 144protected: 145 FunctionNode(const FlyString& name, NonnullRefPtr<Statement> body, Vector<FlyString> parameters = {}) 146 : m_name(name) 147 , m_body(move(body)) 148 , m_parameters(move(parameters)) 149 { 150 } 151 152 void dump(int indent, const char* class_name) const; 153 154private: 155 FlyString m_name; 156 NonnullRefPtr<Statement> m_body; 157 const Vector<FlyString> m_parameters; 158}; 159 160class FunctionDeclaration final 161 : public Declaration 162 , public FunctionNode { 163public: 164 static bool must_have_name() { return true; } 165 166 FunctionDeclaration(String name, NonnullRefPtr<Statement> body, Vector<FlyString> parameters = {}) 167 : FunctionNode(move(name), move(body), move(parameters)) 168 { 169 } 170 171 virtual Value execute(Interpreter&) const override; 172 virtual void dump(int indent) const override; 173 174private: 175 virtual const char* class_name() const override { return "FunctionDeclaration"; } 176}; 177 178class FunctionExpression final : public Expression 179 , public FunctionNode { 180public: 181 static bool must_have_name() { return false; } 182 183 FunctionExpression(const FlyString& name, NonnullRefPtr<Statement> body, Vector<FlyString> parameters = {}) 184 : FunctionNode(name, move(body), move(parameters)) 185 { 186 } 187 188 virtual Value execute(Interpreter&) const override; 189 virtual void dump(int indent) const override; 190 191private: 192 virtual const char* class_name() const override { return "FunctionExpression"; } 193}; 194 195class ErrorExpression final : public Expression { 196public: 197 Value execute(Interpreter&) const override { return js_undefined(); } 198 const char* class_name() const override { return "ErrorExpression"; } 199}; 200 201class ReturnStatement : public Statement { 202public: 203 explicit ReturnStatement(RefPtr<Expression> argument) 204 : m_argument(move(argument)) 205 { 206 } 207 208 const Expression* argument() const { return m_argument; } 209 210 virtual Value execute(Interpreter&) const override; 211 virtual void dump(int indent) const override; 212 213private: 214 virtual const char* class_name() const override { return "ReturnStatement"; } 215 216 RefPtr<Expression> m_argument; 217}; 218 219class IfStatement : public Statement { 220public: 221 IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate) 222 : m_predicate(move(predicate)) 223 , m_consequent(move(consequent)) 224 , m_alternate(move(alternate)) 225 { 226 } 227 228 const Expression& predicate() const { return *m_predicate; } 229 const Statement& consequent() const { return *m_consequent; } 230 const Statement* alternate() const { return m_alternate; } 231 232 virtual Value execute(Interpreter&) const override; 233 virtual void dump(int indent) const override; 234 235private: 236 virtual const char* class_name() const override { return "IfStatement"; } 237 238 NonnullRefPtr<Expression> m_predicate; 239 NonnullRefPtr<Statement> m_consequent; 240 RefPtr<Statement> m_alternate; 241}; 242 243class WhileStatement : public Statement { 244public: 245 WhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body) 246 : m_test(move(test)) 247 , m_body(move(body)) 248 { 249 } 250 251 const Expression& test() const { return *m_test; } 252 const Statement& body() const { return *m_body; } 253 254 virtual Value execute(Interpreter&) const override; 255 virtual void dump(int indent) const override; 256 257private: 258 virtual const char* class_name() const override { return "WhileStatement"; } 259 260 NonnullRefPtr<Expression> m_test; 261 NonnullRefPtr<Statement> m_body; 262}; 263 264class DoWhileStatement : public Statement { 265public: 266 DoWhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body) 267 : m_test(move(test)) 268 , m_body(move(body)) 269 { 270 } 271 272 const Expression& test() const { return *m_test; } 273 const Statement& body() const { return *m_body; } 274 275 virtual Value execute(Interpreter&) const override; 276 virtual void dump(int indent) const override; 277 278private: 279 virtual const char* class_name() const override { return "DoWhileStatement"; } 280 281 NonnullRefPtr<Expression> m_test; 282 NonnullRefPtr<Statement> m_body; 283}; 284 285class ForStatement : public Statement { 286public: 287 ForStatement(RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body) 288 : m_init(move(init)) 289 , m_test(move(test)) 290 , m_update(move(update)) 291 , m_body(move(body)) 292 { 293 } 294 295 const ASTNode* init() const { return m_init; } 296 const Expression* test() const { return m_test; } 297 const Expression* update() const { return m_update; } 298 const Statement& body() const { return *m_body; } 299 300 virtual Value execute(Interpreter&) const override; 301 virtual void dump(int indent) const override; 302 303private: 304 virtual const char* class_name() const override { return "ForStatement"; } 305 306 RefPtr<ASTNode> m_init; 307 RefPtr<Expression> m_test; 308 RefPtr<Expression> m_update; 309 NonnullRefPtr<Statement> m_body; 310}; 311 312enum class BinaryOp { 313 Addition, 314 Subtraction, 315 Multiplication, 316 Division, 317 Modulo, 318 Exponentiation, 319 TypedEquals, 320 TypedInequals, 321 AbstractEquals, 322 AbstractInequals, 323 GreaterThan, 324 GreaterThanEquals, 325 LessThan, 326 LessThanEquals, 327 BitwiseAnd, 328 BitwiseOr, 329 BitwiseXor, 330 LeftShift, 331 RightShift, 332 InstanceOf, 333}; 334 335class BinaryExpression : public Expression { 336public: 337 BinaryExpression(BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs) 338 : m_op(op) 339 , m_lhs(move(lhs)) 340 , m_rhs(move(rhs)) 341 { 342 } 343 344 virtual Value execute(Interpreter&) const override; 345 virtual void dump(int indent) const override; 346 347private: 348 virtual const char* class_name() const override { return "BinaryExpression"; } 349 350 BinaryOp m_op; 351 NonnullRefPtr<Expression> m_lhs; 352 NonnullRefPtr<Expression> m_rhs; 353}; 354 355enum class LogicalOp { 356 And, 357 Or, 358}; 359 360class LogicalExpression : public Expression { 361public: 362 LogicalExpression(LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs) 363 : m_op(op) 364 , m_lhs(move(lhs)) 365 , m_rhs(move(rhs)) 366 { 367 } 368 369 virtual Value execute(Interpreter&) const override; 370 virtual void dump(int indent) const override; 371 372private: 373 virtual const char* class_name() const override { return "LogicalExpression"; } 374 375 LogicalOp m_op; 376 NonnullRefPtr<Expression> m_lhs; 377 NonnullRefPtr<Expression> m_rhs; 378}; 379 380enum class UnaryOp { 381 BitwiseNot, 382 Not, 383 Plus, 384 Minus, 385 Typeof, 386}; 387 388class UnaryExpression : public Expression { 389public: 390 UnaryExpression(UnaryOp op, NonnullRefPtr<Expression> lhs) 391 : m_op(op) 392 , m_lhs(move(lhs)) 393 { 394 } 395 396 virtual Value execute(Interpreter&) const override; 397 virtual void dump(int indent) const override; 398 399private: 400 virtual const char* class_name() const override { return "UnaryExpression"; } 401 402 UnaryOp m_op; 403 NonnullRefPtr<Expression> m_lhs; 404}; 405 406class SequenceExpression final : public Expression { 407public: 408 SequenceExpression(NonnullRefPtrVector<Expression> expressions) 409 : m_expressions(move(expressions)) 410 { 411 } 412 413 virtual void dump(int indent) const override; 414 virtual Value execute(Interpreter&) const override; 415 416private: 417 virtual const char* class_name() const override { return "SequenceExpression"; } 418 419 NonnullRefPtrVector<Expression> m_expressions; 420}; 421 422class Literal : public Expression { 423protected: 424 explicit Literal() {} 425}; 426 427class BooleanLiteral final : public Literal { 428public: 429 explicit BooleanLiteral(bool value) 430 : m_value(value) 431 { 432 } 433 434 virtual Value execute(Interpreter&) const override; 435 virtual void dump(int indent) const override; 436 437private: 438 virtual const char* class_name() const override { return "BooleanLiteral"; } 439 440 bool m_value { false }; 441}; 442 443class NumericLiteral final : public Literal { 444public: 445 explicit NumericLiteral(double value) 446 : m_value(value) 447 { 448 } 449 450 virtual Value execute(Interpreter&) const override; 451 virtual void dump(int indent) const override; 452 453private: 454 virtual const char* class_name() const override { return "NumericLiteral"; } 455 456 double m_value { 0 }; 457}; 458 459class StringLiteral final : public Literal { 460public: 461 explicit StringLiteral(String value) 462 : m_value(move(value)) 463 { 464 } 465 466 virtual Value execute(Interpreter&) const override; 467 virtual void dump(int indent) const override; 468 469private: 470 virtual const char* class_name() const override { return "StringLiteral"; } 471 472 String m_value; 473}; 474 475class NullLiteral final : public Literal { 476public: 477 explicit NullLiteral() {} 478 479 virtual Value execute(Interpreter&) const override; 480 virtual void dump(int indent) const override; 481 482private: 483 virtual const char* class_name() const override { return "NullLiteral"; } 484}; 485 486class Identifier final : public Expression { 487public: 488 explicit Identifier(const FlyString& string) 489 : m_string(string) 490 { 491 } 492 493 const FlyString& string() const { return m_string; } 494 495 virtual Value execute(Interpreter&) const override; 496 virtual void dump(int indent) const override; 497 virtual bool is_identifier() const override { return true; } 498 499private: 500 virtual const char* class_name() const override { return "Identifier"; } 501 502 FlyString m_string; 503}; 504 505class CallExpression : public Expression { 506public: 507 CallExpression(NonnullRefPtr<Expression> callee, NonnullRefPtrVector<Expression> arguments = {}) 508 : m_callee(move(callee)) 509 , m_arguments(move(arguments)) 510 { 511 } 512 513 virtual Value execute(Interpreter&) const override; 514 virtual void dump(int indent) const override; 515 516private: 517 virtual const char* class_name() const override { return "CallExpression"; } 518 519 struct ThisAndCallee { 520 Value this_value; 521 Value callee; 522 }; 523 ThisAndCallee compute_this_and_callee(Interpreter&) const; 524 525 NonnullRefPtr<Expression> m_callee; 526 const NonnullRefPtrVector<Expression> m_arguments; 527}; 528 529class NewExpression final : public CallExpression { 530public: 531 NewExpression(NonnullRefPtr<Expression> callee, NonnullRefPtrVector<Expression> arguments = {}) 532 : CallExpression(move(callee), move(arguments)) 533 { 534 } 535 536private: 537 virtual const char* class_name() const override { return "NewExpression"; } 538 virtual bool is_new_expression() const override { return true; } 539}; 540 541enum class AssignmentOp { 542 Assignment, 543 AdditionAssignment, 544 SubtractionAssignment, 545 MultiplicationAssignment, 546 DivisionAssignment, 547}; 548 549class AssignmentExpression : public Expression { 550public: 551 AssignmentExpression(AssignmentOp op, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs) 552 : m_op(op) 553 , m_lhs(move(lhs)) 554 , m_rhs(move(rhs)) 555 { 556 } 557 558 virtual Value execute(Interpreter&) const override; 559 virtual void dump(int indent) const override; 560 561private: 562 virtual const char* class_name() const override { return "AssignmentExpression"; } 563 564 AssignmentOp m_op; 565 NonnullRefPtr<ASTNode> m_lhs; 566 NonnullRefPtr<Expression> m_rhs; 567}; 568 569enum class UpdateOp { 570 Increment, 571 Decrement, 572}; 573 574class UpdateExpression : public Expression { 575public: 576 UpdateExpression(UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false) 577 : m_op(op) 578 , m_argument(move(argument)) 579 , m_prefixed(prefixed) 580 { 581 } 582 583 virtual Value execute(Interpreter&) const override; 584 virtual void dump(int indent) const override; 585 586private: 587 virtual const char* class_name() const override { return "UpdateExpression"; } 588 589 UpdateOp m_op; 590 NonnullRefPtr<Expression> m_argument; 591 bool m_prefixed; 592}; 593 594enum class DeclarationKind { 595 Var, 596 Let, 597 Const, 598}; 599 600class VariableDeclarator final : public ASTNode { 601public: 602 VariableDeclarator(NonnullRefPtr<Identifier> id, RefPtr<Expression> init) 603 : m_id(move(id)) 604 , m_init(move(init)) 605 { 606 } 607 608 const Identifier& id() const { return m_id; } 609 const Expression* init() const { return m_init; } 610 611 virtual Value execute(Interpreter&) const override; 612 virtual void dump(int indent) const override; 613 614private: 615 virtual const char* class_name() const override { return "VariableDeclarator"; } 616 617 NonnullRefPtr<Identifier> m_id; 618 RefPtr<Expression> m_init; 619}; 620 621class VariableDeclaration : public Declaration { 622public: 623 VariableDeclaration(DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations) 624 : m_declaration_kind(declaration_kind) 625 , m_declarations(move(declarations)) 626 { 627 } 628 629 virtual bool is_variable_declaration() const override { return true; } 630 DeclarationKind declaration_kind() const { return m_declaration_kind; } 631 632 virtual Value execute(Interpreter&) const override; 633 virtual void dump(int indent) const override; 634 635private: 636 virtual const char* class_name() const override { return "VariableDeclaration"; } 637 638 DeclarationKind m_declaration_kind; 639 NonnullRefPtrVector<VariableDeclarator> m_declarations; 640}; 641 642class ObjectExpression : public Expression { 643public: 644 ObjectExpression(HashMap<FlyString, NonnullRefPtr<Expression>> properties = {}) 645 : m_properties(move(properties)) 646 { 647 } 648 649 virtual Value execute(Interpreter&) const override; 650 virtual void dump(int indent) const override; 651 652private: 653 virtual const char* class_name() const override { return "ObjectExpression"; } 654 655 HashMap<FlyString, NonnullRefPtr<Expression>> m_properties; 656}; 657 658class ArrayExpression : public Expression { 659public: 660 ArrayExpression(NonnullRefPtrVector<Expression> elements) 661 : m_elements(move(elements)) 662 { 663 } 664 665 const NonnullRefPtrVector<Expression>& elements() const { return m_elements; } 666 667 virtual Value execute(Interpreter&) const override; 668 virtual void dump(int indent) const override; 669 670private: 671 virtual const char* class_name() const override { return "ArrayExpression"; } 672 673 NonnullRefPtrVector<Expression> m_elements; 674}; 675 676class MemberExpression final : public Expression { 677public: 678 MemberExpression(NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false) 679 : m_object(move(object)) 680 , m_property(move(property)) 681 , m_computed(computed) 682 { 683 } 684 685 virtual Value execute(Interpreter&) const override; 686 virtual void dump(int indent) const override; 687 688 bool is_computed() const { return m_computed; } 689 const Expression& object() const { return *m_object; } 690 const Expression& property() const { return *m_property; } 691 692 PropertyName computed_property_name(Interpreter&) const; 693 694private: 695 virtual bool is_member_expression() const override { return true; } 696 virtual const char* class_name() const override { return "MemberExpression"; } 697 698 NonnullRefPtr<Expression> m_object; 699 NonnullRefPtr<Expression> m_property; 700 bool m_computed { false }; 701}; 702 703class ConditionalExpression final : public Expression { 704public: 705 ConditionalExpression(NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate) 706 : m_test(move(test)) 707 , m_consequent(move(consequent)) 708 , m_alternate(move(alternate)) 709 { 710 } 711 712 virtual void dump(int indent) const override; 713 virtual Value execute(Interpreter&) const override; 714 715private: 716 virtual const char* class_name() const override { return "ConditionalExpression"; } 717 718 NonnullRefPtr<Expression> m_test; 719 NonnullRefPtr<Expression> m_consequent; 720 NonnullRefPtr<Expression> m_alternate; 721}; 722 723class CatchClause final : public ASTNode { 724public: 725 CatchClause(const FlyString& parameter, NonnullRefPtr<BlockStatement> body) 726 : m_parameter(parameter) 727 , m_body(move(body)) 728 { 729 } 730 731 const FlyString& parameter() const { return m_parameter; } 732 const BlockStatement& body() const { return m_body; } 733 734 virtual void dump(int indent) const override; 735 virtual Value execute(Interpreter&) const override; 736 737private: 738 virtual const char* class_name() const override { return "CatchClause"; } 739 740 FlyString m_parameter; 741 NonnullRefPtr<BlockStatement> m_body; 742}; 743 744class TryStatement final : public Statement { 745public: 746 TryStatement(NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer) 747 : m_block(move(block)) 748 , m_handler(move(handler)) 749 , m_finalizer(move(finalizer)) 750 { 751 } 752 753 const BlockStatement& block() const { return m_block; } 754 const CatchClause* handler() const { return m_handler; } 755 const BlockStatement* finalizer() const { return m_finalizer; } 756 757 virtual void dump(int indent) const override; 758 virtual Value execute(Interpreter&) const override; 759 760private: 761 virtual const char* class_name() const override { return "TryStatement"; } 762 763 NonnullRefPtr<BlockStatement> m_block; 764 RefPtr<CatchClause> m_handler; 765 RefPtr<BlockStatement> m_finalizer; 766}; 767 768class ThrowStatement final : public Statement { 769public: 770 explicit ThrowStatement(NonnullRefPtr<Expression> argument) 771 : m_argument(move(argument)) 772 { 773 } 774 775 const Expression& argument() const { return m_argument; } 776 777 virtual void dump(int indent) const override; 778 virtual Value execute(Interpreter&) const override; 779 780private: 781 virtual const char* class_name() const override { return "ThrowStatement"; } 782 783 NonnullRefPtr<Expression> m_argument; 784}; 785 786class SwitchCase final : public ASTNode { 787public: 788 SwitchCase(RefPtr<Expression> test, NonnullRefPtrVector<Statement> consequent) 789 : m_test(move(test)) 790 , m_consequent(move(consequent)) 791 { 792 } 793 794 const Expression* test() const { return m_test; } 795 const NonnullRefPtrVector<Statement>& consequent() const { return m_consequent; } 796 797 virtual void dump(int indent) const override; 798 virtual Value execute(Interpreter&) const override; 799 800private: 801 virtual const char* class_name() const override { return "SwitchCase"; } 802 803 RefPtr<Expression> m_test; 804 NonnullRefPtrVector<Statement> m_consequent; 805}; 806 807class SwitchStatement final : public Statement { 808public: 809 SwitchStatement(NonnullRefPtr<Expression> discriminant, NonnullRefPtrVector<SwitchCase> cases) 810 : m_discriminant(move(discriminant)) 811 , m_cases(move(cases)) 812 { 813 } 814 815 virtual void dump(int indent) const override; 816 virtual Value execute(Interpreter&) const override; 817 818private: 819 virtual const char* class_name() const override { return "SwitchStatement"; } 820 821 NonnullRefPtr<Expression> m_discriminant; 822 NonnullRefPtrVector<SwitchCase> m_cases; 823}; 824 825class BreakStatement final : public Statement { 826public: 827 BreakStatement() {} 828 829 virtual Value execute(Interpreter&) const override; 830 831private: 832 virtual const char* class_name() const override { return "BreakStatement"; } 833}; 834 835class ContinueStatement final : public Statement { 836public: 837 ContinueStatement() {} 838 839 virtual Value execute(Interpreter&) const override; 840 841private: 842 virtual const char* class_name() const override { return "ContinueStatement"; } 843}; 844 845}