statement.cpp 8.7 KB

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