module AST where
import Text.Read
-import Text.ParserCombinators.ReadP hiding ((+++))
+import Text.ParserCombinators.ReadP hiding ((+++), choice)
data Expr = Num Float
- | Add Expr Expr
+ | BinOp BinOp Expr Expr
+ deriving Show
+
+data BinOp = Add | Sub | Mul | Cmp Ordering
deriving Show
instance Read Expr where
- readPrec = parseNum +++ parseAdd
+ readPrec = choice [ parseNum
+ , parseBinOp "<" 10 (Cmp LT)
+ , parseBinOp "+" 20 Add
+ , parseBinOp "-" 20 Sub
+ , parseBinOp "*" 40 Mul
+ ]
where parseNum = Num <$> readPrec
-- use 'prec 1' and 'step' so that parsing 'a'
-- can only go one step deep, to prevent ininfite
-- recursion
- parseAdd = prec 1 $ do
+ parseBinOp s prc op = prec prc $ do
a <- step readPrec
lift $ do
skipSpaces
- char '+'
+ string s
skipSpaces
b <- readPrec
- return (Add a b)
+ return (BinOp op a b)
+