private static GmState StepUnwind(GmInstruction.Unwind _, GmState state)
        {
            var head     = state.Stack.Peek();
            var headNode = state.Heap[head];

            return(headNode switch
            {
                GmNode.Number num => UnwindNum(num, state),
                GmNode.Application ap => UnwindAp(ap, state),
                GmNode.Global global => UnwindGlobal(global, state),
                GmNode.Indirection ind => UnwindInd(ind, state),

                _ => throw new ArgumentOutOfRangeException(nameof(headNode))
            });
        private static GmState Step(GmState state)
        {
            var(instruction, newState) = state.DequeueInstruction();

            return(instruction switch
            {
                GmInstruction.PushGlobal pushGlobal => StepPushGlobal(pushGlobal, newState),
                GmInstruction.PushInt pushInt => StepPushInt(pushInt, newState),
                GmInstruction.MkAp mkAp => StepMkAp(mkAp, newState),
                GmInstruction.Push push => StepPush(push, newState),
                GmInstruction.Update update => StepUpdate(update, newState),
                GmInstruction.Pop pop => StepPop(pop, newState),
                GmInstruction.Slide slide => StepSlide(slide, newState),
                GmInstruction.Alloc alloc => StepAlloc(alloc, newState),
                GmInstruction.Unwind unwind => StepUnwind(unwind, newState),
                GmInstruction.Eval eval => StepEval(eval, newState),
                GmInstruction.Prim prim => StepPrim(prim, newState),
                GmInstruction.Cond cond => StepCond(cond, newState),

                _ => throw new ArgumentOutOfRangeException(nameof(instruction))
            });