expression.h 9.9 KB

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