Advertisement
Guest User

Tinker Interpreter v2

a guest
Aug 2nd, 2015
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.List
  2.  
  3. type Program = ([String], [String], Int, Int, [Int])
  4.  
  5. replace :: [a] -> [a] -> Int -> a -> [a]
  6. replace lst infTail index str =
  7.     if index < (length lst)
  8.         then (take index lst) ++ [str] ++ (drop (index + 1) lst)
  9.     else
  10.         replace (lst ++ infTail) infTail index str
  11.  
  12. getValue :: String -> Int
  13. getValue str = if (head str) == '#' then read (tail str) else 0
  14.  
  15. firstOutermostBracketAndComplement :: String -> (String, String)
  16. firstOutermostBracketAndComplement str = ((takeWhile ('[' ==) str) ++ (takeWhile (']' /=) (dropWhile ('[' ==) str)) ++ (map (\x -> ']') [1..depth]), (dropWhile (']' ==) (dropWhile (']' /=) str)))
  17.     where depth = length (takeWhile ('[' ==) str)
  18.  
  19. separateFirstInstruction :: String -> (String, String)
  20. separateFirstInstruction str
  21.     |elem c "io._$>^v" = ([c], tail str)
  22.     |c == '[' = firstOutermostBracketAndComplement str
  23.     |c == '{' = (str, "")
  24.     |elem c "#+-" = ([c] ++ takeWhile (\x -> elem x "0123456789") (tail str), dropWhile (\x -> elem x "0123456789") (tail str))
  25.         where c = head str
  26.  
  27. splitIntoInstructions' :: String -> [String]
  28. splitIntoInstructions' str
  29.     |str == "" = []
  30.     |otherwise = [inst] ++ (splitIntoInstructions' rest) --map (\x -> "_") [0..]
  31.         where (inst, rest) = separateFirstInstruction str
  32.  
  33. splitIntoInstructions :: String -> [String]
  34. splitIntoInstructions str = if notElem '{' str then splitIntoInstructions' (str ++ "{_}") else splitIntoInstructions' str
  35.  
  36. setUpProgram :: [String] -> Program
  37. setUpProgram lst = if start == [] then ((init lst), infiniteTail, 0, 0, []) else ((init lst), infiniteTail, 0, (\(Just x) -> x) (elemIndex (head start) lst), [])
  38.        where start = filter (\x -> (head x) == '*') lst
  39.              infiniteTail = splitIntoInstructions' (tail (init (last lst)))
  40.  
  41. performStep :: Program -> Program
  42. performStep (source, infiniteTail, value, location, out)
  43.         |s == "_" = (source, infiniteTail, value, location + 1, out)
  44.         |s == "$" = (source, infiniteTail, location, location + 1, out)
  45.         |s == ">" = (source, infiniteTail, value, value, out)
  46.         |s == "^" = (source, infiniteTail, getValue (source !! value), location + 1, out)
  47.         |head s == '+' = (source, infiniteTail, value + (read (tail s)), location + 1, out)
  48.         |head s == '-' = (source, infiniteTail, value - (read (tail s)), location + 1, out)
  49.         |head s == '#' = (source, infiniteTail, read (tail s), location + 1, out)
  50.         |head s == '[' = (replace source infiniteTail value (init (tail s)), infiniteTail, value, location + 1, out)
  51.         |s == "v" = (replace source infiniteTail location ("#" ++ (show value)), infiniteTail, value, location + 1, out)
  52.         |s == "o" = (source, infiniteTail, value, location + 1, out ++ [value])
  53.                 where s = source !! location
  54.  
  55. runProgram :: Program -> [Int] -> [Int]
  56. runProgram (source, infiniteTail, value, location, out) inp
  57.         |location >= (length source) - 1 = runProgram (source ++ infiniteTail, infiniteTail, value, location, out) inp
  58.         |source !! location == "." = out
  59.         |source !! location == "i" = runProgram (source, infiniteTail, head inp, location + 1, out) (tail inp)
  60.         |otherwise = runProgram (performStep (source, infiniteTail, value, location, out)) inp
  61. --                where s = source !! location
  62.                
  63. executeProgram :: String -> [Int] -> [Int]
  64. executeProgram src inp = runProgram (setUpProgram (splitIntoInstructions src)) inp
  65.  
  66. executeProgramNoInput :: String -> [Int]
  67. executeProgramNoInput src = executeProgram src []
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement