git @ Cat's Eye Technologies Turmac / b2b1a6c
Checkpoint fixing gentape subcommand. Chris Pressey 4 months ago
2 changed file(s) with 29 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
55
66 import Data.Char (digitToInt)
77
8 -- Function to generate Turmac rules for writing a string
9 generateTapeWriter :: String -> String
10 generateTapeWriter input = unlines $
8 import Language.Turmac.Model
9
10
11 -- Function to generate Turmac rules for writing a sequence of symbols to the tape
12 generateTapeWriter :: [Symbol] -> [TMRule]
13 generateTapeWriter symbols = unlines $
1114 -- Header line
1215 ["in state,if the symbol is,write the symbol,move the head,go to state"] ++
1316 -- Rules for writing each symbol
1619 moveBackRules
1720 where
1821 -- Generate rules for writing each digit in sequence
19 writeRules = zipWith makeWriteRule [0..] (map digitToInt input)
22 writeRules = zipWith makeWriteRule [0..] symbols
2023
2124 -- Generate rules for moving back to start
2225 moveBackRules =
23 if null input
26 if null symbols
2427 then []
25 else makeBackwardRules (length input) (length input)
28 else makeBackwardRules (length symbols) (length symbols)
2629
27 renderRule :: Int -> Int -> Int -> Char -> Int -> String
28 renderRule state1 sym1 sym2 dir state2 =
29 let
30 st1 = "S" ++ (show state1)
31 st2 = if state2 == -1 then "H" else "S" ++ (show state2)
32 in
33 st1 ++ "," ++ (show sym1) ++ "," ++ (show sym2) ++ "," ++ [dir] ++ "," ++ st2
34
35 -- Create a rule for writing a single digit
36 makeWriteRule :: Int -> Int -> String
37 makeWriteRule state digit =
38 renderRule state 0 digit 'R' (state + 1)
30 -- Create a rule for writing a single symbol
31 makeWriteRule :: Int -> Symbol -> TMRule
32 makeWriteRule state symbol =
33 ("S" ++ show state, "_", symbol, "S" ++ show (state + 1), 1)
3934
4035 -- Create rules for moving back to start
41 makeBackwardRules :: Int -> Int -> [String]
36 makeBackwardRules :: StateId -> Int -> [TMRule]
4237 makeBackwardRules state numMoves =
4338 let
4439 moves = replicate numMoves 'L'
4742 lastState = if null moves then state else state + numMoves
4843 -- For each state in backtracking phase, generate rules for all possible symbols
4944 rules = concatMap (\(s, ns, dir) ->
50 [renderRule s sym sym dir ns | sym <- [0..2]]) -- Handle symbols 0, 1, and 2
45 [(s, sym, sym, ns, dir) | sym <- ["S0", "S1", "S2"]]) -- Handle symbols 0, 1, and 2
5146 (zip3 states (init nextStates) moves)
5247 -- Final state also needs rules for all symbols
5348 finalRules =
54 [renderRule (lastState -1) sym sym 'L' (-1) | sym <- [0..2]]
49 [((lastState - 1), sym, sym, "H", (-1)) | sym <- ["S0", "S1", "S2"]]
5550 in
5651 rules ++ finalRules
4040 trace = False
4141 }
4242
43 -- Note: this is a terrible little hack
44 splitOnCommas s =
45 words [if c == ',' then ' ' else c|c <- s]
46
4347 parseFlags flags ("--backend":s:rest) =
4448 parseFlags flags{ backend = s } rest
4549 parseFlags flags ("--check-complete":rest) =
4650 parseFlags flags{ checkComplete = True } rest
4751 parseFlags flags ("--initial-tape":s:rest) =
48 parseFlags flags{ initialTape = words [if c == ',' then ' ' else c|c <- s] } rest
52 parseFlags flags{ initialTape = splitOnCommas s } rest
4953 parseFlags flags ("--max-steps":n:rest) =
5054 parseFlags flags{ maxSteps = read n } rest
5155 parseFlags flags ("--trace":rest) =
111115 putStrLn $ "Error parsing input file: " ++ errMsg
112116 exitWith $ ExitFailure 1
113117
114 ["gentape", str] -> do
115 putStr $ generateTapeWriter str
118 ["gentape", tapeContents] -> do
119 symbols <- splitOnCommas tapeContents
120 putStr $ generateTapeWriter symbols
116121 exitWith ExitSuccess
117122
118123 _ -> do
119124 putStrLn "Usage: turmac {flags} simulate <turmac-description-file>"
120125 putStrLn " turmac {flags} compile <turmac-description-file>"
121 putStrLn " turmac {flags} gentape <string-of-digits>"
126 putStrLn " turmac {flags} gentape <comma-separated-list-of-symbols>"
122127 putStrLn " where flags are:"
123 putStrLn " --backend : when compiling, specifies backend to use"
124 putStrLn " --check-complete : check description is complete beforehand"
125 putStrLn " --initial-tape : comma-seperated symbols initially on tape"
126 putStrLn " --trace : when simulating, display each step taken"
128 putStrLn " --backend when compiling, specifies backend to use"
129 putStrLn " --check-complete check description is complete beforehand"
130 putStrLn " --initial-tape when simulating, gives initial contents of tape"
131 putStrLn " --trace when simulating, display each step taken"
127132 exitWith $ ExitFailure 2