| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #ifndef EXECUTABLE_SEMANTICS_AST_PATTERN_H_
- #define EXECUTABLE_SEMANTICS_AST_PATTERN_H_
- #include <optional>
- #include <string>
- #include <vector>
- #include "common/ostream.h"
- #include "executable_semantics/ast/expression.h"
- #include "executable_semantics/ast/source_location.h"
- namespace Carbon {
- // Abstract base class of all AST nodes representing patterns.
- //
- // Pattern and its derived classes support LLVM-style RTTI, including
- // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
- // class derived from Pattern must provide a `classof` operation, and
- // every concrete derived class must have a corresponding enumerator
- // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
- // details.
- class Pattern {
- public:
- enum class Kind {
- AutoPattern,
- BindingPattern,
- TuplePattern,
- AlternativePattern,
- ExpressionPattern,
- };
- Pattern(const Pattern&) = delete;
- Pattern& operator=(const Pattern&) = delete;
- // Returns the enumerator corresponding to the most-derived type of this
- // object.
- auto Tag() const -> Kind { return tag; }
- auto SourceLoc() const -> SourceLocation { return loc; }
- void Print(llvm::raw_ostream& out) const;
- LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
- protected:
- // Constructs a Pattern representing syntax at the given line number.
- // `tag` must be the enumerator corresponding to the most-derived type being
- // constructed.
- Pattern(Kind tag, SourceLocation loc) : tag(tag), loc(loc) {}
- private:
- const Kind tag;
- SourceLocation loc;
- };
- // A pattern consisting of the `auto` keyword.
- class AutoPattern : public Pattern {
- public:
- explicit AutoPattern(SourceLocation loc) : Pattern(Kind::AutoPattern, loc) {}
- static auto classof(const Pattern* pattern) -> bool {
- return pattern->Tag() == Kind::AutoPattern;
- }
- };
- // A pattern that matches a value of a specified type, and optionally binds
- // a name to it.
- class BindingPattern : public Pattern {
- public:
- BindingPattern(SourceLocation loc, std::optional<std::string> name,
- Nonnull<const Pattern*> type)
- : Pattern(Kind::BindingPattern, loc), name(std::move(name)), type(type) {}
- static auto classof(const Pattern* pattern) -> bool {
- return pattern->Tag() == Kind::BindingPattern;
- }
- // The name this pattern binds, if any.
- auto Name() const -> const std::optional<std::string>& { return name; }
- // The pattern specifying the type of values that this pattern matches.
- auto Type() const -> Nonnull<const Pattern*> { return type; }
- private:
- std::optional<std::string> name;
- Nonnull<const Pattern*> type;
- };
- // A pattern that matches a tuple value field-wise.
- class TuplePattern : public Pattern {
- public:
- // Represents a portion of a tuple pattern corresponding to a single field.
- struct Field {
- Field(std::string name, Nonnull<const Pattern*> pattern)
- : name(std::move(name)), pattern(pattern) {}
- // The field name. Cannot be empty
- std::string name;
- // The pattern the field must match.
- Nonnull<const Pattern*> pattern;
- };
- TuplePattern(SourceLocation loc, std::vector<Field> fields)
- : Pattern(Kind::TuplePattern, loc), fields(std::move(fields)) {}
- // Converts tuple_literal to a TuplePattern, by wrapping each field in an
- // ExpressionPattern.
- //
- // REQUIRES: tuple_literal->Tag() == Expression::Kind::TupleLiteral
- TuplePattern(Nonnull<Arena*> arena, Nonnull<const Expression*> tuple_literal);
- static auto classof(const Pattern* pattern) -> bool {
- return pattern->Tag() == Kind::TuplePattern;
- }
- auto Fields() const -> const std::vector<Field>& { return fields; }
- private:
- std::vector<Field> fields;
- };
- // Converts paren_contents to a Pattern, interpreting the parentheses as
- // grouping if their contents permit that interpretation, or as forming a
- // tuple otherwise.
- auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
- const ParenContents<Pattern>& paren_contents)
- -> Nonnull<const Pattern*>;
- // Converts paren_contents to a TuplePattern, interpreting the parentheses as
- // forming a tuple.
- auto TuplePatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
- const ParenContents<Pattern>& paren_contents)
- -> Nonnull<const TuplePattern*>;
- // Converts `contents` to ParenContents<Pattern> by replacing each Expression
- // with an ExpressionPattern.
- auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
- const ParenContents<Expression>& contents)
- -> ParenContents<Pattern>;
- // A pattern that matches an alternative of a choice type.
- class AlternativePattern : public Pattern {
- public:
- // Constructs an AlternativePattern that matches a value of the type
- // specified by choice_type if it represents an alternative named
- // alternative_name, and its arguments match `arguments`.
- AlternativePattern(SourceLocation loc, Nonnull<const Expression*> choice_type,
- std::string alternative_name,
- Nonnull<const TuplePattern*> arguments)
- : Pattern(Kind::AlternativePattern, loc),
- choice_type(choice_type),
- alternative_name(std::move(alternative_name)),
- arguments(arguments) {}
- // Constructs an AlternativePattern that matches the alternative specified
- // by `alternative`, if its arguments match `arguments`.
- AlternativePattern(SourceLocation loc, Nonnull<const Expression*> alternative,
- Nonnull<const TuplePattern*> arguments);
- static auto classof(const Pattern* pattern) -> bool {
- return pattern->Tag() == Kind::AlternativePattern;
- }
- auto ChoiceType() const -> Nonnull<const Expression*> { return choice_type; }
- auto AlternativeName() const -> const std::string& {
- return alternative_name;
- }
- auto Arguments() const -> Nonnull<const TuplePattern*> { return arguments; }
- private:
- Nonnull<const Expression*> choice_type;
- std::string alternative_name;
- Nonnull<const TuplePattern*> arguments;
- };
- // A pattern that matches a value if it is equal to the value of a given
- // expression.
- class ExpressionPattern : public Pattern {
- public:
- ExpressionPattern(Nonnull<const Expression*> expression)
- : Pattern(Kind::ExpressionPattern, expression->SourceLoc()),
- expression(expression) {}
- static auto classof(const Pattern* pattern) -> bool {
- return pattern->Tag() == Kind::ExpressionPattern;
- }
- auto Expression() const -> Nonnull<const Expression*> { return expression; }
- private:
- Nonnull<const Carbon::Expression*> expression;
- };
- } // namespace Carbon
- #endif // EXECUTABLE_SEMANTICS_AST_PATTERN_H_
|