--- /dev/null
+module AST where
+
+import Text.ParserCombinators.ReadP
+import Text.Read (readPrec, lift)
+import Data.Char
+import Data.Functor
+
+{-------------------------------------------------------------------}
+{- The pure expression language -}
+{-------------------------------------------------------------------}
+
+data Val = I Int | B Bool
+ deriving Eq
+
+instance Show Val where
+ show (I x) = show x
+ show (B x) = show x
+
+data Expr = Const Val
+ | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr
+ | And Expr Expr | Or Expr Expr | Not Expr
+ | Eq Expr Expr | Gt Expr Expr | Lt Expr Expr
+ | Var String
+ deriving Eq
+
+instance Show Expr where
+ show (Const v) = show v
+ show (Add e1 e2) = show e1 ++ " + " ++ show e2
+ show (Sub e1 e2) = show e1 ++ " - " ++ show e2
+ show (Mul e1 e2) = show e1 ++ " * " ++ show e2
+ show (Div e1 e2) = show e1 ++ " / " ++ show e2
+ show (And e1 e2) = show e1 ++ " & " ++ show e2
+ show (Or e1 e2) = show e1 ++ " | " ++ show e2
+ show (Not e) = "!" ++ show e
+ show (Eq e1 e2) = show e1 ++ " == " ++ show e2
+ show (Gt e1 e2) = show e1 ++ " > " ++ show e2
+ show (Lt e1 e2) = show e1 ++ " < " ++ show e2
+ show (Var s) = s
+
+instance Read Expr where
+ readPrec = lift pExpr
+ where
+ pExpr = pVar +++ pLit +++ pBinOp
+ pBrackets = between (char '(') (char ')')
+
+ pVar = Var <$> munch1 isLetter
+ pLit = pLit' B +++ pLit' I
+ pLit' x = Const . x <$> readS_to_P (readsPrec 10000)
+
+ pBinOp = do
+ -- TODO: figure out how to just use pExpr without getting
+ -- stuck recursively
+ e1 <- pVar +++ pLit +++ pBrackets pBinOp
+ skipSpaces
+ op <- pOp
+ skipSpaces
+ e2 <- pVar +++ pLit +++ pBrackets pBinOp
+ return (op e1 e2)
+
+ pOp = choice
+ [ string "==" $> Eq
+ , char '+' $> Add
+ , char '-' $> Sub
+ , char '*' $> Mul
+ , char '/' $> Div
+ , char '&' $> And
+ , char '|' $> Or
+ , char '>' $> Gt
+ , char '<' $> Lt
+ ]
+
+{-------------------------------------------------------------------}
+{- The statement language -}
+
+
+data Statement = Assign String Expr
+ | If Expr Statement Statement
+ | While Expr Statement
+ | Print Expr
+ | Seq Statement Statement
+ | Try Statement Statement
+ | Pass
+ deriving (Eq, Show)
+