diff --git a/executable_semantics/ast/expression.cpp b/executable_semantics/ast/expression.cpp index 209581f6be72..c1ddc1cee728 100644 --- a/executable_semantics/ast/expression.cpp +++ b/executable_semantics/ast/expression.cpp @@ -161,9 +161,8 @@ void Expression::Print(llvm::raw_ostream& out) const { break; case ExpressionKind::IfExpression: { const auto& if_expr = cast(*this); - out << "if " << *if_expr.condition() << " then " - << *if_expr.then_expression() << " else " - << *if_expr.else_expression(); + out << "if " << if_expr.condition() << " then " + << if_expr.then_expression() << " else " << if_expr.else_expression(); break; } case ExpressionKind::UnimplementedExpression: { diff --git a/executable_semantics/ast/expression.h b/executable_semantics/ast/expression.h index 8d64ab16a48e..4d9668d995bd 100644 --- a/executable_semantics/ast/expression.h +++ b/executable_semantics/ast/expression.h @@ -519,13 +519,18 @@ class IfExpression : public Expression { return InheritsFromIfExpression(node->kind()); } - auto condition() const -> Nonnull { return condition_; } - auto then_expression() const -> Nonnull { - return then_expression_; + auto condition() const -> const Expression& { return *condition_; } + auto condition() -> Expression& { return *condition_; } + + auto then_expression() const -> const Expression& { + return *then_expression_; } - auto else_expression() const -> Nonnull { - return else_expression_; + auto then_expression() -> Expression& { return *then_expression_; } + + auto else_expression() const -> const Expression& { + return *else_expression_; } + auto else_expression() -> Expression& { return *else_expression_; } private: Nonnull condition_; diff --git a/executable_semantics/fuzzing/ast_to_proto.cpp b/executable_semantics/fuzzing/ast_to_proto.cpp index 95411900b88e..df912a31219e 100644 --- a/executable_semantics/fuzzing/ast_to_proto.cpp +++ b/executable_semantics/fuzzing/ast_to_proto.cpp @@ -174,18 +174,12 @@ static auto ExpressionToProto(const Expression& expression) case ExpressionKind::IfExpression: { const auto& if_expression = cast(expression); auto* if_proto = expression_proto.mutable_if_expression(); - if (if_expression.condition()) { - *if_proto->mutable_condition() = - ExpressionToProto(*if_expression.condition()); - } - if (if_expression.then_expression()) { - *if_proto->mutable_then_expression() = - ExpressionToProto(*if_expression.then_expression()); - } - if (if_expression.else_expression()) { - *if_proto->mutable_else_expression() = - ExpressionToProto(*if_expression.else_expression()); - } + *if_proto->mutable_condition() = + ExpressionToProto(if_expression.condition()); + *if_proto->mutable_then_expression() = + ExpressionToProto(if_expression.then_expression()); + *if_proto->mutable_else_expression() = + ExpressionToProto(if_expression.else_expression()); break; } diff --git a/executable_semantics/interpreter/interpreter.cpp b/executable_semantics/interpreter/interpreter.cpp index ac46c3ed8680..cd110caec9cd 100644 --- a/executable_semantics/interpreter/interpreter.cpp +++ b/executable_semantics/interpreter/interpreter.cpp @@ -888,12 +888,12 @@ auto Interpreter::StepExp() -> ErrorOr { const auto& if_expr = cast(exp); if (act.pos() == 0) { return todo_.Spawn( - std::make_unique(if_expr.condition())); + std::make_unique(&if_expr.condition())); } else if (act.pos() == 1) { const auto& condition = cast(*act.results()[0]); return todo_.Spawn(std::make_unique( - condition.value() ? if_expr.then_expression() - : if_expr.else_expression())); + condition.value() ? &if_expr.then_expression() + : &if_expr.else_expression())); } else { return todo_.FinishAction(act.results()[1]); } diff --git a/executable_semantics/interpreter/resolve_names.cpp b/executable_semantics/interpreter/resolve_names.cpp index 416507ad5c44..d113fb9922b5 100644 --- a/executable_semantics/interpreter/resolve_names.cpp +++ b/executable_semantics/interpreter/resolve_names.cpp @@ -144,11 +144,9 @@ static auto ResolveNames(Expression& expression, break; case ExpressionKind::IfExpression: { auto& if_expr = cast(expression); - RETURN_IF_ERROR(ResolveNames(*if_expr.condition(), enclosing_scope)); - RETURN_IF_ERROR( - ResolveNames(*if_expr.then_expression(), enclosing_scope)); - RETURN_IF_ERROR( - ResolveNames(*if_expr.else_expression(), enclosing_scope)); + RETURN_IF_ERROR(ResolveNames(if_expr.condition(), enclosing_scope)); + RETURN_IF_ERROR(ResolveNames(if_expr.then_expression(), enclosing_scope)); + RETURN_IF_ERROR(ResolveNames(if_expr.else_expression(), enclosing_scope)); break; } case ExpressionKind::ArrayTypeLiteral: { diff --git a/executable_semantics/interpreter/type_checker.cpp b/executable_semantics/interpreter/type_checker.cpp index 9e74d1517d42..2b8192068abe 100644 --- a/executable_semantics/interpreter/type_checker.cpp +++ b/executable_semantics/interpreter/type_checker.cpp @@ -1002,19 +1002,19 @@ auto TypeChecker::TypeCheckExp(Nonnull e, return Success(); case ExpressionKind::IfExpression: { auto& if_expr = cast(*e); - RETURN_IF_ERROR(TypeCheckExp(if_expr.condition(), impl_scope)); + RETURN_IF_ERROR(TypeCheckExp(&if_expr.condition(), impl_scope)); RETURN_IF_ERROR(ExpectType(if_expr.source_loc(), "condition of `if`", arena_->New(), - &if_expr.condition()->static_type())); + &if_expr.condition().static_type())); // TODO: Compute the common type and convert both operands to it. - RETURN_IF_ERROR(TypeCheckExp(if_expr.then_expression(), impl_scope)); - RETURN_IF_ERROR(TypeCheckExp(if_expr.else_expression(), impl_scope)); + RETURN_IF_ERROR(TypeCheckExp(&if_expr.then_expression(), impl_scope)); + RETURN_IF_ERROR(TypeCheckExp(&if_expr.else_expression(), impl_scope)); RETURN_IF_ERROR( ExpectExactType(e->source_loc(), "expression of `if` expression", - &if_expr.then_expression()->static_type(), - &if_expr.else_expression()->static_type())); - e->set_static_type(&if_expr.then_expression()->static_type()); + &if_expr.then_expression().static_type(), + &if_expr.else_expression().static_type())); + e->set_static_type(&if_expr.then_expression().static_type()); e->set_value_category(ValueCategory::Let); return Success(); }