import Data.Map.Strict ((!))
import Control.Lens
import Data.List
+import Data.Char
import Numeric
import Control.Monad.State.Strict
, _registers :: Memory
, _inputIndex :: Int
, _stack :: [Word16]
+ , _tracing :: Bool
}
deriving (Show, Eq, Ord)
makeLenses ''Machine
, _registers = M.fromList [ (r, 0) | r <- [0..7] ]
, _memory = memory
, _stack = []
+ , _tracing = False
}
-- traceMachine x =
runAll :: ProgrammedMachine ExecutionState
runAll = do cip <- gets _ip
opcode <- getLocation cip
+ traceMachine
-- opcode' <- traceMachine opcode
-- exState <- runStep opcode'
exState <- runStep opcode
else do let char = (inputs!!iIndex)
putValue tgt char
modify (\m -> m & inputIndex %~ (+ 1))
- advanceIP 2
+ advanceIP 2
return Runnable
runStep 21 =
return Runnable
+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) ++ "<<")
+
getValue :: Word16 -> ProgrammedMachine Word16
getValue loc =
do mem <- gets _memory