mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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:
@@ -14,6 +14,7 @@
|
||||
#include "executable_semantics/ast/paren_contents.h"
|
||||
#include "executable_semantics/ast/source_location.h"
|
||||
#include "executable_semantics/common/arena.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -64,26 +65,24 @@ class Expression {
|
||||
// tuple otherwise.
|
||||
auto ExpressionFromParenContents(
|
||||
Nonnull<Arena*> arena, SourceLocation loc,
|
||||
const ParenContents<Expression>& paren_contents)
|
||||
-> Nonnull<const Expression*>;
|
||||
const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*>;
|
||||
|
||||
// Converts paren_contents to an Expression, interpreting the parentheses as
|
||||
// forming a tuple.
|
||||
auto TupleExpressionFromParenContents(
|
||||
Nonnull<Arena*> arena, SourceLocation loc,
|
||||
const ParenContents<Expression>& paren_contents)
|
||||
-> Nonnull<const Expression*>;
|
||||
const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*>;
|
||||
|
||||
// A FieldInitializer represents the initialization of a single tuple field.
|
||||
struct FieldInitializer {
|
||||
FieldInitializer(std::string name, Nonnull<const Expression*> expression)
|
||||
FieldInitializer(std::string name, Nonnull<Expression*> expression)
|
||||
: name(std::move(name)), expression(expression) {}
|
||||
|
||||
// The field name. Cannot be empty.
|
||||
std::string name;
|
||||
|
||||
// The expression that initializes the field.
|
||||
Nonnull<const Expression*> expression;
|
||||
Nonnull<Expression*> expression;
|
||||
};
|
||||
|
||||
enum class Operator {
|
||||
@@ -117,7 +116,7 @@ class IdentifierExpression : public Expression {
|
||||
class FieldAccessExpression : public Expression {
|
||||
public:
|
||||
explicit FieldAccessExpression(SourceLocation loc,
|
||||
Nonnull<const Expression*> aggregate,
|
||||
Nonnull<Expression*> aggregate,
|
||||
std::string field)
|
||||
: Expression(Kind::FieldAccessExpression, loc),
|
||||
aggregate(aggregate),
|
||||
@@ -128,18 +127,18 @@ class FieldAccessExpression : public Expression {
|
||||
}
|
||||
|
||||
auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
|
||||
auto Aggregate() -> Nonnull<Expression*> { return aggregate; }
|
||||
auto Field() const -> const std::string& { return field; }
|
||||
|
||||
private:
|
||||
Nonnull<const Expression*> aggregate;
|
||||
Nonnull<Expression*> aggregate;
|
||||
std::string field;
|
||||
};
|
||||
|
||||
class IndexExpression : public Expression {
|
||||
public:
|
||||
explicit IndexExpression(SourceLocation loc,
|
||||
Nonnull<const Expression*> aggregate,
|
||||
Nonnull<const Expression*> offset)
|
||||
explicit IndexExpression(SourceLocation loc, Nonnull<Expression*> aggregate,
|
||||
Nonnull<Expression*> offset)
|
||||
: Expression(Kind::IndexExpression, loc),
|
||||
aggregate(aggregate),
|
||||
offset(offset) {}
|
||||
@@ -149,11 +148,13 @@ class IndexExpression : public Expression {
|
||||
}
|
||||
|
||||
auto Aggregate() const -> Nonnull<const Expression*> { return aggregate; }
|
||||
auto Aggregate() -> Nonnull<Expression*> { return aggregate; }
|
||||
auto Offset() const -> Nonnull<const Expression*> { return offset; }
|
||||
auto Offset() -> Nonnull<Expression*> { return offset; }
|
||||
|
||||
private:
|
||||
Nonnull<const Expression*> aggregate;
|
||||
Nonnull<const Expression*> offset;
|
||||
Nonnull<Expression*> aggregate;
|
||||
Nonnull<Expression*> offset;
|
||||
};
|
||||
|
||||
class IntLiteral : public Expression {
|
||||
@@ -233,7 +234,7 @@ class PrimitiveOperatorExpression : public Expression {
|
||||
public:
|
||||
explicit PrimitiveOperatorExpression(
|
||||
SourceLocation loc, Operator op,
|
||||
std::vector<Nonnull<const Expression*>> arguments)
|
||||
std::vector<Nonnull<Expression*>> arguments)
|
||||
: Expression(Kind::PrimitiveOperatorExpression, loc),
|
||||
op(op),
|
||||
arguments(std::move(arguments)) {}
|
||||
@@ -243,20 +244,22 @@ class PrimitiveOperatorExpression : public Expression {
|
||||
}
|
||||
|
||||
auto Op() const -> Operator { return op; }
|
||||
auto Arguments() const -> const std::vector<Nonnull<const Expression*>>& {
|
||||
auto Arguments() const -> llvm::ArrayRef<Nonnull<Expression*>> {
|
||||
return arguments;
|
||||
}
|
||||
auto Arguments() -> llvm::MutableArrayRef<Nonnull<Expression*>> {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
private:
|
||||
Operator op;
|
||||
std::vector<Nonnull<const Expression*>> arguments;
|
||||
std::vector<Nonnull<Expression*>> arguments;
|
||||
};
|
||||
|
||||
class CallExpression : public Expression {
|
||||
public:
|
||||
explicit CallExpression(SourceLocation loc,
|
||||
Nonnull<const Expression*> function,
|
||||
Nonnull<const Expression*> argument)
|
||||
explicit CallExpression(SourceLocation loc, Nonnull<Expression*> function,
|
||||
Nonnull<Expression*> argument)
|
||||
: Expression(Kind::CallExpression, loc),
|
||||
function(function),
|
||||
argument(argument) {}
|
||||
@@ -266,18 +269,20 @@ class CallExpression : public Expression {
|
||||
}
|
||||
|
||||
auto Function() const -> Nonnull<const Expression*> { return function; }
|
||||
auto Function() -> Nonnull<Expression*> { return function; }
|
||||
auto Argument() const -> Nonnull<const Expression*> { return argument; }
|
||||
auto Argument() -> Nonnull<Expression*> { return argument; }
|
||||
|
||||
private:
|
||||
Nonnull<const Expression*> function;
|
||||
Nonnull<const Expression*> argument;
|
||||
Nonnull<Expression*> function;
|
||||
Nonnull<Expression*> argument;
|
||||
};
|
||||
|
||||
class FunctionTypeLiteral : public Expression {
|
||||
public:
|
||||
explicit FunctionTypeLiteral(SourceLocation loc,
|
||||
Nonnull<const Expression*> parameter,
|
||||
Nonnull<const Expression*> return_type,
|
||||
Nonnull<Expression*> parameter,
|
||||
Nonnull<Expression*> return_type,
|
||||
bool is_omitted_return_type)
|
||||
: Expression(Kind::FunctionTypeLiteral, loc),
|
||||
parameter(parameter),
|
||||
@@ -289,12 +294,14 @@ class FunctionTypeLiteral : public Expression {
|
||||
}
|
||||
|
||||
auto Parameter() const -> Nonnull<const Expression*> { return parameter; }
|
||||
auto Parameter() -> Nonnull<Expression*> { return parameter; }
|
||||
auto ReturnType() const -> Nonnull<const Expression*> { return return_type; }
|
||||
auto ReturnType() -> Nonnull<Expression*> { return return_type; }
|
||||
auto IsOmittedReturnType() const -> bool { return is_omitted_return_type; }
|
||||
|
||||
private:
|
||||
Nonnull<const Expression*> parameter;
|
||||
Nonnull<const Expression*> return_type;
|
||||
Nonnull<Expression*> parameter;
|
||||
Nonnull<Expression*> return_type;
|
||||
bool is_omitted_return_type;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user