Advertisement
Guest User

Untitled

a guest
Jul 28th, 2014
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. -- PCA machine implemented!
  2. -- use like:
  3. -- > ghc --make -o eval Main.hs
  4. -- > ./eval "k(skk)(ss)k"
  5. -- or:
  6. -- ghci Main.hs
  7. -- > run "skkk"
  8. --
  9. -- Note that the parser is hillariously permissive, stripping all non s,k,(,) symbols
  10. -- before starting. It also parses (sk))k (and really shouldn't), so no guarantees
  11. -- about what happens if your string is not a vaild expression. (WHY?)
  12. --
  13. -- ... It does work for all the valid expressions I have tried.
  14.  
  15. module Main where
  16.  
  17. import Text.ParserCombinators.Parsec hiding (State)
  18. import System.Environment
  19.  
  20. main :: IO ()
  21. main = do
  22. args <- getArgs
  23. putStrLn . show . run $ (args !! 0)
  24.  
  25.  
  26. data PCAExpr = EK | ES | Ap PCAExpr PCAExpr
  27. deriving (Show)
  28.  
  29.  
  30. parseTerm :: Parser PCAExpr
  31. parseTerm = do
  32. apps <- many1 (parseBr <|> parseS <|> parseK)
  33. return $ foldl1 Ap apps
  34.  
  35.  
  36. parseBr :: Parser PCAExpr
  37. parseBr = do
  38. char '('
  39. x <- parseTerm
  40. char ')'
  41. return x
  42.  
  43. parseS :: Parser PCAExpr
  44. parseS = (char 's' <|> char 'S') >> (return ES)
  45.  
  46. parseK :: Parser PCAExpr
  47. parseK = (char 'k' <|> char 'K') >> (return EK)
  48.  
  49. -- next, operational semantics of machine
  50.  
  51. type State = (Code, Value, Stack)
  52.  
  53. type Code = Item
  54.  
  55. type Value = Item
  56. https://forge.cpsc.ucalgary.ca/svn/research/pll/papers/Chad/PCAMachine/Main.hs
  57. type Stack = [Item]
  58.  
  59. data Item = K
  60. | S
  61. | K0 Item
  62. | S0 Item
  63. | S1 (Item, Item)
  64. | C0 (Item, Item)
  65. | C1 (Item)
  66. | End
  67. deriving (Show, Eq)
  68.  
  69. step :: State -> State
  70. step (K, x, stk) = (End, (K0 x), stk)
  71. step (S, x, stk) = (End, (S0 x), stk)
  72. step (S0 x, y, stk) = (End, (S1 (x,y)), stk)
  73. step (K0 x, y, stk) = (End, x, stk)
  74. step (S1 (x,y), z, stk) = (x, z, ((C0 (y,z)) : stk))
  75. step (End, v, (C0 (y,z)) : stk) = (y, z, (C1 v) : stk)
  76. step (End, v, (C1 w) : stk) = (w, v, stk)
  77.  
  78. eval :: State -> Item
  79. eval (End, x, []) = x
  80. eval state = eval (step state)
  81.  
  82. trace :: State -> IO ()
  83. trace (End, x, []) = do putStrLn (show x)
  84. trace st = do putStrLn (show st)
  85. trace (step st)
  86.  
  87. -- schenanigans to ignore parsing errors because It seems like too
  88. -- much trouble.
  89.  
  90. generateCode :: PCAExpr -> Item -- should just be code, maybe state.
  91. generateCode EK = K
  92. generateCode ES = S
  93. generateCode (Ap t1 t2) = eval ((generateCode t1), (generateCode t2), [])
  94.  
  95. run :: String -> Item
  96. run = generateCode . erase . (parse parseTerm "error") . (filter cheatyPredicate)
  97.  
  98. -- our parser is really, really permissive :D
  99.  
  100. cheatyPredicate :: Char -> Bool
  101. cheatyPredicate 's' = True
  102. cheatyPredicate 'S' = True
  103. cheatyPredicate 'k' = True
  104. cheatyPredicate 'K' = True
  105. cheatyPredicate '(' = True
  106. cheatyPredicate ')' = True
  107. cheatyPredicate _ = False
  108.  
  109. erase :: Either parseError PCAExpr -> PCAExpr
  110. erase (Left _) = error "that didn't work!"
  111. erase (Right exp) = exp
  112.  
  113. -- examples
  114.  
  115. skk = run "skk"
  116.  
  117. skkk = run "skkk"
  118.  
  119. ssss = run "ssss"
  120.  
  121. skss = run "skss"
  122.  
  123. ssks = run "ssks"
  124.  
  125. bigex = run "k(skk)(sk)k"
  126.  
  127. -- the thingy appears to work!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement