statement.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. namespace Carbon {
  7. auto Statement::GetExpressionStatement() const -> const ExpressionStatement& {
  8. return std::get<ExpressionStatement>(value);
  9. }
  10. auto Statement::GetAssign() const -> const Assign& {
  11. return std::get<Assign>(value);
  12. }
  13. auto Statement::GetVariableDefinition() const -> const VariableDefinition& {
  14. return std::get<VariableDefinition>(value);
  15. }
  16. auto Statement::GetIf() const -> const If& { return std::get<If>(value); }
  17. auto Statement::GetReturn() const -> const Return& {
  18. return std::get<Return>(value);
  19. }
  20. auto Statement::GetSequence() const -> const Sequence& {
  21. return std::get<Sequence>(value);
  22. }
  23. auto Statement::GetBlock() const -> const Block& {
  24. return std::get<Block>(value);
  25. }
  26. auto Statement::GetWhile() const -> const While& {
  27. return std::get<While>(value);
  28. }
  29. auto Statement::GetBreak() const -> const Break& {
  30. return std::get<Break>(value);
  31. }
  32. auto Statement::GetContinue() const -> const Continue& {
  33. return std::get<Continue>(value);
  34. }
  35. auto Statement::GetMatch() const -> const Match& {
  36. return std::get<Match>(value);
  37. }
  38. auto Statement::GetContinuation() const -> const Continuation& {
  39. return std::get<Continuation>(value);
  40. }
  41. auto Statement::GetRun() const -> const Run& { return std::get<Run>(value); }
  42. auto Statement::GetAwait() const -> const Await& {
  43. return std::get<Await>(value);
  44. }
  45. auto Statement::MakeExpressionStatement(int line_num, const Expression* exp)
  46. -> const Statement* {
  47. auto* s = new Statement();
  48. s->line_num = line_num;
  49. s->value = ExpressionStatement({.exp = exp});
  50. return s;
  51. }
  52. auto Statement::MakeAssign(int line_num, const Expression* lhs,
  53. const Expression* rhs) -> const Statement* {
  54. auto* s = new Statement();
  55. s->line_num = line_num;
  56. s->value = Assign({.lhs = lhs, .rhs = rhs});
  57. return s;
  58. }
  59. auto Statement::MakeVariableDefinition(int line_num, const Expression* pat,
  60. const Expression* init)
  61. -> const Statement* {
  62. auto* s = new Statement();
  63. s->line_num = line_num;
  64. s->value = VariableDefinition({.pat = pat, .init = init});
  65. return s;
  66. }
  67. auto Statement::MakeIf(int line_num, const Expression* cond,
  68. const Statement* then_stmt, const Statement* else_stmt)
  69. -> const Statement* {
  70. auto* s = new Statement();
  71. s->line_num = line_num;
  72. s->value = If({.cond = cond, .then_stmt = then_stmt, .else_stmt = else_stmt});
  73. return s;
  74. }
  75. auto Statement::MakeWhile(int line_num, const Expression* cond,
  76. const Statement* body) -> const Statement* {
  77. auto* s = new Statement();
  78. s->line_num = line_num;
  79. s->value = While({.cond = cond, .body = body});
  80. return s;
  81. }
  82. auto Statement::MakeBreak(int line_num) -> const Statement* {
  83. auto* s = new Statement();
  84. s->line_num = line_num;
  85. s->value = Break();
  86. return s;
  87. }
  88. auto Statement::MakeContinue(int line_num) -> const Statement* {
  89. auto* s = new Statement();
  90. s->line_num = line_num;
  91. s->value = Continue();
  92. return s;
  93. }
  94. auto Statement::MakeReturn(int line_num, const Expression* e)
  95. -> const Statement* {
  96. auto* s = new Statement();
  97. s->line_num = line_num;
  98. s->value = Return({.exp = e});
  99. return s;
  100. }
  101. auto Statement::MakeSequence(int line_num, const Statement* s1,
  102. const Statement* s2) -> const Statement* {
  103. auto* s = new Statement();
  104. s->line_num = line_num;
  105. s->value = Sequence({.stmt = s1, .next = s2});
  106. return s;
  107. }
  108. auto Statement::MakeBlock(int line_num, const Statement* stmt)
  109. -> const Statement* {
  110. auto* s = new Statement();
  111. s->line_num = line_num;
  112. s->value = Block({.stmt = stmt});
  113. return s;
  114. }
  115. auto Statement::MakeMatch(
  116. int line_num, const Expression* exp,
  117. std::list<std::pair<const Expression*, const Statement*>>* clauses)
  118. -> const Statement* {
  119. auto* s = new Statement();
  120. s->line_num = line_num;
  121. s->value = Match({.exp = exp, .clauses = clauses});
  122. return s;
  123. }
  124. // Returns an AST node for a continuation statement give its line number and
  125. // parts.
  126. auto Statement::MakeContinuation(int line_num,
  127. std::string continuation_variable,
  128. const Statement* body) -> const Statement* {
  129. auto* s = new Statement();
  130. s->line_num = line_num;
  131. s->value =
  132. Continuation({.continuation_variable = std::move(continuation_variable),
  133. .body = body});
  134. return s;
  135. }
  136. // Returns an AST node for a run statement give its line number and argument.
  137. auto Statement::MakeRun(int line_num, const Expression* argument)
  138. -> const Statement* {
  139. auto* s = new Statement();
  140. s->line_num = line_num;
  141. s->value = Run({.argument = argument});
  142. return s;
  143. }
  144. // Returns an AST node for an await statement give its line number.
  145. auto Statement::MakeAwait(int line_num) -> const Statement* {
  146. auto* s = new Statement();
  147. s->line_num = line_num;
  148. s->value = Await();
  149. return s;
  150. }
  151. void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
  152. if (depth == 0) {
  153. out << " ... ";
  154. return;
  155. }
  156. switch (tag()) {
  157. case StatementKind::Match:
  158. out << "match (" << *GetMatch().exp << ") {";
  159. if (depth < 0 || depth > 1) {
  160. out << "\n";
  161. for (auto& clause : *GetMatch().clauses) {
  162. out << "case " << *clause.first << " =>\n";
  163. clause.second->PrintDepth(depth - 1, out);
  164. out << "\n";
  165. }
  166. } else {
  167. out << "...";
  168. }
  169. out << "}";
  170. break;
  171. case StatementKind::While:
  172. out << "while (" << *GetWhile().cond << ")\n";
  173. GetWhile().body->PrintDepth(depth - 1, out);
  174. break;
  175. case StatementKind::Break:
  176. out << "break;";
  177. break;
  178. case StatementKind::Continue:
  179. out << "continue;";
  180. break;
  181. case StatementKind::VariableDefinition:
  182. out << "var " << *GetVariableDefinition().pat << " = "
  183. << *GetVariableDefinition().init << ";";
  184. break;
  185. case StatementKind::ExpressionStatement:
  186. out << *GetExpressionStatement().exp << ";";
  187. break;
  188. case StatementKind::Assign:
  189. out << *GetAssign().lhs << " = " << *GetAssign().rhs << ";";
  190. break;
  191. case StatementKind::If:
  192. out << "if (" << *GetIf().cond << ")\n";
  193. GetIf().then_stmt->PrintDepth(depth - 1, out);
  194. if (GetIf().else_stmt) {
  195. out << "\nelse\n";
  196. GetIf().else_stmt->PrintDepth(depth - 1, out);
  197. }
  198. break;
  199. case StatementKind::Return:
  200. out << "return " << *GetReturn().exp << ";";
  201. break;
  202. case StatementKind::Sequence:
  203. GetSequence().stmt->PrintDepth(depth, out);
  204. if (depth < 0 || depth > 1) {
  205. out << "\n";
  206. } else {
  207. out << " ";
  208. }
  209. if (GetSequence().next) {
  210. GetSequence().next->PrintDepth(depth - 1, out);
  211. }
  212. break;
  213. case StatementKind::Block:
  214. out << "{";
  215. if (depth < 0 || depth > 1) {
  216. out << "\n";
  217. }
  218. if (GetBlock().stmt) {
  219. GetBlock().stmt->PrintDepth(depth, out);
  220. if (depth < 0 || depth > 1) {
  221. out << "\n";
  222. }
  223. }
  224. out << "}";
  225. if (depth < 0 || depth > 1) {
  226. out << "\n";
  227. }
  228. break;
  229. case StatementKind::Continuation:
  230. out << "continuation " << GetContinuation().continuation_variable << " ";
  231. if (depth < 0 || depth > 1) {
  232. out << "\n";
  233. }
  234. GetContinuation().body->PrintDepth(depth - 1, out);
  235. if (depth < 0 || depth > 1) {
  236. out << "\n";
  237. }
  238. break;
  239. case StatementKind::Run:
  240. out << "run " << *GetRun().argument << ";";
  241. break;
  242. case StatementKind::Await:
  243. out << "await;";
  244. break;
  245. }
  246. }
  247. } // namespace Carbon