+traceMachine :: ProgrammedMachine ()
+traceMachine = do
+ isTracing <- gets _tracing
+ when isTracing
+ do cip <- gets _ip
+ opcode <- getLocation cip
+ a <- getLocation (cip + 1)
+ b <- getLocation (cip + 2)
+ c <- getLocation (cip + 3)
+ let sa = show a
+ let sb = show b
+ let sc = show c
+ va <- getValue (cip + 1)
+ vb <- getValue (cip + 2)
+ vc <- getValue (cip + 3)
+ let sva = show va
+ let svb = show vb
+ let svc = show vc
+ let traceText =
+ case opcode of
+ 0 -> ["halt"]
+ 1 -> ["set", sa, sb, "*", sva, svb]
+ 2 -> ["push", sa, "*", sva]
+ 3 -> ["pop", sa, "*", sva]
+ 4 -> ["eq", sa, sb, sc, "*", sva, svb, svc]
+ 5 -> ["gt", sa, sb, sc, "*", sva, svb, svc]
+ 6 -> ["jmp", sa, "*", sva]
+ 7 -> ["jt", sa, sb, "*", sva, svb]
+ 8 -> ["jf", sa, sb, "*", sva, svb]
+ 9 -> ["add", sa, sb, sc, "*", sva, svb, svc]
+ 10 -> ["mul", sa, sb, sc, "*", sva, svb, svc]
+ 11 -> ["mod", sa, sb, sc, "*", sva, svb, svc]
+ 12 -> ["and", sa, sb, sc, "*", sva, svb, svc]
+ 13 -> ["or", sa, sb, sc, "*", sva, svb, svc]
+ 14 -> ["not", sa, sb, "*", sva, svb]
+ 15 -> ["rmem", sa, sb, "*", sva, svb]
+ 16 -> ["wmem", sa, sb, "*", sva, svb]
+ 17 -> ["call", sa, "*", sva]
+ 18 -> ["ret"]
+ 19 -> ["out", sa, "*", sva]
+ 20 -> ["in", sa, "*", sva]
+ 21 -> ["noop", sa, sb, sc, "*", sva, svb, svc]
+ _ -> ["illegal", sa, sb, sc, "*", sva, svb, svc]
+ tell $ fmap (fromIntegral . ord) (">> " ++ (show cip) ++ ": " ++ (intercalate " " traceText) ++ "<<")
+