statement.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "explorer/ast/statement.h"
  5. #include "common/check.h"
  6. #include "explorer/common/arena.h"
  7. #include "llvm/Support/Casting.h"
  8. namespace Carbon {
  9. using llvm::cast;
  10. Statement::~Statement() = default;
  11. void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
  12. if (depth == 0) {
  13. out << " ... ";
  14. return;
  15. }
  16. switch (kind()) {
  17. case StatementKind::Match: {
  18. const auto& match = cast<Match>(*this);
  19. out << "match (" << match.expression() << ") {";
  20. if (depth < 0 || depth > 1) {
  21. out << "\n";
  22. for (auto& clause : match.clauses()) {
  23. out << "case " << clause.pattern() << " =>\n";
  24. clause.statement().PrintDepth(depth - 1, out);
  25. out << "\n";
  26. }
  27. } else {
  28. out << "...";
  29. }
  30. out << "}";
  31. break;
  32. }
  33. case StatementKind::While: {
  34. const auto& while_stmt = cast<While>(*this);
  35. out << "while (" << while_stmt.condition() << ")\n";
  36. while_stmt.body().PrintDepth(depth - 1, out);
  37. break;
  38. }
  39. case StatementKind::Break:
  40. out << "break;";
  41. break;
  42. case StatementKind::Continue:
  43. out << "continue;";
  44. break;
  45. case StatementKind::VariableDefinition: {
  46. const auto& var = cast<VariableDefinition>(*this);
  47. if (var.is_returned()) {
  48. out << "returned ";
  49. }
  50. out << "var " << var.pattern();
  51. if (var.has_init()) {
  52. out << " = " << var.init();
  53. }
  54. out << ";";
  55. break;
  56. }
  57. case StatementKind::ExpressionStatement:
  58. out << cast<ExpressionStatement>(*this).expression() << ";";
  59. break;
  60. case StatementKind::Assign: {
  61. const auto& assign = cast<Assign>(*this);
  62. out << assign.lhs() << " = " << assign.rhs() << ";";
  63. break;
  64. }
  65. case StatementKind::If: {
  66. const auto& if_stmt = cast<If>(*this);
  67. out << "if (" << if_stmt.condition() << ")\n";
  68. if_stmt.then_block().PrintDepth(depth - 1, out);
  69. if (if_stmt.else_block()) {
  70. out << "\nelse\n";
  71. (*if_stmt.else_block())->PrintDepth(depth - 1, out);
  72. }
  73. break;
  74. }
  75. case StatementKind::ReturnVar: {
  76. out << "return var;";
  77. break;
  78. }
  79. case StatementKind::ReturnExpression: {
  80. const auto& ret = cast<ReturnExpression>(*this);
  81. if (ret.is_omitted_expression()) {
  82. out << "return;";
  83. } else {
  84. out << "return " << ret.expression() << ";";
  85. }
  86. break;
  87. }
  88. case StatementKind::Block: {
  89. const auto& block = cast<Block>(*this);
  90. out << "{";
  91. if (depth < 0 || depth > 1) {
  92. out << "\n";
  93. }
  94. for (const auto* statement : block.statements()) {
  95. statement->PrintDepth(depth, out);
  96. if (depth < 0 || depth > 1) {
  97. out << "\n";
  98. }
  99. }
  100. out << "}";
  101. if (depth < 0 || depth > 1) {
  102. out << "\n";
  103. }
  104. break;
  105. }
  106. case StatementKind::Continuation: {
  107. const auto& cont = cast<Continuation>(*this);
  108. out << "continuation " << cont.name() << " ";
  109. if (depth < 0 || depth > 1) {
  110. out << "\n";
  111. }
  112. cont.body().PrintDepth(depth - 1, out);
  113. if (depth < 0 || depth > 1) {
  114. out << "\n";
  115. }
  116. break;
  117. }
  118. case StatementKind::Run:
  119. out << "run " << cast<Run>(*this).argument() << ";";
  120. break;
  121. case StatementKind::Await:
  122. out << "await;";
  123. break;
  124. }
  125. }
  126. } // namespace Carbon