PrintAs.hs revision e9458b1a7a19a63aa4c179f9ab20f4d50681c168
3a6c7a7ff823616f56cd3d205fc44664a683effdChristian MaederDescription : print the abstract syntax so that it can be re-parsed
73dfcef93ee2ba07fedf4f3c74bace31853d1b9fChristian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederLicense : GPLv2 or higher, see LICENSE.txt
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederMaintainer : Christian.Maeder@dfki.de
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederStability : experimental
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederPortability : portable
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowskiprinting data types of the abstract syntax
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maederimport qualified Data.Set as Set
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder-- | short cut for: if b then empty else d
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaedernoPrint :: Bool -> Doc -> Doc
60bf7f52638962c93ec43da9aad8cafc9f09c318Christian MaedernoPrint b d = if b then empty else d
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian MaedernoNullPrint :: [a] -> Doc -> Doc
60bf7f52638962c93ec43da9aad8cafc9f09c318Christian MaedernoNullPrint = noPrint . null
60bf7f52638962c93ec43da9aad8cafc9f09c318Christian MaedersemiDs :: Pretty a => [a] -> Doc
60bf7f52638962c93ec43da9aad8cafc9f09c318Christian MaedersemiDs = fsep . punctuate semi . map pretty
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaedersemiAnnoted :: Pretty a => [Annoted a] -> Doc
60bf7f52638962c93ec43da9aad8cafc9f09c318Christian MaedersemiAnnoted = vcat . map (printSemiAnno pretty True)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maederinstance Pretty Variance where
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder pretty = sidDoc . mkSimpleId . show
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maederinstance Pretty a => Pretty (AnyKind a) where
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder pretty knd = case knd of
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder ClassKind ci -> pretty ci
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski FunKind v k1 k2 _ -> fsep
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski [ pretty v <> (case k1 of
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski FunKind {} -> parens
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski _ -> id) (pretty k1)
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski , funArrow, pretty k2]
6abfd7000f15635fd29746bd841b4c36819e552bTill MossakowskivarOfTypeArg :: TypeArg -> Id
6abfd7000f15635fd29746bd841b4c36819e552bTill MossakowskivarOfTypeArg (TypeArg i _ _ _ _ _ _) = i
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maederinstance Pretty TypePattern where
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder pretty tp = case tp of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder TypePattern name@(Id ts cs _) args _ ->
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder let ds = map (pretty . varOfTypeArg) args in
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder if placeCount name == length args then
6abfd7000f15635fd29746bd841b4c36819e552bTill Mossakowski let (ras, dts) = mapAccumL ( \ l t -> if isPlace t then
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder x : r -> (r, x)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder _ -> error "Pretty TypePattern"
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder else (l, printTypeToken t)) ds ts
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder in fsep $ dts ++ (if null cs then [] else
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [brackets $ sepByCommas $ map printTypeId cs])
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder else printTypeId name <+> fsep ds
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder TypePatternToken t -> printTypeToken t
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder MixfixTypePattern ts -> fsep $ map pretty ts
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder BracketTypePattern k l _ -> bracket k $ ppWithCommas l
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder TypePatternArg t _ -> parens $ pretty t
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder-- | put proper brackets around a document
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maederbracket :: BracketKind -> Doc -> Doc
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maederbracket b = case b of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder Parens -> parens
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder Squares -> brackets
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder Braces -> specBraces
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder NoBrackets -> id
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder-- | print a 'Kind' plus a preceding colon (or nothing)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintKind :: Kind -> Doc
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian MaederprintKind k = noPrint (k == universe) $ printVarKind NonVar (VarKind k)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder-- | print the kind of a variable with its variance and a preceding colon
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintVarKind :: Variance -> VarKind -> Doc
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till MossakowskiprintVarKind e vk = case vk of
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowski Downset t -> less <+> pretty t
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowski VarKind k -> colon <+> pretty e <> pretty k
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowski MissingKind -> empty
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowskidata TypePrec = Outfix | Prefix | Lazyfix | ProdInfix | FunInfix | Absfix
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowski deriving (Eq, Ord)
b20cc520e698253354303b7bf3bc17f84240b213Klaus LuettichparenPrec :: TypePrec -> (TypePrec, Doc) -> Doc
da955132262baab309a50fdffe228c9efe68251dCui JianparenPrec p1 (p2, d) = if p2 < p1 then d else parens d
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintTypeToken :: Token -> Doc
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintTypeToken t = let
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder l = ("*", cross) : map ( \ (a, d) -> (show a, d) )
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [ (FunArr, funArrow)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , (PFunArr, pfun)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , (ContFunArr, cfun)
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder , (PContFunArr, pcfun) ]
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder in case lookup (tokStr t) l of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder _ -> pretty t
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintTypeId :: Id -> Doc
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintTypeId (Id ts cs _) = let (toks, pls) = splitMixToken ts in
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder fcat $ map printTypeToken toks
10b1417752a7cd79344892ad4dbb14831851c638Ewaryst Schulz ++ (if null cs then [] else [brackets $ sepByCommas $ map printTypeId cs])
10b1417752a7cd79344892ad4dbb14831851c638Ewaryst Schulz ++ map printTypeToken pls
10b1417752a7cd79344892ad4dbb14831851c638Ewaryst SchulztoMixType :: Type -> (TypePrec, Doc)
831b0d8f47480be51d14f2cf122913507859f9c3Ewaryst SchulztoMixType typ = case typ of
831b0d8f47480be51d14f2cf122913507859f9c3Ewaryst Schulz TypeName name _ _ -> (Outfix, printTypeId name)
831b0d8f47480be51d14f2cf122913507859f9c3Ewaryst Schulz TypeToken tt -> (Outfix, printTypeToken tt)
831b0d8f47480be51d14f2cf122913507859f9c3Ewaryst Schulz TypeAbs v t _ ->
10b1417752a7cd79344892ad4dbb14831851c638Ewaryst Schulz (Absfix, sep [ lambda <+> pretty v, bullet <+> snd (toMixType t)])
10b1417752a7cd79344892ad4dbb14831851c638Ewaryst Schulz ExpandedType t1 _ -> toMixType t1 -- here we print the unexpanded type
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder BracketType k l _ ->
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (Outfix, bracket k $ sepByCommas $ map (snd . toMixType) l)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder KindedType t kind _ -> (Lazyfix, sep
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [ parenPrec Lazyfix $ toMixType t
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , colon <+> printList0 (Set.toList kind)])
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder MixfixType ts -> (Prefix, fsep $ map (snd . toMixType) ts)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder TypeAppl t1 t2 -> let
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (topTy, tyArgs) = getTypeApplAux False typ
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder aArgs = (Prefix, sep [ parenPrec ProdInfix $ toMixType t1
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , parenPrec Prefix $ toMixType t2 ])
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder in case topTy of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder TypeName name@(Id ts cs _) _k _i ->
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder case map toMixType tyArgs of
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder [dArg] -> case ts of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [e] | name == lazyTypeId ->
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (Lazyfix, pretty e <+> parenPrec Lazyfix dArg)
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [e1, e2, e3] | not (isPlace e1) && isPlace e2
07baaf27fc0029203075ed916999006dcc619ef0Christian Maeder && not (isPlace e3) && null cs ->
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (Outfix, fsep [pretty e1, snd dArg, pretty e3])
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [dArg1, dArg2] -> case ts of
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [_, e2, _] | isInfix name && null cs ->
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder if tokStr e2 == prodS then
3a6decfd748f532d5cb03fbcb7a42fa37b0faab3Christian Maeder (ProdInfix, fsep
07baaf27fc0029203075ed916999006dcc619ef0Christian Maeder [ parenPrec ProdInfix dArg1
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , cross, parenPrec ProdInfix dArg2])
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian Maeder else -- assume fun type
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (FunInfix, fsep
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder [ parenPrec FunInfix dArg1
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder , printTypeToken e2, snd dArg2])
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder dArgs -> if isProductIdWithArgs name $ length tyArgs then
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder (ProdInfix, fsep $ punctuate (space <> cross) $
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder map (parenPrec ProdInfix) dArgs) else aArgs
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maederinstance Pretty Type where
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder pretty = snd . toMixType
8d97ef4f234681b11bb5924bd4d03adef858d2d2Christian MaederprintTypeScheme :: PolyId -> TypeScheme -> Doc
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian MaederprintTypeScheme (PolyId _ tys _) (TypeScheme vs t _) =
acabd9ab36e1870f6f02c513bcfbfd10ffd118e0Christian Maeder let tdoc = pretty t in
999f839e42d594e4ae288208fec398626837c41cTill Mossakowski if null vs || not (null tys) then tdoc else
9a80079e082fdf4fe8e19f8fc61e6cd8799b47a7Christian Maeder fsep [forallDoc, semiDs vs, bullet <+> tdoc]
999f839e42d594e4ae288208fec398626837c41cTill Mossakowski-- no curried notation for bound variables
999f839e42d594e4ae288208fec398626837c41cTill Mossakowskiinstance Pretty TypeScheme where
999f839e42d594e4ae288208fec398626837c41cTill Mossakowski pretty = printTypeScheme (PolyId applId [] nullRange)
9a80079e082fdf4fe8e19f8fc61e6cd8799b47a7Christian Maederinstance Pretty Partiality where
ad69cb3627839ed3d33f13d71c81378b65a24b35Till Mossakowski pretty p = case p of
ad69cb3627839ed3d33f13d71c81378b65a24b35Till Mossakowski Partial -> quMarkD
_ -> error "printTermRec.foldApplTerm"