git @ Cat's Eye Technologies Burro / a8064fc
Improve debugger visualization, again. Chris Pressey a month ago
1 changed file(s) with 31 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
66 import Control.Monad.Trans.State (StateT, evalStateT, get, put, modify)
77 import Control.Monad.IO.Class
88 import System.Environment
9
910 import Language.Burro.Definition hiding (get, exec, run, interpret)
1011 import qualified Language.Burro.Definition as Burro
1112
13
1214 -- Debugger state containing indentation level, tape position and Burro state
1315 data DebugState = DebugState {
14 indentLevel :: Int,
16 indents :: [String],
1517 tapePos :: Integer,
1618 burroState :: State
1719 }
2325 x | x >= 0 -> str ++ (replicate x ' ')
2426 _ -> str
2527
26 indentation :: Int -> String
27 indentation n = replicate (n * 4) ' '
28 -- | Visualize the current execution state of the Burro program in a readable way.
29 dump :: Burro -> DebuggerM ()
30 dump p = do
31 ds <- get
32 liftIO $ putStrLn $ showState (burroState ds) (tapePos ds) (indents ds) p
2833
29 -- | Visualize the current execution state of the Burro program in a readable way.
30 dump :: Burro -> String -> DebuggerM ()
31 dump p msg = do
32 ds <- get
33 liftIO $ putStrLn $ showState (burroState ds) (tapePos ds) (indentLevel ds) p msg
34
35 showState (State tape stack halt) pos indent p msg =
34 showState (State tape stack halt) pos indents p =
3635 let
3736 tapes = ljust 40 $ "(" ++ show tape ++ ")@" ++ show pos
3837 stacks = ljust 20 $ "(" ++ show stack ++ ")"
3938 halts = if halt then "[H]" else "[_]"
40 desc = indentation indent ++ show p ++ " " ++ msg
39 desc = concat (map (\i -> i ++ " ") indents) ++ show p
4140 in
4241 tapes ++ stacks ++ " " ++ halts ++ " " ++ desc
4342
44 withIndent :: DebuggerM a -> DebuggerM a
45 withIndent action = do
46 modify (\s -> s { indentLevel = indentLevel s + 1 })
43 withIndent :: String -> DebuggerM a -> DebuggerM a
44 withIndent x action = do
45 modify (\s -> s { indents = (x:indents s) })
4746 result <- action
48 modify (\s -> s { indentLevel = indentLevel s - 1 })
47 modify (\s -> s { indents = tail $ indents s })
4948 return result
5049
5150 exec :: Burro -> DebuggerM ()
5554
5655 exec Null = do
5756 ds <- get
58 dump Null ""
57 dump Null
5958
6059 exec ToggleHalt = do
6160 ds <- get
62 dump ToggleHalt ""
61 dump ToggleHalt
6362 let State dat stack halt = burroState ds
6463 let newState = State dat stack (not halt)
6564 put ds { burroState = newState }
6665
6766 exec Inc = do
6867 ds <- get
69 dump Inc ""
68 dump Inc
7069 let State dat stack halt = burroState ds
7170 let newState = State (inc dat) stack halt
7271 put ds { burroState = newState }
7372
7473 exec Dec = do
7574 ds <- get
76 dump Dec ""
75 dump Dec
7776 let State dat stack halt = burroState ds
7877 let newState = State (dec dat) stack halt
7978 put ds { burroState = newState }
8079
8180 exec GoLeft = do
8281 ds <- get
83 dump GoLeft ""
82 dump GoLeft
8483 let State dat stack halt = burroState ds
8584 let newState = State (left dat) stack halt
8685 modify (\s -> s { tapePos = tapePos s - 1, burroState = newState })
8786
8887 exec GoRight = do
8988 ds <- get
90 dump GoRight ""
89 dump GoRight
9190 let State dat stack halt = burroState ds
9291 let newState = State (right dat) stack halt
9392 modify (\s -> s { tapePos = tapePos s + 1, burroState = newState })
9493
9594 exec p@(Test thn els) = do
9695 ds <- get
97 dump p "[test]"
96 dump p
9897 let State dat stack halt = burroState ds
9998 let x = Burro.get dat
10099 let (dat', stack') = swap dat stack
102101 let s' = State dat' stack'' halt
103102 put ds { burroState = s' }
104103
105 withIndent $
106 if x > 0 then do
107 dump thn "[then]"
104 if x > 0 then
105 withIndent "[then]" $ do
106 dump thn
108107 exec thn
109 else if x < 0 then do
110 dump els "[else]"
108 else if x < 0 then
109 withIndent "[else]" $ do
110 dump els
111111 exec els
112 else do
113 dump Null "[non]"
112 else do
113 withIndent "[non-]" $ do
114 dump Null
114115
115116 ds' <- get
116117 let State dat'' stack''' halt' = burroState ds'
135136 interpret :: Burro -> IO ()
136137 interpret program = do
137138 let initialState = DebugState {
138 indentLevel = 0,
139 indents = [],
139140 tapePos = 0,
140141 burroState = newstate
141142 }