data Exp a b c = Lit a | Bop b (Exp a b c) (Exp a b c) | Occ c | Set v (Exp a b c) | Let c (Exp a b c) (Exp a b c) data Var = Var Char type Expr = Exp Val Opr Var data Stmt = Simple Expr | If Expr Stmt Stmt | Block [Stmt] | While Expr Stmt type Val = Either Int Bool type State = Var -> Val type Cmd = State -> State eval :: Expr -> Env -> Val tran :: Stmt -> Env -> Cmd tt, ff :: Val tt = Right True ff = Right False num :: Int -> Val num = Left litb :: Bool -> Expr Val b c litn :: Int -> Expr Val b c litn = Lit . Left litb = Lit . Right type Env = [(Var, Val)] type Tnv = [(Var, Tipe)] data Tipe = TInt | TBool data TBop = (Tipe, Tipe, Tipe) data TSig = [(Opr,TSig)] same x@(Just x') (Just y') = if x'==y' then x else Nothing same _ _ = Nothing tchk :: Expr -> Tnv -> Maybe Tipe tchk (Lit (Left _)) tnv = TInt tchk (Lit (Right _)) tnv = TInt tchk (Occ x) tnv = tnv x tchk (Bop b tchk (Set x e) tnv = same (tnv x) (tchk tnv e)