Skip to content

Commit 8a854a4

Browse files
committed
redesign ext stg pretty printed syntax to look like Haskell
1 parent 11f8721 commit 8a854a4

File tree

1 file changed

+157
-100
lines changed

1 file changed

+157
-100
lines changed

external-stg/lib/Stg/Pretty.hs

Lines changed: 157 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ a <+> b = a >> char ' ' >> b
216216

217217
x <$$> y = x <> newline <> y
218218

219-
line = newline
220219
hang i d = align (nest i d)
221220
indent i d = hang i (textS (spaces i) <> d)
222221

@@ -229,32 +228,10 @@ spaces :: Int -> String
229228
spaces n | n <= 0 = ""
230229
| otherwise = replicate n ' '
231230

232-
233231
textS = text . T.pack
234-
textBS = text . T.pack . BS.unpack
235232

236233
--------------------------------------------------------
237234

238-
replaceNewlineBS :: ByteString -> ByteString
239-
replaceNewlineBS = BS.map f where
240-
f = \case
241-
'\r' -> ' '
242-
'\n' -> ' '
243-
c -> c
244-
245-
{-
246-
data ForeignCall
247-
data PrimCall = PrimCall -- Name Name
248-
data UpdateFlag = ReEntrant | Updatable | SingleEntry
249-
-}
250-
251-
smallRArrow :: Doc
252-
smallRArrow = "->"
253-
254-
maybeParens :: Bool -> Doc -> Doc
255-
maybeParens True = parens
256-
maybeParens False = id
257-
258235
ppType :: Type -> Doc
259236
ppType t = red $ case t of
260237
SingleValue r -> ppPrimRep r
@@ -272,23 +249,28 @@ colorBinderExport b = case binderScope b of
272249
ModulePrivate -> id
273250
ModulePublic -> green
274251

252+
pprBinderTypeSig :: Binder -> Doc
253+
pprBinderTypeSig b = pprVar b <+> text "::" <+> ppType (binderType b)
275254

276255
pprBinder :: Binder -> Doc
277-
pprBinder b = parens $
278-
pprVar b <+> text ":" <+>
279-
ppType (binderType b) <+>
280-
parens (pretty $ replaceNewlineBS $ binderTypeSig b) <+>
281-
parens (pretty $ show $ binderDetails b)
282-
where
283-
BinderId u = binderId b
256+
pprBinder b = pprVar b
284257

258+
{-
259+
name handling design:
260+
+ show normal (binder name for public functions)
261+
+ show only the unique id for module local names, to keep the code short
262+
the module local names are GHC generated most of the time anyway
263+
the binder name could be displayed in the hover
264+
-}
285265
pprVar :: Binder -> Doc
286266
pprVar b@Binder{..}
287267
| binderScope == ModulePublic
288-
= colorBinderExport b . pretty $ binderUniqueName
268+
= colorBinderExport b . pretty $ binderName
289269
| otherwise
290-
= colorBinderExport b . pretty $ binderName <> BS.pack ('_' : show u)
291-
where BinderId u = binderId
270+
-- = colorBinderExport b . pretty $ binderName <> BS.pack ('_' : show u)
271+
= colorBinderExport b . pretty $ BS.pack (show u)
272+
where
273+
BinderId u = binderId
292274

293275
instance Pretty Type where
294276
pretty = ppType
@@ -316,19 +298,19 @@ instance Pretty LitNumType where
316298
LitNumWord64 -> "Word64"
317299

318300
instance Pretty Lit where
319-
pretty (LitChar x) = "'" <> char x <> "'#"
320-
pretty (LitString x) = "\"" <> textBS x <> "\"#"
301+
pretty (LitChar x) = text (T.pack $ show x)
302+
pretty (LitString x) = text (T.pack $ show x)
321303
pretty LitNullAddr = "nullAddr#"
322-
pretty (LitFloat x) = "FLOAT" <> parens (pprRational x)
323-
pretty (LitDouble x) = "DOUBLE" <> parens (pprRational x)
324-
pretty (LitLabel x s) = "LABEL"<> parens (pretty x) <+> textS (show s)
325-
pretty (LitNumber t i) = "#" <> pretty t <> "#" <> pretty i
304+
pretty (LitFloat x) = (pprRational x)
305+
pretty (LitDouble x) = (pprRational x)
306+
pretty (LitLabel x s) = text "LABEL" <+> parens (pretty x) <+> textS (show s)
307+
pretty (LitNumber t i) = pretty i
326308
pretty (LitRubbish t) = text "#Rubbish" <+> pretty t
327309

328310
instance Pretty AltCon where
329-
pretty (AltDataCon dc) = pretty dc
311+
pretty (AltDataCon dc) = pprDataConName dc
330312
pretty (AltLit l) = pretty l
331-
pretty AltDefault = text "DEFAULT"
313+
pretty AltDefault = text "_"
332314

333315
instance Pretty AltType where
334316
pretty = \case
@@ -341,13 +323,10 @@ instance Pretty Binder where
341323
pretty = pprBinder
342324

343325

344-
pprExpr :: Expr -> Doc
345-
pprExpr = pprExpr' False
346-
347326
pprAlt :: Id -> Int -> Alt -> Doc
348327
pprAlt scrutId idx (Alt con bndrs rhs) =
349-
(hsep (pretty con : map (pprBinder) bndrs) <+> smallRArrow) <$$>
350-
indent 2 (withStgPoint (SP_AltExpr scrutId idx) $ pprExpr' False rhs)
328+
(hsep (pretty con : map (pprBinder) bndrs) <+> text "-> do") <$$>
329+
indent 2 (withStgPoint (SP_AltExpr scrutId idx) $ pprExpr rhs)
351330

352331
pprArg :: Arg -> Doc
353332
pprArg = \case
@@ -371,92 +350,170 @@ instance Pretty PrimCall where
371350

372351
pprOp :: StgOp -> Doc
373352
pprOp = \case
374-
StgPrimOp op -> text "_stg_prim_" <> pretty op
375-
StgPrimCallOp p -> text "_stg_prim_call" <> pretty p
376-
StgFCallOp f -> text "_stg_foreign_call" <+> pretty f
353+
StgPrimOp op -> text "primop" <+> pretty (show op)
354+
StgPrimCallOp (PrimCall sym uid) -> text "cmmcall" <+> pretty (show sym)-- <+> text "-- from package:" <+> pretty uid
355+
StgFCallOp ForeignCall{..} -> case foreignCTarget of
356+
StaticTarget _ sym _ _ -> text "foreigncall" <+> pretty (show sym)
357+
DynamicTarget -> text "foreigncall dynamic_call_target"
377358

378-
pprExpr' :: Bool -> Expr -> Doc
379-
pprExpr' hasParens exp = do
359+
{-
360+
- put infix names to parenthesis
361+
done - do not use fully qualified names
362+
done - omit parenthesis from: sat_srv @ (_)
363+
- show in hower:
364+
+ type
365+
+ unit
366+
+ module
367+
+ id details
368+
369+
- add jump to definition where possible
370+
+ display first few lines of definition
371+
372+
done - show type signatures for top level binders
373+
374+
done - use import "network" Network.Socket
375+
done + use import list
376+
377+
done - use normal let syntax for let no escape, add comment that it is stack allocated
378+
done - use haskell data definition syntax
379+
done - show only the module's data type definitons
380+
done - add comment for stack allocated unboxed tuples: -- stack allocated
381+
done - simple printer for foreign calls
382+
- do not show dead binders
383+
-}
384+
385+
putDefaultLast :: [Alt] -> [Doc] -> [Doc]
386+
putDefaultLast (Alt AltDefault _ _ : _) (first : rest) = rest ++ [first]
387+
putDefaultLast _ l = l
388+
389+
pprExpr :: Expr -> Doc
390+
pprExpr exp = do
380391
stgPoint <- getStgPoint
381392
annotate stgPoint $ case exp of
382393
StgLit l -> pretty l
383-
StgCase x b at alts -> maybeParens hasParens
384-
$ sep [ hsep [ text "case"
385-
, withStgPoint (SP_CaseScrutineeExpr $ Id b) $
386-
pprExpr' False x
387-
, text "of"
388-
, pprBinder b
389-
, text ":"
390-
, parens (pretty at)
391-
, text "{" ]
392-
, indent 2 $ vcat $ [pprAlt (Id b) idx a | (idx, a) <- zip [0..] alts]
393-
, "}"
394-
]
395-
StgApp f args -> maybeParens hasParens $ (pprVar f) <+> (hsep $ map (pprArg) args)
396-
StgOpApp op args ty n -> maybeParens hasParens $ (pprOp op) <+> (hsep $ map (pprArg) args) <+> text "::" <+> (pretty ty) <+> maybe mempty (parens . ppTyConName) n
397-
StgConApp dc args _t -> maybeParens hasParens $ (pretty dc) <+> (hsep $ map (pprArg) args)
398-
StgLet b e -> maybeParens hasParens $ text "let" <+> (align $ pprBinding b) <$$> text "in" <+> align (withStgPoint (SP_LetExpr stgPoint) $ pprExpr' False e)
399-
StgLetNoEscape b e -> maybeParens hasParens $ text "lettail" <+> (align $ pprBinding b) <$$> text "in" <+> align (withStgPoint (SP_LetNoEscapeExpr stgPoint) $ pprExpr' False e)
400-
StgTick tickish e -> pprExpr' hasParens e
394+
StgCase x b at [Alt AltDefault [] rhs] -> sep
395+
[ withStgPoint (SP_CaseScrutineeExpr $ Id b) $
396+
pprBinder b <+> text "<-" <+> pprExpr x
397+
, withStgPoint (SP_AltExpr (Id b) 0) $
398+
pprExpr rhs
399+
]
400+
StgCase x b at [Alt con bndrs rhs] -> sep
401+
[ withStgPoint (SP_CaseScrutineeExpr $ Id b) $
402+
pprBinder b <+> text "@" <+> parens (hsep $ pretty con : map (pprBinder) bndrs) <+> text "<-" <+> pprExpr x
403+
, withStgPoint (SP_AltExpr (Id b) 0) $
404+
pprExpr rhs
405+
]
406+
StgCase x b at alts -> sep
407+
[ withStgPoint (SP_CaseScrutineeExpr $ Id b) $
408+
pprBinder b <+> text "<-" <+> pprExpr x
409+
, text "case" <+> pprVar b <+> text "of"
410+
, indent 2 $ vcat $ putDefaultLast alts [pprAlt (Id b) idx a | (idx, a) <- zip [0..] alts]
411+
]
412+
StgApp f args -> (pprVar f) <+> (hsep $ map (pprArg) args)
413+
StgOpApp op args ty n -> (pprOp op) <+> (hsep $ map (pprArg) args){- <+> text "::" <+> (pretty ty) <+> maybe mempty (parens . ppTyConName) n -}
414+
StgConApp dc args _t -> addUnboxedCommentIfNecessary dc $ (pprDataConName dc) <+> (hsep $ map (pprArg) args)
415+
StgLet b e -> text "let" <+> (align $ pprBinding b) <$$> align (withStgPoint (SP_LetExpr stgPoint) $ pprExpr e)
416+
StgLetNoEscape b e -> vsep
417+
[ text "-- stack allocating let"
418+
, text "let" <+> (align $ pprBinding b) <$$> align (withStgPoint (SP_LetNoEscapeExpr stgPoint) $ pprExpr e)
419+
]
420+
StgTick tickish e -> pprExpr e
401421

402422
instance Pretty Expr where
403423
pretty = pprExpr
404424

425+
addUnboxedCommentIfNecessary :: DataCon -> Doc -> Doc
426+
addUnboxedCommentIfNecessary DataCon{..} doc = case dcRep of
427+
UnboxedTupleCon{} -> doc -- vsep [text "-- stack allocated unboxed tuple", doc]
428+
_ -> doc
429+
405430
pprRhs :: Id -> Rhs -> Doc
406-
pprRhs rhsId = \case
407-
StgRhsClosure _ u bs e -> text "\\closure" <+> hsep (map pprBinder bs) <+> text "->" <+> braces (line <> (withStgPoint (SP_RhsClosureExpr rhsId) $ pprExpr e))
408-
StgRhsCon d vs -> annotate (SP_RhsCon rhsId) $ pretty d <+> (hsep $ map (pprArg) vs)
431+
pprRhs rhsId@(Id rhsBinder) = \case
432+
StgRhsClosure _ u bs e -> pprBinder rhsBinder <+> hsep (map pprBinder bs) <+> text "= do" <+> (newline <> (indent 2 $ withStgPoint (SP_RhsClosureExpr rhsId) $ pprExpr e))
433+
StgRhsCon dc vs -> annotate (SP_RhsCon rhsId) $ do
434+
pprBinder rhsBinder <+> text "=" <+> addUnboxedCommentIfNecessary dc (pprDataConName dc <+> (hsep $ map (pprArg) vs))
409435

410436
pprBinding :: Binding -> Doc
411437
pprBinding = \case
412-
StgNonRec b r -> pprTopBind (b,r)
413-
StgRec bs -> text "rec" <+> braces (line <> vsep (map pprTopBind bs))
438+
StgNonRec b r -> pprBind (b,r)
439+
StgRec bs -> vsep (map pprBind bs)
414440
where
415-
pprTopBind (b,rhs) =
416-
(pprBinder b <+> equals <$$> (indent 2 $ pprRhs (Id b) rhs))
417-
<> line
441+
pprBind (b,rhs) =
442+
(pprRhs (Id b) rhs)
418443

419444
pprTopBinding :: TopBinding -> Doc
420445
pprTopBinding = \case
421446
StgTopLifted (StgNonRec b r) -> pprTopBind (b,r)
422-
StgTopLifted (StgRec bs) -> text "rec" <+> braces (line <> vsep (map pprTopBind bs))
423-
StgTopStringLit b s -> pprTopBind' (const $ textS . show) (b,s)
447+
StgTopLifted (StgRec bs) -> vsep (map pprTopBind bs)
448+
StgTopStringLit b s -> pprTopBind' (\(Id b) str -> pprBinder b <+> text "=" <+> (textS . show $ str)) (b,s)
424449
where
425450
pprTopBind = pprTopBind' pprRhs
426-
pprTopBind' f (b,rhs) =
427-
(pprBinder b <+> equals <$$> (indent 2 $ f (Id b) rhs))
428-
<> line
451+
pprTopBind' f (b, rhs) = sep
452+
[ pprBinderTypeSig b
453+
, f (Id b) rhs
454+
, mempty
455+
]
429456

430457
instance Pretty TopBinding where
431458
pretty = pprTopBinding
432459

433460
ppTyConName :: TyCon -> Doc
434-
ppTyConName TyCon{..} = pretty tcUnitId <> text "_" <> pretty tcModule <> text "." <> pretty tcName
461+
ppTyConName TyCon{..} = {-pretty tcUnitId <> text "_" <> pretty tcModule <> text "." <> -}pretty tcName
435462

436463
pprTyCon :: TyCon -> Doc
437-
pprTyCon TyCon{..} = pretty tcUnitId <> text "_" <> pretty tcModule <> text "." <> pretty tcName <$$> (indent 2 $ vsep (map pretty tcDataCons)) <> line where
464+
pprTyCon TyCon{..} = {-pretty tcUnitId <> text "_" <> pretty tcModule <> text "." <> -}
465+
text "data" <+> pretty tcName <$$> (indent 2 $ vsep ([text c <+> pprDataConDef dc | (dc, c) <- zip tcDataCons ("=" : repeat "|")]))
466+
467+
pprDataConDef :: DataCon -> Doc
468+
pprDataConDef DataCon{..} = case dcRep of
469+
AlgDataCon dcArgsRep -> pretty dcName <+> hsep (map ppPrimRep dcArgsRep)
470+
x -> textS $ "-- " ++ show x
438471

439-
pprDataCon :: DataCon -> Doc
440-
pprDataCon DataCon{..} = pretty dcUnitId <> text "_" <> pretty dcModule <> text "." <> pretty dcName <+> text "::" <+> textS (show dcRep) <+> parens (textS (show dcId))
472+
pprDataConName :: DataCon -> Doc
473+
pprDataConName DataCon{..} = {-pretty dcUnitId <> text "_" <> pretty dcModule <> text "." <> -}pretty dcName{- <+> text "::" <+> textS (show dcRep) <+> parens (textS (show dcId))-}
441474

475+
{-
442476
instance Pretty DataCon where
443477
pretty = pprDataCon
444-
478+
-}
445479
pprModule :: Module -> Doc
446-
pprModule m =
447-
comment (pretty $ modulePhase m)
448-
<$$> text "package" <+> pretty (moduleUnitId m)
449-
<$$> text "module" <+> pretty (moduleName m) <+> "where" <> line
450-
451-
<$$> vsep [text "using" <+> pretty u <+> text ":" <+> pretty mod | (u, ml) <- moduleDependency m, mod <- ml] <> line
452-
453-
<$$> text "externals" <$$> vsep [indent 2 $ vsep (map pprBinder bl) | (_, ml) <- moduleExternalTopIds m, (_, bl) <- ml] <> line
454-
455-
<$$> text "type" <$$> vsep [indent 2 $ vsep (map pprTyCon tl) | (_, ml) <- moduleTyCons m, (_, tl) <- ml] <> line
456-
457-
<$$> vsep (map (pprTopBinding) (moduleTopBindings m))
480+
pprModule Module{..} = vsep
481+
[ text "-- package:" <+> pretty moduleUnitId
482+
, text "module" <+> pretty moduleName
483+
, indent 2 $ pprExportList moduleTopBindings
484+
, " ) where"
485+
, mempty
486+
, vsep [pprImportList u mod il | (u, ml) <- moduleExternalTopIds, (mod, il) <- ml]
487+
, mempty
488+
, vsep
489+
[ pprTyCon tc <> newline
490+
| (uid, ml) <- moduleTyCons
491+
, uid == moduleUnitId
492+
, (modName, tl) <- ml
493+
, modName == moduleName
494+
, tc <- tl
495+
]
496+
, vsep (map (pprTopBinding) moduleTopBindings)
497+
]
498+
499+
pprImportList :: UnitId -> ModuleName -> [Binder] -> Doc
500+
pprImportList u mod bl = text "import" <+> text "\"" <> pretty u <> text "\"" <+> pretty mod <+> align (collection "(" ")" "," $ map pprVar bl)
501+
502+
pprExportList :: [TopBinding] -> Doc
503+
pprExportList l = vsep
504+
[ text t <+> pprVar b
505+
| (b, t) <- zip exportedBinders ("(" : repeat ",")
506+
]
507+
where
508+
exportedBinders = filter ((ModulePublic ==) . binderScope) $ getTopBinders l
458509

459-
-- <$$> pprForeignStubs (moduleForeignStubs m)
510+
getTopBinders :: [TopBinding] -> [Binder]
511+
getTopBinders topBindings = concatMap go topBindings
512+
where
513+
go = \case
514+
StgTopStringLit b _ -> [b]
515+
StgTopLifted (StgNonRec b _) -> [b]
516+
StgTopLifted (StgRec l) -> map fst l
460517

461518
instance Pretty Module where
462519
pretty = pprModule

0 commit comments

Comments
 (0)