5 import Text.ParserCombinators.ReadP hiding ((+++), choice)
7 newtype Program = Program [AST]
10 instance Read Program where
11 readPrec = fmap Program $ lift $ sepBy1 (readS_to_P reads) $ do
16 data AST = Function String [String] Expr
20 | BinOp BinOpType Expr Expr
25 data BinOpType = Add | Sub | Mul | Cmp Ordering
28 instance Read AST where
29 readPrec = parseFunction +++ (Eval <$> readPrec)
30 where parseFunction = lift $ do
34 name <- munch1 isAlpha
35 params <- between (char '(') (char ')') $
36 sepBy (munch1 isAlpha) skipSpaces
38 body <- readS_to_P reads
39 return (Function name params body)
41 instance Read Expr where
42 readPrec = choice [ parseParens
50 , parseBinOp ">" (Cmp GT)
51 , parseBinOp "<" (Cmp LT)
52 , parseBinOp "==" (Cmp EQ)
54 where parseParens = step $ lift $
55 between (char '(') (char ')') (readS_to_P reads)
56 parseNum = Num <$> readPrec
57 parseVar = Var <$> lift (munch1 isAlpha)
59 func <- lift (munch1 isAlpha)
60 params <- lift $ between (char '(') (char ')') $
61 sepBy (readS_to_P reads)
62 (skipSpaces >> char ',' >> skipSpaces)
63 return (Call func params)
64 parseBinOp s typ = step $ do
71 return (BinOp typ a b)
81 thenE <- step readPrec
86 elseE <- step readPrec
87 return (If cond thenE elseE)