expression.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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/ast_node.h"
  12. #include "executable_semantics/ast/paren_contents.h"
  13. #include "executable_semantics/ast/source_location.h"
  14. #include "executable_semantics/common/arena.h"
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/Support/Compiler.h"
  17. namespace Carbon {
  18. class Value;
  19. class NamedEntity;
  20. class Expression : public virtual AstNode {
  21. public:
  22. // The value category of a Carbon expression indicates whether it evaluates
  23. // to a variable or a value. A variable can be mutated, and can have its
  24. // address taken, whereas a value cannot.
  25. enum class ValueCategory {
  26. // A variable. This roughly corresponds to a C/C++ lvalue.
  27. Var,
  28. // A value. This roughly corresponds to a C/C++ rvalue.
  29. Let,
  30. };
  31. ~Expression() override = 0;
  32. void Print(llvm::raw_ostream& out) const override;
  33. static auto classof(const AstNode* node) {
  34. return InheritsFromExpression(node->kind());
  35. }
  36. // Returns the enumerator corresponding to the most-derived type of this
  37. // object.
  38. auto kind() const -> ExpressionKind {
  39. return static_cast<ExpressionKind>(root_kind());
  40. }
  41. // The static type of this expression. Cannot be called before typechecking.
  42. auto static_type() const -> const Value& { return **static_type_; }
  43. // Sets the static type of this expression. Can only be called once, during
  44. // typechecking.
  45. void set_static_type(Nonnull<const Value*> type) { static_type_ = type; }
  46. // Returns whether the static type has been set. Should only be called
  47. // during typechecking: before typechecking it's guaranteed to be false,
  48. // and after typechecking it's guaranteed to be true.
  49. auto has_static_type() const -> bool { return static_type_.has_value(); }
  50. // The value category of this expression. Cannot be called before
  51. // typechecking.
  52. auto value_category() const -> ValueCategory { return *value_category_; }
  53. // Sets the value category of this expression. Can be called multiple times,
  54. // but the argument must have the same value each time.
  55. void set_value_category(ValueCategory value_category) {
  56. CHECK(!value_category_.has_value() || value_category == *value_category_);
  57. value_category_ = value_category;
  58. }
  59. protected:
  60. // Constructs an Expression representing syntax at the given line number.
  61. // `kind` must be the enumerator corresponding to the most-derived type being
  62. // constructed.
  63. Expression() = default;
  64. private:
  65. std::optional<Nonnull<const Value*>> static_type_;
  66. std::optional<ValueCategory> value_category_;
  67. };
  68. // A FieldInitializer represents the initialization of a single struct field.
  69. class FieldInitializer {
  70. public:
  71. FieldInitializer(std::string name, Nonnull<Expression*> expression)
  72. : name_(std::move(name)), expression_(expression) {}
  73. auto name() const -> const std::string& { return name_; }
  74. auto expression() const -> const Expression& { return *expression_; }
  75. auto expression() -> Expression& { return *expression_; }
  76. private:
  77. // The field name. Cannot be empty.
  78. std::string name_;
  79. // The expression that initializes the field.
  80. Nonnull<Expression*> expression_;
  81. };
  82. enum class Operator {
  83. Add,
  84. And,
  85. Deref,
  86. Eq,
  87. Mul,
  88. Neg,
  89. Not,
  90. Or,
  91. Sub,
  92. Ptr,
  93. };
  94. // Returns the lexical representation of `op`, such as "+" for `Add`.
  95. auto ToString(Operator op) -> std::string_view;
  96. class IdentifierExpression : public Expression {
  97. public:
  98. explicit IdentifierExpression(SourceLocation source_loc, std::string name)
  99. : AstNode(AstNodeKind::IdentifierExpression, source_loc),
  100. name_(std::move(name)) {}
  101. static auto classof(const AstNode* node) -> bool {
  102. return InheritsFromIdentifierExpression(node->kind());
  103. }
  104. auto name() const -> const std::string& { return name_; }
  105. // Returns the NamedEntity this identifier refers to. Cannot be called before
  106. // name resolution.
  107. auto named_entity() const -> const NamedEntity& { return **named_entity_; }
  108. // Sets the value returned by named_entity. Can be called only once,
  109. // during name resolution.
  110. void set_named_entity(Nonnull<const NamedEntity*> named_entity) {
  111. CHECK(!named_entity_.has_value());
  112. named_entity_ = named_entity;
  113. }
  114. // Returns true if set_named_entity has been called. Should be used only
  115. // for debugging purposes.
  116. // TODO: remove this once we no longer need the CHECKs that use it.
  117. auto has_named_entity() const -> bool { return named_entity_.has_value(); }
  118. private:
  119. std::string name_;
  120. std::optional<Nonnull<const NamedEntity*>> named_entity_;
  121. };
  122. class FieldAccessExpression : public Expression {
  123. public:
  124. explicit FieldAccessExpression(SourceLocation source_loc,
  125. Nonnull<Expression*> aggregate,
  126. std::string field)
  127. : AstNode(AstNodeKind::FieldAccessExpression, source_loc),
  128. aggregate_(aggregate),
  129. field_(std::move(field)) {}
  130. static auto classof(const AstNode* node) -> bool {
  131. return InheritsFromFieldAccessExpression(node->kind());
  132. }
  133. auto aggregate() const -> const Expression& { return *aggregate_; }
  134. auto aggregate() -> Expression& { return *aggregate_; }
  135. auto field() const -> const std::string& { return field_; }
  136. private:
  137. Nonnull<Expression*> aggregate_;
  138. std::string field_;
  139. };
  140. class IndexExpression : public Expression {
  141. public:
  142. explicit IndexExpression(SourceLocation source_loc,
  143. Nonnull<Expression*> aggregate,
  144. Nonnull<Expression*> offset)
  145. : AstNode(AstNodeKind::IndexExpression, source_loc),
  146. aggregate_(aggregate),
  147. offset_(offset) {}
  148. static auto classof(const AstNode* node) -> bool {
  149. return InheritsFromIndexExpression(node->kind());
  150. }
  151. auto aggregate() const -> const Expression& { return *aggregate_; }
  152. auto aggregate() -> Expression& { return *aggregate_; }
  153. auto offset() const -> const Expression& { return *offset_; }
  154. auto offset() -> Expression& { return *offset_; }
  155. private:
  156. Nonnull<Expression*> aggregate_;
  157. Nonnull<Expression*> offset_;
  158. };
  159. class IntLiteral : public Expression {
  160. public:
  161. explicit IntLiteral(SourceLocation source_loc, int value)
  162. : AstNode(AstNodeKind::IntLiteral, source_loc), value_(value) {}
  163. static auto classof(const AstNode* node) -> bool {
  164. return InheritsFromIntLiteral(node->kind());
  165. }
  166. auto value() const -> int { return value_; }
  167. private:
  168. int value_;
  169. };
  170. class BoolLiteral : public Expression {
  171. public:
  172. explicit BoolLiteral(SourceLocation source_loc, bool value)
  173. : AstNode(AstNodeKind::BoolLiteral, source_loc), value_(value) {}
  174. static auto classof(const AstNode* node) -> bool {
  175. return InheritsFromBoolLiteral(node->kind());
  176. }
  177. auto value() const -> bool { return value_; }
  178. private:
  179. bool value_;
  180. };
  181. class StringLiteral : public Expression {
  182. public:
  183. explicit StringLiteral(SourceLocation source_loc, std::string value)
  184. : AstNode(AstNodeKind::StringLiteral, source_loc),
  185. value_(std::move(value)) {}
  186. static auto classof(const AstNode* node) -> bool {
  187. return InheritsFromStringLiteral(node->kind());
  188. }
  189. auto value() const -> const std::string& { return value_; }
  190. private:
  191. std::string value_;
  192. };
  193. class StringTypeLiteral : public Expression {
  194. public:
  195. explicit StringTypeLiteral(SourceLocation source_loc)
  196. : AstNode(AstNodeKind::StringTypeLiteral, source_loc) {}
  197. static auto classof(const AstNode* node) -> bool {
  198. return InheritsFromStringTypeLiteral(node->kind());
  199. }
  200. };
  201. class TupleLiteral : public Expression {
  202. public:
  203. explicit TupleLiteral(SourceLocation source_loc)
  204. : TupleLiteral(source_loc, {}) {}
  205. explicit TupleLiteral(SourceLocation source_loc,
  206. std::vector<Nonnull<Expression*>> fields)
  207. : AstNode(AstNodeKind::TupleLiteral, source_loc),
  208. fields_(std::move(fields)) {}
  209. static auto classof(const AstNode* node) -> bool {
  210. return InheritsFromTupleLiteral(node->kind());
  211. }
  212. auto fields() const -> llvm::ArrayRef<Nonnull<const Expression*>> {
  213. return fields_;
  214. }
  215. auto fields() -> llvm::ArrayRef<Nonnull<Expression*>> { return fields_; }
  216. private:
  217. std::vector<Nonnull<Expression*>> fields_;
  218. };
  219. // A non-empty literal value of a struct type.
  220. //
  221. // It can't be empty because the syntax `{}` is a struct type literal as well
  222. // as a literal value of that type, so for consistency we always represent it
  223. // as a StructTypeLiteral rather than let it oscillate unpredictably between
  224. // the two.
  225. class StructLiteral : public Expression {
  226. public:
  227. explicit StructLiteral(SourceLocation loc,
  228. std::vector<FieldInitializer> fields)
  229. : AstNode(AstNodeKind::StructLiteral, loc), fields_(std::move(fields)) {
  230. CHECK(!fields_.empty())
  231. << "`{}` is represented as a StructTypeLiteral, not a StructLiteral.";
  232. }
  233. static auto classof(const AstNode* node) -> bool {
  234. return InheritsFromStructLiteral(node->kind());
  235. }
  236. auto fields() const -> llvm::ArrayRef<FieldInitializer> { return fields_; }
  237. auto fields() -> llvm::MutableArrayRef<FieldInitializer> { return fields_; }
  238. private:
  239. std::vector<FieldInitializer> fields_;
  240. };
  241. // A literal representing a struct type.
  242. //
  243. // Code that handles this type may sometimes need to have special-case handling
  244. // for `{}`, which is a struct value in addition to being a struct type.
  245. class StructTypeLiteral : public Expression {
  246. public:
  247. explicit StructTypeLiteral(SourceLocation loc) : StructTypeLiteral(loc, {}) {}
  248. explicit StructTypeLiteral(SourceLocation loc,
  249. std::vector<FieldInitializer> fields)
  250. : AstNode(AstNodeKind::StructTypeLiteral, loc),
  251. fields_(std::move(fields)) {}
  252. static auto classof(const AstNode* node) -> bool {
  253. return InheritsFromStructTypeLiteral(node->kind());
  254. }
  255. auto fields() const -> llvm::ArrayRef<FieldInitializer> { return fields_; }
  256. auto fields() -> llvm::MutableArrayRef<FieldInitializer> { return fields_; }
  257. private:
  258. std::vector<FieldInitializer> fields_;
  259. };
  260. class PrimitiveOperatorExpression : public Expression {
  261. public:
  262. explicit PrimitiveOperatorExpression(
  263. SourceLocation source_loc, Operator op,
  264. std::vector<Nonnull<Expression*>> arguments)
  265. : AstNode(AstNodeKind::PrimitiveOperatorExpression, source_loc),
  266. op_(op),
  267. arguments_(std::move(arguments)) {}
  268. static auto classof(const AstNode* node) -> bool {
  269. return InheritsFromPrimitiveOperatorExpression(node->kind());
  270. }
  271. auto op() const -> Operator { return op_; }
  272. auto arguments() const -> llvm::ArrayRef<Nonnull<Expression*>> {
  273. return arguments_;
  274. }
  275. auto arguments() -> llvm::MutableArrayRef<Nonnull<Expression*>> {
  276. return arguments_;
  277. }
  278. private:
  279. Operator op_;
  280. std::vector<Nonnull<Expression*>> arguments_;
  281. };
  282. class CallExpression : public Expression {
  283. public:
  284. explicit CallExpression(SourceLocation source_loc,
  285. Nonnull<Expression*> function,
  286. Nonnull<Expression*> argument)
  287. : AstNode(AstNodeKind::CallExpression, source_loc),
  288. function_(function),
  289. argument_(argument) {}
  290. static auto classof(const AstNode* node) -> bool {
  291. return InheritsFromCallExpression(node->kind());
  292. }
  293. auto function() const -> const Expression& { return *function_; }
  294. auto function() -> Expression& { return *function_; }
  295. auto argument() const -> const Expression& { return *argument_; }
  296. auto argument() -> Expression& { return *argument_; }
  297. private:
  298. Nonnull<Expression*> function_;
  299. Nonnull<Expression*> argument_;
  300. };
  301. class FunctionTypeLiteral : public Expression {
  302. public:
  303. explicit FunctionTypeLiteral(SourceLocation source_loc,
  304. Nonnull<Expression*> parameter,
  305. Nonnull<Expression*> return_type)
  306. : AstNode(AstNodeKind::FunctionTypeLiteral, source_loc),
  307. parameter_(parameter),
  308. return_type_(return_type) {}
  309. static auto classof(const AstNode* node) -> bool {
  310. return InheritsFromFunctionTypeLiteral(node->kind());
  311. }
  312. auto parameter() const -> const Expression& { return *parameter_; }
  313. auto parameter() -> Expression& { return *parameter_; }
  314. auto return_type() const -> const Expression& { return *return_type_; }
  315. auto return_type() -> Expression& { return *return_type_; }
  316. private:
  317. Nonnull<Expression*> parameter_;
  318. Nonnull<Expression*> return_type_;
  319. };
  320. class BoolTypeLiteral : public Expression {
  321. public:
  322. explicit BoolTypeLiteral(SourceLocation source_loc)
  323. : AstNode(AstNodeKind::BoolTypeLiteral, source_loc) {}
  324. static auto classof(const AstNode* node) -> bool {
  325. return InheritsFromBoolTypeLiteral(node->kind());
  326. }
  327. };
  328. class IntTypeLiteral : public Expression {
  329. public:
  330. explicit IntTypeLiteral(SourceLocation source_loc)
  331. : AstNode(AstNodeKind::IntTypeLiteral, source_loc) {}
  332. static auto classof(const AstNode* node) -> bool {
  333. return InheritsFromIntTypeLiteral(node->kind());
  334. }
  335. };
  336. class ContinuationTypeLiteral : public Expression {
  337. public:
  338. explicit ContinuationTypeLiteral(SourceLocation source_loc)
  339. : AstNode(AstNodeKind::ContinuationTypeLiteral, source_loc) {}
  340. static auto classof(const AstNode* node) -> bool {
  341. return InheritsFromContinuationTypeLiteral(node->kind());
  342. }
  343. };
  344. class TypeTypeLiteral : public Expression {
  345. public:
  346. explicit TypeTypeLiteral(SourceLocation source_loc)
  347. : AstNode(AstNodeKind::TypeTypeLiteral, source_loc) {}
  348. static auto classof(const AstNode* node) -> bool {
  349. return InheritsFromTypeTypeLiteral(node->kind());
  350. }
  351. };
  352. class IntrinsicExpression : public Expression {
  353. public:
  354. enum class Intrinsic {
  355. Print,
  356. };
  357. explicit IntrinsicExpression(std::string_view intrinsic_name,
  358. Nonnull<TupleLiteral*> args,
  359. SourceLocation source_loc)
  360. : AstNode(AstNodeKind::IntrinsicExpression, source_loc),
  361. intrinsic_(FindIntrinsic(intrinsic_name, source_loc)),
  362. args_(args) {}
  363. static auto classof(const AstNode* node) -> bool {
  364. return InheritsFromIntrinsicExpression(node->kind());
  365. }
  366. auto intrinsic() const -> Intrinsic { return intrinsic_; }
  367. auto args() const -> const TupleLiteral& { return *args_; }
  368. auto args() -> TupleLiteral& { return *args_; }
  369. private:
  370. // Returns the enumerator corresponding to the intrinsic named `name`,
  371. // or raises a fatal compile error if there is no such enumerator.
  372. static auto FindIntrinsic(std::string_view name, SourceLocation source_loc)
  373. -> Intrinsic;
  374. Intrinsic intrinsic_;
  375. Nonnull<TupleLiteral*> args_;
  376. };
  377. // An expression whose semantics have not been implemented. This can be used
  378. // as a placeholder during development, in order to implement and test parsing
  379. // of a new expression syntax without having to implement its semantics.
  380. class UnimplementedExpression : public Expression {
  381. public:
  382. // Constructs an UnimplementedExpression with the given label and the given
  383. // children, which must all be convertible to Nonnull<AstNode*>. The label
  384. // should correspond roughly to the name of the class that will eventually
  385. // replace this usage of UnimplementedExpression.
  386. template <typename... Children>
  387. UnimplementedExpression(SourceLocation source_loc, std::string label,
  388. Children... children)
  389. : AstNode(AstNodeKind::UnimplementedExpression, source_loc),
  390. label_(std::move(label)) {
  391. AddChildren(children...);
  392. }
  393. static auto classof(const AstNode* node) -> bool {
  394. return InheritsFromUnimplementedExpression(node->kind());
  395. }
  396. auto label() const -> std::string_view { return label_; }
  397. auto children() const -> llvm::ArrayRef<Nonnull<const AstNode*>> {
  398. return children_;
  399. }
  400. private:
  401. void AddChildren() {}
  402. template <typename... Children>
  403. void AddChildren(Nonnull<AstNode*> child, Children... children) {
  404. children_.push_back(child);
  405. AddChildren(children...);
  406. }
  407. std::string label_;
  408. std::vector<Nonnull<AstNode*>> children_;
  409. };
  410. // Converts paren_contents to an Expression, interpreting the parentheses as
  411. // grouping if their contents permit that interpretation, or as forming a
  412. // tuple otherwise.
  413. auto ExpressionFromParenContents(
  414. Nonnull<Arena*> arena, SourceLocation source_loc,
  415. const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*>;
  416. // Converts paren_contents to an Expression, interpreting the parentheses as
  417. // forming a tuple.
  418. auto TupleExpressionFromParenContents(
  419. Nonnull<Arena*> arena, SourceLocation source_loc,
  420. const ParenContents<Expression>& paren_contents) -> Nonnull<TupleLiteral*>;
  421. } // namespace Carbon
  422. #endif // EXECUTABLE_SEMANTICS_AST_EXPRESSION_H_