statement.cpp 6.9 KB

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