ASTCodegen.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/AST.h>
  7. #include <LibJS/Bytecode/Generator.h>
  8. #include <LibJS/Bytecode/Instruction.h>
  9. #include <LibJS/Bytecode/Op.h>
  10. #include <LibJS/Bytecode/Register.h>
  11. namespace JS {
  12. Optional<Bytecode::Register> ASTNode::generate_bytecode(Bytecode::Generator&) const
  13. {
  14. dbgln("Missing generate_bytecode()");
  15. TODO();
  16. }
  17. Optional<Bytecode::Register> ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
  18. {
  19. for (auto& child : children()) {
  20. [[maybe_unused]] auto reg = child.generate_bytecode(generator);
  21. }
  22. return {};
  23. }
  24. Optional<Bytecode::Register> ExpressionStatement::generate_bytecode(Bytecode::Generator& generator) const
  25. {
  26. return m_expression->generate_bytecode(generator);
  27. }
  28. Optional<Bytecode::Register> BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const
  29. {
  30. auto lhs_reg = m_lhs->generate_bytecode(generator);
  31. auto rhs_reg = m_rhs->generate_bytecode(generator);
  32. VERIFY(lhs_reg.has_value());
  33. VERIFY(rhs_reg.has_value());
  34. auto dst_reg = generator.allocate_register();
  35. switch (m_op) {
  36. case BinaryOp::Addition:
  37. generator.emit<Bytecode::Op::Add>(dst_reg, *lhs_reg, *rhs_reg);
  38. return dst_reg;
  39. case BinaryOp::Subtraction:
  40. generator.emit<Bytecode::Op::Sub>(dst_reg, *lhs_reg, *rhs_reg);
  41. return dst_reg;
  42. case BinaryOp::LessThan:
  43. generator.emit<Bytecode::Op::LessThan>(dst_reg, *lhs_reg, *rhs_reg);
  44. return dst_reg;
  45. default:
  46. TODO();
  47. }
  48. }
  49. Optional<Bytecode::Register> NumericLiteral::generate_bytecode(Bytecode::Generator& generator) const
  50. {
  51. auto dst = generator.allocate_register();
  52. generator.emit<Bytecode::Op::Load>(dst, m_value);
  53. return dst;
  54. }
  55. Optional<Bytecode::Register> StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
  56. {
  57. auto dst = generator.allocate_register();
  58. generator.emit<Bytecode::Op::NewString>(dst, m_value);
  59. return dst;
  60. }
  61. Optional<Bytecode::Register> Identifier::generate_bytecode(Bytecode::Generator& generator) const
  62. {
  63. auto reg = generator.allocate_register();
  64. generator.emit<Bytecode::Op::GetVariable>(reg, m_string);
  65. return reg;
  66. }
  67. Optional<Bytecode::Register> AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
  68. {
  69. if (is<Identifier>(*m_lhs)) {
  70. auto& identifier = static_cast<Identifier const&>(*m_lhs);
  71. auto rhs_reg = m_rhs->generate_bytecode(generator);
  72. VERIFY(rhs_reg.has_value());
  73. generator.emit<Bytecode::Op::SetVariable>(identifier.string(), *rhs_reg);
  74. return rhs_reg;
  75. }
  76. TODO();
  77. }
  78. Optional<Bytecode::Register> WhileStatement::generate_bytecode(Bytecode::Generator& generator) const
  79. {
  80. auto test_label = generator.make_label();
  81. auto test_result_reg = m_test->generate_bytecode(generator);
  82. VERIFY(test_result_reg.has_value());
  83. auto& test_jump = generator.emit<Bytecode::Op::JumpIfFalse>(*test_result_reg);
  84. auto body_result_reg = m_body->generate_bytecode(generator);
  85. generator.emit<Bytecode::Op::Jump>(test_label);
  86. test_jump.set_target(generator.make_label());
  87. return body_result_reg;
  88. }
  89. }