statement.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 "executable_semantics/ast/statement.h"
  5. #include "common/check.h"
  6. #include "executable_semantics/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. out << "var " << var.pattern() << " = " << var.init() << ";";
  48. break;
  49. }
  50. case StatementKind::ExpressionStatement:
  51. out << cast<ExpressionStatement>(*this).expression() << ";";
  52. break;
  53. case StatementKind::Assign: {
  54. const auto& assign = cast<Assign>(*this);
  55. out << assign.lhs() << " = " << assign.rhs() << ";";
  56. break;
  57. }
  58. case StatementKind::If: {
  59. const auto& if_stmt = cast<If>(*this);
  60. out << "if (" << if_stmt.condition() << ")\n";
  61. if_stmt.then_block().PrintDepth(depth - 1, out);
  62. if (if_stmt.else_block()) {
  63. out << "\nelse\n";
  64. (*if_stmt.else_block())->PrintDepth(depth - 1, out);
  65. }
  66. break;
  67. }
  68. case StatementKind::Return: {
  69. const auto& ret = cast<Return>(*this);
  70. if (ret.is_omitted_expression()) {
  71. out << "return;";
  72. } else {
  73. out << "return " << ret.expression() << ";";
  74. }
  75. break;
  76. }
  77. case StatementKind::Block: {
  78. const auto& block = cast<Block>(*this);
  79. out << "{";
  80. if (depth < 0 || depth > 1) {
  81. out << "\n";
  82. }
  83. for (const auto* statement : block.statements()) {
  84. statement->PrintDepth(depth, out);
  85. if (depth < 0 || depth > 1) {
  86. out << "\n";
  87. }
  88. }
  89. out << "}";
  90. if (depth < 0 || depth > 1) {
  91. out << "\n";
  92. }
  93. break;
  94. }
  95. case StatementKind::Continuation: {
  96. const auto& cont = cast<Continuation>(*this);
  97. out << "continuation " << cont.continuation_variable() << " ";
  98. if (depth < 0 || depth > 1) {
  99. out << "\n";
  100. }
  101. cont.body().PrintDepth(depth - 1, out);
  102. if (depth < 0 || depth > 1) {
  103. out << "\n";
  104. }
  105. break;
  106. }
  107. case StatementKind::Run:
  108. out << "run " << cast<Run>(*this).argument() << ";";
  109. break;
  110. case StatementKind::Await:
  111. out << "await;";
  112. break;
  113. }
  114. }
  115. } // namespace Carbon