unwind :: GMState -> GMState
unwind state
    = newState (hLookup heap a)
    where
        (a:as) = getStack state
        heap = getHeap state
        ((i, stack):dump) = getDump state
        newState (NNum n) 
            = putCode i (putStack (a:stack) (putDump dump state))
        newState (NAp a1 a2) = putCode [Unwind] (putStack (a1:a:as) state) 
        newState (NGlobal n c)
            | length as >= n = putCode c (putStack as' state)
            | otherwise      = putCode i (putStack (last (a:as):stack) (putDump dump state))
            where as' = rearrange n heap (a:as)
        newState (NInd aInd) = putCode [Unwind] (putStack (aInd:as) state)
        newState (NConstr t as)
            = putCode i (putStack (a:stack) (putDump dump state))
unwind :: GMState -> GMState
unwind state
    = newState (hLookup heap a)
    where
        (a:as) = getStack state
        heap = getHeap state
        ((i, stack):dump) = getDump state
        newState (NNum n) 
            = putCode i (putStack (a:stack) (putDump dump state))
        newState (NAp a1 a2) = putCode [Unwind] (putStack (a1:a:as) state) 
        newState (NGlobal n c)
            | length as >= n = putCode c (putStack as' state)
            | otherwise      = putCode i (putStack (last (a:as):stack) (putDump dump state))
            where as' = rearrange n heap (a:as)
        newState (NInd aInd) = putCode [Unwind] (putStack (aInd:as) state)
        newState (NConstr t as)
            = putCode i (putStack (a:stack) (putDump dump state))
unwind state
    = newState (hLookup heap a)
    where
        (a:as) = getStack state
        heap = getHeap state
        ((i, stack):dump) = getDump state
        newState (NNum n) 
            = putCode i (putStack (a:stack) (putDump dump state))
        newState (NAp a1 a2) = putCode [Unwind] (putStack (a1:a:as) state) 
        newState (NGlobal n c)
            | length as >= n = putCode c (putStack as' state)
            | otherwise      = putCode i (putStack (last (a:as):stack) (putDump dump state))
            where as' = rearrange n heap (a:as)
        newState (NInd aInd) = putCode [Unwind] (putStack (aInd:as) state)
        newState (NConstr t as)
            = putCode i (putStack (a:stack) (putDump dump state))