expression.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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/ADT/ArrayRef.h"
  15. #include "llvm/Support/Compiler.h"
  16. namespace Carbon {
  17. class Expression {
  18. public:
  19. enum class Kind {
  20. BoolTypeLiteral,
  21. BoolLiteral,
  22. CallExpression,
  23. FunctionTypeLiteral,
  24. FieldAccessExpression,
  25. IndexExpression,
  26. IntTypeLiteral,
  27. ContinuationTypeLiteral, // The type of a continuation value.
  28. IntLiteral,
  29. PrimitiveOperatorExpression,
  30. StringLiteral,
  31. StringTypeLiteral,
  32. TupleLiteral,
  33. StructLiteral,
  34. StructTypeLiteral,
  35. TypeTypeLiteral,
  36. IdentifierExpression,
  37. IntrinsicExpression,
  38. };
  39. void Print(llvm::raw_ostream& out) const;
  40. LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
  41. // Returns the enumerator corresponding to the most-derived type of this
  42. // object.
  43. auto kind() const -> Kind { return kind_; }
  44. auto source_loc() const -> SourceLocation { return source_loc_; }
  45. protected:
  46. // Constructs an Expression representing syntax at the given line number.
  47. // `kind` must be the enumerator corresponding to the most-derived type being
  48. // constructed.
  49. Expression(Kind kind, SourceLocation source_loc)
  50. : kind_(kind), source_loc_(source_loc) {}
  51. private:
  52. const Kind kind_;
  53. SourceLocation source_loc_;
  54. };
  55. // Converts paren_contents to an Expression, interpreting the parentheses as
  56. // grouping if their contents permit that interpretation, or as forming a
  57. // tuple otherwise.
  58. auto ExpressionFromParenContents(
  59. Nonnull<Arena*> arena, SourceLocation source_loc,
  60. const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*>;
  61. // Converts paren_contents to an Expression, interpreting the parentheses as
  62. // forming a tuple.
  63. auto TupleExpressionFromParenContents(
  64. Nonnull<Arena*> arena, SourceLocation source_loc,
  65. const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*>;
  66. // A FieldInitializer represents the initialization of a single tuple field.
  67. struct FieldInitializer {
  68. FieldInitializer(std::string name, Nonnull<Expression*> expression)
  69. : name(std::move(name)), expression(expression) {}
  70. // The field name. Cannot be empty.
  71. std::string name;
  72. // The expression that initializes the field.
  73. Nonnull<Expression*> expression;
  74. };
  75. enum class Operator {
  76. Add,
  77. And,
  78. Deref,
  79. Eq,
  80. Mul,
  81. Neg,
  82. Not,
  83. Or,
  84. Sub,
  85. Ptr,
  86. };
  87. class IdentifierExpression : public Expression {
  88. public:
  89. explicit IdentifierExpression(SourceLocation source_loc, std::string name)
  90. : Expression(Kind::IdentifierExpression, source_loc),
  91. name(std::move(name)) {}
  92. static auto classof(const Expression* exp) -> bool {
  93. return exp->kind() == Kind::IdentifierExpression;
  94. }
  95. auto Name() const -> const std::string& { return name; }
  96. private:
  97. std::string name;
  98. };
  99. class FieldAccessExpression : public Expression {
  100. public:
  101. explicit FieldAccessExpression(SourceLocation source_loc,
  102. Nonnull<Expression*> aggregate,
  103. std::string field)
  104. : Expression(Kind::FieldAccessExpression, source_loc),
  105. aggregate(aggregate),
  106. field(std::move(field)) {}
  107. static auto classof(const Expression* exp) -> bool {
  108. return exp->kind() == Kind::FieldAccessExpression;
  109. }
  110. auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
  111. auto Aggregate() -> Nonnull<Expression*> { return aggregate; }
  112. auto Field() const -> const std::string& { return field; }
  113. private:
  114. Nonnull<Expression*> aggregate;
  115. std::string field;
  116. };
  117. class IndexExpression : public Expression {
  118. public:
  119. explicit IndexExpression(SourceLocation source_loc,
  120. Nonnull<Expression*> aggregate,
  121. Nonnull<Expression*> offset)
  122. : Expression(Kind::IndexExpression, source_loc),
  123. aggregate(aggregate),
  124. offset(offset) {}
  125. static auto classof(const Expression* exp) -> bool {
  126. return exp->kind() == Kind::IndexExpression;
  127. }
  128. auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
  129. auto Aggregate() -> Nonnull<Expression*> { return aggregate; }
  130. auto Offset() const -> Nonnull<const Expression*> { return offset; }
  131. auto Offset() -> Nonnull<Expression*> { return offset; }
  132. private:
  133. Nonnull<Expression*> aggregate;
  134. Nonnull<Expression*> offset;
  135. };
  136. class IntLiteral : public Expression {
  137. public:
  138. explicit IntLiteral(SourceLocation source_loc, int val)
  139. : Expression(Kind::IntLiteral, source_loc), val(val) {}
  140. static auto classof(const Expression* exp) -> bool {
  141. return exp->kind() == Kind::IntLiteral;
  142. }
  143. auto Val() const -> int { return val; }
  144. private:
  145. int val;
  146. };
  147. class BoolLiteral : public Expression {
  148. public:
  149. explicit BoolLiteral(SourceLocation source_loc, bool val)
  150. : Expression(Kind::BoolLiteral, source_loc), val(val) {}
  151. static auto classof(const Expression* exp) -> bool {
  152. return exp->kind() == Kind::BoolLiteral;
  153. }
  154. auto Val() const -> bool { return val; }
  155. private:
  156. bool val;
  157. };
  158. class StringLiteral : public Expression {
  159. public:
  160. explicit StringLiteral(SourceLocation source_loc, std::string val)
  161. : Expression(Kind::StringLiteral, source_loc), val(std::move(val)) {}
  162. static auto classof(const Expression* exp) -> bool {
  163. return exp->kind() == Kind::StringLiteral;
  164. }
  165. auto Val() const -> const std::string& { return val; }
  166. private:
  167. std::string val;
  168. };
  169. class StringTypeLiteral : public Expression {
  170. public:
  171. explicit StringTypeLiteral(SourceLocation source_loc)
  172. : Expression(Kind::StringTypeLiteral, source_loc) {}
  173. static auto classof(const Expression* exp) -> bool {
  174. return exp->kind() == Kind::StringTypeLiteral;
  175. }
  176. };
  177. class TupleLiteral : public Expression {
  178. public:
  179. explicit TupleLiteral(SourceLocation source_loc)
  180. : TupleLiteral(source_loc, {}) {}
  181. explicit TupleLiteral(SourceLocation source_loc,
  182. std::vector<FieldInitializer> fields)
  183. : Expression(Kind::TupleLiteral, source_loc), fields(std::move(fields)) {}
  184. static auto classof(const Expression* exp) -> bool {
  185. return exp->kind() == Kind::TupleLiteral;
  186. }
  187. auto Fields() const -> const std::vector<FieldInitializer>& { return fields; }
  188. private:
  189. std::vector<FieldInitializer> fields;
  190. };
  191. // A non-empty literal value of a struct type.
  192. //
  193. // It can't be empty because the syntax `{}` is a struct type literal as well
  194. // as a literal value of that type, so for consistency we always represent it
  195. // as a StructTypeLiteral rather than let it oscillate unpredictably between
  196. // the two.
  197. class StructLiteral : public Expression {
  198. public:
  199. explicit StructLiteral(SourceLocation loc,
  200. std::vector<FieldInitializer> fields)
  201. : Expression(Kind::StructLiteral, loc), fields_(std::move(fields)) {
  202. CHECK(!fields_.empty())
  203. << "`{}` is represented as a StructTypeLiteral, not a StructLiteral.";
  204. }
  205. static auto classof(const Expression* exp) -> bool {
  206. return exp->kind() == Kind::StructLiteral;
  207. }
  208. auto fields() const -> const std::vector<FieldInitializer>& {
  209. return fields_;
  210. }
  211. private:
  212. std::vector<FieldInitializer> fields_;
  213. };
  214. // A literal representing a struct type.
  215. //
  216. // Code that handles this type may sometimes need to have special-case handling
  217. // for `{}`, which is a struct value in addition to being a struct type.
  218. class StructTypeLiteral : public Expression {
  219. public:
  220. explicit StructTypeLiteral(SourceLocation loc) : StructTypeLiteral(loc, {}) {}
  221. explicit StructTypeLiteral(SourceLocation loc,
  222. std::vector<FieldInitializer> fields)
  223. : Expression(Kind::StructTypeLiteral, loc), fields_(std::move(fields)) {}
  224. static auto classof(const Expression* exp) -> bool {
  225. return exp->kind() == Kind::StructTypeLiteral;
  226. }
  227. auto fields() const -> const std::vector<FieldInitializer>& {
  228. return fields_;
  229. }
  230. private:
  231. std::vector<FieldInitializer> fields_;
  232. };
  233. class PrimitiveOperatorExpression : public Expression {
  234. public:
  235. explicit PrimitiveOperatorExpression(
  236. SourceLocation source_loc, Operator op,
  237. std::vector<Nonnull<Expression*>> arguments)
  238. : Expression(Kind::PrimitiveOperatorExpression, source_loc),
  239. op(op),
  240. arguments(std::move(arguments)) {}
  241. static auto classof(const Expression* exp) -> bool {
  242. return exp->kind() == Kind::PrimitiveOperatorExpression;
  243. }
  244. auto Op() const -> Operator { return op; }
  245. auto Arguments() const -> llvm::ArrayRef<Nonnull<Expression*>> {
  246. return arguments;
  247. }
  248. auto Arguments() -> llvm::MutableArrayRef<Nonnull<Expression*>> {
  249. return arguments;
  250. }
  251. private:
  252. Operator op;
  253. std::vector<Nonnull<Expression*>> arguments;
  254. };
  255. class CallExpression : public Expression {
  256. public:
  257. explicit CallExpression(SourceLocation source_loc,
  258. Nonnull<Expression*> function,
  259. Nonnull<Expression*> argument)
  260. : Expression(Kind::CallExpression, source_loc),
  261. function(function),
  262. argument(argument) {}
  263. static auto classof(const Expression* exp) -> bool {
  264. return exp->kind() == Kind::CallExpression;
  265. }
  266. auto Function() const -> Nonnull<const Expression*> { return function; }
  267. auto Function() -> Nonnull<Expression*> { return function; }
  268. auto Argument() const -> Nonnull<const Expression*> { return argument; }
  269. auto Argument() -> Nonnull<Expression*> { return argument; }
  270. private:
  271. Nonnull<Expression*> function;
  272. Nonnull<Expression*> argument;
  273. };
  274. class FunctionTypeLiteral : public Expression {
  275. public:
  276. explicit FunctionTypeLiteral(SourceLocation source_loc,
  277. Nonnull<Expression*> parameter,
  278. Nonnull<Expression*> return_type,
  279. bool is_omitted_return_type)
  280. : Expression(Kind::FunctionTypeLiteral, source_loc),
  281. parameter(parameter),
  282. return_type(return_type),
  283. is_omitted_return_type(is_omitted_return_type) {}
  284. static auto classof(const Expression* exp) -> bool {
  285. return exp->kind() == Kind::FunctionTypeLiteral;
  286. }
  287. auto Parameter() const -> Nonnull<const Expression*> { return parameter; }
  288. auto Parameter() -> Nonnull<Expression*> { return parameter; }
  289. auto ReturnType() const -> Nonnull<const Expression*> { return return_type; }
  290. auto ReturnType() -> Nonnull<Expression*> { return return_type; }
  291. auto IsOmittedReturnType() const -> bool { return is_omitted_return_type; }
  292. private:
  293. Nonnull<Expression*> parameter;
  294. Nonnull<Expression*> return_type;
  295. bool is_omitted_return_type;
  296. };
  297. class BoolTypeLiteral : public Expression {
  298. public:
  299. explicit BoolTypeLiteral(SourceLocation source_loc)
  300. : Expression(Kind::BoolTypeLiteral, source_loc) {}
  301. static auto classof(const Expression* exp) -> bool {
  302. return exp->kind() == Kind::BoolTypeLiteral;
  303. }
  304. };
  305. class IntTypeLiteral : public Expression {
  306. public:
  307. explicit IntTypeLiteral(SourceLocation source_loc)
  308. : Expression(Kind::IntTypeLiteral, source_loc) {}
  309. static auto classof(const Expression* exp) -> bool {
  310. return exp->kind() == Kind::IntTypeLiteral;
  311. }
  312. };
  313. class ContinuationTypeLiteral : public Expression {
  314. public:
  315. explicit ContinuationTypeLiteral(SourceLocation source_loc)
  316. : Expression(Kind::ContinuationTypeLiteral, source_loc) {}
  317. static auto classof(const Expression* exp) -> bool {
  318. return exp->kind() == Kind::ContinuationTypeLiteral;
  319. }
  320. };
  321. class TypeTypeLiteral : public Expression {
  322. public:
  323. explicit TypeTypeLiteral(SourceLocation source_loc)
  324. : Expression(Kind::TypeTypeLiteral, source_loc) {}
  325. static auto classof(const Expression* exp) -> bool {
  326. return exp->kind() == Kind::TypeTypeLiteral;
  327. }
  328. };
  329. class IntrinsicExpression : public Expression {
  330. public:
  331. enum class IntrinsicKind {
  332. Print,
  333. };
  334. explicit IntrinsicExpression(IntrinsicKind intrinsic)
  335. : Expression(Kind::IntrinsicExpression, SourceLocation("<intrinsic>", 0)),
  336. intrinsic(intrinsic) {}
  337. static auto classof(const Expression* exp) -> bool {
  338. return exp->kind() == Kind::IntrinsicExpression;
  339. }
  340. auto Intrinsic() const -> IntrinsicKind { return intrinsic; }
  341. private:
  342. IntrinsicKind intrinsic;
  343. };
  344. } // namespace Carbon
  345. #endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_