From b278e4edcfe3673c979db81930b3e7d70597bb67 Mon Sep 17 00:00:00 2001 From: Jon Meow <46229924+jonmeow@users.noreply.github.com> Date: Mon, 18 Oct 2021 10:25:35 -0700 Subject: [PATCH] Refactor Statement accessors (#890) --- executable_semantics/ast/statement.cpp | 38 ++-- executable_semantics/ast/statement.h | 170 ++++++++++-------- .../interpreter/interpreter.cpp | 46 ++--- .../interpreter/type_checker.cpp | 74 ++++---- 4 files changed, 174 insertions(+), 154 deletions(-) diff --git a/executable_semantics/ast/statement.cpp b/executable_semantics/ast/statement.cpp index e05e480d8b48..a2e71deded33 100644 --- a/executable_semantics/ast/statement.cpp +++ b/executable_semantics/ast/statement.cpp @@ -36,8 +36,8 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const { } case Kind::While: { const auto& while_stmt = cast(*this); - out << "while (" << *while_stmt.Cond() << ")\n"; - while_stmt.Body()->PrintDepth(depth - 1, out); + out << "while (" << while_stmt.condition() << ")\n"; + while_stmt.body().PrintDepth(depth - 1, out); break; } case Kind::Break: @@ -48,46 +48,46 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const { break; case Kind::VariableDefinition: { const auto& var = cast(*this); - out << "var " << *var.Pat() << " = " << *var.Init() << ";"; + out << "var " << var.pattern() << " = " << var.init() << ";"; break; } case Kind::ExpressionStatement: - out << *cast(*this).Exp() << ";"; + out << cast(*this).expression() << ";"; break; case Kind::Assign: { const auto& assign = cast(*this); - out << *assign.Lhs() << " = " << *assign.Rhs() << ";"; + out << assign.lhs() << " = " << assign.rhs() << ";"; break; } case Kind::If: { const auto& if_stmt = cast(*this); - out << "if (" << *if_stmt.Cond() << ")\n"; - if_stmt.ThenStmt()->PrintDepth(depth - 1, out); - if (if_stmt.ElseStmt()) { + out << "if (" << if_stmt.condition() << ")\n"; + if_stmt.then_statement().PrintDepth(depth - 1, out); + if (if_stmt.else_statement()) { out << "\nelse\n"; - (*if_stmt.ElseStmt())->PrintDepth(depth - 1, out); + (*if_stmt.else_statement())->PrintDepth(depth - 1, out); } break; } case Kind::Return: { const auto& ret = cast(*this); - if (ret.IsOmittedExp()) { + if (ret.is_omitted_expression()) { out << "return;"; } else { - out << "return " << *ret.Exp() << ";"; + out << "return " << ret.expression() << ";"; } break; } case Kind::Sequence: { const auto& seq = cast(*this); - seq.Stmt()->PrintDepth(depth, out); + seq.statement().PrintDepth(depth, out); if (depth < 0 || depth > 1) { out << "\n"; } else { out << " "; } - if (seq.Next()) { - (*seq.Next())->PrintDepth(depth - 1, out); + if (seq.next()) { + (*seq.next())->PrintDepth(depth - 1, out); } break; } @@ -97,8 +97,8 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const { if (depth < 0 || depth > 1) { out << "\n"; } - if (block.Stmt()) { - (*block.Stmt())->PrintDepth(depth, out); + if (block.statement()) { + (*block.statement())->PrintDepth(depth, out); if (depth < 0 || depth > 1) { out << "\n"; } @@ -111,18 +111,18 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const { } case Kind::Continuation: { const auto& cont = cast(*this); - out << "continuation " << cont.ContinuationVariable() << " "; + out << "continuation " << cont.continuation_variable() << " "; if (depth < 0 || depth > 1) { out << "\n"; } - cont.Body()->PrintDepth(depth - 1, out); + cont.body().PrintDepth(depth - 1, out); if (depth < 0 || depth > 1) { out << "\n"; } break; } case Kind::Run: - out << "run " << *cast(*this).Argument() << ";"; + out << "run " << cast(*this).argument() << ";"; break; case Kind::Await: out << "await;"; diff --git a/executable_semantics/ast/statement.h b/executable_semantics/ast/statement.h index c1e0c7a19473..fccf46b03da4 100644 --- a/executable_semantics/ast/statement.h +++ b/executable_semantics/ast/statement.h @@ -60,166 +60,180 @@ class Statement { class ExpressionStatement : public Statement { public: - ExpressionStatement(SourceLocation source_loc, Nonnull exp) - : Statement(Kind::ExpressionStatement, source_loc), exp(exp) {} + ExpressionStatement(SourceLocation source_loc, + Nonnull expression) + : Statement(Kind::ExpressionStatement, source_loc), + expression_(expression) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::ExpressionStatement; } - auto Exp() const -> Nonnull { return exp; } - auto Exp() -> Nonnull { return exp; } + auto expression() const -> const Expression& { return *expression_; } + auto expression() -> Expression& { return *expression_; } private: - Nonnull exp; + Nonnull expression_; }; class Assign : public Statement { public: Assign(SourceLocation source_loc, Nonnull lhs, Nonnull rhs) - : Statement(Kind::Assign, source_loc), lhs(lhs), rhs(rhs) {} + : Statement(Kind::Assign, source_loc), lhs_(lhs), rhs_(rhs) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Assign; } - auto Lhs() const -> Nonnull { return lhs; } - auto Lhs() -> Nonnull { return lhs; } - auto Rhs() const -> Nonnull { return rhs; } - auto Rhs() -> Nonnull { return rhs; } + auto lhs() const -> const Expression& { return *lhs_; } + auto lhs() -> Expression& { return *lhs_; } + auto rhs() const -> const Expression& { return *rhs_; } + auto rhs() -> Expression& { return *rhs_; } private: - Nonnull lhs; - Nonnull rhs; + Nonnull lhs_; + Nonnull rhs_; }; class VariableDefinition : public Statement { public: - VariableDefinition(SourceLocation source_loc, Nonnull pat, + VariableDefinition(SourceLocation source_loc, Nonnull pattern, Nonnull init) - : Statement(Kind::VariableDefinition, source_loc), pat(pat), init(init) {} + : Statement(Kind::VariableDefinition, source_loc), + pattern_(pattern), + init_(init) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::VariableDefinition; } - auto Pat() const -> Nonnull { return pat; } - auto Pat() -> Nonnull { return pat; } - auto Init() const -> Nonnull { return init; } - auto Init() -> Nonnull { return init; } + auto pattern() const -> const Pattern& { return *pattern_; } + auto pattern() -> Pattern& { return *pattern_; } + auto init() const -> const Expression& { return *init_; } + auto init() -> Expression& { return *init_; } private: - Nonnull pat; - Nonnull init; + Nonnull pattern_; + Nonnull init_; }; class If : public Statement { public: - If(SourceLocation source_loc, Nonnull cond, - Nonnull then_stmt, - std::optional> else_stmt) + If(SourceLocation source_loc, Nonnull condition, + Nonnull then_statement, + std::optional> else_statement) : Statement(Kind::If, source_loc), - cond(cond), - then_stmt(then_stmt), - else_stmt(else_stmt) {} + condition_(condition), + then_statement_(then_statement), + else_statement_(else_statement) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::If; } - auto Cond() const -> Nonnull { return cond; } - auto Cond() -> Nonnull { return cond; } - auto ThenStmt() const -> Nonnull { return then_stmt; } - auto ThenStmt() -> Nonnull { return then_stmt; } - auto ElseStmt() const -> std::optional> { - return else_stmt; + auto condition() const -> const Expression& { return *condition_; } + auto condition() -> Expression& { return *condition_; } + auto then_statement() const -> const Statement& { return *then_statement_; } + auto then_statement() -> Statement& { return *then_statement_; } + auto else_statement() const -> std::optional> { + return else_statement_; + } + auto else_statement() -> std::optional> { + return else_statement_; } - auto ElseStmt() -> std::optional> { return else_stmt; } private: - Nonnull cond; - Nonnull then_stmt; - std::optional> else_stmt; + Nonnull condition_; + Nonnull then_statement_; + std::optional> else_statement_; }; class Return : public Statement { public: Return(Nonnull arena, SourceLocation source_loc) : Return(source_loc, arena->New(source_loc), true) {} - Return(SourceLocation source_loc, Nonnull exp, - bool is_omitted_exp) + Return(SourceLocation source_loc, Nonnull expression, + bool is_omitted_expression) : Statement(Kind::Return, source_loc), - exp(exp), - is_omitted_exp(is_omitted_exp) {} + expression_(expression), + is_omitted_expression_(is_omitted_expression) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Return; } - auto Exp() const -> Nonnull { return exp; } - auto Exp() -> Nonnull { return exp; } - auto IsOmittedExp() const -> bool { return is_omitted_exp; } + auto expression() const -> const Expression& { return *expression_; } + auto expression() -> Expression& { return *expression_; } + auto is_omitted_expression() const -> bool { return is_omitted_expression_; } private: - Nonnull exp; - bool is_omitted_exp; + Nonnull expression_; + bool is_omitted_expression_; }; class Sequence : public Statement { public: - Sequence(SourceLocation source_loc, Nonnull stmt, + Sequence(SourceLocation source_loc, Nonnull statement, std::optional> next) - : Statement(Kind::Sequence, source_loc), stmt(stmt), next(next) {} + : Statement(Kind::Sequence, source_loc), + statement_(statement), + next_(next) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Sequence; } - auto Stmt() const -> Nonnull { return stmt; } - auto Stmt() -> Nonnull { return stmt; } - auto Next() const -> std::optional> { return next; } - auto Next() -> std::optional> { return next; } + auto statement() const -> const Statement& { return *statement_; } + auto statement() -> Statement& { return *statement_; } + auto next() const -> std::optional> { + return next_; + } + auto next() -> std::optional> { return next_; } private: - Nonnull stmt; - std::optional> next; + Nonnull statement_; + std::optional> next_; }; class Block : public Statement { public: - Block(SourceLocation source_loc, std::optional> stmt) - : Statement(Kind::Block, source_loc), stmt(stmt) {} + Block(SourceLocation source_loc, std::optional> statement) + : Statement(Kind::Block, source_loc), statement_(statement) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Block; } - auto Stmt() const -> std::optional> { return stmt; } - auto Stmt() -> std::optional> { return stmt; } + auto statement() const -> std::optional> { + return statement_; + } + auto statement() -> std::optional> { return statement_; } private: - std::optional> stmt; + std::optional> statement_; }; class While : public Statement { public: - While(SourceLocation source_loc, Nonnull cond, + While(SourceLocation source_loc, Nonnull condition, Nonnull body) - : Statement(Kind::While, source_loc), cond(cond), body(body) {} + : Statement(Kind::While, source_loc), + condition_(condition), + body_(body) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::While; } - auto Cond() const -> Nonnull { return cond; } - auto Cond() -> Nonnull { return cond; } - auto Body() const -> Nonnull { return body; } - auto Body() -> Nonnull { return body; } + auto condition() const -> const Expression& { return *condition_; } + auto condition() -> Expression& { return *condition_; } + auto body() const -> const Statement& { return *body_; } + auto body() -> Statement& { return *body_; } private: - Nonnull cond; - Nonnull body; + Nonnull condition_; + Nonnull body_; }; class Break : public Statement { @@ -289,22 +303,22 @@ class Continuation : public Statement { Continuation(SourceLocation source_loc, std::string continuation_variable, Nonnull body) : Statement(Kind::Continuation, source_loc), - continuation_variable(std::move(continuation_variable)), - body(body) {} + continuation_variable_(std::move(continuation_variable)), + body_(body) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Continuation; } - auto ContinuationVariable() const -> const std::string& { - return continuation_variable; + auto continuation_variable() const -> const std::string& { + return continuation_variable_; } - auto Body() const -> Nonnull { return body; } - auto Body() -> Nonnull { return body; } + auto body() const -> const Statement& { return *body_; } + auto body() -> Statement& { return *body_; } private: - std::string continuation_variable; - Nonnull body; + std::string continuation_variable_; + Nonnull body_; }; // A run statement. @@ -313,17 +327,17 @@ class Continuation : public Statement { class Run : public Statement { public: Run(SourceLocation source_loc, Nonnull argument) - : Statement(Kind::Run, source_loc), argument(argument) {} + : Statement(Kind::Run, source_loc), argument_(argument) {} static auto classof(const Statement* stmt) -> bool { return stmt->kind() == Kind::Run; } - auto Argument() const -> Nonnull { return argument; } - auto Argument() -> Nonnull { return argument; } + auto argument() const -> const Expression& { return *argument_; } + auto argument() -> Expression& { return *argument_; } private: - Nonnull argument; + Nonnull argument_; }; // An await statement. diff --git a/executable_semantics/interpreter/interpreter.cpp b/executable_semantics/interpreter/interpreter.cpp index 24e95e58dd20..258c6f84ae32 100644 --- a/executable_semantics/interpreter/interpreter.cpp +++ b/executable_semantics/interpreter/interpreter.cpp @@ -805,11 +805,12 @@ auto Interpreter::StepStmt() -> Transition { // { { (while (e) s) :: C, E, F} :: S, H} // -> { { e :: (while ([]) s) :: C, E, F} :: S, H} act->Clear(); - return Spawn{arena->New(cast(*stmt).Cond())}; + return Spawn{ + arena->New(&cast(*stmt).condition())}; } else if (cast(*act->results().back()).Val()) { // { {true :: (while ([]) s) :: C, E, F} :: S, H} // -> { { s :: (while (e) s) :: C, E, F } :: S, H} - return Spawn{arena->New(cast(*stmt).Body())}; + return Spawn{arena->New(&cast(*stmt).body())}; } else { // { {false :: (while ([]) s) :: C, E, F} :: S, H} // -> { { C, E, F } :: S, H} @@ -843,9 +844,9 @@ auto Interpreter::StepStmt() -> Transition { case Statement::Kind::Block: { if (act->pos() == 0) { const auto& block = cast(*stmt); - if (block.Stmt()) { + if (block.statement()) { frame->scopes.Push(arena->New(CurrentEnv())); - return Spawn{arena->New(*block.Stmt())}; + return Spawn{arena->New(*block.statement())}; } else { return Done{}; } @@ -861,10 +862,10 @@ auto Interpreter::StepStmt() -> Transition { // { {(var x = e) :: C, E, F} :: S, H} // -> { {e :: (var x = []) :: C, E, F} :: S, H} return Spawn{arena->New( - cast(*stmt).Init())}; + &cast(*stmt).init())}; } else if (act->pos() == 1) { - return Spawn{ - arena->New(cast(*stmt).Pat())}; + return Spawn{arena->New( + &cast(*stmt).pattern())}; } else { // { { v :: (x = []) :: C, E, F} :: S, H} // -> { { C, E(x := a), F} :: S, H(a := copy(v))} @@ -886,7 +887,7 @@ auto Interpreter::StepStmt() -> Transition { // { {e :: C, E, F} :: S, H} // -> { {e :: C, E, F} :: S, H} return Spawn{arena->New( - cast(*stmt).Exp())}; + &cast(*stmt).expression())}; } else { return Done{}; } @@ -894,11 +895,11 @@ auto Interpreter::StepStmt() -> Transition { if (act->pos() == 0) { // { {(lv = e) :: C, E, F} :: S, H} // -> { {lv :: ([] = e) :: C, E, F} :: S, H} - return Spawn{arena->New(cast(*stmt).Lhs())}; + return Spawn{arena->New(&cast(*stmt).lhs())}; } else if (act->pos() == 1) { // { { a :: ([] = e) :: C, E, F} :: S, H} // -> { { e :: (a = []) :: C, E, F} :: S, H} - return Spawn{arena->New(cast(*stmt).Rhs())}; + return Spawn{arena->New(&cast(*stmt).rhs())}; } else { // { { v :: (a = []) :: C, E, F} :: S, H} // -> { { C, E, F} :: S, H(a := v)} @@ -911,19 +912,20 @@ auto Interpreter::StepStmt() -> Transition { if (act->pos() == 0) { // { {(if (e) then_stmt else else_stmt) :: C, E, F} :: S, H} // -> { { e :: (if ([]) then_stmt else else_stmt) :: C, E, F} :: S, H} - return Spawn{arena->New(cast(*stmt).Cond())}; + return Spawn{ + arena->New(&cast(*stmt).condition())}; } else if (cast(*act->results()[0]).Val()) { // { {true :: if ([]) then_stmt else else_stmt :: C, E, F} :: // S, H} // -> { { then_stmt :: C, E, F } :: S, H} return Delegate{ - arena->New(cast(*stmt).ThenStmt())}; - } else if (cast(*stmt).ElseStmt()) { + arena->New(&cast(*stmt).then_statement())}; + } else if (cast(*stmt).else_statement()) { // { {false :: if ([]) then_stmt else else_stmt :: C, E, F} :: // S, H} // -> { { else_stmt :: C, E, F } :: S, H} return Delegate{ - arena->New(*cast(*stmt).ElseStmt())}; + arena->New(*cast(*stmt).else_statement())}; } else { return Done{}; } @@ -931,7 +933,8 @@ auto Interpreter::StepStmt() -> Transition { if (act->pos() == 0) { // { {return e :: C, E, F} :: S, H} // -> { {e :: return [] :: C, E, F} :: S, H} - return Spawn{arena->New(cast(*stmt).Exp())}; + return Spawn{ + arena->New(&cast(*stmt).expression())}; } else { // { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H} // -> { {v :: C', E', F'} :: S, H} @@ -944,11 +947,11 @@ auto Interpreter::StepStmt() -> Transition { // -> { { s1 :: s2 :: C, E, F} :: S, H} const auto& seq = cast(*stmt); if (act->pos() == 0) { - return Spawn{arena->New(seq.Stmt())}; + return Spawn{arena->New(&seq.statement())}; } else { - if (seq.Next()) { + if (seq.next()) { return Delegate{ - arena->New(*cast(*stmt).Next())}; + arena->New(*cast(*stmt).next())}; } else { return Done{}; } @@ -962,7 +965,7 @@ auto Interpreter::StepStmt() -> Transition { Stack> todo; todo.Push(arena->New( arena->New(arena, stmt->source_loc()))); - todo.Push(arena->New(cast(*stmt).Body())); + todo.Push(arena->New(&cast(*stmt).body())); auto continuation_stack = arena->New>>(); auto continuation_frame = arena->New("__continuation", scopes, todo); @@ -973,7 +976,7 @@ auto Interpreter::StepStmt() -> Transition { continuation_frame->continuation = continuation_address; // Bind the continuation object to the continuation variable frame->scopes.Top()->values.Set( - cast(*stmt).ContinuationVariable(), + cast(*stmt).continuation_variable(), continuation_address); // Pop the continuation statement. frame->todo.Pop(); @@ -982,7 +985,8 @@ auto Interpreter::StepStmt() -> Transition { case Statement::Kind::Run: if (act->pos() == 0) { // Evaluate the argument of the run statement. - return Spawn{arena->New(cast(*stmt).Argument())}; + return Spawn{ + arena->New(&cast(*stmt).argument())}; } else { frame->todo.Pop(1); // Push an expression statement action to ignore the result diff --git a/executable_semantics/interpreter/type_checker.cpp b/executable_semantics/interpreter/type_checker.cpp index 73703cbc4f48..8d63645bb0e1 100644 --- a/executable_semantics/interpreter/type_checker.cpp +++ b/executable_semantics/interpreter/type_checker.cpp @@ -840,10 +840,10 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } case Statement::Kind::While: { auto& while_stmt = cast(*s); - TypeCheckExp(while_stmt.Cond(), types, values); + TypeCheckExp(&while_stmt.condition(), types, values); ExpectType(s->source_loc(), "condition of `while`", - arena->New(), &while_stmt.Cond()->static_type()); - TypeCheckStmt(while_stmt.Body(), types, values, return_type_context); + arena->New(), &while_stmt.condition().static_type()); + TypeCheckStmt(&while_stmt.body(), types, values, return_type_context); return TCResult(types); } case Statement::Kind::Break: @@ -851,8 +851,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, return TCResult(types); case Statement::Kind::Block: { auto& block = cast(*s); - if (block.Stmt()) { - TypeCheckStmt(*block.Stmt(), types, values, return_type_context); + if (block.statement()) { + TypeCheckStmt(*block.statement(), types, values, return_type_context); return TCResult(types); } else { return TCResult(types); @@ -860,18 +860,18 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } case Statement::Kind::VariableDefinition: { auto& var = cast(*s); - TypeCheckExp(var.Init(), types, values); - const Value& rhs_ty = var.Init()->static_type(); - auto lhs_res = TypeCheckPattern(var.Pat(), types, values, &rhs_ty); + TypeCheckExp(&var.init(), types, values); + const Value& rhs_ty = var.init().static_type(); + auto lhs_res = TypeCheckPattern(&var.pattern(), types, values, &rhs_ty); return TCResult(lhs_res.types); } case Statement::Kind::Sequence: { auto& seq = cast(*s); auto stmt_res = - TypeCheckStmt(seq.Stmt(), types, values, return_type_context); + TypeCheckStmt(&seq.statement(), types, values, return_type_context); auto checked_types = stmt_res.types; - if (seq.Next()) { - auto next_res = TypeCheckStmt(*seq.Next(), checked_types, values, + if (seq.next()) { + auto next_res = TypeCheckStmt(*seq.next(), checked_types, values, return_type_context); checked_types = next_res.types; } @@ -879,30 +879,32 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } case Statement::Kind::Assign: { auto& assign = cast(*s); - TypeCheckExp(assign.Rhs(), types, values); - auto lhs_res = TypeCheckExp(assign.Lhs(), types, values); - ExpectType(s->source_loc(), "assign", &assign.Lhs()->static_type(), - &assign.Rhs()->static_type()); + TypeCheckExp(&assign.rhs(), types, values); + auto lhs_res = TypeCheckExp(&assign.lhs(), types, values); + ExpectType(s->source_loc(), "assign", &assign.lhs().static_type(), + &assign.rhs().static_type()); return TCResult(lhs_res.types); } case Statement::Kind::ExpressionStatement: { - TypeCheckExp(cast(*s).Exp(), types, values); + TypeCheckExp(&cast(*s).expression(), types, values); return TCResult(types); } case Statement::Kind::If: { auto& if_stmt = cast(*s); - TypeCheckExp(if_stmt.Cond(), types, values); + TypeCheckExp(&if_stmt.condition(), types, values); ExpectType(s->source_loc(), "condition of `if`", arena->New(), - &if_stmt.Cond()->static_type()); - TypeCheckStmt(if_stmt.ThenStmt(), types, values, return_type_context); - if (if_stmt.ElseStmt()) { - TypeCheckStmt(*if_stmt.ElseStmt(), types, values, return_type_context); + &if_stmt.condition().static_type()); + TypeCheckStmt(&if_stmt.then_statement(), types, values, + return_type_context); + if (if_stmt.else_statement()) { + TypeCheckStmt(*if_stmt.else_statement(), types, values, + return_type_context); } return TCResult(types); } case Statement::Kind::Return: { auto& ret = cast(*s); - TypeCheckExp(ret.Exp(), types, values); + TypeCheckExp(&ret.expression(), types, values); if (return_type_context->is_auto()) { if (return_type_context->deduced_return_type()) { // Only one return is allowed when the return type is `auto`. @@ -912,14 +914,14 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } else { // Infer the auto return from the first `return` statement. return_type_context->set_deduced_return_type( - &ret.Exp()->static_type()); + &ret.expression().static_type()); } } else { ExpectType(s->source_loc(), "return", *return_type_context->deduced_return_type(), - &ret.Exp()->static_type()); + &ret.expression().static_type()); } - if (ret.IsOmittedExp() != return_type_context->is_omitted()) { + if (ret.is_omitted_expression() != return_type_context->is_omitted()) { FATAL_COMPILATION_ERROR(s->source_loc()) << *s << " should" << (return_type_context->is_omitted() ? " not" : "") @@ -929,16 +931,15 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, TypeEnv types, } case Statement::Kind::Continuation: { auto& cont = cast(*s); - TypeCheckStmt(cont.Body(), types, values, return_type_context); - types.Set(cont.ContinuationVariable(), arena->New()); + TypeCheckStmt(&cont.body(), types, values, return_type_context); + types.Set(cont.continuation_variable(), arena->New()); return TCResult(types); } case Statement::Kind::Run: { auto& run = cast(*s); - TypeCheckExp(run.Argument(), types, values); + TypeCheckExp(&run.argument(), types, values); ExpectType(s->source_loc(), "argument of `run`", - arena->New(), - &run.Argument()->static_type()); + arena->New(), &run.argument().static_type()); return TCResult(types); } case Statement::Kind::Await: { @@ -986,22 +987,23 @@ void TypeChecker::ExpectReturnOnAllPaths( return; } case Statement::Kind::Block: - ExpectReturnOnAllPaths(cast(*stmt).Stmt(), stmt->source_loc()); + ExpectReturnOnAllPaths(cast(*stmt).statement(), + stmt->source_loc()); return; case Statement::Kind::If: { auto& if_stmt = cast(*stmt); - ExpectReturnOnAllPaths(if_stmt.ThenStmt(), stmt->source_loc()); - ExpectReturnOnAllPaths(if_stmt.ElseStmt(), stmt->source_loc()); + ExpectReturnOnAllPaths(&if_stmt.then_statement(), stmt->source_loc()); + ExpectReturnOnAllPaths(if_stmt.else_statement(), stmt->source_loc()); return; } case Statement::Kind::Return: return; case Statement::Kind::Sequence: { auto& seq = cast(*stmt); - if (seq.Next()) { - ExpectReturnOnAllPaths(seq.Next(), stmt->source_loc()); + if (seq.next()) { + ExpectReturnOnAllPaths(seq.next(), stmt->source_loc()); } else { - ExpectReturnOnAllPaths(seq.Stmt(), stmt->source_loc()); + ExpectReturnOnAllPaths(&seq.statement(), stmt->source_loc()); } return; }