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
+13 -9
View File
@@ -15,6 +15,7 @@
#include "executable_semantics/ast/pattern.h"
#include "executable_semantics/ast/source_location.h"
#include "executable_semantics/common/nonnull.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
namespace Carbon {
@@ -60,7 +61,7 @@ class Declaration {
class FunctionDeclaration : public Declaration {
public:
FunctionDeclaration(Nonnull<const FunctionDefinition*> definition)
FunctionDeclaration(Nonnull<FunctionDefinition*> definition)
: Declaration(Kind::FunctionDeclaration, definition->source_loc()),
definition(definition) {}
@@ -69,9 +70,10 @@ class FunctionDeclaration : public Declaration {
}
auto Definition() const -> const FunctionDefinition& { return *definition; }
auto Definition() -> FunctionDefinition& { return *definition; }
private:
Nonnull<const FunctionDefinition*> definition;
Nonnull<FunctionDefinition*> definition;
};
class ClassDeclaration : public Declaration {
@@ -88,6 +90,7 @@ class ClassDeclaration : public Declaration {
}
auto Definition() const -> const ClassDefinition& { return definition; }
auto Definition() -> ClassDefinition& { return definition; }
private:
ClassDefinition definition;
@@ -97,7 +100,7 @@ class ChoiceDeclaration : public Declaration {
public:
class Alternative {
public:
Alternative(std::string name, Nonnull<const Expression*> signature)
Alternative(std::string name, Nonnull<Expression*> signature)
: name_(name), signature_(signature) {}
auto name() const -> const std::string& { return name_; }
@@ -105,7 +108,7 @@ class ChoiceDeclaration : public Declaration {
private:
std::string name_;
Nonnull<const Expression*> signature_;
Nonnull<Expression*> signature_;
};
ChoiceDeclaration(SourceLocation loc, std::string name,
@@ -131,9 +134,8 @@ class ChoiceDeclaration : public Declaration {
// Global variable definition implements the Declaration concept.
class VariableDeclaration : public Declaration {
public:
VariableDeclaration(SourceLocation loc,
Nonnull<const BindingPattern*> binding,
Nonnull<const Expression*> initializer)
VariableDeclaration(SourceLocation loc, Nonnull<BindingPattern*> binding,
Nonnull<Expression*> initializer)
: Declaration(Kind::VariableDeclaration, loc),
binding(binding),
initializer(initializer) {}
@@ -143,14 +145,16 @@ class VariableDeclaration : public Declaration {
}
auto Binding() const -> Nonnull<const BindingPattern*> { return binding; }
auto Binding() -> Nonnull<BindingPattern*> { return binding; }
auto Initializer() const -> Nonnull<const Expression*> { return initializer; }
auto Initializer() -> Nonnull<Expression*> { return initializer; }
private:
// TODO: split this into a non-optional name and a type, initialized by
// a constructor that takes a BindingPattern and handles errors like a
// missing name.
Nonnull<const BindingPattern*> binding;
Nonnull<const Expression*> initializer;
Nonnull<BindingPattern*> binding;
Nonnull<Expression*> initializer;
};
} // namespace Carbon