Advertisement
Baidicoot

FarTooGeneral

Apr 22nd, 2020
442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Control.Monad ((>=>))
  2.  
  3. data Elem a = Leaf | Node a | Branch (Elem a) (Elem a) deriving(Show)
  4.  
  5. data Ins i d
  6.     = PutState
  7.     | TakeState
  8.     | Exec
  9.     | Define
  10.     | Lookup
  11.     | Lit d
  12.    -- | Ins i
  13.     deriving(Eq, Show)
  14.  
  15. data RunErr
  16.     = TypeErr
  17.     | OutOfRange
  18.     | InsErr
  19.     deriving(Show)
  20.  
  21. toList :: [a] -> Elem a
  22. toList [] = Leaf
  23. toList (x:xs) = Branch (Node x) (toList xs)
  24.  
  25. unwrapNode :: Elem a -> Either RunErr a
  26. unwrapNode (Node a) = Right a
  27. unwrapNode _ = Left TypeErr
  28.  
  29. {- STACK/LIST OPERATIONS -}
  30.  
  31. top :: Elem a -> Either RunErr (Elem a)
  32. top (Branch x _) = Right x
  33. top Leaf = Left OutOfRange
  34. top (Node _) = Left TypeErr
  35.  
  36. pop :: Elem a -> Either RunErr (Elem a)
  37. pop (Branch _ xs) = Right xs
  38. pop Leaf = Left OutOfRange
  39. pop (Node _) = Left TypeErr
  40.  
  41. tpop :: Elem a -> Either RunErr (Elem a, Elem a) -- (top, pop)
  42. tpop (Branch x xs) = Right (x, xs)
  43. tpop Leaf = Left OutOfRange
  44. tpop (Node _) = Left TypeErr
  45.  
  46. push :: Elem a -> Elem a -> Either RunErr (Elem a)
  47. push x = Right . Branch x
  48.  
  49. append :: Elem a -> Elem a -> Either RunErr (Elem a)
  50. append e (Branch x xs) = (append e xs) >>= (\xs' -> return (Branch x xs'))
  51. append e Leaf = Right (Branch e Leaf)
  52. append _ _ = Left TypeErr
  53.  
  54. {- MAP OPERATIONS -}
  55.  
  56. indexMap :: (Eq a) => a -> Elem a -> Either RunErr (Elem a)
  57. indexMap a map = do
  58.     e <- top map
  59.     case e of
  60.         (Branch (Node a') e) | a == a' -> return e
  61.         (Branch (Node _) _) -> do
  62.             map' <- pop map
  63.            indexMap a map'
  64.         _ -> Left TypeErr
  65.  
  66. appendMap :: a -> Elem a -> Elem a -> Either RunErr (Elem a)
  67. appendMap k v = append (Branch (Node k) v)
  68.  
  69. {- INSTRUCTION OPERATIONS -}
  70.  
  71. single :: (Eq i, Eq d) => Ins i d -> Elem (Ins i d) -> Either RunErr (Elem (Ins i d))
  72. single PutState e = do
  73.     (stack, map) <- tpop e
  74.     stack' <- push e stack
  75.    return (Branch stack' map)
  76. single TakeState e = top e >>= (\state -> top state)
  77. single Define e = do
  78.     (stack, map) <- tpop e
  79.     k <- (top >=> unwrapNode) stack
  80.     (v, stack') <- (pop >=> tpop) stack
  81.    map' <- appendMap k v map
  82.     return (Branch stack' map')
  83. single Lookup e = do
  84.     (stack, map) <- tpop e
  85.     k <- (top >=> unwrapNode) stack
  86.     v <- indexMap k map
  87.     stack' <- (pop >=> push v) stack
  88.    return (Branch stack' map)
  89. single Exec e = do
  90.     (stack, map) <- tpop e
  91.     (v, stack') <- tpop stack
  92.    multiple v (Branch stack' map)
  93. single d e = do
  94.     stack <- top e
  95.     map <- pop e
  96.     stack' <- push (Node d) stack
  97.    return (Branch stack' map)
  98.  
  99. multiple :: (Eq i, Eq d) => Elem (Ins i d) -> Elem (Ins i d) -> Either RunErr (Elem (Ins i d))
  100. multiple (Branch (Node ins) next) state = single ins state >>= (\state' -> multiple next state')
  101. multiple Leaf state = Right state -- return once program is finished
  102. multiple _ _ = Left TypeErr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement