expression.h 9.8 KB

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