summaryrefslogtreecommitdiff
path: root/Parser.hs
blob: f2961ba9d9f8f5ebebb14ae93e13523fda09773a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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