statement.cpp 8.6 KB

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