PrintAs.hs revision 3f69b6948966979163bdfe8331c38833d5d90ecd
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettModule : $Header$
e071fb22ea9923a2a4ff41184d80ca46b55ee932Till MossakowskiCopyright : (c) Christian Maeder and Uni Bremen 2003
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettMaintainer : Christian.Maeder@dfki.de
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettStability : experimental
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettPortability : portable
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettprinting data types of the abstract syntax
f909337bf7012aca169c0b56b89efbd4a310f8daAndy Gimblettimport Data.List (groupBy, mapAccumL)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | short cut for: if b then empty else d
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettnoPrint :: Bool -> Doc -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettnoPrint b d = if b then empty else d
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettnoNullPrint :: [a] -> Doc -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettnoNullPrint = noPrint . null
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettsemiDs :: Pretty a => [a] -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettsemiDs = fsep . punctuate semi . map pretty
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettsemiAnnoted :: Pretty a => [Annoted a] -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettsemiAnnoted = vcat . map (printSemiAnno pretty True)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettinstance Pretty Variance where
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett pretty = sidDoc . mkSimpleId . show
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettinstance Pretty a => Pretty (AnyKind a) where
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett pretty knd = case knd of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett ClassKind ci -> pretty ci
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett FunKind v k1 k2 _ -> fsep [pretty v <>
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett FunKind _ _ _ _ -> parens
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett _ -> id) (pretty k1)
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettvarOfTypeArg :: TypeArg -> Id
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettvarOfTypeArg (TypeArg i _ _ _ _ _ _) = i
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettinstance Pretty TypePattern where
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett pretty tp = case tp of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypePattern name@(Id ts cs _) args _ ->
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett let ds = map (pretty . varOfTypeArg) args in
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett if placeCount name == length args then
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett let (ras, dts) = mapAccumL ( \ l t -> if isPlace t then
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett x : r -> (r, x)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett _ -> error "Pretty TypePattern"
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett else (l, printTypeToken t)) ds ts
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett in fsep $ dts ++ (if null cs then [] else
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett [brackets $ sepByCommas $ map printTypeId cs])
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett else printTypeId name <+> fsep ds
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypePatternToken t -> printTypeToken t
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett MixfixTypePattern ts -> fsep $ map pretty ts
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett BracketTypePattern k l _ -> bracket k $ ppWithCommas l
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypePatternArg t _ -> parens $ pretty t
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | put proper brackets around a document
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettbracket :: BracketKind -> Doc -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettbracket b = case b of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett Parens -> parens
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett Squares -> brackets
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett Braces -> specBraces
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett NoBrackets -> id
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | print a 'Kind' plus a preceding colon (or nothing)
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettprintKind :: Kind -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettprintKind k = noPrint (k == universe) $ printVarKind InVar (VarKind k)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | print the kind of a variable with its variance and a preceding colon
29ac9ecacf0983a565b89f133ff2bdf2ac02b0c4Andy GimblettprintVarKind :: Variance -> VarKind -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettprintVarKind e vk = case vk of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett space <> less <+> pretty t
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett VarKind k -> space <> colon <+>
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett pretty e <> pretty k
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett MissingKind -> empty
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata TypePrec = Outfix | Prefix | ProdInfix | FunInfix | Absfix
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett deriving (Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettparenPrec :: TypePrec -> (TypePrec, Doc) -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettparenPrec p1 (p2, d) = if p2 < p1 then d else parens d
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettprintTypeToken :: Token -> Doc
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettprintTypeToken t = let
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett l = ("*", cross) : map ( \ (a, d) -> (show a, d) )
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett [ (FunArr, funArrow)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett , (PFunArr, pfun)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett , (ContFunArr, cfun)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett , (PContFunArr, pcfun) ]
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett in case lookup (tokStr t) l of
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett _ -> pretty t
2f06b54890375b6cac90394b80b07bd451d728fcAndy GimblettprintTypeId :: Id -> Doc
2f06b54890375b6cac90394b80b07bd451d728fcAndy GimblettprintTypeId (Id ts cs _) =
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett let (toks, pls) = splitMixToken ts
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett in fcat $ map printTypeToken toks ++
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett (if null cs then [] else
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett [brackets $ sepByCommas $ map printTypeId cs])
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett ++ map printTypeToken pls
2f06b54890375b6cac90394b80b07bd451d728fcAndy GimbletttoMixType :: Type -> (TypePrec, Doc)
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy GimbletttoMixType typ = case typ of
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett TypeName name _ _ -> (Outfix, printTypeId name)
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett TypeToken tt -> (Outfix, printTypeToken tt)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypeAbs v t _ -> (Absfix, sep [ lambda <+> pretty v
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett , bullet <+> snd (toMixType t)])
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett ExpandedType t1 _ -> toMixType t1 -- here we print the unexpanded type
f909337bf7012aca169c0b56b89efbd4a310f8daAndy Gimblett BracketType k l _ -> (Outfix, bracket k $ sepByCommas $ map
f909337bf7012aca169c0b56b89efbd4a310f8daAndy Gimblett (snd . toMixType) l)
f909337bf7012aca169c0b56b89efbd4a310f8daAndy Gimblett KindedType t kind _ -> (Prefix,
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett fsep [parenPrec Prefix $ toMixType t, colon, pretty kind])
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett MixfixType ts -> (Prefix, fsep $ map (snd . toMixType) ts)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypeAppl t1 t2 -> let
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett (topTy, tyArgs) = getTypeApplAux False typ
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett aArgs = (Prefix, sep [ parenPrec ProdInfix $ toMixType t1
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett , parenPrec Prefix $ toMixType t2 ])
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett in case topTy of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett TypeName name@(Id ts cs _) _k _i ->
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett case map toMixType tyArgs of
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett [e1, e2, e3] | not (isPlace e1) && isPlace e2
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett && not (isPlace e3) && null cs ->
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett (Outfix, fsep [pretty e1, snd dArg, pretty e3])
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett [dArg1, dArg2] ->
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett [e1, e2, e3] | isPlace e1 && not (isPlace e2)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett && isPlace e3 && null cs ->
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett if tokStr e2 == prodS then
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett (ProdInfix, fsep [
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett parenPrec ProdInfix dArg1, cross,
2f06b54890375b6cac90394b80b07bd451d728fcAndy Gimblett parenPrec ProdInfix dArg2])
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett else -- assume fun type
a09bfcbcb0fba5663fca1968aa82daebf2e092c4Andy Gimblett (FunInfix, fsep [
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett parenPrec FunInfix dArg1, printTypeToken e2, snd dArg2])