X-Git-Url: http://git.lukelau.me/?p=timetravel.git;a=blobdiff_plain;f=AST.hs;fp=AST.hs;h=cf1fc409c70e16b5754a9f4d1d2274ca51e8f92f;hp=0000000000000000000000000000000000000000;hb=9a09a1be54afb5e15dfea8a8676bd6e1941b37ec;hpb=7c8e673e4ad1b59527ae5fb6f15365e4f40905c6 diff --git a/AST.hs b/AST.hs new file mode 100644 index 0000000..cf1fc40 --- /dev/null +++ b/AST.hs @@ -0,0 +1,84 @@ +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) +