pattern.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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/expression.h"
  11. #include "executable_semantics/ast/source_location.h"
  12. #include "llvm/ADT/ArrayRef.h"
  13. namespace Carbon {
  14. class Value;
  15. // Abstract base class of all AST nodes representing patterns.
  16. //
  17. // Pattern and its derived classes support LLVM-style RTTI, including
  18. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  19. // class derived from Pattern must provide a `classof` operation, and
  20. // every concrete derived class must have a corresponding enumerator
  21. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  22. // details.
  23. class Pattern {
  24. public:
  25. enum class Kind {
  26. AutoPattern,
  27. BindingPattern,
  28. TuplePattern,
  29. AlternativePattern,
  30. ExpressionPattern,
  31. };
  32. Pattern(const Pattern&) = delete;
  33. Pattern& operator=(const Pattern&) = delete;
  34. void Print(llvm::raw_ostream& out) const;
  35. LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
  36. // Returns the enumerator corresponding to the most-derived type of this
  37. // object.
  38. auto kind() const -> Kind { return kind_; }
  39. auto source_loc() const -> SourceLocation { return source_loc_; }
  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. protected:
  50. // Constructs a Pattern representing syntax at the given line number.
  51. // `kind` must be the enumerator corresponding to the most-derived type being
  52. // constructed.
  53. Pattern(Kind kind, SourceLocation source_loc)
  54. : kind_(kind), source_loc_(source_loc) {}
  55. private:
  56. const Kind kind_;
  57. SourceLocation source_loc_;
  58. std::optional<Nonnull<const Value*>> static_type_;
  59. };
  60. // A pattern consisting of the `auto` keyword.
  61. class AutoPattern : public Pattern {
  62. public:
  63. explicit AutoPattern(SourceLocation source_loc)
  64. : Pattern(Kind::AutoPattern, source_loc) {}
  65. static auto classof(const Pattern* pattern) -> bool {
  66. return pattern->kind() == Kind::AutoPattern;
  67. }
  68. };
  69. // A pattern that matches a value of a specified type, and optionally binds
  70. // a name to it.
  71. class BindingPattern : public Pattern {
  72. public:
  73. BindingPattern(SourceLocation source_loc, std::optional<std::string> name,
  74. Nonnull<Pattern*> type)
  75. : Pattern(Kind::BindingPattern, source_loc),
  76. name(std::move(name)),
  77. type(type) {}
  78. static auto classof(const Pattern* pattern) -> bool {
  79. return pattern->kind() == Kind::BindingPattern;
  80. }
  81. // The name this pattern binds, if any.
  82. auto Name() const -> const std::optional<std::string>& { return name; }
  83. // The pattern specifying the type of values that this pattern matches.
  84. auto Type() const -> Nonnull<const Pattern*> { return type; }
  85. auto Type() -> Nonnull<Pattern*> { return type; }
  86. private:
  87. std::optional<std::string> name;
  88. Nonnull<Pattern*> type;
  89. };
  90. // A pattern that matches a tuple value field-wise.
  91. class TuplePattern : public Pattern {
  92. public:
  93. // Represents a portion of a tuple pattern corresponding to a single field.
  94. struct Field {
  95. Field(std::string name, Nonnull<Pattern*> pattern)
  96. : name(std::move(name)), pattern(pattern) {}
  97. // The field name. Cannot be empty
  98. std::string name;
  99. // The pattern the field must match.
  100. Nonnull<Pattern*> pattern;
  101. };
  102. TuplePattern(SourceLocation source_loc, std::vector<Field> fields)
  103. : Pattern(Kind::TuplePattern, source_loc), fields(std::move(fields)) {}
  104. static auto classof(const Pattern* pattern) -> bool {
  105. return pattern->kind() == Kind::TuplePattern;
  106. }
  107. auto Fields() const -> llvm::ArrayRef<Field> { return fields; }
  108. auto Fields() -> llvm::MutableArrayRef<Field> { return fields; }
  109. private:
  110. std::vector<Field> fields;
  111. };
  112. // Converts paren_contents to a Pattern, interpreting the parentheses as
  113. // grouping if their contents permit that interpretation, or as forming a
  114. // tuple otherwise.
  115. auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation source_loc,
  116. const ParenContents<Pattern>& paren_contents)
  117. -> Nonnull<Pattern*>;
  118. // Converts paren_contents to a TuplePattern, interpreting the parentheses as
  119. // forming a tuple.
  120. auto TuplePatternFromParenContents(Nonnull<Arena*> arena,
  121. SourceLocation source_loc,
  122. const ParenContents<Pattern>& paren_contents)
  123. -> Nonnull<TuplePattern*>;
  124. // Converts `contents` to ParenContents<Pattern> by replacing each Expression
  125. // with an ExpressionPattern.
  126. auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
  127. const ParenContents<Expression>& contents)
  128. -> ParenContents<Pattern>;
  129. // A pattern that matches an alternative of a choice type.
  130. class AlternativePattern : public Pattern {
  131. public:
  132. // Constructs an AlternativePattern that matches a value of the type
  133. // specified by choice_type if it represents an alternative named
  134. // alternative_name, and its arguments match `arguments`.
  135. AlternativePattern(SourceLocation source_loc,
  136. Nonnull<Expression*> choice_type,
  137. std::string alternative_name,
  138. Nonnull<TuplePattern*> arguments)
  139. : Pattern(Kind::AlternativePattern, source_loc),
  140. choice_type(choice_type),
  141. alternative_name(std::move(alternative_name)),
  142. arguments(arguments) {}
  143. // Constructs an AlternativePattern that matches the alternative specified
  144. // by `alternative`, if its arguments match `arguments`.
  145. AlternativePattern(SourceLocation source_loc,
  146. Nonnull<Expression*> alternative,
  147. Nonnull<TuplePattern*> arguments);
  148. static auto classof(const Pattern* pattern) -> bool {
  149. return pattern->kind() == Kind::AlternativePattern;
  150. }
  151. auto ChoiceType() const -> Nonnull<const Expression*> { return choice_type; }
  152. auto ChoiceType() -> Nonnull<Expression*> { return choice_type; }
  153. auto AlternativeName() const -> const std::string& {
  154. return alternative_name;
  155. }
  156. auto Arguments() const -> Nonnull<const TuplePattern*> { return arguments; }
  157. auto Arguments() -> Nonnull<TuplePattern*> { return arguments; }
  158. private:
  159. Nonnull<Expression*> choice_type;
  160. std::string alternative_name;
  161. Nonnull<TuplePattern*> arguments;
  162. };
  163. // A pattern that matches a value if it is equal to the value of a given
  164. // expression.
  165. class ExpressionPattern : public Pattern {
  166. public:
  167. ExpressionPattern(Nonnull<Expression*> expression)
  168. : Pattern(Kind::ExpressionPattern, expression->source_loc()),
  169. expression(expression) {}
  170. static auto classof(const Pattern* pattern) -> bool {
  171. return pattern->kind() == Kind::ExpressionPattern;
  172. }
  173. auto Expression() const -> Nonnull<const Expression*> { return expression; }
  174. auto Expression() -> Nonnull<Carbon::Expression*> { return expression; }
  175. private:
  176. Nonnull<Carbon::Expression*> expression;
  177. };
  178. } // namespace Carbon
  179. #endif // EXECUTABLE_SEMANTICS_AST_PATTERN_H_