Factor out a Pattern sum type from Expression (#685)

`Pattern` is intended to pilot some changes I would like to apply to all our sum types:
- The alternatives are expressed as derived classes rather than members of a `std::variant`.
- The alternatives are classes in the [style guide sense](https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes), meaning they can have invariants, but can't have public data members.
- Creating an object is expressed using a constructor rather than a factory function.
- Accessing an alternative is expressed as a cast (using LLVM's RTTI system) rather than `std::get` or a `Get` method.

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This commit is contained in:
Geoff Romer
2021-07-30 12:24:12 -07:00
committed by GitHub
co-authored by Jon Meow
parent b08f6bb0f1
commit 6ac3adfa53
31 changed files with 1302 additions and 575 deletions
+21 -49
View File
@@ -4,6 +4,8 @@
#include "executable_semantics/ast/expression.h"
#include <optional>
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/error.h"
#include "llvm/ADT/StringExtras.h"
@@ -11,6 +13,24 @@
namespace Carbon {
auto ExpressionFromParenContents(
int line_num, const ParenContents<Expression>& paren_contents)
-> const Expression* {
std::optional<const Expression*> single_term = paren_contents.SingleTerm();
if (single_term.has_value()) {
return *single_term;
} else {
return TupleExpressionFromParenContents(line_num, paren_contents);
}
}
auto TupleExpressionFromParenContents(
int line_num, const ParenContents<Expression>& paren_contents)
-> const Expression* {
return Expression::MakeTupleLiteral(
line_num, paren_contents.TupleElements<FieldInitializer>(line_num));
}
auto Expression::GetIdentifierExpression() const
-> const IdentifierExpression& {
return std::get<IdentifierExpression>(value);
@@ -25,10 +45,6 @@ auto Expression::GetIndexExpression() const -> const IndexExpression& {
return std::get<IndexExpression>(value);
}
auto Expression::GetBindingExpression() const -> const BindingExpression& {
return std::get<BindingExpression>(value);
}
auto Expression::GetIntLiteral() const -> int {
return std::get<IntLiteral>(value).value;
}
@@ -75,13 +91,6 @@ auto Expression::MakeBoolTypeLiteral(int line_num) -> const Expression* {
return t;
}
auto Expression::MakeAutoTypeLiteral(int line_num) -> const Expression* {
auto* t = global_arena->New<Expression>();
t->line_num = line_num;
t->value = AutoTypeLiteral();
return t;
}
// Returns a Continuation type AST node at the given source location.
auto Expression::MakeContinuationTypeLiteral(int line_num)
-> const Expression* {
@@ -108,16 +117,6 @@ auto Expression::MakeIdentifierExpression(int line_num, std::string var)
return v;
}
auto Expression::MakeBindingExpression(int line_num,
std::optional<std::string> var,
const Expression* type)
-> const Expression* {
auto* v = global_arena->New<Expression>();
v->line_num = line_num;
v->value = BindingExpression({.name = std::move(var), .type = type});
return v;
}
auto Expression::MakeIntLiteral(int line_num, int i) -> const Expression* {
auto* e = global_arena->New<Expression>();
e->line_num = line_num;
@@ -166,21 +165,7 @@ auto Expression::MakeTupleLiteral(int line_num,
-> const Expression* {
auto* e = global_arena->New<Expression>();
e->line_num = line_num;
int i = 0;
bool seen_named_member = false;
for (auto& arg : args) {
if (arg.name == "") {
if (seen_named_member) {
FATAL_USER_ERROR(line_num)
<< "positional members must come before named members";
}
arg.name = std::to_string(i);
++i;
} else {
seen_named_member = true;
}
}
e->value = TupleLiteral({.fields = args});
e->value = TupleLiteral({.fields = std::move(args)});
return e;
}
@@ -269,16 +254,6 @@ void Expression::Print(llvm::raw_ostream& out) const {
case ExpressionKind::IdentifierExpression:
out << GetIdentifierExpression().name;
break;
case ExpressionKind::BindingExpression: {
const BindingExpression& binding = GetBindingExpression();
if (binding.name.has_value()) {
out << *binding.name;
} else {
out << "_";
}
out << ": " << *binding.type;
break;
}
case ExpressionKind::CallExpression:
out << *GetCallExpression().function;
if (GetCallExpression().argument->tag() == ExpressionKind::TupleLiteral) {
@@ -296,9 +271,6 @@ void Expression::Print(llvm::raw_ostream& out) const {
case ExpressionKind::TypeTypeLiteral:
out << "Type";
break;
case ExpressionKind::AutoTypeLiteral:
out << "auto";
break;
case ExpressionKind::ContinuationTypeLiteral:
out << "Continuation";
break;