expression.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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/expression.h"
  5. #include <cassert>
  6. #include <iostream>
  7. namespace Carbon {
  8. auto Expression::GetVariable() const -> const Variable& {
  9. return std::get<Variable>(value);
  10. }
  11. auto Expression::GetFieldAccess() const -> const FieldAccess& {
  12. return std::get<FieldAccess>(value);
  13. }
  14. auto Expression::GetIndex() const -> const Index& {
  15. return std::get<Index>(value);
  16. }
  17. auto Expression::GetPatternVariable() const -> const PatternVariable& {
  18. return std::get<PatternVariable>(value);
  19. }
  20. auto Expression::GetInteger() const -> int {
  21. return std::get<IntLiteral>(value).value;
  22. }
  23. auto Expression::GetBoolean() const -> bool {
  24. return std::get<BoolLiteral>(value).value;
  25. }
  26. auto Expression::GetTuple() const -> const Tuple& {
  27. return std::get<Tuple>(value);
  28. }
  29. auto Expression::GetPrimitiveOperator() const -> const PrimitiveOperator& {
  30. return std::get<PrimitiveOperator>(value);
  31. }
  32. auto Expression::GetCall() const -> const Call& {
  33. return std::get<Call>(value);
  34. }
  35. auto Expression::GetFunctionType() const -> const FunctionType& {
  36. return std::get<FunctionType>(value);
  37. }
  38. auto Expression::MakeTypeType(int line_num) -> const Expression* {
  39. auto* t = new Expression();
  40. t->line_num = line_num;
  41. t->value = TypeT();
  42. return t;
  43. }
  44. auto Expression::MakeIntType(int line_num) -> const Expression* {
  45. auto* t = new Expression();
  46. t->line_num = line_num;
  47. t->value = IntT();
  48. return t;
  49. }
  50. auto Expression::MakeBoolType(int line_num) -> const Expression* {
  51. auto* t = new Expression();
  52. t->line_num = line_num;
  53. t->value = BoolT();
  54. return t;
  55. }
  56. auto Expression::MakeAutoType(int line_num) -> const Expression* {
  57. auto* t = new Expression();
  58. t->line_num = line_num;
  59. t->value = AutoT();
  60. return t;
  61. }
  62. // Returns a Continuation type AST node at the given source location.
  63. auto Expression::MakeContinuationType(int line_num) -> const Expression* {
  64. auto* type = new Expression();
  65. type->line_num = line_num;
  66. type->value = ContinuationT();
  67. return type;
  68. }
  69. auto Expression::MakeFunType(int line_num, const Expression* param,
  70. const Expression* ret) -> const Expression* {
  71. auto* t = new Expression();
  72. t->line_num = line_num;
  73. t->value = FunctionType({.parameter = param, .return_type = ret});
  74. return t;
  75. }
  76. auto Expression::MakeVar(int line_num, std::string var) -> const Expression* {
  77. auto* v = new Expression();
  78. v->line_num = line_num;
  79. v->value = Variable({.name = new std::string(std::move(var))});
  80. return v;
  81. }
  82. auto Expression::MakeVarPat(int line_num, std::string var,
  83. const Expression* type) -> const Expression* {
  84. auto* v = new Expression();
  85. v->line_num = line_num;
  86. v->value =
  87. PatternVariable({.name = new std::string(std::move(var)), .type = type});
  88. return v;
  89. }
  90. auto Expression::MakeInt(int line_num, int i) -> const Expression* {
  91. auto* e = new Expression();
  92. e->line_num = line_num;
  93. e->value = IntLiteral({.value = i});
  94. return e;
  95. }
  96. auto Expression::MakeBool(int line_num, bool b) -> const Expression* {
  97. auto* e = new Expression();
  98. e->line_num = line_num;
  99. e->value = BoolLiteral({.value = b});
  100. return e;
  101. }
  102. auto Expression::MakeOp(int line_num, enum Operator op,
  103. std::vector<const Expression*>* args)
  104. -> const Expression* {
  105. auto* e = new Expression();
  106. e->line_num = line_num;
  107. e->value = PrimitiveOperator({.op = op, .arguments = args});
  108. return e;
  109. }
  110. auto Expression::MakeUnOp(int line_num, enum Operator op, const Expression* arg)
  111. -> const Expression* {
  112. auto* e = new Expression();
  113. e->line_num = line_num;
  114. e->value = PrimitiveOperator(
  115. {.op = op, .arguments = new std::vector<const Expression*>{arg}});
  116. return e;
  117. }
  118. auto Expression::MakeBinOp(int line_num, enum Operator op,
  119. const Expression* arg1, const Expression* arg2)
  120. -> const Expression* {
  121. auto* e = new Expression();
  122. e->line_num = line_num;
  123. e->value = PrimitiveOperator(
  124. {.op = op, .arguments = new std::vector<const Expression*>{arg1, arg2}});
  125. return e;
  126. }
  127. auto Expression::MakeCall(int line_num, const Expression* fun,
  128. const Expression* arg) -> const Expression* {
  129. auto* e = new Expression();
  130. e->line_num = line_num;
  131. e->value = Call({.function = fun, .argument = arg});
  132. return e;
  133. }
  134. auto Expression::MakeGetField(int line_num, const Expression* exp,
  135. std::string field) -> const Expression* {
  136. auto* e = new Expression();
  137. e->line_num = line_num;
  138. e->value = FieldAccess(
  139. {.aggregate = exp, .field = new std::string(std::move(field))});
  140. return e;
  141. }
  142. auto Expression::MakeTuple(int line_num, std::vector<FieldInitializer>* args)
  143. -> const Expression* {
  144. auto* e = new Expression();
  145. e->line_num = line_num;
  146. int i = 0;
  147. bool seen_named_member = false;
  148. for (auto& arg : *args) {
  149. if (arg.name == "") {
  150. if (seen_named_member) {
  151. std::cerr << line_num
  152. << ": positional members must come before named members"
  153. << std::endl;
  154. exit(-1);
  155. }
  156. arg.name = std::to_string(i);
  157. ++i;
  158. } else {
  159. seen_named_member = true;
  160. }
  161. }
  162. e->value = Tuple({.fields = args});
  163. return e;
  164. }
  165. // Create an AST node for an empty tuple.
  166. // TODO(geoffromer): remove this and rewrite its callers to use
  167. // `MakeTuple(line_num, {})`, once that works.
  168. auto Expression::MakeUnit(int line_num) -> const Expression* {
  169. auto* unit = new Expression();
  170. unit->line_num = line_num;
  171. auto* args = new std::vector<FieldInitializer>();
  172. unit->value = Tuple({.fields = args});
  173. return unit;
  174. }
  175. auto Expression::MakeIndex(int line_num, const Expression* exp,
  176. const Expression* i) -> const Expression* {
  177. auto* e = new Expression();
  178. e->line_num = line_num;
  179. e->value = Index({.aggregate = exp, .offset = i});
  180. return e;
  181. }
  182. static void PrintOp(Operator op) {
  183. switch (op) {
  184. case Operator::Add:
  185. std::cout << "+";
  186. break;
  187. case Operator::Neg:
  188. case Operator::Sub:
  189. std::cout << "-";
  190. break;
  191. case Operator::Mul:
  192. case Operator::Deref:
  193. case Operator::Ptr:
  194. std::cout << "*";
  195. break;
  196. case Operator::Not:
  197. std::cout << "not";
  198. break;
  199. case Operator::And:
  200. std::cout << "and";
  201. break;
  202. case Operator::Or:
  203. std::cout << "or";
  204. break;
  205. case Operator::Eq:
  206. std::cout << "==";
  207. break;
  208. }
  209. }
  210. static void PrintFields(std::vector<FieldInitializer>* fields) {
  211. int i = 0;
  212. for (auto iter = fields->begin(); iter != fields->end(); ++iter, ++i) {
  213. if (i != 0) {
  214. std::cout << ", ";
  215. }
  216. std::cout << iter->name << " = ";
  217. PrintExp(iter->expression);
  218. }
  219. }
  220. void PrintExp(const Expression* e) {
  221. switch (e->tag()) {
  222. case ExpressionKind::Index:
  223. PrintExp(e->GetIndex().aggregate);
  224. std::cout << "[";
  225. PrintExp(e->GetIndex().offset);
  226. std::cout << "]";
  227. break;
  228. case ExpressionKind::GetField:
  229. PrintExp(e->GetFieldAccess().aggregate);
  230. std::cout << ".";
  231. std::cout << *e->GetFieldAccess().field;
  232. break;
  233. case ExpressionKind::Tuple:
  234. std::cout << "(";
  235. PrintFields(e->GetTuple().fields);
  236. std::cout << ")";
  237. break;
  238. case ExpressionKind::Integer:
  239. std::cout << e->GetInteger();
  240. break;
  241. case ExpressionKind::Boolean:
  242. std::cout << std::boolalpha;
  243. std::cout << e->GetBoolean();
  244. break;
  245. case ExpressionKind::PrimitiveOp: {
  246. std::cout << "(";
  247. PrimitiveOperator op = e->GetPrimitiveOperator();
  248. if (op.arguments->size() == 0) {
  249. PrintOp(op.op);
  250. } else if (op.arguments->size() == 1) {
  251. PrintOp(op.op);
  252. std::cout << " ";
  253. auto iter = op.arguments->begin();
  254. PrintExp(*iter);
  255. } else if (op.arguments->size() == 2) {
  256. auto iter = op.arguments->begin();
  257. PrintExp(*iter);
  258. std::cout << " ";
  259. PrintOp(op.op);
  260. std::cout << " ";
  261. ++iter;
  262. PrintExp(*iter);
  263. }
  264. std::cout << ")";
  265. break;
  266. }
  267. case ExpressionKind::Variable:
  268. std::cout << *e->GetVariable().name;
  269. break;
  270. case ExpressionKind::PatternVariable:
  271. PrintExp(e->GetPatternVariable().type);
  272. std::cout << ": ";
  273. std::cout << *e->GetPatternVariable().name;
  274. break;
  275. case ExpressionKind::Call:
  276. PrintExp(e->GetCall().function);
  277. if (e->GetCall().argument->tag() == ExpressionKind::Tuple) {
  278. PrintExp(e->GetCall().argument);
  279. } else {
  280. std::cout << "(";
  281. PrintExp(e->GetCall().argument);
  282. std::cout << ")";
  283. }
  284. break;
  285. case ExpressionKind::BoolT:
  286. std::cout << "Bool";
  287. break;
  288. case ExpressionKind::IntT:
  289. std::cout << "Int";
  290. break;
  291. case ExpressionKind::TypeT:
  292. std::cout << "Type";
  293. break;
  294. case ExpressionKind::AutoT:
  295. std::cout << "auto";
  296. break;
  297. case ExpressionKind::ContinuationT:
  298. std::cout << "Continuation";
  299. break;
  300. case ExpressionKind::FunctionT:
  301. std::cout << "fn ";
  302. PrintExp(e->GetFunctionType().parameter);
  303. std::cout << " -> ";
  304. PrintExp(e->GetFunctionType().return_type);
  305. break;
  306. }
  307. }
  308. } // namespace Carbon