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 [ parseNum
49 , parseBinOp ">" (Cmp GT)
50 , parseBinOp "<" (Cmp LT)
51 , parseBinOp "==" (Cmp EQ)
53 where parseNum = Num <$> readPrec
54 parseVar = Var <$> lift (munch1 isAlpha)
56 func <- lift (munch1 isAlpha)
57 params <- lift $ between (char '(') (char ')') $
58 sepBy (readS_to_P reads)
59 (skipSpaces >> char ',' >> skipSpaces)
60 return (Call func params)
61 parseBinOp s typ = step $ do
68 return (BinOp typ a b)
78 thenE <- step readPrec
83 elseE <- step readPrec
84 return (If cond thenE elseE)