Guest User

Untitled

a guest
Sep 27th, 2014
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Prelude
  2. import System.Environment
  3. import Data.Array
  4.  
  5. type Memory = [Int]
  6.  
  7. data Registers = Registers { pc :: Int,
  8.                              is :: Int,
  9.                              r0 :: Int,
  10.                              r1 :: Int
  11.                            } deriving (Show)
  12.  
  13. type State = (Memory, Registers)
  14.  
  15. emptyMem ::     Int -> Memory
  16. emptyMem size = take size $ repeat 0
  17.  
  18. constructMem :: [String] -> Memory
  19. constructMem s = constructMemFromString s 16
  20.  
  21. constructMemFromString ::            [String] -> Int -> Memory
  22. constructMemFromString code size = (take size (map (constrain . read) code)) ++ emptyMem (size - length code)
  23.  
  24. setMemVal :: Memory -> Int -> Int -> Memory
  25. setMemVal (x:xs) i v
  26.    | i == 0    = [v] ++ xs
  27.    | otherwise = x:(setMemVal xs (i-1) v)
  28.  
  29. getMemVal :: Memory -> Int -> Int
  30. getMemVal m v = m !! v
  31.  
  32. constructRegisters = (Registers 0 0 0 0)
  33.  
  34. getPC :: Registers -> Int
  35. getPC (Registers pc _ _ _) = pc
  36.  
  37. constrain :: Int -> Int
  38. constrain x = mod x 16
  39.  
  40. add (m, Registers pc is r0 r1 ) =
  41.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) (constrain (r0 + r1)) r1)
  42.  
  43. sub (m, Registers pc is r0 r1 ) =
  44.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) (constrain (r0 - r1)) r1)
  45.  
  46. incR0 (m, Registers pc is r0 r1 ) =
  47.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) (constrain (r0 + 1)) r1)
  48.  
  49. incR1 (m, Registers pc is r0 r1 ) =
  50.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) r0 (constrain (r1 + 1)))
  51.  
  52. decR0 (m, Registers pc is r0 r1 ) =
  53.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) (constrain (r0 - 1)) r1)
  54.  
  55. decR1 (m, Registers pc is r0 r1 ) =
  56.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) r0 (constrain (r1 - 1)))
  57.  
  58. ding (m, Registers pc is r0 r1 ) = do {
  59.    putStrLn "DING!";
  60.    return $ (m, Registers (constrain (pc + 1)) (getMemVal m pc) r0 r1);
  61. }
  62.  
  63. out (m, Registers pc is r0 r1 ) = do {
  64.    putStrLn $ show $ getMemVal m (constrain (pc + 1));
  65.    return $ (m, Registers (constrain (pc + 2)) (getMemVal m pc) r0 r1);
  66. }
  67.  
  68. loadR0 (m, Registers pc is r0 r1 ) =
  69.    return $ (m, Registers (constrain (pc + 2)) (getMemVal m pc) (getMemVal m (getMemVal m (constrain (pc + 1)))) r1)
  70.  
  71. loadR1 (m, Registers pc is r0 r1 ) =
  72.    return $ (m, Registers (constrain (pc + 2)) (getMemVal m pc) r0 (getMemVal m (getMemVal m (constrain (pc + 1)))))
  73.  
  74. storeR0 (m, Registers pc is r0 r1 ) =
  75.    return $ (setMemVal m (getMemVal m (constrain (pc + 1))) r0, Registers (constrain (pc + 2)) (getMemVal m pc) r0 r1)
  76.  
  77. storeR1 (m, Registers pc is r0 r1 ) =
  78.    return $ (setMemVal m (getMemVal m (constrain (pc + 1))) r1, Registers (constrain (pc + 2)) (getMemVal m pc) r0 r1)
  79.  
  80. jmp (m, Registers pc is r0 r1 ) =
  81.    return $ (m, Registers (constrain (getMemVal m (pc + 1))) (getMemVal m pc) r0 r1)
  82.  
  83. jmpR0 (m, Registers pc is r0 r1 ) =
  84.    return $ if r0 == 0 then (m, Registers (constrain (getMemVal m (pc + 1))) is r0 r1) else (m, Registers (pc + 1) (getMemVal m pc) r0 r1)
  85.  
  86. jmpNotR0 (m, Registers pc is r0 r1 ) =
  87.    return $ if r0 /= 0 then (m, Registers (constrain (getMemVal m (pc + 1))) is r0 r1) else (m, Registers (pc + 1) (getMemVal m pc) r0 r1)
  88.  
  89. executeInstruction :: State -> Int -> IO State
  90. executeInstruction s nis
  91.    | nis == 1 = add s
  92.    | nis == 2 = sub s
  93.    | nis == 3 = incR0 s
  94.    | nis == 4 = incR1 s
  95.    | nis == 5 = decR0 s
  96.    | nis == 6 = decR1 s
  97.    | nis == 7 = ding s
  98.    | nis == 8 = out s
  99.    | nis == 9 = loadR0 s
  100.    | nis == 10 = loadR1 s
  101.    | nis == 11 = storeR0 s
  102.    | nis == 12 = storeR1 s
  103.    | nis == 13 = jmp s
  104.    | nis == 14 = jmpR0 s
  105.    | nis == 15 = jmpNotR0 s
  106.    | otherwise = return s
  107.  
  108. fetchExecute :: State -> IO State
  109. fetchExecute (m, r) = executeInstruction (m, r) (getMemVal m (getPC r))
  110.  
  111. run :: State -> IO()
  112. run (m,r) = do
  113.    if getMemVal m (getPC r) == 0 then return () else do {
  114.       newState <- fetchExecute (m,r);
  115.       run newState;
  116.    }
  117.  
  118. main = do {
  119.     args <- getArgs;
  120.    run ((constructMem args), (constructRegisters))
  121. }
Advertisement
Add Comment
Please, Sign In to add comment