statement.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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() << " " << AssignOperatorToString(assign.op()) << " "
  70. << assign.rhs() << ";";
  71. break;
  72. }
  73. case StatementKind::IncrementDecrement: {
  74. const auto& inc_dec = cast<IncrementDecrement>(*this);
  75. out << (inc_dec.is_increment() ? "++" : "--") << inc_dec.argument();
  76. break;
  77. }
  78. case StatementKind::If: {
  79. const auto& if_stmt = cast<If>(*this);
  80. out << "if (" << if_stmt.condition() << ")\n";
  81. if_stmt.then_block().PrintDepth(depth - 1, out);
  82. if (if_stmt.else_block()) {
  83. out << "\nelse\n";
  84. (*if_stmt.else_block())->PrintDepth(depth - 1, out);
  85. }
  86. break;
  87. }
  88. case StatementKind::ReturnVar: {
  89. out << "return var;";
  90. break;
  91. }
  92. case StatementKind::ReturnExpression: {
  93. const auto& ret = cast<ReturnExpression>(*this);
  94. if (ret.is_omitted_expression()) {
  95. out << "return;";
  96. } else {
  97. out << "return " << ret.expression() << ";";
  98. }
  99. break;
  100. }
  101. case StatementKind::Block: {
  102. const auto& block = cast<Block>(*this);
  103. out << "{";
  104. if (depth < 0 || depth > 1) {
  105. out << "\n";
  106. }
  107. for (const auto* statement : block.statements()) {
  108. statement->PrintDepth(depth, out);
  109. if (depth < 0 || depth > 1) {
  110. out << "\n";
  111. }
  112. }
  113. out << "}";
  114. if (depth < 0 || depth > 1) {
  115. out << "\n";
  116. }
  117. break;
  118. }
  119. case StatementKind::Continuation: {
  120. const auto& cont = cast<Continuation>(*this);
  121. out << "continuation " << cont.name() << " ";
  122. if (depth < 0 || depth > 1) {
  123. out << "\n";
  124. }
  125. cont.body().PrintDepth(depth - 1, out);
  126. if (depth < 0 || depth > 1) {
  127. out << "\n";
  128. }
  129. break;
  130. }
  131. case StatementKind::Run:
  132. out << "run " << cast<Run>(*this).argument() << ";";
  133. break;
  134. case StatementKind::Await:
  135. out << "await;";
  136. break;
  137. }
  138. }
  139. auto AssignOperatorToString(AssignOperator op) -> std::string_view {
  140. switch (op) {
  141. case AssignOperator::Plain:
  142. return "=";
  143. case AssignOperator::Add:
  144. return "+=";
  145. case AssignOperator::Div:
  146. return "/=";
  147. case AssignOperator::Mul:
  148. return "*=";
  149. case AssignOperator::Mod:
  150. return "%=";
  151. case AssignOperator::Sub:
  152. return "-=";
  153. case AssignOperator::And:
  154. return "&=";
  155. case AssignOperator::Or:
  156. return "|=";
  157. case AssignOperator::Xor:
  158. return "^=";
  159. case AssignOperator::ShiftLeft:
  160. return "<<=";
  161. case AssignOperator::ShiftRight:
  162. return ">>=";
  163. }
  164. }
  165. } // namespace Carbon