module Typecheck (inferExpr, checkExpr) where import Syntax import Control.Monad type Environment = [(Idnt,Typ)] assertInt TInt = Just () assertInt _ = Nothing assertRec (TRecord ts) = Just ts assertRec _ = Nothing assertVar (TVariant ts) = Just ts assertVar _ = Nothing assertPtr (TPtr t) = Just t assertPtr _ = Nothing inferExpr :: Expr -> Environment -> Maybe Typ inferExpr (Var name) env = lookup name env inferExpr (IntLit _) _ = Just TInt inferExpr (Record _) _ = undefined inferExpr (Variant t v e) env = do ts <- assertVar t tt <- lookup v ts checkExpr e env tt return t inferExpr (Add e1 e2) env = do checkExpr e1 env TInt checkExpr e2 env TInt return TInt inferExpr (Mult e1 e2) env = do checkExpr e1 env TInt checkExpr e2 env TInt return TInt inferExpr (Neg e) env = do checkExpr e env TInt return TInt inferExpr (Deref e1) env = do t <- inferExpr e1 env tt <- assertPtr t return tt checkExpr :: Expr -> Environment -> Typ -> Maybe () checkExpr e env t = do t' <- inferExpr e env guard (t==t') return ()