summaryrefslogtreecommitdiff
path: root/prototypes/Inspector.hs
blob: b725294dce88db8b3b8031af8fa827afe39f3781 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Data.List
import Data.Maybe
import Control.Arrow
import Control.Category hiding ((.), id)
import Control.Monad.Writer
import Control.Monad.State
import Control.Monad.Identity
import Debug.Trace
import System.Environment
import System.IO

import LambdaCube.Compiler.Pretty

import LamMachine

--------------------------------------------------------------------------------

data StepTree a b
    = NoStep
--    | Ready a
    | Step a b (StepTree a b)
    | Steps a (StepTree a b) (StepTree a b)
  deriving Show

stepTree :: MSt -> StepTree StepTag MSt
stepTree = fst . steps 0
                       (runState $ return NoStep)
                       (\t c -> runState $ Step t <$> get <*> state c)
                       (\t c2 c1 -> runState $ Steps t <$> state c1 <*> state c2)

stepList (initSt -> st) = ("Start", st): f (stepTree st)
  where
    f = \case
        NoStep -> []
        Step t x st -> (t, x): f st
        Steps _ a b -> f a ++ f b


data Command = UpArrow | DownArrow | LeftArrow | RightArrow
    | IntArg Int | ProgramChange
    deriving (Eq, Show)

getCommand pr msg = do
  putStr $ (if pr then "\n" else "\CR") ++ "-------------- " ++ msg ++ " --------> "
  getChar >>= \case
    '\ESC' -> getChar >>= \case
     '[' -> getChar >>= \case
      'A' -> c 4 >> ret UpArrow
      'B' -> c 4 >> ret DownArrow
      'C' -> c 4 >> ret LeftArrow
      'D' -> c 4 >> ret RightArrow
      c -> clear c
     c -> clear c
    d | '0' <= d && d <= '9' -> readI [d]
    'n' -> ret ProgramChange
    c -> clear c
  where
    ret a = {-putStr ("  --  " ++ show a) >> -} return a
    readI ds = getChar >>= \case
        d | '0' <= d && d <= '9' -> readI $ d: ds
        '\n' -> c 1 >> ret (IntArg $ read $ reverse ds)
        c -> clear c
    clear _ = getCommand True msg
    c n = replicateM n $ putChar '\b'


main = do
  hSetBuffering stdin NoBuffering
  hSetBuffering stdout NoBuffering
  getArgs >>= \case
    [b, n] -> 
        putStrLn $ ppShow $ hnf $ case b of
            "lazy" -> t' $ read n
            "seq" -> t'' $ read n
    _ -> cycle True mempty
  where
    cycle (pr :: Bool) st = do
        n <- getCommand pr $ message st
        case (n, st) of
            (DownArrow, st@(_, _:_:_)) -> cycle' $ goLeft st
            (UpArrow, st@(_:_, _)) -> cycle' $ goRight st
            (LeftArrow, st@(_, _:_:_)) -> cycle' $ iterate goLeft st !! 100
            (RightArrow, st@(_:_, _)) -> cycle' $ iterate goRight st !! 100
            (IntArg n, _) -> cycle' ([], stepList $ t' n)
            (ProgramChange, _) -> cycle' ([], stepList $ test) --t'' 0)
            _ ->  cycle False st

    cycle' st@(h, (_, x): _) = do
        putStr $ "\n" ++ ppShow x
        cycle True st
    cycle' st = cycle True st

    goLeft (xs, y: ys) = (y: xs, ys)
    goLeft xs = xs
    goRight (x: xs, ys) = (xs, x: ys)
    goRight xs = xs

    message ([], []) = ""
    message (h, x) = show (length h) ++ " " ++ f x
        where
          f ((msg,_):_) = msg
          f _ = ""

mread :: Read a => String -> Maybe a
mread s = case reads s of
    [(a, "")] -> Just a
    _ -> Nothing