{- | Convert STG-code into a string for readable output. -} module StrPos(strPCode,strPCode',strPExp) where import Util.Extra(mixLine,mixSpace,mix) import PosCode import Id import Char -- \#if defined(__HBC__) -- import ForeignCode -- for ImpExp's Show instance -- import Syntax -- for CallConv's Show instance -- \#endif strPCode :: Show a => (Id -> String,Id -> a) -> [(Id,PosLambda)] -> [Char] strPCode p code = mixLine (map (strPBinding p "") code) strPCode' :: (Id -> String) -> [(Id,PosLambda)] -> [Char] strPCode' p code = mixLine (map (strPBinding' p "") code) strPLambda :: (Id -> String) -> String -> PosLambda -> String strPLambda p o (PosLambda pos lamfl fvs bvs e) = (case lamfl of LamFLNone -> "" LamFLIntro -> "INT " LamFLLambda -> "LAMBDA " ) ++ "{" ++ mixSpace (map (p.snd) fvs) ++ "} \\ {" ++ mixSpace (map (p.snd) bvs) ++ "} ->\n" ++ strPExp p (' ':o) e strPLambda p o (PosPrimitive pos fun) = "primitive " ++ p fun ++ "\n" strPLambda p o (PosForeign pos fun arity str c ie) = "foreign "++show ie++" "++show c++" \""++str++"\" " ++ p fun ++ "\n" strPBinding :: (Show a) => (Id -> String, Id -> a) -> String -> (Id, PosLambda) -> String strPBinding' :: (Id -> String) -> String -> PosBinding -> String strPBinding (p,a) o (i,l) = o ++ p i ++ "["++show (a i)++"] = " ++ strPLambda p o l ++ "\n" strPBinding' p o (i,l) = o ++ p i ++ " = " ++ strPLambda p o l ++ "\n" strPExp :: (Id -> String) -> String -> PosExp -> String strPExp p o (PosExpDict e) = "{d}" ++ strPExp p o e strPExp p o (PosExpLet rec pos bs e) = o ++ sLet ++ concatMap ((++"\n").strPBinding' p (' ':o)) bs ++ strPExp p o e where sLet = if rec then "letrec\n" else "let\n" strPExp p o (PosExpCase pos e args) = o ++ "case " ++ strPExp p "" e ++ " of\n" ++ mixLine (map (strPAlt p (' ':o)) args) strPExp p o (PosExpApp pos args) = o ++ "@(" ++ mix ", " (map (strPExp p (' ':o)) args) ++ ")" strPExp p o (PosExpThunk pos ap args) = o ++ (if ap then "APPLY" else "") ++ "<" ++ mixSpace (map (strPExp p (' ':o)) args) ++ ">" strPExp p o (PosExpFatBar b e1 e2) = o ++ "fatbar" ++ (if b then " that can fail\n" else "\n") ++ strPExp p (' ':o) e1 ++ "\n" ++ o ++ "--\n" ++ strPExp p (' ':o) e2 strPExp p o (PosExpFail) = o ++ "fail" strPExp p o (PosExpIf pos guard e1 e2 e3) = o ++ "if "++(if guard then "[guard] " else "") ++ strPExp p (' ':o) e1 ++ o ++ "\n" ++ o ++ "then " ++ strPExp p (' ':o) e2++ o ++ "\n" ++ o ++ "else " ++ strPExp p (' ':o) e3 strPExp p o (PosExpLambda pos int bes bvs e) = o ++ "(" ++ (if int then "INT " else "") ++ "{" ++ mixSpace (map (p.snd) bes) ++ "} \\ {" ++ mixSpace (map (p.snd) bvs) ++ "} ->\n" ++ strPExp p (' ':o) e ++ ")" strPExp p o (PosPrim pos prim _) = o ++ strPrim prim strPExp p o (PosVar pos i) = o ++ p i strPExp p o (PosCon pos c) = o ++ p c ++ "{c}" strPExp p o (PosInt pos i) = o ++ show i strPExp p o (PosChar pos i) = o ++ "'" ++ [((toEnum i) :: Char)] ++ "'" strPExp p o (PosFloat pos i) = o ++ show i++"F" strPExp p o (PosDouble pos i) = o ++ show i strPExp p o (PosString pos s) = o ++ show s strPExp p o (PosInteger pos i) = o ++ show i++"L" strPAlt :: (Id -> String) -> String -> PosAlt -> String strPAlt p o (PosAltCon pos c args e) = o ++ p c ++ concatMap ((' ':).p.snd) args ++ " ->\n" ++ strPExp p (' ':o) e strPAlt p o (PosAltInt pos i int e) = o ++ on ++ " ->\n" ++ strPExp p (' ':o) e where on = if int then show i else show (chr i)