summaryrefslogtreecommitdiff
path: root/parser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'parser.hs')
-rw-r--r--parser.hs33
1 files changed, 33 insertions, 0 deletions
diff --git a/parser.hs b/parser.hs
new file mode 100644
index 0000000..f2961ba
--- /dev/null
+++ b/parser.hs
@@ -0,0 +1,33 @@
+module Parser(parseProgram) where
+
+import AST
+
+
+parseProgram :: String -> Either String Program
+parseProgram src = do
+ (inss, "") <- parseLoop 0 src
+ return $ Program $ IStart : inss
+
+parseLoop :: Int -> String -> Either String ([Instruction], String)
+parseLoop 0 "" = Right ([], "")
+parseLoop _ "" = Left "More '[' than ']'"
+parseLoop 0 (']':_) = Left "Unexpected ']'"
+parseLoop _ (']':cs) = Right ([], cs)
+parseLoop d ('[':cs) = do
+ (lp, rest) <- parseLoop (d+1) cs
+ (after, rest') <- parseLoop d rest
+ return (ILoop lp 0 : after, rest')
+parseLoop d (c:cs)
+ | Just ins <- parseSimple c = do
+ (lp, rest) <- parseLoop d cs
+ return (ins:lp, rest)
+parseLoop d (_:cs) = parseLoop d cs
+
+parseSimple :: Char -> Maybe Instruction
+parseSimple '+' = Just $ IAdd 1 0
+parseSimple '-' = Just $ IAdd (-1) 0
+parseSimple '>' = Just $ ISlide 1
+parseSimple '<' = Just $ ISlide (-1)
+parseSimple ',' = Just $ IInput 0
+parseSimple '.' = Just $ IOutput 0
+parseSimple _ = Nothing