statement.cpp 8.3 KB

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