pattern.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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_PATTERN_H_
  5. #define EXECUTABLE_SEMANTICS_AST_PATTERN_H_
  6. #include <optional>
  7. #include <string>
  8. #include <vector>
  9. #include "common/ostream.h"
  10. #include "executable_semantics/ast/ast_node.h"
  11. #include "executable_semantics/ast/ast_rtti.h"
  12. #include "executable_semantics/ast/expression.h"
  13. #include "executable_semantics/ast/source_location.h"
  14. #include "executable_semantics/ast/static_scope.h"
  15. #include "llvm/ADT/ArrayRef.h"
  16. namespace Carbon {
  17. class Value;
  18. // Abstract base class of all AST nodes representing patterns.
  19. //
  20. // Pattern and its derived classes support LLVM-style RTTI, including
  21. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  22. // class derived from Pattern must provide a `classof` operation, and
  23. // every concrete derived class must have a corresponding enumerator
  24. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  25. // details.
  26. class Pattern : public AstNode {
  27. public:
  28. Pattern(const Pattern&) = delete;
  29. auto operator=(const Pattern&) -> Pattern& = delete;
  30. ~Pattern() override = 0;
  31. void Print(llvm::raw_ostream& out) const override;
  32. static auto classof(const AstNode* node) -> bool {
  33. return InheritsFromPattern(node->kind());
  34. }
  35. // Returns the enumerator corresponding to the most-derived type of this
  36. // object.
  37. auto kind() const -> PatternKind {
  38. return static_cast<PatternKind>(root_kind());
  39. }
  40. // The static type of this pattern. Cannot be called before typechecking.
  41. auto static_type() const -> const Value& { return **static_type_; }
  42. // Sets the static type of this expression. Can only be called once, during
  43. // typechecking.
  44. void set_static_type(Nonnull<const Value*> type) { static_type_ = type; }
  45. // Returns whether the static type has been set. Should only be called
  46. // during typechecking: before typechecking it's guaranteed to be false,
  47. // and after typechecking it's guaranteed to be true.
  48. auto has_static_type() const -> bool { return static_type_.has_value(); }
  49. // The value of this pattern. Cannot be called before typechecking.
  50. auto value() const -> const Value& { return **value_; }
  51. // Sets the value of this pattern. Can only be called once, during
  52. // typechecking.
  53. void set_value(Nonnull<const Value*> value) { value_ = value; }
  54. // Returns whether the value has been set. Should only be called
  55. // during typechecking: before typechecking it's guaranteed to be false,
  56. // and after typechecking it's guaranteed to be true.
  57. auto has_value() const -> bool { return value_.has_value(); }
  58. protected:
  59. // Constructs a Pattern representing syntax at the given line number.
  60. // `kind` must be the enumerator corresponding to the most-derived type being
  61. // constructed.
  62. Pattern(AstNodeKind kind, SourceLocation source_loc)
  63. : AstNode(kind, source_loc) {}
  64. private:
  65. std::optional<Nonnull<const Value*>> static_type_;
  66. std::optional<Nonnull<const Value*>> value_;
  67. };
  68. // A pattern consisting of the `auto` keyword.
  69. class AutoPattern : public Pattern {
  70. public:
  71. explicit AutoPattern(SourceLocation source_loc)
  72. : Pattern(AstNodeKind::AutoPattern, source_loc) {}
  73. static auto classof(const AstNode* node) -> bool {
  74. return InheritsFromAutoPattern(node->kind());
  75. }
  76. };
  77. // A pattern that matches a value of a specified type, and optionally binds
  78. // a name to it.
  79. class BindingPattern : public Pattern {
  80. public:
  81. using ImplementsCarbonNamedEntity = void;
  82. BindingPattern(SourceLocation source_loc, std::string name,
  83. Nonnull<Pattern*> type)
  84. : Pattern(AstNodeKind::BindingPattern, source_loc),
  85. name_(std::move(name)),
  86. type_(type) {}
  87. static auto classof(const AstNode* node) -> bool {
  88. return InheritsFromBindingPattern(node->kind());
  89. }
  90. // The name this pattern binds, if any. If equal to AnonymousName, indicates
  91. // that this BindingPattern does not bind a name, which in turn means it
  92. // should not be used as a NamedEntity.
  93. auto name() const -> const std::string& { return name_; }
  94. // The pattern specifying the type of values that this pattern matches.
  95. auto type() const -> const Pattern& { return *type_; }
  96. auto type() -> Pattern& { return *type_; }
  97. auto value_category() const -> ValueCategory { return ValueCategory::Var; }
  98. private:
  99. std::string name_;
  100. Nonnull<Pattern*> type_;
  101. };
  102. // A pattern that matches a tuple value field-wise.
  103. class TuplePattern : public Pattern {
  104. public:
  105. TuplePattern(SourceLocation source_loc, std::vector<Nonnull<Pattern*>> fields)
  106. : Pattern(AstNodeKind::TuplePattern, source_loc),
  107. fields_(std::move(fields)) {}
  108. static auto classof(const AstNode* node) -> bool {
  109. return InheritsFromTuplePattern(node->kind());
  110. }
  111. auto fields() const -> llvm::ArrayRef<Nonnull<const Pattern*>> {
  112. return fields_;
  113. }
  114. auto fields() -> llvm::ArrayRef<Nonnull<Pattern*>> { return fields_; }
  115. private:
  116. std::vector<Nonnull<Pattern*>> fields_;
  117. };
  118. // Converts paren_contents to a Pattern, interpreting the parentheses as
  119. // grouping if their contents permit that interpretation, or as forming a
  120. // tuple otherwise.
  121. auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation source_loc,
  122. const ParenContents<Pattern>& paren_contents)
  123. -> Nonnull<Pattern*>;
  124. // Converts paren_contents to a TuplePattern, interpreting the parentheses as
  125. // forming a tuple.
  126. auto TuplePatternFromParenContents(Nonnull<Arena*> arena,
  127. SourceLocation source_loc,
  128. const ParenContents<Pattern>& paren_contents)
  129. -> Nonnull<TuplePattern*>;
  130. // Converts `contents` to ParenContents<Pattern> by replacing each Expression
  131. // with an ExpressionPattern.
  132. auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
  133. const ParenContents<Expression>& contents)
  134. -> ParenContents<Pattern>;
  135. // A pattern that matches an alternative of a choice type.
  136. class AlternativePattern : public Pattern {
  137. public:
  138. // Constructs an AlternativePattern that matches a value of the type
  139. // specified by choice_type if it represents an alternative named
  140. // alternative_name, and its arguments match `arguments`.
  141. AlternativePattern(SourceLocation source_loc,
  142. Nonnull<Expression*> choice_type,
  143. std::string alternative_name,
  144. Nonnull<TuplePattern*> arguments)
  145. : Pattern(AstNodeKind::AlternativePattern, source_loc),
  146. choice_type_(choice_type),
  147. alternative_name_(std::move(alternative_name)),
  148. arguments_(arguments) {}
  149. // Constructs an AlternativePattern that matches the alternative specified
  150. // by `alternative`, if its arguments match `arguments`.
  151. AlternativePattern(SourceLocation source_loc,
  152. Nonnull<Expression*> alternative,
  153. Nonnull<TuplePattern*> arguments);
  154. static auto classof(const AstNode* node) -> bool {
  155. return InheritsFromAlternativePattern(node->kind());
  156. }
  157. auto choice_type() const -> const Expression& { return *choice_type_; }
  158. auto choice_type() -> Expression& { return *choice_type_; }
  159. auto alternative_name() const -> const std::string& {
  160. return alternative_name_;
  161. }
  162. auto arguments() const -> const TuplePattern& { return *arguments_; }
  163. auto arguments() -> TuplePattern& { return *arguments_; }
  164. private:
  165. Nonnull<Expression*> choice_type_;
  166. std::string alternative_name_;
  167. Nonnull<TuplePattern*> arguments_;
  168. };
  169. // A pattern that matches a value if it is equal to the value of a given
  170. // expression.
  171. class ExpressionPattern : public Pattern {
  172. public:
  173. explicit ExpressionPattern(Nonnull<Expression*> expression)
  174. : Pattern(AstNodeKind::ExpressionPattern, expression->source_loc()),
  175. expression_(expression) {}
  176. static auto classof(const AstNode* node) -> bool {
  177. return InheritsFromExpressionPattern(node->kind());
  178. }
  179. auto expression() const -> const Expression& { return *expression_; }
  180. auto expression() -> Expression& { return *expression_; }
  181. private:
  182. Nonnull<Expression*> expression_;
  183. };
  184. } // namespace Carbon
  185. #endif // EXECUTABLE_SEMANTICS_AST_PATTERN_H_