expression.h 8.4 KB

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