Make the AST mutable (#849)

The code is pretty intertwined: having the AST be truly mutable means (to me) changing parser.ypp to return non-const values, but then the way things are passed around between objects should be non-const (particularly an issue with lists), which then creates issues with construction of lists in the TypeChecker, which then TypeChecker needs to mostly be non-const.

Due to the difficulties in breaking this apart, whereas I'd previously considering refactoring accessor naming in the same PR, I've largely avoided doing so. The intent is then that this PR focuses mainly on const -> non-const AST behavior.

call_main moves out of interpreter.cpp so that interpreter.cpp can receive a fully const AST.
This commit is contained in:
Jon Meow
2021-09-27 10:57:31 -07:00
committed by GitHub
parent 721743bc58
commit 04ab30f231
15 changed files with 282 additions and 270 deletions
+22 -16
View File
@@ -12,6 +12,7 @@
#include "common/ostream.h"
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/source_location.h"
#include "llvm/ADT/ArrayRef.h"
namespace Carbon {
@@ -71,7 +72,7 @@ class AutoPattern : public Pattern {
class BindingPattern : public Pattern {
public:
BindingPattern(SourceLocation loc, std::optional<std::string> name,
Nonnull<const Pattern*> type)
Nonnull<Pattern*> type)
: Pattern(Kind::BindingPattern, loc), name(std::move(name)), type(type) {}
static auto classof(const Pattern* pattern) -> bool {
@@ -83,10 +84,11 @@ class BindingPattern : public Pattern {
// The pattern specifying the type of values that this pattern matches.
auto Type() const -> Nonnull<const Pattern*> { return type; }
auto Type() -> Nonnull<Pattern*> { return type; }
private:
std::optional<std::string> name;
Nonnull<const Pattern*> type;
Nonnull<Pattern*> type;
};
// A pattern that matches a tuple value field-wise.
@@ -94,14 +96,14 @@ 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)
Field(std::string name, Nonnull<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;
Nonnull<Pattern*> pattern;
};
TuplePattern(SourceLocation loc, std::vector<Field> fields)
@@ -111,13 +113,14 @@ class TuplePattern : public Pattern {
// ExpressionPattern.
//
// REQUIRES: tuple_literal->Tag() == Expression::Kind::TupleLiteral
TuplePattern(Nonnull<Arena*> arena, Nonnull<const Expression*> tuple_literal);
TuplePattern(Nonnull<Arena*> arena, Nonnull<Expression*> tuple_literal);
static auto classof(const Pattern* pattern) -> bool {
return pattern->Tag() == Kind::TuplePattern;
}
auto Fields() const -> const std::vector<Field>& { return fields; }
auto Fields() const -> llvm::ArrayRef<Field> { return fields; }
auto Fields() -> llvm::MutableArrayRef<Field> { return fields; }
private:
std::vector<Field> fields;
@@ -128,13 +131,13 @@ class TuplePattern : public Pattern {
// tuple otherwise.
auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
const ParenContents<Pattern>& paren_contents)
-> Nonnull<const Pattern*>;
-> Nonnull<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*>;
-> Nonnull<TuplePattern*>;
// Converts `contents` to ParenContents<Pattern> by replacing each Expression
// with an ExpressionPattern.
@@ -148,9 +151,9 @@ class AlternativePattern : public Pattern {
// 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,
AlternativePattern(SourceLocation loc, Nonnull<Expression*> choice_type,
std::string alternative_name,
Nonnull<const TuplePattern*> arguments)
Nonnull<TuplePattern*> arguments)
: Pattern(Kind::AlternativePattern, loc),
choice_type(choice_type),
alternative_name(std::move(alternative_name)),
@@ -158,30 +161,32 @@ class AlternativePattern : public Pattern {
// 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);
AlternativePattern(SourceLocation loc, Nonnull<Expression*> alternative,
Nonnull<TuplePattern*> arguments);
static auto classof(const Pattern* pattern) -> bool {
return pattern->Tag() == Kind::AlternativePattern;
}
auto ChoiceType() const -> Nonnull<const Expression*> { return choice_type; }
auto ChoiceType() -> Nonnull<Expression*> { return choice_type; }
auto AlternativeName() const -> const std::string& {
return alternative_name;
}
auto Arguments() const -> Nonnull<const TuplePattern*> { return arguments; }
auto Arguments() -> Nonnull<TuplePattern*> { return arguments; }
private:
Nonnull<const Expression*> choice_type;
Nonnull<Expression*> choice_type;
std::string alternative_name;
Nonnull<const TuplePattern*> arguments;
Nonnull<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)
ExpressionPattern(Nonnull<Expression*> expression)
: Pattern(Kind::ExpressionPattern, expression->SourceLoc()),
expression(expression) {}
@@ -190,9 +195,10 @@ class ExpressionPattern : public Pattern {
}
auto Expression() const -> Nonnull<const Expression*> { return expression; }
auto Expression() -> Nonnull<Carbon::Expression*> { return expression; }
private:
Nonnull<const Carbon::Expression*> expression;
Nonnull<Carbon::Expression*> expression;
};
} // namespace Carbon