summaryrefslogtreecommitdiff
path: root/bf.hs
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2013-03-03 18:43:23 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2013-03-03 18:43:23 +0000
commita519418a10475f69255cb0d38cc84edea853f6fc (patch)
tree5240f88d4b311d544bd26a3603c434ac3306e0f9 /bf.hs
parente153db198ee560438315d6b45d49cc16a58c0d1d (diff)
downloadbf-a519418a10475f69255cb0d38cc84edea853f6fc.tar.bz2
Initial version from Episode 3 of 'AiH'
Enjoy playing with this -- we will extend it to include executing the code next time.
Diffstat (limited to 'bf.hs')
-rw-r--r--bf.hs48
1 files changed, 48 insertions, 0 deletions
diff --git a/bf.hs b/bf.hs
new file mode 100644
index 0000000..8b757b6
--- /dev/null
+++ b/bf.hs
@@ -0,0 +1,48 @@
+import Text.Parsec
+import Text.Parsec.String
+
+data BFInstruction = GoBack | GoForward | Increment | Decrement | Input
+ | Output | Loop [BFInstruction]
+ deriving (Show)
+
+parseBack, parseForward, parseIncrement, parseLoop,
+ parseDecrement, parseInput, parseOutput :: Parser BFInstruction
+
+parseGen :: Char -> BFInstruction -> Parser BFInstruction
+parseGen x y = char x >> return y
+
+parseBack = parseGen '<' GoBack
+parseForward = parseGen '>' GoForward
+parseIncrement = parseGen '+' Increment
+parseDecrement = parseGen '-' Decrement
+parseInput = parseGen ',' Input
+parseOutput = parseGen '.' Output
+
+parseLoop = do
+ char '['
+ insn <- parseInstructions
+ char ']'
+ return $ Loop insn
+
+parseComment :: Parser ()
+parseComment = do
+ many $ noneOf "<>+-,.[]"
+ return ()
+
+parseInstruction :: Parser BFInstruction
+parseInstruction = do
+ parseComment
+ i <- parseBack <|> parseForward <|> parseIncrement <|> parseDecrement
+ <|> parseInput <|> parseOutput <|> parseLoop
+ parseComment
+ return i
+
+parseInstructions :: Parser [BFInstruction]
+parseInstructions = many parseInstruction
+
+main :: IO ()
+main = do
+ cont <- readFile "hello.bf"
+ case parse parseInstructions "hello.bf" cont of
+ Left e -> print e
+ Right insn -> print insn