-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSyntax.hs
56 lines (39 loc) · 1.81 KB
/
Syntax.hs
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
module Syntax
( Instruction(..)
, SyntaxTree
, ParseError
, showParseError
, parse
) where
import Control.Arrow (first)
data Instruction = IncrementPointer -- >
| DecrementPointer -- <
| IncrementByte -- +
| DecrementByte -- -
| Output -- .
| Input -- ,
| Squared [Instruction] -- [ ... ]
deriving (Show)
type SyntaxTree = [Instruction]
type ParseError = String
showParseError :: ParseError -> IO ()
showParseError = putStrLn
parse :: String -> Either ParseError SyntaxTree
parse str = fst <$> parse' 0 str
parse' :: Int -> String -> Either ParseError (SyntaxTree, String)
parse' 0 [] = Right ([], [])
parse' depth [] = Left "Error: Unbalanced square brackets"
parse' depth (x:xs) = case x of
'>' -> continueParsing IncrementPointer xs
'<' -> continueParsing DecrementPointer xs
'+' -> continueParsing IncrementByte xs
'-' -> continueParsing DecrementByte xs
'.' -> continueParsing Output xs
',' -> continueParsing Input xs
'[' -> uncurry continueParsing . first Squared =<< parse' (depth + 1) xs
']' -> if depth == 0
then Left "Error: Unbalanced square brackets"
else Right ([], xs)
_ -> parse' depth xs
where continueParsing :: Instruction -> String -> Either ParseError (SyntaxTree, String)
continueParsing instr cont = first (instr :) <$> parse' depth cont