git @ Cat's Eye Technologies ZOWIE / da19d96
Factor out. Chris Pressey 11 months ago
5 changed file(s) with 113 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
0 module Language.ZOWIE.Machine where
1
2 import Language.ZOWIE.Registers
3 import Language.ZOWIE.State
4
5
6 run s = s
0 module Language.ZOWIE.Registers where
1
2 import Language.ZOWIE.State
3
4 data Register = TtyRegister
5 | BeginTransactionRegister
6 | CommitRegister
7 | CommitAndRepeatRegister
8 | AdditionRegister
9 | SubtractionRegister
10 | MultiplicationRegister
11 | NegationRegister
12 | RegularRegister Addr
13
14
15 mapRegister 0 = TtyRegister
16 mapRegister 1 = BeginTransactionRegister
17 mapRegister 2 = CommitRegister
18 mapRegister 3 = CommitAndRepeatRegister
19 mapRegister 4 = AdditionRegister
20 mapRegister 5 = SubtractionRegister
21 mapRegister 6 = MultiplicationRegister
22 mapRegister 7 = NegationRegister
23 mapRegister x = RegularRegister x
24
25 readAddr :: State -> Addr -> IO Value
26 readAddr state@State{ mem=mem } addr =
27 case mapRegister addr of
28 TtyRegister -> do
29 i <- readLn
30 return i
31 BeginTransactionRegister -> return 1
32 CommitRegister -> return 2
33 CommitAndRepeatRegister -> return 3
34 AdditionRegister -> return 4
35 SubtractionRegister -> return 5
36 MultiplicationRegister -> return 6
37 NegationRegister -> return 7
38 RegularRegister x -> return (readMem mem x)
39
40 writeAddr :: State -> Addr -> Value -> IO State
41 writeAddr state@State{ mem=mem } addr payload =
42 case mapRegister addr of
43 TtyRegister -> do
44 print payload
45 return state
46 BeginTransactionRegister ->
47 return $ beginTransaction state
48 CommitRegister ->
49 return $ if payload > 0 then commit state else rollback state
50 CommitAndRepeatRegister ->
51 return $ if payload > 0 then commitAndRepeat state else commit state
52 AdditionRegister ->
53 return state{ mem=(writeMem mem 8 ((readMem mem 8) + payload)) }
54 SubtractionRegister ->
55 return state{ mem=(writeMem mem 8 ((readMem mem 8) - payload)) }
56 MultiplicationRegister ->
57 return state{ mem=(writeMem mem 8 ((readMem mem 8) * payload)) }
58 NegationRegister ->
59 return state{ mem=(writeMem mem 8 (if payload == 0 then 1 else 0)) }
60 RegularRegister x ->
61 return state{ mem=(writeMem mem x payload) }
0 module Language.ZOWIE.State where
1
2 import qualified Data.Map.Strict as Map
3
4
5 type Addr = Integer
6 type Value = Integer
7
8 type Memory = Map.Map Addr Value
9
10 data Instruction = Immediate Addr Value
11 | Direct Addr Addr
12 | Indirect Addr Addr Value
13 deriving (Show, Ord, Eq)
14
15 data State = State {
16 pc :: Addr,
17 mem :: Memory,
18 prog :: [Instruction],
19 saved :: Maybe State
20 } deriving (Show, Ord, Eq)
21
22
23 readMem mem addr = Map.findWithDefault 0 addr mem
24 writeMem mem addr value = Map.insert addr value mem
25
26
27 beginTransaction :: State -> State
28 beginTransaction state@State{} =
29 state{ saved=(Just state) }
30
31 rollback :: State -> State
32 rollback state@State{ pc=pc, saved=(Just previous) } =
33 previous{ pc=pc }
34
35 commit :: State -> State
36 commit state@State{ saved=(Just previous) } =
37 state{ saved=(saved previous) }
38
39 commitAndRepeat :: State -> State
40 commitAndRepeat state@State{ saved=(Just previous) } =
41 state{ pc=((pc previous) - 1) }
+0
-107
impl/ZOWIE.hs/src/Language/ZOWIE.hs less more
0 module Language.ZOWIE where
1
2 import qualified Data.Map.Strict as Map
3
4
5 type Addr = Integer
6 type Value = Integer
7 type Memory = Map.Map Addr Value
8
9 readMem mem addr = Map.findWithDefault 0 addr mem
10 writeMem mem addr value = Map.insert addr value mem
11
12 data Instruction = Immediate Addr Value
13 | Direct Addr Addr
14 | Indirect Addr Addr Value
15 deriving (Show, Ord, Eq)
16
17 data State = State {
18 pc :: Addr,
19 mem :: Memory,
20 prog :: [Instruction],
21 saved :: Maybe State
22 } deriving (Show, Ord, Eq)
23
24 data Register = TtyRegister
25 | BeginTransactionRegister
26 | CommitRegister
27 | CommitAndRepeatRegister
28 | AdditionRegister
29 | SubtractionRegister
30 | MultiplicationRegister
31 | NegationRegister
32 | RegularRegister Addr
33
34
35 mapRegister 0 = TtyRegister
36 mapRegister 1 = BeginTransactionRegister
37 mapRegister 2 = CommitRegister
38 mapRegister 3 = CommitAndRepeatRegister
39 mapRegister 4 = AdditionRegister
40 mapRegister 5 = SubtractionRegister
41 mapRegister 6 = MultiplicationRegister
42 mapRegister 7 = NegationRegister
43 mapRegister x = RegularRegister x
44
45
46 readAddr :: State -> Addr -> IO Value
47 readAddr state@State{ mem=mem } addr =
48 case mapRegister addr of
49 TtyRegister -> do
50 i <- readLn
51 return i
52 BeginTransactionRegister -> return 1
53 CommitRegister -> return 2
54 CommitAndRepeatRegister -> return 3
55 AdditionRegister -> return 4
56 SubtractionRegister -> return 5
57 MultiplicationRegister -> return 6
58 NegationRegister -> return 7
59 RegularRegister x -> return (readMem mem x)
60
61
62 writeAddr :: State -> Addr -> Value -> IO State
63 writeAddr state@State{ mem=mem } addr payload =
64 case mapRegister addr of
65 TtyRegister -> do
66 print payload
67 return state
68 BeginTransactionRegister ->
69 return $ beginTransaction state
70 CommitRegister ->
71 return $ if payload > 0 then commit state else rollback state
72 CommitAndRepeatRegister ->
73 return $ if payload > 0 then commitAndRepeat state else commit state
74 AdditionRegister ->
75 return state{ mem=(writeMem mem 8 ((readMem mem 8) + payload)) }
76 SubtractionRegister ->
77 return state{ mem=(writeMem mem 8 ((readMem mem 8) - payload)) }
78 MultiplicationRegister ->
79 return state{ mem=(writeMem mem 8 ((readMem mem 8) * payload)) }
80 NegationRegister ->
81 return state{ mem=(writeMem mem 8 (if payload == 0 then 1 else 0)) }
82 RegularRegister x ->
83 return state{ mem=(writeMem mem x payload) }
84
85
86 beginTransaction :: State -> State
87 beginTransaction state@State{} =
88 state{ saved=(Just state) }
89
90
91 rollback :: State -> State
92 rollback state@State{ pc=pc, saved=(Just previous) } =
93 previous{ pc=pc }
94
95
96 commit :: State -> State
97 commit state@State{ saved=(Just previous) } =
98 state{ saved=(saved previous) }
99
100
101 commitAndRepeat :: State -> State
102 commitAndRepeat state@State{ saved=(Just previous) } =
103 state{ pc=((pc previous) - 1) }
104
105
106 run s = s
33 import System.Exit
44 import System.IO
55
6 import Language.ZOWIE
6 import qualified Language.ZOWIE.Machine as Machine
77
88
99 main = do
1111 case args of
1212 ["run", fileName] -> do
1313 text <- readFile fileName
14 putStrLn $ show $ reverse $ run text
14 putStrLn $ show $ reverse $ Machine.run text
1515 return ()
1616 _ -> do
1717 abortWith "Usage: zowie run <carriage-program-text-filename>"