statement.cpp 7.1 KB

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