expression.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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. #ifndef EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
  5. #define EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_
  6. #include <optional>
  7. #include <string>
  8. #include <variant>
  9. #include <vector>
  10. #include "common/ostream.h"
  11. #include "executable_semantics/ast/paren_contents.h"
  12. #include "llvm/Support/Compiler.h"
  13. namespace Carbon {
  14. class Expression {
  15. public:
  16. enum class Kind {
  17. BoolTypeLiteral,
  18. BoolLiteral,
  19. CallExpression,
  20. FunctionTypeLiteral,
  21. FieldAccessExpression,
  22. IndexExpression,
  23. IntTypeLiteral,
  24. ContinuationTypeLiteral, // The type of a continuation value.
  25. IntLiteral,
  26. PrimitiveOperatorExpression,
  27. StringLiteral,
  28. StringTypeLiteral,
  29. TupleLiteral,
  30. TypeTypeLiteral,
  31. IdentifierExpression,
  32. IntrinsicExpression,
  33. };
  34. // Returns the enumerator corresponding to the most-derived type of this
  35. // object.
  36. auto Tag() const -> Kind { return tag; }
  37. auto LineNumber() const -> int { return line_num; }
  38. void Print(llvm::raw_ostream& out) const;
  39. LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
  40. protected:
  41. // Constructs an Expression representing syntax at the given line number.
  42. // `tag` must be the enumerator corresponding to the most-derived type being
  43. // constructed.
  44. Expression(Kind tag, int line_num) : tag(tag), line_num(line_num) {}
  45. private:
  46. const Kind tag;
  47. int line_num;
  48. };
  49. // Converts paren_contents to an Expression, interpreting the parentheses as
  50. // grouping if their contents permit that interpretation, or as forming a
  51. // tuple otherwise.
  52. auto ExpressionFromParenContents(
  53. int line_num, const ParenContents<Expression>& paren_contents)
  54. -> const Expression*;
  55. // Converts paren_contents to an Expression, interpreting the parentheses as
  56. // forming a tuple.
  57. auto TupleExpressionFromParenContents(
  58. int line_num, const ParenContents<Expression>& paren_contents)
  59. -> const Expression*;
  60. // A FieldInitializer represents the initialization of a single tuple field.
  61. struct FieldInitializer {
  62. FieldInitializer(std::string name, const Expression* expression)
  63. : name(std::move(name)), expression(expression) {}
  64. // The field name. Cannot be empty.
  65. std::string name;
  66. // The expression that initializes the field.
  67. const Expression* expression;
  68. };
  69. enum class Operator {
  70. Add,
  71. And,
  72. Deref,
  73. Eq,
  74. Mul,
  75. Neg,
  76. Not,
  77. Or,
  78. Sub,
  79. Ptr,
  80. };
  81. class IdentifierExpression : public Expression {
  82. public:
  83. explicit IdentifierExpression(int line_num, std::string name)
  84. : Expression(Kind::IdentifierExpression, line_num),
  85. name(std::move(name)) {}
  86. static auto classof(const Expression* exp) -> bool {
  87. return exp->Tag() == Kind::IdentifierExpression;
  88. }
  89. auto Name() const -> const std::string& { return name; }
  90. private:
  91. std::string name;
  92. };
  93. class FieldAccessExpression : public Expression {
  94. public:
  95. explicit FieldAccessExpression(int line_num, const Expression* aggregate,
  96. std::string field)
  97. : Expression(Kind::FieldAccessExpression, line_num),
  98. aggregate(aggregate),
  99. field(std::move(field)) {}
  100. static auto classof(const Expression* exp) -> bool {
  101. return exp->Tag() == Kind::FieldAccessExpression;
  102. }
  103. auto Aggregate() const -> const Expression* { return aggregate; }
  104. auto Field() const -> const std::string& { return field; }
  105. private:
  106. const Expression* aggregate;
  107. std::string field;
  108. };
  109. class IndexExpression : public Expression {
  110. public:
  111. explicit IndexExpression(int line_num, const Expression* aggregate,
  112. const Expression* offset)
  113. : Expression(Kind::IndexExpression, line_num),
  114. aggregate(aggregate),
  115. offset(offset) {}
  116. static auto classof(const Expression* exp) -> bool {
  117. return exp->Tag() == Kind::IndexExpression;
  118. }
  119. auto Aggregate() const -> const Expression* { return aggregate; }
  120. auto Offset() const -> const Expression* { return offset; }
  121. private:
  122. const Expression* aggregate;
  123. const Expression* offset;
  124. };
  125. class IntLiteral : public Expression {
  126. public:
  127. explicit IntLiteral(int line_num, int val)
  128. : Expression(Kind::IntLiteral, line_num), val(val) {}
  129. static auto classof(const Expression* exp) -> bool {
  130. return exp->Tag() == Kind::IntLiteral;
  131. }
  132. auto Val() const -> int { return val; }
  133. private:
  134. int val;
  135. };
  136. class BoolLiteral : public Expression {
  137. public:
  138. explicit BoolLiteral(int line_num, bool val)
  139. : Expression(Kind::BoolLiteral, line_num), val(val) {}
  140. static auto classof(const Expression* exp) -> bool {
  141. return exp->Tag() == Kind::BoolLiteral;
  142. }
  143. auto Val() const -> bool { return val; }
  144. private:
  145. bool val;
  146. };
  147. class StringLiteral : public Expression {
  148. public:
  149. explicit StringLiteral(int line_num, std::string val)
  150. : Expression(Kind::StringLiteral, line_num), val(std::move(val)) {}
  151. static auto classof(const Expression* exp) -> bool {
  152. return exp->Tag() == Kind::StringLiteral;
  153. }
  154. auto Val() const -> const std::string& { return val; }
  155. private:
  156. std::string val;
  157. };
  158. class StringTypeLiteral : public Expression {
  159. public:
  160. explicit StringTypeLiteral(int line_num)
  161. : Expression(Kind::StringTypeLiteral, line_num) {}
  162. static auto classof(const Expression* exp) -> bool {
  163. return exp->Tag() == Kind::StringTypeLiteral;
  164. }
  165. };
  166. class TupleLiteral : public Expression {
  167. public:
  168. explicit TupleLiteral(int line_num) : TupleLiteral(line_num, {}) {}
  169. explicit TupleLiteral(int line_num, std::vector<FieldInitializer> fields)
  170. : Expression(Kind::TupleLiteral, line_num), fields(std::move(fields)) {}
  171. static auto classof(const Expression* exp) -> bool {
  172. return exp->Tag() == Kind::TupleLiteral;
  173. }
  174. auto Fields() const -> const std::vector<FieldInitializer>& { return fields; }
  175. private:
  176. std::vector<FieldInitializer> fields;
  177. };
  178. class PrimitiveOperatorExpression : public Expression {
  179. public:
  180. explicit PrimitiveOperatorExpression(int line_num, Operator op,
  181. std::vector<const Expression*> arguments)
  182. : Expression(Kind::PrimitiveOperatorExpression, line_num),
  183. op(op),
  184. arguments(std::move(arguments)) {}
  185. static auto classof(const Expression* exp) -> bool {
  186. return exp->Tag() == Kind::PrimitiveOperatorExpression;
  187. }
  188. auto Op() const -> Operator { return op; }
  189. auto Arguments() const -> const std::vector<const Expression*>& {
  190. return arguments;
  191. }
  192. private:
  193. Operator op;
  194. std::vector<const Expression*> arguments;
  195. };
  196. class CallExpression : public Expression {
  197. public:
  198. explicit CallExpression(int line_num, const Expression* function,
  199. const Expression* argument)
  200. : Expression(Kind::CallExpression, line_num),
  201. function(function),
  202. argument(argument) {}
  203. static auto classof(const Expression* exp) -> bool {
  204. return exp->Tag() == Kind::CallExpression;
  205. }
  206. auto Function() const -> const Expression* { return function; }
  207. auto Argument() const -> const Expression* { return argument; }
  208. private:
  209. const Expression* function;
  210. const Expression* argument;
  211. };
  212. class FunctionTypeLiteral : public Expression {
  213. public:
  214. explicit FunctionTypeLiteral(int line_num, const Expression* parameter,
  215. const Expression* return_type,
  216. bool is_omitted_return_type)
  217. : Expression(Kind::FunctionTypeLiteral, line_num),
  218. parameter(parameter),
  219. return_type(return_type),
  220. is_omitted_return_type(is_omitted_return_type) {}
  221. static auto classof(const Expression* exp) -> bool {
  222. return exp->Tag() == Kind::FunctionTypeLiteral;
  223. }
  224. auto Parameter() const -> const Expression* { return parameter; }
  225. auto ReturnType() const -> const Expression* { return return_type; }
  226. auto IsOmittedReturnType() const -> bool { return is_omitted_return_type; }
  227. private:
  228. const Expression* parameter;
  229. const Expression* return_type;
  230. bool is_omitted_return_type;
  231. };
  232. class BoolTypeLiteral : public Expression {
  233. public:
  234. explicit BoolTypeLiteral(int line_num)
  235. : Expression(Kind::BoolTypeLiteral, line_num) {}
  236. static auto classof(const Expression* exp) -> bool {
  237. return exp->Tag() == Kind::BoolTypeLiteral;
  238. }
  239. };
  240. class IntTypeLiteral : public Expression {
  241. public:
  242. explicit IntTypeLiteral(int line_num)
  243. : Expression(Kind::IntTypeLiteral, line_num) {}
  244. static auto classof(const Expression* exp) -> bool {
  245. return exp->Tag() == Kind::IntTypeLiteral;
  246. }
  247. };
  248. class ContinuationTypeLiteral : public Expression {
  249. public:
  250. explicit ContinuationTypeLiteral(int line_num)
  251. : Expression(Kind::ContinuationTypeLiteral, line_num) {}
  252. static auto classof(const Expression* exp) -> bool {
  253. return exp->Tag() == Kind::ContinuationTypeLiteral;
  254. }
  255. };
  256. class TypeTypeLiteral : public Expression {
  257. public:
  258. explicit TypeTypeLiteral(int line_num)
  259. : Expression(Kind::TypeTypeLiteral, line_num) {}
  260. static auto classof(const Expression* exp) -> bool {
  261. return exp->Tag() == Kind::TypeTypeLiteral;
  262. }
  263. };
  264. class IntrinsicExpression : public Expression {
  265. public:
  266. enum class IntrinsicKind {
  267. Print,
  268. };
  269. explicit IntrinsicExpression(IntrinsicKind intrinsic)
  270. : Expression(Kind::IntrinsicExpression, -1), intrinsic(intrinsic) {}
  271. static auto classof(const Expression* exp) -> bool {
  272. return exp->Tag() == Kind::IntrinsicExpression;
  273. }
  274. auto Intrinsic() const -> IntrinsicKind { return intrinsic; }
  275. private:
  276. IntrinsicKind intrinsic;
  277. };
  278. } // namespace Carbon
  279. #endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_