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
+1 -1
View File
@@ -22,7 +22,7 @@ struct AST {
// Import directives.
std::vector<LibraryName> imports;
// The file's ordered declarations.
std::vector<Nonnull<const Declaration*>> declarations;
std::vector<Nonnull<Declaration*>> declarations;
};
} // namespace Carbon
+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
+3 -6
View File
@@ -18,10 +18,8 @@ using llvm::cast;
auto ExpressionFromParenContents(
Nonnull<Arena*> arena, SourceLocation loc,
const ParenContents<Expression>& paren_contents)
-> Nonnull<const Expression*> {
std::optional<Nonnull<const Expression*>> single_term =
paren_contents.SingleTerm();
const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*> {
std::optional<Nonnull<Expression*>> single_term = paren_contents.SingleTerm();
if (single_term.has_value()) {
return *single_term;
} else {
@@ -31,8 +29,7 @@ auto ExpressionFromParenContents(
auto TupleExpressionFromParenContents(
Nonnull<Arena*> arena, SourceLocation loc,
const ParenContents<Expression>& paren_contents)
-> Nonnull<const Expression*> {
const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*> {
return arena->New<TupleLiteral>(
loc, paren_contents.TupleElements<FieldInitializer>(loc));
}
+32 -25
View File
@@ -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;
};
@@ -26,13 +26,12 @@ class FunctionDefinition {
public:
FunctionDefinition(SourceLocation source_loc, std::string name,
std::vector<GenericBinding> deduced_params,
Nonnull<const TuplePattern*> param_pattern,
Nonnull<const Pattern*> return_type,
bool is_omitted_return_type,
std::optional<Nonnull<const Statement*>> body)
Nonnull<TuplePattern*> param_pattern,
Nonnull<Pattern*> return_type, bool is_omitted_return_type,
std::optional<Nonnull<Statement*>> body)
: source_loc_(source_loc),
name_(std::move(name)),
deduced_parameters_(deduced_params),
deduced_parameters_(std::move(deduced_params)),
param_pattern_(param_pattern),
return_type_(return_type),
is_omitted_return_type_(is_omitted_return_type),
@@ -48,6 +47,7 @@ class FunctionDefinition {
return deduced_parameters_;
}
auto param_pattern() const -> const TuplePattern& { return *param_pattern_; }
auto param_pattern() -> TuplePattern& { return *param_pattern_; }
auto return_type() const -> const Pattern& { return *return_type_; }
auto is_omitted_return_type() const -> bool {
return is_omitted_return_type_;
@@ -55,15 +55,16 @@ class FunctionDefinition {
auto body() const -> std::optional<Nonnull<const Statement*>> {
return body_;
}
auto body() -> std::optional<Nonnull<Statement*>> { return body_; }
private:
SourceLocation source_loc_;
std::string name_;
std::vector<GenericBinding> deduced_parameters_;
Nonnull<const TuplePattern*> param_pattern_;
Nonnull<const Pattern*> return_type_;
Nonnull<TuplePattern*> param_pattern_;
Nonnull<Pattern*> return_type_;
bool is_omitted_return_type_;
std::optional<Nonnull<const Statement*>> body_;
std::optional<Nonnull<Statement*>> body_;
};
} // namespace Carbon
+4 -5
View File
@@ -28,16 +28,16 @@ template <typename Term>
struct ParenContents {
struct Element {
std::optional<std::string> name;
Nonnull<const Term*> term;
Nonnull<Term*> term;
};
// If this object represents a single term, with no name and no trailing
// comma, this method returns that term. This typically means the parentheses
// can be interpreted as grouping.
auto SingleTerm() const -> std::optional<Nonnull<const Term*>>;
auto SingleTerm() const -> std::optional<Nonnull<Term*>>;
// Converts `elements` to std::vector<TupleElement>. TupleElement must
// have a constructor that takes a std::string and a Nonnull<const Term*>.
// have a constructor that takes a std::string and a Nonnull<Term*>.
//
// TODO: Find a way to deduce TupleElement from Term.
template <typename TupleElement>
@@ -50,8 +50,7 @@ struct ParenContents {
// Implementation details only below here.
template <typename Term>
auto ParenContents<Term>::SingleTerm() const
-> std::optional<Nonnull<const Term*>> {
auto ParenContents<Term>::SingleTerm() const -> std::optional<Nonnull<Term*>> {
if (elements.size() == 1 && !elements.front().name.has_value() &&
!has_trailing_comma) {
return elements.front().term;
+8 -9
View File
@@ -55,7 +55,7 @@ void Pattern::Print(llvm::raw_ostream& out) const {
}
TuplePattern::TuplePattern(Nonnull<Arena*> arena,
Nonnull<const Expression*> tuple_literal)
Nonnull<Expression*> tuple_literal)
: Pattern(Kind::TuplePattern, tuple_literal->SourceLoc()) {
const auto& tuple = cast<TupleLiteral>(*tuple_literal);
for (const FieldInitializer& init : tuple.Fields()) {
@@ -66,9 +66,8 @@ TuplePattern::TuplePattern(Nonnull<Arena*> arena,
auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
const ParenContents<Pattern>& paren_contents)
-> Nonnull<const Pattern*> {
std::optional<Nonnull<const Pattern*>> single_term =
paren_contents.SingleTerm();
-> Nonnull<Pattern*> {
std::optional<Nonnull<Pattern*>> single_term = paren_contents.SingleTerm();
if (single_term.has_value()) {
return *single_term;
} else {
@@ -78,7 +77,7 @@ auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
auto TuplePatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
const ParenContents<Pattern>& paren_contents)
-> Nonnull<const TuplePattern*> {
-> Nonnull<TuplePattern*> {
return arena->New<TuplePattern>(
loc, paren_contents.TupleElements<TuplePattern::Field>(loc));
}
@@ -86,8 +85,8 @@ auto TuplePatternFromParenContents(Nonnull<Arena*> arena, SourceLocation loc,
// Used by AlternativePattern for constructor initialization. Produces a helpful
// error for incorrect expressions, rather than letting a default cast error
// apply.
static const FieldAccessExpression& RequireFieldAccess(
Nonnull<const Expression*> alternative) {
static auto RequireFieldAccess(Nonnull<Expression*> alternative)
-> FieldAccessExpression& {
if (alternative->Tag() != Expression::Kind::FieldAccessExpression) {
FATAL_PROGRAM_ERROR(alternative->SourceLoc())
<< "Alternative pattern must have the form of a field access.";
@@ -96,8 +95,8 @@ static const FieldAccessExpression& RequireFieldAccess(
}
AlternativePattern::AlternativePattern(SourceLocation loc,
Nonnull<const Expression*> alternative,
Nonnull<const TuplePattern*> arguments)
Nonnull<Expression*> alternative,
Nonnull<TuplePattern*> arguments)
: Pattern(Kind::AlternativePattern, loc),
choice_type(RequireFieldAccess(alternative).Aggregate()),
alternative_name(RequireFieldAccess(alternative).Field()),
+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
+54 -42
View File
@@ -12,6 +12,7 @@
#include "executable_semantics/ast/pattern.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 {
@@ -58,7 +59,7 @@ class Statement {
class ExpressionStatement : public Statement {
public:
ExpressionStatement(SourceLocation loc, Nonnull<const Expression*> exp)
ExpressionStatement(SourceLocation loc, Nonnull<Expression*> exp)
: Statement(Kind::ExpressionStatement, loc), exp(exp) {}
static auto classof(const Statement* stmt) -> bool {
@@ -66,15 +67,15 @@ class ExpressionStatement : public Statement {
}
auto Exp() const -> Nonnull<const Expression*> { return exp; }
auto Exp() -> Nonnull<Expression*> { return exp; }
private:
Nonnull<const Expression*> exp;
Nonnull<Expression*> exp;
};
class Assign : public Statement {
public:
Assign(SourceLocation loc, Nonnull<const Expression*> lhs,
Nonnull<const Expression*> rhs)
Assign(SourceLocation loc, Nonnull<Expression*> lhs, Nonnull<Expression*> rhs)
: Statement(Kind::Assign, loc), lhs(lhs), rhs(rhs) {}
static auto classof(const Statement* stmt) -> bool {
@@ -82,17 +83,19 @@ class Assign : public Statement {
}
auto Lhs() const -> Nonnull<const Expression*> { return lhs; }
auto Lhs() -> Nonnull<Expression*> { return lhs; }
auto Rhs() const -> Nonnull<const Expression*> { return rhs; }
auto Rhs() -> Nonnull<Expression*> { return rhs; }
private:
Nonnull<const Expression*> lhs;
Nonnull<const Expression*> rhs;
Nonnull<Expression*> lhs;
Nonnull<Expression*> rhs;
};
class VariableDefinition : public Statement {
public:
VariableDefinition(SourceLocation loc, Nonnull<const Pattern*> pat,
Nonnull<const Expression*> init)
VariableDefinition(SourceLocation loc, Nonnull<Pattern*> pat,
Nonnull<Expression*> init)
: Statement(Kind::VariableDefinition, loc), pat(pat), init(init) {}
static auto classof(const Statement* stmt) -> bool {
@@ -100,18 +103,20 @@ class VariableDefinition : public Statement {
}
auto Pat() const -> Nonnull<const Pattern*> { return pat; }
auto Pat() -> Nonnull<Pattern*> { return pat; }
auto Init() const -> Nonnull<const Expression*> { return init; }
auto Init() -> Nonnull<Expression*> { return init; }
private:
Nonnull<const Pattern*> pat;
Nonnull<const Expression*> init;
Nonnull<Pattern*> pat;
Nonnull<Expression*> init;
};
class If : public Statement {
public:
If(SourceLocation loc, Nonnull<const Expression*> cond,
Nonnull<const Statement*> then_stmt,
std::optional<Nonnull<const Statement*>> else_stmt)
If(SourceLocation loc, Nonnull<Expression*> cond,
Nonnull<Statement*> then_stmt,
std::optional<Nonnull<Statement*>> else_stmt)
: Statement(Kind::If, loc),
cond(cond),
then_stmt(then_stmt),
@@ -122,23 +127,25 @@ class If : public Statement {
}
auto Cond() const -> Nonnull<const Expression*> { return cond; }
auto Cond() -> Nonnull<Expression*> { return cond; }
auto ThenStmt() const -> Nonnull<const Statement*> { return then_stmt; }
auto ThenStmt() -> Nonnull<Statement*> { return then_stmt; }
auto ElseStmt() const -> std::optional<Nonnull<const Statement*>> {
return else_stmt;
}
auto ElseStmt() -> std::optional<Nonnull<Statement*>> { return else_stmt; }
private:
Nonnull<const Expression*> cond;
Nonnull<const Statement*> then_stmt;
std::optional<Nonnull<const Statement*>> else_stmt;
Nonnull<Expression*> cond;
Nonnull<Statement*> then_stmt;
std::optional<Nonnull<Statement*>> else_stmt;
};
class Return : public Statement {
public:
Return(Nonnull<Arena*> arena, SourceLocation loc)
: Return(loc, arena->New<TupleLiteral>(loc), true) {}
Return(SourceLocation loc, Nonnull<const Expression*> exp,
bool is_omitted_exp)
Return(SourceLocation loc, Nonnull<Expression*> exp, bool is_omitted_exp)
: Statement(Kind::Return, loc),
exp(exp),
is_omitted_exp(is_omitted_exp) {}
@@ -148,17 +155,18 @@ class Return : public Statement {
}
auto Exp() const -> Nonnull<const Expression*> { return exp; }
auto Exp() -> Nonnull<Expression*> { return exp; }
auto IsOmittedExp() const -> bool { return is_omitted_exp; }
private:
Nonnull<const Expression*> exp;
Nonnull<Expression*> exp;
bool is_omitted_exp;
};
class Sequence : public Statement {
public:
Sequence(SourceLocation loc, Nonnull<const Statement*> stmt,
std::optional<Nonnull<const Statement*>> next)
Sequence(SourceLocation loc, Nonnull<Statement*> stmt,
std::optional<Nonnull<Statement*>> next)
: Statement(Kind::Sequence, loc), stmt(stmt), next(next) {}
static auto classof(const Statement* stmt) -> bool {
@@ -166,16 +174,18 @@ class Sequence : public Statement {
}
auto Stmt() const -> Nonnull<const Statement*> { return stmt; }
auto Stmt() -> Nonnull<Statement*> { return stmt; }
auto Next() const -> std::optional<Nonnull<const Statement*>> { return next; }
auto Next() -> std::optional<Nonnull<Statement*>> { return next; }
private:
Nonnull<const Statement*> stmt;
std::optional<Nonnull<const Statement*>> next;
Nonnull<Statement*> stmt;
std::optional<Nonnull<Statement*>> next;
};
class Block : public Statement {
public:
Block(SourceLocation loc, std::optional<Nonnull<const Statement*>> stmt)
Block(SourceLocation loc, std::optional<Nonnull<Statement*>> stmt)
: Statement(Kind::Block, loc), stmt(stmt) {}
static auto classof(const Statement* stmt) -> bool {
@@ -183,15 +193,15 @@ class Block : public Statement {
}
auto Stmt() const -> std::optional<Nonnull<const Statement*>> { return stmt; }
auto Stmt() -> std::optional<Nonnull<Statement*>> { return stmt; }
private:
std::optional<Nonnull<const Statement*>> stmt;
std::optional<Nonnull<Statement*>> stmt;
};
class While : public Statement {
public:
While(SourceLocation loc, Nonnull<const Expression*> cond,
Nonnull<const Statement*> body)
While(SourceLocation loc, Nonnull<Expression*> cond, Nonnull<Statement*> body)
: Statement(Kind::While, loc), cond(cond), body(body) {}
static auto classof(const Statement* stmt) -> bool {
@@ -199,11 +209,13 @@ class While : public Statement {
}
auto Cond() const -> Nonnull<const Expression*> { return cond; }
auto Cond() -> Nonnull<Expression*> { return cond; }
auto Body() const -> Nonnull<const Statement*> { return body; }
auto Body() -> Nonnull<Statement*> { return body; }
private:
Nonnull<const Expression*> cond;
Nonnull<const Statement*> body;
Nonnull<Expression*> cond;
Nonnull<Statement*> body;
};
class Break : public Statement {
@@ -226,10 +238,8 @@ class Continue : public Statement {
class Match : public Statement {
public:
Match(
SourceLocation loc, Nonnull<const Expression*> exp,
std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
clauses)
Match(SourceLocation loc, Nonnull<Expression*> exp,
std::vector<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>> clauses)
: Statement(Kind::Match, loc), exp(exp), clauses(std::move(clauses)) {}
static auto classof(const Statement* stmt) -> bool {
@@ -237,15 +247,15 @@ class Match : public Statement {
}
auto Exp() const -> Nonnull<const Expression*> { return exp; }
auto Clauses() const -> const std::vector<
std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>& {
auto Exp() -> Nonnull<Expression*> { return exp; }
auto Clauses() const
-> llvm::ArrayRef<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>> {
return clauses;
}
private:
Nonnull<const Expression*> exp;
std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>
clauses;
Nonnull<Expression*> exp;
std::vector<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>> clauses;
};
// A continuation statement.
@@ -256,7 +266,7 @@ class Match : public Statement {
class Continuation : public Statement {
public:
Continuation(SourceLocation loc, std::string continuation_variable,
Nonnull<const Statement*> body)
Nonnull<Statement*> body)
: Statement(Kind::Continuation, loc),
continuation_variable(std::move(continuation_variable)),
body(body) {}
@@ -269,10 +279,11 @@ class Continuation : public Statement {
return continuation_variable;
}
auto Body() const -> Nonnull<const Statement*> { return body; }
auto Body() -> Nonnull<Statement*> { return body; }
private:
std::string continuation_variable;
Nonnull<const Statement*> body;
Nonnull<Statement*> body;
};
// A run statement.
@@ -280,7 +291,7 @@ class Continuation : public Statement {
// __run <argument>;
class Run : public Statement {
public:
Run(SourceLocation loc, Nonnull<const Expression*> argument)
Run(SourceLocation loc, Nonnull<Expression*> argument)
: Statement(Kind::Run, loc), argument(argument) {}
static auto classof(const Statement* stmt) -> bool {
@@ -288,9 +299,10 @@ class Run : public Statement {
}
auto Argument() const -> Nonnull<const Expression*> { return argument; }
auto Argument() -> Nonnull<Expression*> { return argument; }
private:
Nonnull<const Expression*> argument;
Nonnull<Expression*> argument;
};
// An await statement.