pattern.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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 CARBON_EXPLORER_AST_PATTERN_H_
  5. #define CARBON_EXPLORER_AST_PATTERN_H_
  6. #include <optional>
  7. #include <string>
  8. #include <vector>
  9. #include "common/ostream.h"
  10. #include "explorer/ast/ast_node.h"
  11. #include "explorer/ast/ast_rtti.h"
  12. #include "explorer/ast/expression.h"
  13. #include "explorer/ast/value_category.h"
  14. #include "explorer/ast/value_node.h"
  15. #include "explorer/common/source_location.h"
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/STLFunctionalExtras.h"
  18. namespace Carbon {
  19. class Value;
  20. // Abstract base class of all AST nodes representing patterns.
  21. //
  22. // Pattern and its derived classes support LLVM-style RTTI, including
  23. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  24. // class derived from Pattern must provide a `classof` operation, and
  25. // every concrete derived class must have a corresponding enumerator
  26. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  27. // details.
  28. class Pattern : public AstNode {
  29. public:
  30. Pattern(const Pattern&) = delete;
  31. auto operator=(const Pattern&) -> Pattern& = delete;
  32. ~Pattern() override = 0;
  33. void Print(llvm::raw_ostream& out) const override;
  34. void PrintID(llvm::raw_ostream& out) const override;
  35. static auto classof(const AstNode* node) -> bool {
  36. return InheritsFromPattern(node->kind());
  37. }
  38. // Returns the enumerator corresponding to the most-derived type of this
  39. // object.
  40. auto kind() const -> PatternKind {
  41. return static_cast<PatternKind>(root_kind());
  42. }
  43. // The static type of this pattern. Cannot be called before typechecking.
  44. auto static_type() const -> const Value& {
  45. CARBON_CHECK(static_type_.has_value());
  46. return **static_type_;
  47. }
  48. auto has_static_type() const -> bool { return static_type_.has_value(); }
  49. // Sets the static type of this expression. Can only be called once, during
  50. // typechecking.
  51. void set_static_type(Nonnull<const Value*> type) {
  52. CARBON_CHECK(!static_type_.has_value());
  53. static_type_ = type;
  54. }
  55. // The value of this pattern. Cannot be called before typechecking.
  56. // TODO: Rename to avoid confusion with BindingPattern::constant_value
  57. auto value() const -> const Value& { return **value_; }
  58. // Sets the value of this pattern. Can only be called once, during
  59. // typechecking.
  60. void set_value(Nonnull<const Value*> value) {
  61. CARBON_CHECK(!value_) << "set_value called more than once";
  62. value_ = value;
  63. }
  64. // Returns whether the value has been set. Should only be called
  65. // during typechecking: before typechecking it's guaranteed to be false,
  66. // and after typechecking it's guaranteed to be true.
  67. auto has_value() const -> bool { return value_.has_value(); }
  68. // Determines whether the pattern has already been type-checked. Should
  69. // only be used by type-checking.
  70. auto is_type_checked() const -> bool {
  71. return static_type_.has_value() && value_.has_value();
  72. }
  73. protected:
  74. // Constructs a Pattern representing syntax at the given line number.
  75. // `kind` must be the enumerator corresponding to the most-derived type being
  76. // constructed.
  77. Pattern(AstNodeKind kind, SourceLocation source_loc)
  78. : AstNode(kind, source_loc) {}
  79. private:
  80. std::optional<Nonnull<const Value*>> static_type_;
  81. std::optional<Nonnull<const Value*>> value_;
  82. };
  83. // Call the given `visitor` on all patterns nested within the given pattern,
  84. // including `pattern` itself. Aborts and returns `false` if `visitor` returns
  85. // `false`, otherwise returns `true`.
  86. auto VisitNestedPatterns(const Pattern& pattern,
  87. llvm::function_ref<bool(const Pattern&)> visitor)
  88. -> bool;
  89. // A pattern consisting of the `auto` keyword.
  90. class AutoPattern : public Pattern {
  91. public:
  92. explicit AutoPattern(SourceLocation source_loc)
  93. : Pattern(AstNodeKind::AutoPattern, source_loc) {}
  94. static auto classof(const AstNode* node) -> bool {
  95. return InheritsFromAutoPattern(node->kind());
  96. }
  97. };
  98. class VarPattern : public Pattern {
  99. public:
  100. explicit VarPattern(SourceLocation source_loc, Nonnull<Pattern*> pattern)
  101. : Pattern(AstNodeKind::VarPattern, source_loc), pattern_(pattern) {}
  102. static auto classof(const AstNode* node) -> bool {
  103. return InheritsFromVarPattern(node->kind());
  104. }
  105. auto pattern() const -> const Pattern& { return *pattern_; }
  106. auto pattern() -> Pattern& { return *pattern_; }
  107. auto value_category() const -> ValueCategory { return ValueCategory::Var; }
  108. private:
  109. Nonnull<Pattern*> pattern_;
  110. };
  111. // A pattern that matches a value of a specified type, and optionally binds
  112. // a name to it.
  113. class BindingPattern : public Pattern {
  114. public:
  115. using ImplementsCarbonValueNode = void;
  116. BindingPattern(SourceLocation source_loc, std::string name,
  117. Nonnull<Pattern*> type,
  118. std::optional<ValueCategory> value_category)
  119. : Pattern(AstNodeKind::BindingPattern, source_loc),
  120. name_(std::move(name)),
  121. type_(type),
  122. value_category_(value_category) {}
  123. static auto classof(const AstNode* node) -> bool {
  124. return InheritsFromBindingPattern(node->kind());
  125. }
  126. // The name this pattern binds, if any. If equal to AnonymousName, indicates
  127. // that this BindingPattern does not bind a name, which in turn means it
  128. // should not be used as a ValueNode.
  129. auto name() const -> const std::string& { return name_; }
  130. // The pattern specifying the type of values that this pattern matches.
  131. auto type() const -> const Pattern& { return *type_; }
  132. auto type() -> Pattern& { return *type_; }
  133. // Returns the value category of this pattern. Can only be called after
  134. // typechecking.
  135. auto value_category() const -> ValueCategory {
  136. return value_category_.value();
  137. }
  138. // Returns whether the value category has been set. Should only be called
  139. // during typechecking.
  140. auto has_value_category() const -> bool {
  141. return value_category_.has_value();
  142. }
  143. // Sets the value category of the variable being bound. Can only be called
  144. // once during typechecking
  145. void set_value_category(ValueCategory vc) {
  146. CARBON_CHECK(!value_category_.has_value());
  147. value_category_ = vc;
  148. }
  149. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  150. return std::nullopt;
  151. }
  152. auto symbolic_identity() const -> std::optional<Nonnull<const Value*>> {
  153. return std::nullopt;
  154. }
  155. private:
  156. std::string name_;
  157. Nonnull<Pattern*> type_;
  158. std::optional<ValueCategory> value_category_;
  159. };
  160. class AddrPattern : public Pattern {
  161. public:
  162. explicit AddrPattern(SourceLocation source_loc,
  163. Nonnull<BindingPattern*> binding)
  164. : Pattern(AstNodeKind::AddrPattern, source_loc), binding_(binding) {}
  165. static auto classof(const AstNode* node) -> bool {
  166. return InheritsFromAddrPattern(node->kind());
  167. }
  168. auto binding() const -> const BindingPattern& { return *binding_; }
  169. auto binding() -> BindingPattern& { return *binding_; }
  170. private:
  171. Nonnull<BindingPattern*> binding_;
  172. };
  173. // A pattern that matches a tuple value field-wise.
  174. class TuplePattern : public Pattern {
  175. public:
  176. TuplePattern(SourceLocation source_loc, std::vector<Nonnull<Pattern*>> fields)
  177. : Pattern(AstNodeKind::TuplePattern, source_loc),
  178. fields_(std::move(fields)) {}
  179. static auto classof(const AstNode* node) -> bool {
  180. return InheritsFromTuplePattern(node->kind());
  181. }
  182. auto fields() const -> llvm::ArrayRef<Nonnull<const Pattern*>> {
  183. return fields_;
  184. }
  185. auto fields() -> llvm::ArrayRef<Nonnull<Pattern*>> { return fields_; }
  186. private:
  187. std::vector<Nonnull<Pattern*>> fields_;
  188. };
  189. class GenericBinding : public Pattern {
  190. public:
  191. using ImplementsCarbonValueNode = void;
  192. GenericBinding(SourceLocation source_loc, std::string name,
  193. Nonnull<Expression*> type)
  194. : Pattern(AstNodeKind::GenericBinding, source_loc),
  195. name_(std::move(name)),
  196. type_(type) {}
  197. void Print(llvm::raw_ostream& out) const override;
  198. void PrintID(llvm::raw_ostream& out) const override;
  199. static auto classof(const AstNode* node) -> bool {
  200. return InheritsFromGenericBinding(node->kind());
  201. }
  202. auto name() const -> const std::string& { return name_; }
  203. auto type() const -> const Expression& { return *type_; }
  204. auto type() -> Expression& { return *type_; }
  205. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  206. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  207. return std::nullopt;
  208. }
  209. auto symbolic_identity() const -> std::optional<Nonnull<const Value*>> {
  210. return symbolic_identity_;
  211. }
  212. void set_symbolic_identity(Nonnull<const Value*> value) {
  213. CARBON_CHECK(!symbolic_identity_.has_value());
  214. symbolic_identity_ = value;
  215. }
  216. // The impl binding associated with this type variable.
  217. auto impl_binding() const -> std::optional<Nonnull<const ImplBinding*>> {
  218. return impl_binding_;
  219. }
  220. // Set the impl binding.
  221. void set_impl_binding(Nonnull<const ImplBinding*> binding) {
  222. CARBON_CHECK(!impl_binding_.has_value());
  223. impl_binding_ = binding;
  224. }
  225. // Return the original generic binding.
  226. auto original() const -> Nonnull<const GenericBinding*> {
  227. if (original_.has_value()) {
  228. return *original_;
  229. } else {
  230. return this;
  231. }
  232. }
  233. // Set the original generic binding.
  234. void set_original(Nonnull<const GenericBinding*> orig) { original_ = orig; }
  235. // Returns whether this binding has been named as a type within its own type
  236. // expression via `.Self`. Set by type-checking.
  237. auto named_as_type_via_dot_self() const -> bool {
  238. return named_as_type_via_dot_self_;
  239. }
  240. // Set that this binding was named as a type within its own type expression
  241. // via `.Self`. May only be called during type-checking.
  242. void set_named_as_type_via_dot_self() { named_as_type_via_dot_self_ = true; }
  243. private:
  244. std::string name_;
  245. Nonnull<Expression*> type_;
  246. std::optional<Nonnull<const Value*>> symbolic_identity_;
  247. std::optional<Nonnull<const ImplBinding*>> impl_binding_;
  248. std::optional<Nonnull<const GenericBinding*>> original_;
  249. bool named_as_type_via_dot_self_ = false;
  250. };
  251. // Converts paren_contents to a Pattern, interpreting the parentheses as
  252. // grouping if their contents permit that interpretation, or as forming a
  253. // tuple otherwise.
  254. auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation source_loc,
  255. const ParenContents<Pattern>& paren_contents)
  256. -> Nonnull<Pattern*>;
  257. // Converts paren_contents to a TuplePattern, interpreting the parentheses as
  258. // forming a tuple.
  259. auto TuplePatternFromParenContents(Nonnull<Arena*> arena,
  260. SourceLocation source_loc,
  261. const ParenContents<Pattern>& paren_contents)
  262. -> Nonnull<TuplePattern*>;
  263. // Converts `contents` to ParenContents<Pattern> by replacing each Expression
  264. // with an ExpressionPattern.
  265. auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
  266. const ParenContents<Expression>& contents)
  267. -> ParenContents<Pattern>;
  268. // A pattern that matches an alternative of a choice type.
  269. class AlternativePattern : public Pattern {
  270. public:
  271. // Constructs an AlternativePattern that matches the alternative specified
  272. // by `alternative`, if its arguments match `arguments`.
  273. static auto Create(Nonnull<Arena*> arena, SourceLocation source_loc,
  274. Nonnull<Expression*> alternative,
  275. Nonnull<TuplePattern*> arguments)
  276. -> ErrorOr<Nonnull<AlternativePattern*>> {
  277. CARBON_ASSIGN_OR_RETURN(
  278. Nonnull<SimpleMemberAccessExpression*> member_access,
  279. RequireSimpleMemberAccess(alternative));
  280. return arena->New<AlternativePattern>(source_loc, &member_access->object(),
  281. member_access->member_name(),
  282. arguments);
  283. }
  284. // Constructs an AlternativePattern that matches a value of the type
  285. // specified by choice_type if it represents an alternative named
  286. // alternative_name, and its arguments match `arguments`.
  287. AlternativePattern(SourceLocation source_loc,
  288. Nonnull<Expression*> choice_type,
  289. std::string alternative_name,
  290. Nonnull<TuplePattern*> arguments)
  291. : Pattern(AstNodeKind::AlternativePattern, source_loc),
  292. choice_type_(choice_type),
  293. alternative_name_(std::move(alternative_name)),
  294. arguments_(arguments) {}
  295. static auto classof(const AstNode* node) -> bool {
  296. return InheritsFromAlternativePattern(node->kind());
  297. }
  298. auto choice_type() const -> const Expression& { return *choice_type_; }
  299. auto choice_type() -> Expression& { return *choice_type_; }
  300. auto alternative_name() const -> const std::string& {
  301. return alternative_name_;
  302. }
  303. auto arguments() const -> const TuplePattern& { return *arguments_; }
  304. auto arguments() -> TuplePattern& { return *arguments_; }
  305. private:
  306. static auto RequireSimpleMemberAccess(Nonnull<Expression*> alternative)
  307. -> ErrorOr<Nonnull<SimpleMemberAccessExpression*>>;
  308. Nonnull<Expression*> choice_type_;
  309. std::string alternative_name_;
  310. Nonnull<TuplePattern*> arguments_;
  311. };
  312. // A pattern that matches a value if it is equal to the value of a given
  313. // expression.
  314. class ExpressionPattern : public Pattern {
  315. public:
  316. explicit ExpressionPattern(Nonnull<Expression*> expression)
  317. : Pattern(AstNodeKind::ExpressionPattern, expression->source_loc()),
  318. expression_(expression) {}
  319. static auto classof(const AstNode* node) -> bool {
  320. return InheritsFromExpressionPattern(node->kind());
  321. }
  322. auto expression() const -> const Expression& { return *expression_; }
  323. auto expression() -> Expression& { return *expression_; }
  324. private:
  325. Nonnull<Expression*> expression_;
  326. };
  327. } // namespace Carbon
  328. #endif // CARBON_EXPLORER_AST_PATTERN_H_