module CC.AST.Typed( module CC.AST.Typed, module CC.Types ) where import Data.List import CC.Pretty import CC.Types data Program = Program [Def] deriving (Show, Read) data Def = Def Name Expr deriving (Show, Read) data Type = TFun Type Type | TInt | TTup [Type] | TyVar Int deriving (Show, Read) data TypeScheme = TypeScheme [Int] Type deriving (Show, Read) data Expr = Lam Type Occ Expr | Let Occ Expr Expr | Call Type Expr Expr | Int Int | Tup [Expr] | Var Occ deriving (Show, Read) data Occ = Occ Name Type deriving (Show, Read) exprType :: Expr -> Type exprType (Lam typ _ _) = typ exprType (Let _ _ body) = exprType body exprType (Call typ _ _) = typ exprType (Int _) = TInt exprType (Tup es) = TTup (map exprType es) exprType (Var (Occ _ typ)) = typ instance Pretty Type where prettyPrec _ TInt = "Int" prettyPrec p (TFun a b) = precParens p 2 (prettyPrec 3 a ++ " -> " ++ prettyPrec 2 b) prettyPrec _ (TTup ts) = "(" ++ intercalate ", " (map pretty ts) ++ ")" prettyPrec _ (TyVar i) = 't' : show i instance Pretty TypeScheme where prettyPrec p (TypeScheme bnds ty) = precParens p 2 ("forall " ++ intercalate " " (map (pretty . TyVar) bnds) ++ ". " ++ prettyPrec 2 ty) instance Pretty Expr where prettyPrec p (Lam ty (Occ n t) e) = precParens p 2 $ "(\\(" ++ n ++ " :: " ++ pretty t ++ ") -> " ++ prettyPrec 2 e ++ ") :: " ++ pretty ty prettyPrec p (Let (Occ n t) rhs e) = precParens p 2 $ "let (" ++ n ++ " :: " ++ pretty t ++ ") = " ++ pretty rhs ++ " " ++ (case e of Let _ _ _ -> pretty e _ -> "in " ++ pretty e) prettyPrec p (Call ty e1 e2) = precParens p 2 $ prettyPrec 3 e1 ++ " " ++ prettyPrec 3 e2 ++ " :: " ++ pretty ty prettyPrec _ (Int i) = show i prettyPrec _ (Tup es) = "(" ++ intercalate ", " (map pretty es) ++ ")" prettyPrec p (Var (Occ n t)) = precParens p 2 $ show n ++ " :: " ++ pretty t instance Pretty Def where pretty (Def n e) = n ++ " = " ++ pretty e instance Pretty Program where pretty (Program defs) = concatMap ((++ "\n") . pretty) defs