81 lines
2.5 KiB
Haskell
81 lines
2.5 KiB
Haskell
module Main where
|
|
|
|
import Data.Char
|
|
import Data.Sequence hiding (null)
|
|
import System.Console.Haskeline
|
|
import System.Environment
|
|
|
|
name :: String
|
|
name = "brainfuck"
|
|
|
|
version :: String
|
|
version = "0.1.0"
|
|
|
|
prompt :: String
|
|
prompt = name ++ "> "
|
|
|
|
printUsage :: IO ()
|
|
printUsage = do printVersion
|
|
putStrLn("\nUsage: " ++
|
|
"\n\twithout arguments - runs REPL" ++
|
|
"\n\t-h/--help - display this help message" ++
|
|
"\n\nMore information can be found on " ++
|
|
"https://github.com/hellerve/unlambda")
|
|
|
|
printVersion :: IO ()
|
|
printVersion = putStrLn (name ++ " Version " ++ version)
|
|
|
|
printCommands :: IO ()
|
|
printCommands = putStrLn "Press Ctrl-C to exit interpreter"
|
|
|
|
program :: String -> Seq Int -> Int -> IO ()
|
|
program "" _ _ = return ()
|
|
program ('>' : l) tape ptr = program l tape (ptr+1)
|
|
program ('<' : l) tape ptr = program l tape (ptr-1)
|
|
program ('+' : l) tape ptr = let newtape = update ptr ((index tape ptr) + 1) tape
|
|
in program l newtape ptr
|
|
program ('-' : l) tape ptr = let newtape = update ptr ((index tape ptr) - 1) tape
|
|
in program l newtape ptr
|
|
program ('.' : l) tape ptr = do putChar $ chr $ index tape ptr
|
|
program l tape ptr
|
|
program (',' : l) tape ptr = do x <- getChar
|
|
let newtape = update ptr (ord x) tape
|
|
program l newtape ptr
|
|
program (x : _) _ _ = putStrLn ("Unknown instruction: " ++ [x])
|
|
|
|
main :: IO ()
|
|
main = do
|
|
args <- getArgs
|
|
if null args
|
|
then do printVersion
|
|
printCommands
|
|
putStrLn ""
|
|
repl
|
|
else
|
|
if(head args == "-h") || (head args == "--help")
|
|
then printUsage
|
|
else exec args
|
|
|
|
exec :: [String] -> IO ()
|
|
exec _ = undefined
|
|
|
|
getInput :: IO String
|
|
getInput = runInputT defaultSettings repl_
|
|
where repl_ = do
|
|
x <- getInputLine "> "
|
|
case x of
|
|
Nothing -> return ""
|
|
Just i -> return i
|
|
|
|
repl :: IO ()
|
|
repl = do input <- getInput
|
|
case input of
|
|
"" -> repl
|
|
"quit" -> putStrLn "Bye"
|
|
x -> do program x (zeroes 30000 empty) 0
|
|
putStrLn ""
|
|
repl
|
|
where zeroes :: Int -> Seq Int -> Seq Int
|
|
zeroes 0 l = l
|
|
zeroes n l = zeroes (n-1) (l |> 0)
|