module Core.Pretty(showPretty, dropModule, isOperator) where import List import Maybe import Char import Core.CoreType dropModule :: String -> String dropModule x = f x False x where f x False ('.':_) = x f _ True ('.':x) = f x False x f x _ (_:xs) = f x True xs f x _ [] = x isOperator x = case dropModule x of (x:_) | isAlphaNum x || x `elem` "'_" -> False _ -> True showPretty :: Core -> String showPretty x = unlines $ showCore x indent :: [String] -> [String] indent = map (" " ++) showCore :: Core -> [String] showCore (Core modName depends xs) = ("module " ++ modName ++ " where") : "" : map ("import " ++) depends ++ "" : showItems xs showItems :: [CoreItem] -> [String] showItems xs = concat $ intersperse [[]] $ map showItem xs showItem :: CoreItem -> [String] showItem (CoreData name free []) = ["data " ++ name ++ concatMap (' ':) free] showItem (CoreData name free (c:tors)) = ("data " ++ name ++ concatMap (' ':) free ++ " =") : (" " ++ showCtor c) : (indent $ map (("| " ++) . showCtor) tors) showItem (CoreFunc decl body) = (showExprLine False decl ++ " = ") : (indent $ showExpr False body) showCtor :: CoreCtor -> String showCtor (CoreCtor name args) = name ++ " " ++ ['{' | useRecords] ++ (concat $ intersperse sep $ map f args) ++ ['}' | useRecords] where useRecords = any (isJust . snd) args sep = ([','|useRecords]++" ") f (typ, Nothing) = typ f (typ, Just x) = "_" ++ x ++ " :: " ++ typ showExprLine :: Bool -> CoreExpr -> String showExprLine b y = case showExpr b y of [x] -> x xs -> "{" ++ concat (intersperse "; " xs) ++ "}" bracket False x = x bracket b [x] = ["(" ++ x ++ ")"] bracket b xs = ["("] ++ indent xs ++ [")"] -- True = should bracket showExpr :: Bool -> CoreExpr -> [String] showExpr b (CoreCon x) = showExpr b (CoreVar x) showExpr b (CoreVar x) | x == "Prelude.[]" = ["[]"] -- technically these aren't in | x == "Prelude.:" = ["(:)"] -- the prelude | isOperator x = ["(" ++ x ++ ")"] | otherwise = [x] showExpr b (CoreInt x) = [show x] showExpr b (CoreChr x) = [show x] showExpr b (CoreStr x) = [show x] showExpr b (CorePos x y) = showExpr b y showExpr b (CoreInteger x) = [show x] showExpr b (CoreApp x []) = showExpr b x showExpr b (CoreApp x y) = bracket b $ if all singleton items then [concat (intersperse " " (map head items))] else concat items where items = map (showExpr True) (x:y) showExpr b (CoreCase x y) = bracket b $ line1 ++ rest where line1 = if singleton subject then ["case " ++ head subject ++ " of"] else ["case"] ++ indent subject ++ ["of"] subject = showExpr True x rest = concatMap f y f (a,b) = indent $ [showExprLine False a ++ " ->"] ++ indent (showExpr False b) showExpr b (CoreLet x y) = bracket b $ ["let"] ++ indent (showItems x) ++ ["in"] ++ showExpr True y singleton [x] = True singleton _ = False