From 4b69c204bb8cb048c0ce0f4ccb5c22963544dc38 Mon Sep 17 00:00:00 2001 From: Jon Meow <46229924+jonmeow@users.noreply.github.com> Date: Mon, 12 Jul 2021 11:43:06 -0700 Subject: [PATCH] Migrate Action to variant (#637) --- executable_semantics/interpreter/action.cpp | 148 ++++++++------ executable_semantics/interpreter/action.h | 80 ++++++-- .../interpreter/interpreter.cpp | 189 ++++++++++-------- 3 files changed, 252 insertions(+), 165 deletions(-) diff --git a/executable_semantics/interpreter/action.cpp b/executable_semantics/interpreter/action.cpp index f274e7d11591..307d7b269c7a 100644 --- a/executable_semantics/interpreter/action.cpp +++ b/executable_semantics/interpreter/action.cpp @@ -17,29 +17,106 @@ namespace Carbon { -void PrintAct(Action* act, std::ostream& out) { - switch (act->tag) { +namespace { + +struct TagVisitor { + template + auto operator()(const Alternative&) -> ActionKind { + return Alternative::Kind; + } +}; + +} // namespace + +auto Action::tag() const -> ActionKind { + return std::visit(TagVisitor(), value); +} + +auto Action::MakeLValAction(const Expression* e) -> Action* { + auto* act = new Action(); + act->value = LValAction({.exp = e}); + return act; +} + +auto Action::MakeExpressionAction(const Expression* e) -> Action* { + auto* act = new Action(); + act->value = ExpressionAction({.exp = e}); + return act; +} + +auto Action::MakeStatementAction(const Statement* s) -> Action* { + auto* act = new Action(); + act->value = StatementAction({.stmt = s}); + return act; +} + +auto Action::MakeValAction(const Value* v) -> Action* { + auto* act = new Action(); + act->value = ValAction({.val = v}); + return act; +} + +auto Action::MakeExpToLValAction() -> Action* { + auto* act = new Action(); + act->value = ExpToLValAction(); + return act; +} + +auto Action::MakeDeleteTmpAction(Address a) -> Action* { + auto* act = new Action(); + act->value = DeleteTmpAction({.delete_tmp = a}); + return act; +} + +auto Action::GetLValAction() const -> const LValAction& { + return std::get(value); +} + +auto Action::GetExpressionAction() const -> const ExpressionAction& { + return std::get(value); +} + +auto Action::GetStatementAction() const -> const StatementAction& { + return std::get(value); +} + +auto Action::GetValAction() const -> const ValAction& { + return std::get(value); +} + +auto Action::GetExpToLValAction() const -> const ExpToLValAction& { + return std::get(value); +} + +auto Action::GetDeleteTmpAction() const -> const DeleteTmpAction& { + return std::get(value); +} + +void Action::Print(std::ostream& out) { + switch (tag()) { case ActionKind::DeleteTmpAction: - std::cout << "delete_tmp(" << act->u.delete_tmp << ")"; + std::cout << "delete_tmp(" << GetDeleteTmpAction().delete_tmp << ")"; break; case ActionKind::ExpToLValAction: out << "exp=>lval"; break; case ActionKind::LValAction: + PrintExp(GetLValAction().exp); + break; case ActionKind::ExpressionAction: - PrintExp(act->u.exp); + PrintExp(GetExpressionAction().exp); break; case ActionKind::StatementAction: - PrintStatement(act->u.stmt, 1); + PrintStatement(GetStatementAction().stmt, 1); break; case ActionKind::ValAction: - PrintValue(act->u.val, out); + PrintValue(GetValAction().val, out); break; } - out << "<" << act->pos << ">"; - if (act->results.size() > 0) { + out << "<" << pos << ">"; + if (results.size() > 0) { out << "("; - for (auto& result : act->results) { + for (auto& result : results) { if (result) { PrintValue(result, out); } @@ -49,61 +126,14 @@ void PrintAct(Action* act, std::ostream& out) { } } -void PrintActList(Stack ls, std::ostream& out) { +void Action::PrintList(Stack ls, std::ostream& out) { if (!ls.IsEmpty()) { - PrintAct(ls.Pop(), out); + PrintList(ls.Pop(), out); if (!ls.IsEmpty()) { out << " :: "; - PrintActList(ls, out); + PrintList(ls, out); } } } -auto MakeExpAct(const Expression* e) -> Action* { - auto* act = new Action(); - act->tag = ActionKind::ExpressionAction; - act->u.exp = e; - act->pos = 0; - return act; -} - -auto MakeLvalAct(const Expression* e) -> Action* { - auto* act = new Action(); - act->tag = ActionKind::LValAction; - act->u.exp = e; - act->pos = 0; - return act; -} - -auto MakeStmtAct(const Statement* s) -> Action* { - auto* act = new Action(); - act->tag = ActionKind::StatementAction; - act->u.stmt = s; - act->pos = 0; - return act; -} - -auto MakeValAct(const Value* v) -> Action* { - auto* act = new Action(); - act->tag = ActionKind::ValAction; - act->u.val = v; - act->pos = 0; - return act; -} - -auto MakeExpToLvalAct() -> Action* { - auto* act = new Action(); - act->tag = ActionKind::ExpToLValAction; - act->pos = 0; - return act; -} - -auto MakeDeleteAct(Address a) -> Action* { - auto* act = new Action(); - act->tag = ActionKind::DeleteTmpAction; - act->pos = 0; - act->u.delete_tmp = a; - return act; -} - } // namespace Carbon diff --git a/executable_semantics/interpreter/action.h b/executable_semantics/interpreter/action.h index a03c667bd811..e1727a2a3e18 100644 --- a/executable_semantics/interpreter/action.h +++ b/executable_semantics/interpreter/action.h @@ -24,30 +24,72 @@ enum class ActionKind { DeleteTmpAction }; +struct LValAction { + static constexpr ActionKind Kind = ActionKind::LValAction; + const Expression* exp; +}; + +struct ExpressionAction { + static constexpr ActionKind Kind = ActionKind::ExpressionAction; + const Expression* exp; +}; + +struct StatementAction { + static constexpr ActionKind Kind = ActionKind::StatementAction; + const Statement* stmt; +}; + +struct ValAction { + static constexpr ActionKind Kind = ActionKind::ValAction; + const Value* val; +}; + +struct ExpToLValAction { + static constexpr ActionKind Kind = ActionKind::ExpToLValAction; +}; + +struct DeleteTmpAction { + static constexpr ActionKind Kind = ActionKind::DeleteTmpAction; + Address delete_tmp; +}; + struct Action { - ActionKind tag; - union { - const Expression* exp; // for LValAction and ExpressionAction - const Statement* stmt; - const Value* val; // for finished actions with a value (ValAction) - Address delete_tmp; - } u; - int pos; // position or state of the action, starts at 0 and goes up to - // the number of subexpressions. + auto tag() const -> ActionKind; + + static auto MakeLValAction(const Expression* e) -> Action*; + static auto MakeExpressionAction(const Expression* e) -> Action*; + static auto MakeStatementAction(const Statement* s) -> Action*; + static auto MakeValAction(const Value* v) -> Action*; + static auto MakeExpToLValAction() -> Action*; + static auto MakeDeleteTmpAction(Address a) -> Action*; + + static void PrintList(Stack ls, std::ostream& out); + + auto GetLValAction() const -> const LValAction&; + auto GetExpressionAction() const -> const ExpressionAction&; + auto GetStatementAction() const -> const StatementAction&; + auto GetValAction() const -> const ValAction&; + auto GetExpToLValAction() const -> const ExpToLValAction&; + auto GetDeleteTmpAction() const -> const DeleteTmpAction&; + + void Print(std::ostream& out); + + // The position or state of the action. Starts at 0 and goes up to the number + // of subexpressions. + // // pos indicates how many of the entries in the following `results` vector // will be filled in the next time this action is active. // For each i < pos, results[i] contains a pointer to a Value. - std::vector results; // results from subexpression -}; + int pos = 0; -void PrintAct(Action* act, std::ostream& out); -void PrintActList(Stack ls, std::ostream& out); -auto MakeExpAct(const Expression* e) -> Action*; -auto MakeLvalAct(const Expression* e) -> Action*; -auto MakeStmtAct(const Statement* s) -> Action*; -auto MakeValAct(const Value* v) -> Action*; -auto MakeExpToLvalAct() -> Action*; -auto MakeDeleteAct(Address a) -> Action*; + // Results from a subexpression. + std::vector results; + + private: + std::variant + value; +}; } // namespace Carbon diff --git a/executable_semantics/interpreter/interpreter.cpp b/executable_semantics/interpreter/interpreter.cpp index 142bf2e8e782..663838d4a638 100644 --- a/executable_semantics/interpreter/interpreter.cpp +++ b/executable_semantics/interpreter/interpreter.cpp @@ -173,7 +173,7 @@ void PrintEnv(Env values, std::ostream& out) { void PrintFrame(Frame* frame, std::ostream& out) { out << frame->name; out << "{"; - PrintActList(frame->todo, out); + Action::PrintList(frame->todo, out); out << "}"; } @@ -376,9 +376,9 @@ void CallFunction(int line_num, std::vector operas, } // Create the new frame and push it on the stack auto* scope = new Scope(*matches, params); - auto* frame = - new Frame(operas[0]->GetFunctionValue().name, Stack(scope), - Stack(MakeStmtAct(operas[0]->GetFunctionValue().body))); + auto* frame = new Frame(operas[0]->GetFunctionValue().name, Stack(scope), + Stack(Action::MakeStatementAction( + operas[0]->GetFunctionValue().body))); state->stack.Push(frame); break; } @@ -386,7 +386,7 @@ void CallFunction(int line_num, std::vector operas, const Value* arg = CopyVal(operas[1], line_num); const Value* sv = Value::MakeStructValue(operas[0], arg); Frame* frame = state->stack.Top(); - frame->todo.Push(MakeValAct(sv)); + frame->todo.Push(Action::MakeValAction(sv)); break; } case ValKind::AlternativeConstructorValue: { @@ -396,7 +396,7 @@ void CallFunction(int line_num, std::vector operas, operas[0]->GetAlternativeConstructorValue().choice_name, state->heap.AllocateValue(arg)); Frame* frame = state->stack.Top(); - frame->todo.Push(MakeValAct(av)); + frame->todo.Push(Action::MakeValAction(av)); break; } default: @@ -424,18 +424,19 @@ void DeallocateLocals(int line_num, Frame* frame) { } } -void CreateTuple(Frame* frame, Action* act, const Expression* /*exp*/) { +void CreateTuple(Frame* frame, Action* act, const Expression* exp) { // { { (v1,...,vn) :: C, E, F} :: S, H} // -> { { `(v1,...,vn) :: C, E, F} :: S, H} std::vector elements; - auto f = act->u.exp->GetTupleLiteral().fields.begin(); + auto f = exp->GetTupleLiteral().fields.begin(); + for (auto i = act->results.begin(); i != act->results.end(); ++i, ++f) { Address a = state->heap.AllocateValue(*i); // copy? elements.push_back({.name = f->name, .address = a}); } const Value* tv = Value::MakeTupleValue(std::move(elements)); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(tv)); + frame->todo.Push(Action::MakeValAction(tv)); } // Returns an updated environment that includes the bindings of @@ -615,7 +616,7 @@ void PatternAssignment(const Value* pat, const Value* val, int line_num) { void StepLvalue() { Frame* frame = state->stack.Top(); Action* act = frame->todo.Top(); - const Expression* exp = act->u.exp; + const Expression* exp = act->GetLValAction().exp; if (tracing_output) { std::cout << "--- step lvalue "; PrintExp(exp); @@ -634,7 +635,7 @@ void StepLvalue() { } const Value* v = Value::MakePointerValue(*pointer); frame->todo.Pop(); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } case ExpressionKind::FieldAccessExpression: { @@ -642,7 +643,7 @@ void StepLvalue() { // { {e.f :: C, E, F} :: S, H} // -> { e :: [].f :: C, E, F} :: S, H} frame->todo.Push( - MakeLvalAct(exp->GetFieldAccessExpression().aggregate)); + Action::MakeLValAction(exp->GetFieldAccessExpression().aggregate)); act->pos++; } else { // { v :: [].f :: C, E, F} :: S, H} @@ -652,7 +653,7 @@ void StepLvalue() { GetMember(ValToPtr(str, exp->line_num), exp->GetFieldAccessExpression().field, exp->line_num); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(Value::MakePointerValue(a))); + frame->todo.Push(Action::MakeValAction(Value::MakePointerValue(a))); } break; } @@ -660,10 +661,12 @@ void StepLvalue() { if (act->pos == 0) { // { {e[i] :: C, E, F} :: S, H} // -> { e :: [][i] :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(exp->GetIndexExpression().aggregate)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetIndexExpression().aggregate)); act->pos++; } else if (act->pos == 1) { - frame->todo.Push(MakeExpAct(exp->GetIndexExpression().offset)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetIndexExpression().offset)); act->pos++; } else if (act->pos == 2) { // { v :: [][i] :: C, E, F} :: S, H} @@ -678,7 +681,7 @@ void StepLvalue() { exit(-1); } frame->todo.Pop(1); - frame->todo.Push(MakeValAct(Value::MakePointerValue(*a))); + frame->todo.Push(Action::MakeValAction(Value::MakePointerValue(*a))); } break; } @@ -687,7 +690,7 @@ void StepLvalue() { // { {(f1=e1,...) :: C, E, F} :: S, H} // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H} const Expression* e1 = exp->GetTupleLiteral().fields[0].expression; - frame->todo.Push(MakeLvalAct(e1)); + frame->todo.Push(Action::MakeLValAction(e1)); act->pos++; } else if (act->pos != static_cast(exp->GetTupleLiteral().fields.size())) { @@ -697,7 +700,7 @@ void StepLvalue() { // H} const Expression* elt = exp->GetTupleLiteral().fields[act->pos].expression; - frame->todo.Push(MakeLvalAct(elt)); + frame->todo.Push(Action::MakeLValAction(elt)); act->pos++; } else { CreateTuple(frame, act, exp); @@ -716,8 +719,8 @@ void StepLvalue() { case ExpressionKind::ContinuationTypeLiteral: case ExpressionKind::BindingExpression: { frame->todo.Pop(); - frame->todo.Push(MakeExpToLvalAct()); - frame->todo.Push(MakeExpAct(exp)); + frame->todo.Push(Action::MakeExpToLValAction()); + frame->todo.Push(Action::MakeExpressionAction(exp)); } } } @@ -727,7 +730,7 @@ void StepLvalue() { void StepExp() { Frame* frame = state->stack.Top(); Action* act = frame->todo.Top(); - const Expression* exp = act->u.exp; + const Expression* exp = act->GetExpressionAction().exp; if (tracing_output) { std::cout << "--- step exp "; PrintExp(exp); @@ -736,13 +739,14 @@ void StepExp() { switch (exp->tag()) { case ExpressionKind::BindingExpression: { if (act->pos == 0) { - frame->todo.Push(MakeExpAct(exp->GetBindingExpression().type)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetBindingExpression().type)); act->pos++; } else { auto v = Value::MakeBindingPlaceholderValue( exp->GetBindingExpression().name, act->results[0]); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); } break; } @@ -750,10 +754,12 @@ void StepExp() { if (act->pos == 0) { // { { e[i] :: C, E, F} :: S, H} // -> { { e :: [][i] :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(exp->GetIndexExpression().aggregate)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetIndexExpression().aggregate)); act->pos++; } else if (act->pos == 1) { - frame->todo.Push(MakeExpAct(exp->GetIndexExpression().offset)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetIndexExpression().offset)); act->pos++; } else if (act->pos == 2) { auto tuple = act->results[0]; @@ -771,7 +777,7 @@ void StepExp() { } frame->todo.Pop(1); const Value* element = state->heap.Read(*a, exp->line_num); - frame->todo.Push(MakeValAct(element)); + frame->todo.Push(Action::MakeValAction(element)); break; } default: @@ -790,7 +796,7 @@ void StepExp() { // { {(f1=e1,...) :: C, E, F} :: S, H} // -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H} const Expression* e1 = exp->GetTupleLiteral().fields[0].expression; - frame->todo.Push(MakeExpAct(e1)); + frame->todo.Push(Action::MakeExpressionAction(e1)); act->pos++; } else { CreateTuple(frame, act, exp); @@ -803,7 +809,7 @@ void StepExp() { // H} const Expression* elt = exp->GetTupleLiteral().fields[act->pos].expression; - frame->todo.Push(MakeExpAct(elt)); + frame->todo.Push(Action::MakeExpressionAction(elt)); act->pos++; } else { CreateTuple(frame, act, exp); @@ -815,7 +821,7 @@ void StepExp() { // { { e.f :: C, E, F} :: S, H} // -> { { e :: [].f :: C, E, F} :: S, H} frame->todo.Push( - MakeLvalAct(exp->GetFieldAccessExpression().aggregate)); + Action::MakeLValAction(exp->GetFieldAccessExpression().aggregate)); act->pos++; } else { // { { v :: [].f :: C, E, F} :: S, H} @@ -825,7 +831,7 @@ void StepExp() { exp->GetFieldAccessExpression().field, exp->line_num); const Value* element = state->heap.Read(a, exp->line_num); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(element)); + frame->todo.Push(Action::MakeValAction(element)); } break; } @@ -841,20 +847,22 @@ void StepExp() { } const Value* pointee = state->heap.Read(*pointer, exp->line_num); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(pointee)); + frame->todo.Push(Action::MakeValAction(pointee)); break; } case ExpressionKind::IntLiteral: CHECK(act->pos == 0); // { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H} frame->todo.Pop(1); - frame->todo.Push(MakeValAct(Value::MakeIntValue(exp->GetIntLiteral()))); + frame->todo.Push( + Action::MakeValAction(Value::MakeIntValue(exp->GetIntLiteral()))); break; case ExpressionKind::BoolLiteral: CHECK(act->pos == 0); // { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H} frame->todo.Pop(1); - frame->todo.Push(MakeValAct(Value::MakeBoolValue(exp->GetBoolLiteral()))); + frame->todo.Push( + Action::MakeValAction(Value::MakeBoolValue(exp->GetBoolLiteral()))); break; case ExpressionKind::PrimitiveOperatorExpression: if (act->pos != @@ -864,7 +872,7 @@ void StepExp() { // -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H} const Expression* arg = exp->GetPrimitiveOperatorExpression().arguments[act->pos]; - frame->todo.Push(MakeExpAct(arg)); + frame->todo.Push(Action::MakeExpressionAction(arg)); act->pos++; } else { // { {v :: op(vs,[]) :: C, E, F} :: S, H} @@ -872,19 +880,21 @@ void StepExp() { const Value* v = EvalPrim(exp->GetPrimitiveOperatorExpression().op, act->results, exp->line_num); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); } break; case ExpressionKind::CallExpression: if (act->pos == 0) { // { {e1(e2) :: C, E, F} :: S, H} // -> { {e1 :: [](e2) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(exp->GetCallExpression().function)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetCallExpression().function)); act->pos++; } else if (act->pos == 1) { // { { v :: [](e) :: C, E, F} :: S, H} // -> { { e :: v([]) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(exp->GetCallExpression().argument)); + frame->todo.Push( + Action::MakeExpressionAction(exp->GetCallExpression().argument)); act->pos++; } else if (act->pos == 2) { // { { v2 :: v1([]) :: C, E, F} :: S, H} @@ -900,38 +910,40 @@ void StepExp() { CHECK(act->pos == 0); const Value* v = Value::MakeIntType(); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } case ExpressionKind::BoolTypeLiteral: { CHECK(act->pos == 0); const Value* v = Value::MakeBoolType(); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } case ExpressionKind::AutoTypeLiteral: { CHECK(act->pos == 0); const Value* v = Value::MakeAutoType(); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } case ExpressionKind::TypeTypeLiteral: { CHECK(act->pos == 0); const Value* v = Value::MakeTypeType(); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } case ExpressionKind::FunctionTypeLiteral: { if (act->pos == 0) { - frame->todo.Push(MakeExpAct(exp->GetFunctionTypeLiteral().parameter)); + frame->todo.Push(Action::MakeExpressionAction( + exp->GetFunctionTypeLiteral().parameter)); act->pos++; } else if (act->pos == 1) { // { { pt :: fn [] -> e :: C, E, F} :: S, H} // -> { { e :: fn pt -> []) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(exp->GetFunctionTypeLiteral().return_type)); + frame->todo.Push(Action::MakeExpressionAction( + exp->GetFunctionTypeLiteral().return_type)); act->pos++; } else if (act->pos == 2) { // { { rt :: fn pt -> [] :: C, E, F} :: S, H} @@ -939,7 +951,7 @@ void StepExp() { const Value* v = Value::MakeFunctionType(act->results[0], act->results[1]); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); } break; } @@ -947,16 +959,16 @@ void StepExp() { CHECK(act->pos == 0); const Value* v = Value::MakeContinuationType(); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(v)); + frame->todo.Push(Action::MakeValAction(v)); break; } } // switch (exp->tag) } auto IsWhileAct(Action* act) -> bool { - switch (act->tag) { + switch (act->tag()) { case ActionKind::StatementAction: - switch (act->u.stmt->tag) { + switch (act->GetStatementAction().stmt->tag) { case StatementKind::While: return true; default: @@ -968,9 +980,9 @@ auto IsWhileAct(Action* act) -> bool { } auto IsBlockAct(Action* act) -> bool { - switch (act->tag) { + switch (act->tag()) { case ActionKind::StatementAction: - switch (act->u.stmt->tag) { + switch (act->GetStatementAction().stmt->tag) { case StatementKind::Block: return true; default: @@ -986,7 +998,7 @@ auto IsBlockAct(Action* act) -> bool { void StepStmt() { Frame* frame = state->stack.Top(); Action* act = frame->todo.Top(); - const Statement* stmt = act->u.stmt; + const Statement* stmt = act->GetStatementAction().stmt; CHECK(stmt != nullptr && "null statement!"); if (tracing_output) { std::cout << "--- step stmt "; @@ -998,7 +1010,7 @@ void StepStmt() { if (act->pos == 0) { // { { (match (e) ...) :: C, E, F} :: S, H} // -> { { e :: (match ([]) ...) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetMatch().exp)); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetMatch().exp)); act->pos++; } else { // Regarding act->pos: @@ -1022,7 +1034,7 @@ void StepStmt() { // start interpreting the pattern of the clause // { {v :: (match ([]) ...) :: C, E, F} :: S, H} // -> { {pi :: (match ([]) ...) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(c->first)); + frame->todo.Push(Action::MakeExpressionAction(c->first)); act->pos++; } else { // try to match auto v = act->results[0]; @@ -1036,11 +1048,11 @@ void StepStmt() { frame->scopes.Push(new_scope); const Statement* body_block = Statement::MakeBlock(stmt->line_num, c->second); - Action* body_act = MakeStmtAct(body_block); + Action* body_act = Action::MakeStatementAction(body_block); body_act->pos = 1; frame->todo.Pop(1); frame->todo.Push(body_act); - frame->todo.Push(MakeStmtAct(c->second)); + frame->todo.Push(Action::MakeStatementAction(c->second)); } else { // this case did not match, moving on act->pos++; @@ -1057,14 +1069,14 @@ void StepStmt() { if (act->pos == 0) { // { { (while (e) s) :: C, E, F} :: S, H} // -> { { e :: (while ([]) s) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetWhile().cond)); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetWhile().cond)); act->pos++; } else if (ValToBool(act->results[0], stmt->line_num)) { // { {true :: (while ([]) s) :: C, E, F} :: S, H} // -> { { s :: (while (e) s) :: C, E, F } :: S, H} frame->todo.Top()->pos = 0; frame->todo.Top()->results.clear(); - frame->todo.Push(MakeStmtAct(stmt->GetWhile().body)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetWhile().body)); } else { // { {false :: (while ([]) s) :: C, E, F} :: S, H} // -> { { C, E, F } :: S, H} @@ -1105,7 +1117,7 @@ void StepStmt() { if (stmt->GetBlock().stmt) { auto* scope = new Scope(CurrentEnv(state), {}); frame->scopes.Push(scope); - frame->todo.Push(MakeStmtAct(stmt->GetBlock().stmt)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetBlock().stmt)); act->pos++; act->pos++; } else { @@ -1123,10 +1135,12 @@ void StepStmt() { if (act->pos == 0) { // { {(var x = e) :: C, E, F} :: S, H} // -> { {e :: (var x = []) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetVariableDefinition().init)); + frame->todo.Push( + Action::MakeExpressionAction(stmt->GetVariableDefinition().init)); act->pos++; } else if (act->pos == 1) { - frame->todo.Push(MakeExpAct(stmt->GetVariableDefinition().pat)); + frame->todo.Push( + Action::MakeExpressionAction(stmt->GetVariableDefinition().pat)); act->pos++; } else if (act->pos == 2) { // { { v :: (x = []) :: C, E, F} :: S, H} @@ -1151,7 +1165,7 @@ void StepStmt() { if (act->pos == 0) { // { {e :: C, E, F} :: S, H} // -> { {e :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetExpression())); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetExpression())); act->pos++; } else { frame->todo.Pop(1); @@ -1161,12 +1175,12 @@ void StepStmt() { if (act->pos == 0) { // { {(lv = e) :: C, E, F} :: S, H} // -> { {lv :: ([] = e) :: C, E, F} :: S, H} - frame->todo.Push(MakeLvalAct(stmt->GetAssign().lhs)); + frame->todo.Push(Action::MakeLValAction(stmt->GetAssign().lhs)); act->pos++; } else if (act->pos == 1) { // { { a :: ([] = e) :: C, E, F} :: S, H} // -> { { e :: (a = []) :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetAssign().rhs)); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetAssign().rhs)); act->pos++; } else if (act->pos == 2) { // { { v :: (a = []) :: C, E, F} :: S, H} @@ -1181,20 +1195,20 @@ void StepStmt() { 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} - frame->todo.Push(MakeExpAct(stmt->GetIf().cond)); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetIf().cond)); act->pos++; } else if (ValToBool(act->results[0], stmt->line_num)) { // { {true :: if ([]) then_stmt else else_stmt :: C, E, F} :: // S, H} // -> { { then_stmt :: C, E, F } :: S, H} frame->todo.Pop(1); - frame->todo.Push(MakeStmtAct(stmt->GetIf().then_stmt)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetIf().then_stmt)); } else if (stmt->GetIf().else_stmt) { // { {false :: if ([]) then_stmt else else_stmt :: C, E, F} :: // S, H} // -> { { else_stmt :: C, E, F } :: S, H} frame->todo.Pop(1); - frame->todo.Push(MakeStmtAct(stmt->GetIf().else_stmt)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetIf().else_stmt)); } else { frame->todo.Pop(1); } @@ -1203,7 +1217,7 @@ void StepStmt() { if (act->pos == 0) { // { {return e :: C, E, F} :: S, H} // -> { {e :: return [] :: C, E, F} :: S, H} - frame->todo.Push(MakeExpAct(stmt->GetReturn())); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetReturn())); act->pos++; } else { // { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H} @@ -1212,7 +1226,7 @@ void StepStmt() { DeallocateLocals(stmt->line_num, frame); state->stack.Pop(1); frame = state->stack.Top(); - frame->todo.Push(MakeValAct(ret_val)); + frame->todo.Push(Action::MakeValAction(ret_val)); } break; case StatementKind::Sequence: @@ -1221,9 +1235,9 @@ void StepStmt() { // -> { { s1 :: s2 :: C, E, F} :: S, H} frame->todo.Pop(1); if (stmt->GetSequence().next) { - frame->todo.Push(MakeStmtAct(stmt->GetSequence().next)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetSequence().next)); } - frame->todo.Push(MakeStmtAct(stmt->GetSequence().stmt)); + frame->todo.Push(Action::MakeStatementAction(stmt->GetSequence().stmt)); break; case StatementKind::Continuation: { CHECK(act->pos == 0); @@ -1233,9 +1247,9 @@ void StepStmt() { Stack scopes; scopes.Push(scope); Stack todo; - todo.Push(MakeStmtAct(Statement::MakeReturn( + todo.Push(Action::MakeStatementAction(Statement::MakeReturn( stmt->line_num, Expression::MakeTupleLiteral(stmt->line_num, {})))); - todo.Push(MakeStmtAct(stmt->GetContinuation().body)); + todo.Push(Action::MakeStatementAction(stmt->GetContinuation().body)); Frame* continuation_frame = new Frame("__continuation", scopes, todo); Address continuation_address = state->heap.AllocateValue( Value::MakeContinuationValue({continuation_frame})); @@ -1251,14 +1265,15 @@ void StepStmt() { case StatementKind::Run: if (act->pos == 0) { // Evaluate the argument of the run statement. - frame->todo.Push(MakeExpAct(stmt->GetRun().argument)); + frame->todo.Push(Action::MakeExpressionAction(stmt->GetRun().argument)); act->pos++; } else { frame->todo.Pop(1); // Push an expression statement action to ignore the result // value from the continuation. - Action* ignore_result = MakeStmtAct(Statement::MakeExpStmt( - stmt->line_num, Expression::MakeTupleLiteral(stmt->line_num, {}))); + Action* ignore_result = Action::MakeStatementAction( + Statement::MakeExpStmt(stmt->line_num, Expression::MakeTupleLiteral( + stmt->line_num, {}))); ignore_result->pos = 0; frame->todo.Push(ignore_result); // Push the continuation onto the current stack. @@ -1329,7 +1344,7 @@ auto GetMember(Address a, const std::string& f, int line_num) -> Address { void InsertDelete(Action* del, Stack& todo) { if (!todo.IsEmpty()) { - switch (todo.Top()->tag) { + switch (todo.Top()->tag()) { case ActionKind::StatementAction: { // This places the delete before the enclosing statement. // Not sure if that is OK. Conceptually it should go after @@ -1362,24 +1377,24 @@ void Step() { } Action* act = frame->todo.Top(); - switch (act->tag) { + switch (act->tag()) { case ActionKind::DeleteTmpAction: - state->heap.Deallocate(act->u.delete_tmp); + state->heap.Deallocate(act->GetDeleteTmpAction().delete_tmp); frame->todo.Pop(1); - frame->todo.Push(MakeValAct(act->results[0])); + frame->todo.Push(Action::MakeValAction(act->results[0])); break; case ActionKind::ExpToLValAction: { Address a = state->heap.AllocateValue(act->results[0]); - auto del = MakeDeleteAct(a); + auto del = Action::MakeDeleteTmpAction(a); frame->todo.Pop(1); InsertDelete(del, frame->todo); - frame->todo.Push(MakeValAct(Value::MakePointerValue(a))); + frame->todo.Push(Action::MakeValAction(Value::MakePointerValue(a))); break; } case ActionKind::ValAction: { Action* val_act = frame->todo.Pop(); Action* act = frame->todo.Top(); - act->results.push_back(val_act->u.val); + act->results.push_back(val_act->GetValAction().val); break; } case ActionKind::LValAction: @@ -1405,7 +1420,7 @@ auto InterpProgram(std::list* fs) -> int { const Expression* arg = Expression::MakeTupleLiteral(0, {}); const Expression* call_main = Expression::MakeCallExpression( 0, Expression::MakeIdentifierExpression(0, "main"), arg); - auto todo = Stack(MakeExpAct(call_main)); + auto todo = Stack(Action::MakeExpressionAction(call_main)); auto* scope = new Scope(globals, std::list()); auto* frame = new Frame("top", Stack(scope), todo); state->stack = Stack(frame); @@ -1417,29 +1432,29 @@ auto InterpProgram(std::list* fs) -> int { while (state->stack.CountExceeds(1) || state->stack.Top()->todo.CountExceeds(1) || - state->stack.Top()->todo.Top()->tag != ActionKind::ValAction) { + state->stack.Top()->todo.Top()->tag() != ActionKind::ValAction) { Step(); if (tracing_output) { PrintState(std::cout); } } - const Value* v = state->stack.Top()->todo.Top()->u.val; + const Value* v = state->stack.Top()->todo.Top()->GetValAction().val; return ValToInt(v, 0); } // Interpret an expression at compile-time. auto InterpExp(Env values, const Expression* e) -> const Value* { - auto todo = Stack(MakeExpAct(e)); + auto todo = Stack(Action::MakeExpressionAction(e)); auto* scope = new Scope(values, std::list()); auto* frame = new Frame("InterpExp", Stack(scope), todo); state->stack = Stack(frame); while (state->stack.CountExceeds(1) || state->stack.Top()->todo.CountExceeds(1) || - state->stack.Top()->todo.Top()->tag != ActionKind::ValAction) { + state->stack.Top()->todo.Top()->tag() != ActionKind::ValAction) { Step(); } - const Value* v = state->stack.Top()->todo.Top()->u.val; + const Value* v = state->stack.Top()->todo.Top()->GetValAction().val; return v; }