statement.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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 (const 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::For: {
  40. const auto& for_stmt = cast<For>(*this);
  41. out << "for (" << for_stmt.variable_declaration() << " in "
  42. << for_stmt.loop_target() << ")\n";
  43. for_stmt.body().PrintDepth(depth - 1, out);
  44. break;
  45. }
  46. case StatementKind::Break:
  47. out << "break;";
  48. break;
  49. case StatementKind::Continue:
  50. out << "continue;";
  51. break;
  52. case StatementKind::VariableDefinition: {
  53. const auto& var = cast<VariableDefinition>(*this);
  54. if (var.is_returned()) {
  55. out << "returned ";
  56. }
  57. out << "var " << var.pattern();
  58. if (var.has_init()) {
  59. out << " = " << var.init();
  60. }
  61. out << ";";
  62. break;
  63. }
  64. case StatementKind::ExpressionStatement:
  65. out << cast<ExpressionStatement>(*this).expression() << ";";
  66. break;
  67. case StatementKind::Assign: {
  68. const auto& assign = cast<Assign>(*this);
  69. out << assign.lhs() << " = " << assign.rhs() << ";";
  70. break;
  71. }
  72. case StatementKind::If: {
  73. const auto& if_stmt = cast<If>(*this);
  74. out << "if (" << if_stmt.condition() << ")\n";
  75. if_stmt.then_block().PrintDepth(depth - 1, out);
  76. if (if_stmt.else_block()) {
  77. out << "\nelse\n";
  78. (*if_stmt.else_block())->PrintDepth(depth - 1, out);
  79. }
  80. break;
  81. }
  82. case StatementKind::ReturnVar: {
  83. out << "return var;";
  84. break;
  85. }
  86. case StatementKind::ReturnExpression: {
  87. const auto& ret = cast<ReturnExpression>(*this);
  88. if (ret.is_omitted_expression()) {
  89. out << "return;";
  90. } else {
  91. out << "return " << ret.expression() << ";";
  92. }
  93. break;
  94. }
  95. case StatementKind::Block: {
  96. const auto& block = cast<Block>(*this);
  97. out << "{";
  98. if (depth < 0 || depth > 1) {
  99. out << "\n";
  100. }
  101. for (const auto* statement : block.statements()) {
  102. statement->PrintDepth(depth, out);
  103. if (depth < 0 || depth > 1) {
  104. out << "\n";
  105. }
  106. }
  107. out << "}";
  108. if (depth < 0 || depth > 1) {
  109. out << "\n";
  110. }
  111. break;
  112. }
  113. case StatementKind::Continuation: {
  114. const auto& cont = cast<Continuation>(*this);
  115. out << "continuation " << cont.name() << " ";
  116. if (depth < 0 || depth > 1) {
  117. out << "\n";
  118. }
  119. cont.body().PrintDepth(depth - 1, out);
  120. if (depth < 0 || depth > 1) {
  121. out << "\n";
  122. }
  123. break;
  124. }
  125. case StatementKind::Run:
  126. out << "run " << cast<Run>(*this).argument() << ";";
  127. break;
  128. case StatementKind::Await:
  129. out << "await;";
  130. break;
  131. }
  132. }
  133. } // namespace Carbon