PrintAs.hs revision 3d3889e0cefcdce9b3f43c53aaa201943ac2e895
967e5f3c25249c779575864692935627004d3f9eChristian MaederModule : $Header$
81d182b21020b815887e9057959228546cf61b6bChristian MaederDescription : print the abstract syntax so that it can be re-parsed
f11f713bebd8e1e623a0a4361065df256033de47Christian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederLicense : GPLv2 or higher, see LICENSE.txt
3f69b6948966979163bdfe8331c38833d5d90ecdChristian MaederMaintainer : Christian.Maeder@dfki.de
967e5f3c25249c779575864692935627004d3f9eChristian MaederStability : experimental
89054b2b95a3f92e78324dc852f3d34704e2ca49Christian MaederPortability : portable
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maederprinting data types of the abstract syntax
967e5f3c25249c779575864692935627004d3f9eChristian Maederimport qualified Data.Set as Set
fd896e2068ad7e50aed66ac18c3720ea7ff2619fChristian Maeder-- | short cut for: if b then empty else d
717686b54b9650402e2ebfbaadf433eab8ba5171Christian MaedernoPrint :: Bool -> Doc -> Doc
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian MaedernoPrint b d = if b then empty else d
967e5f3c25249c779575864692935627004d3f9eChristian MaedernoNullPrint :: [a] -> Doc -> Doc
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaedernoNullPrint = noPrint . null
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaedersemiDs :: Pretty a => [a] -> Doc
7a879b08ae0ca30006f9be887a73212b07f10204Christian MaedersemiDs = fsep . punctuate semi . map pretty
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaedersemiAnnoted :: Pretty a => [Annoted a] -> Doc
7a879b08ae0ca30006f9be887a73212b07f10204Christian MaedersemiAnnoted = vcat . map (printSemiAnno pretty True)
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maederinstance Pretty Variance where
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder pretty = sidDoc . mkSimpleId . show
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maederinstance Pretty a => Pretty (AnyKind a) where
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder pretty knd = case knd of
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder ClassKind ci -> pretty ci
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder FunKind v k1 k2 _ -> fsep
6e39bfd041946fce4982ac89834be73fd1bfb39aChristian Maeder [ pretty v <> (case k1 of
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder FunKind {} -> parens
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder _ -> id) (pretty k1)
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder , funArrow, pretty k2]
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaedervarOfTypeArg :: TypeArg -> Id
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian MaedervarOfTypeArg (TypeArg i _ _ _ _ _ _) = i
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maederinstance Pretty TypePattern where
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder pretty tp = case tp of
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder TypePattern name@(Id ts cs _) args _ ->
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder let ds = map (pretty . varOfTypeArg) args in
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder if placeCount name == length args then
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder let (ras, dts) = mapAccumL ( \ l t -> if isPlace t then
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder x : r -> (r, x)
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder _ -> error "Pretty TypePattern"
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder else (l, printTypeToken t)) ds ts
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder in fsep $ dts ++ (if null cs then [] else
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder [brackets $ sepByCommas $ map printTypeId cs])
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder else printTypeId name <+> fsep ds
67086e0fe40a985c5e8a3cf50e611f43234580c2Christian Maeder TypePatternToken t -> printTypeToken t
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder MixfixTypePattern ts -> fsep $ map pretty ts
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder BracketTypePattern k l _ -> bracket k $ ppWithCommas l
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder TypePatternArg t _ -> parens $ pretty t
d48085f765fca838c1d972d2123601997174583dChristian Maeder-- | put proper brackets around a document
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maederbracket :: BracketKind -> Doc -> Doc
d48085f765fca838c1d972d2123601997174583dChristian Maederbracket b = case b of
d48085f765fca838c1d972d2123601997174583dChristian Maeder Parens -> parens
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder Squares -> brackets
d48085f765fca838c1d972d2123601997174583dChristian Maeder Braces -> specBraces
717686b54b9650402e2ebfbaadf433eab8ba5171Christian Maeder NoBrackets -> id
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder-- | print a 'Kind' plus a preceding colon (or nothing)
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederprintKind :: Kind -> Doc
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederprintKind k = noPrint (k == universe) $ printVarKind NonVar (VarKind k)
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder-- | print the kind of a variable with its variance and a preceding colon
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederprintVarKind :: Variance -> VarKind -> Doc
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederprintVarKind e vk = case vk of
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder Downset t -> less <+> pretty t
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder VarKind k -> colon <+> pretty e <> pretty k
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder MissingKind -> empty
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maederdata TypePrec = Outfix | Prefix | Lazyfix | ProdInfix | FunInfix | Absfix
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder deriving (Eq, Ord)
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederparenPrec :: TypePrec -> (TypePrec, Doc) -> Doc
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederparenPrec p1 (p2, d) = if p2 < p1 then d else parens d
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian MaederprintTypeToken :: Token -> Doc
83814002b4922114cbe7e9ba728472a0bf44aac5Christian MaederprintTypeToken t = let
a578ec30cded5e396a7ce9a3b469e8cd3a88246aChristian Maeder l = ("*", cross) : map ( \ (a, d) -> (show a, d) )
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder [ (FunArr, funArrow)
967e5f3c25249c779575864692935627004d3f9eChristian Maeder , (PFunArr, pfun)
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder , (ContFunArr, cfun)
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder , (PContFunArr, pcfun) ]
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder in case lookup (tokStr t) l of
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder _ -> pretty t
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian MaederprintTypeId :: Id -> Doc
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian MaederprintTypeId (Id ts cs _) = let (toks, pls) = splitMixToken ts in
a89e661aad28f1b39f4fc9f9f9a4d46074234123Christian Maeder fcat $ map printTypeToken toks
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder ++ (if null cs then [] else [brackets $ sepByCommas $ map printTypeId cs])
99f1a09ee1847410faf46527f5465bd2070800c2Christian Maeder ++ map printTypeToken pls
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian MaedertoMixType :: Type -> (TypePrec, Doc)
81d182b21020b815887e9057959228546cf61b6bChristian MaedertoMixType typ = case typ of
242397ba0f1cc490e892130bf0df239deeecf5daChristian Maeder TypeName name _ _ -> (Outfix, printTypeId name)
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder TypeToken tt -> (Outfix, printTypeToken tt)
242397ba0f1cc490e892130bf0df239deeecf5daChristian Maeder TypeAbs v t _ ->
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder (Absfix, sep [ lambda <+> pretty v, bullet <+> snd (toMixType t)])
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder ExpandedType t1 _ -> toMixType t1 -- here we print the unexpanded type
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder BracketType k l _ ->
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder (Outfix, bracket k $ sepByCommas $ map (snd . toMixType) l)
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder KindedType t kind _ -> (Lazyfix, sep
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder [ parenPrec Lazyfix $ toMixType t
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder , colon <+> printList0 (Set.toList kind)])
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder MixfixType ts -> (Prefix, fsep $ map (snd . toMixType) ts)
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder TypeAppl t1 t2 -> let
2e9985cd67e4f2414becb670ef33b8f16513e41dChristian Maeder (topTy, tyArgs) = getTypeApplAux False typ
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder aArgs = (Prefix, sep [ parenPrec ProdInfix $ toMixType t1
a89e661aad28f1b39f4fc9f9f9a4d46074234123Christian Maeder , parenPrec Prefix $ toMixType t2 ])
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder in case topTy of
bfa9e03532243ceb487f0384d0f6a447f1ce7670Till Mossakowski TypeName name@(Id ts cs _) _k _i ->
7221c71b38c871ce66eee4537cb681d468308dfbChristian Maeder case map toMixType tyArgs of
7221c71b38c871ce66eee4537cb681d468308dfbChristian Maeder [dArg] -> case ts of
7221c71b38c871ce66eee4537cb681d468308dfbChristian Maeder [e] | name == lazyTypeId ->
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder (Lazyfix, pretty e <+> parenPrec Lazyfix dArg)
842eedc62639561781b6c33533d1949693ef6cc5Christian Maeder [e1, e2, e3] | not (isPlace e1) && isPlace e2
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski && not (isPlace e3) && null cs ->
842eedc62639561781b6c33533d1949693ef6cc5Christian Maeder (Outfix, fsep [pretty e1, snd dArg, pretty e3])
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder [dArg1, dArg2] -> case ts of
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder [_, e2, _] | isInfix name && null cs ->
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder if tokStr e2 == prodS then
842eedc62639561781b6c33533d1949693ef6cc5Christian Maeder (ProdInfix, fsep
bfa9e03532243ceb487f0384d0f6a447f1ce7670Till Mossakowski [ parenPrec ProdInfix dArg1
967e5f3c25249c779575864692935627004d3f9eChristian Maeder , cross, parenPrec ProdInfix dArg2])
967e5f3c25249c779575864692935627004d3f9eChristian Maeder else -- assume fun type
967e5f3c25249c779575864692935627004d3f9eChristian Maeder (FunInfix, fsep
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder [ parenPrec FunInfix dArg1
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian Maeder , printTypeToken e2, snd dArg2])
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian Maeder dArgs -> if isProductIdWithArgs name $ length tyArgs then
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder (ProdInfix, fsep $ punctuate (space <> cross) $
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder map (parenPrec ProdInfix) dArgs) else aArgs
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian Maederinstance Pretty Type where
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian Maeder pretty = snd . toMixType
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian MaederprintTypeScheme :: PolyId -> TypeScheme -> Doc
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian MaederprintTypeScheme (PolyId _ tys _) (TypeScheme vs t _) =
967e5f3c25249c779575864692935627004d3f9eChristian Maeder let tdoc = pretty t in
967e5f3c25249c779575864692935627004d3f9eChristian Maeder if null vs || not (null tys) then tdoc else
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder fsep [forallDoc, semiDs vs, bullet <+> tdoc]
deb7bff126ec547bd812d0c8683ad6e785a45abbChristian Maeder-- no curried notation for bound variables
deb7bff126ec547bd812d0c8683ad6e785a45abbChristian Maederinstance Pretty TypeScheme where
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder pretty = printTypeScheme (PolyId applId [] nullRange)
ad187062b0009820118c1b773a232e29b879a2faChristian Maederinstance Pretty Partiality where
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder pretty p = case p of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder Partial -> quMarkD
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder Total -> empty
ad187062b0009820118c1b773a232e29b879a2faChristian Maederinstance Pretty Quantifier where
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder pretty q = case q of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder Universal -> forallDoc
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder Existential -> exists
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder Unique -> unique
ad187062b0009820118c1b773a232e29b879a2faChristian Maederinstance Pretty TypeQual where
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder pretty q = case q of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder OfType -> colon
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder AsType -> text asS
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder InType -> inDoc
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder Inferred -> colon
ad187062b0009820118c1b773a232e29b879a2faChristian Maederinstance Pretty Term where
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder pretty = printTerm . rmSomeTypes
ad187062b0009820118c1b773a232e29b879a2faChristian MaederisSimpleTerm :: Term -> Bool
ad187062b0009820118c1b773a232e29b879a2faChristian MaederisSimpleTerm trm = case trm of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder QualVar _ -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder QualOp {} -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder ResolvedMixTerm {} -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder ApplTerm {} -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder TupleTerm _ _ -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder TermToken _ -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder BracketTerm {} -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder-- | used only to produce CASL applications
ad187062b0009820118c1b773a232e29b879a2faChristian MaederisSimpleArgTerm :: Term -> Bool
ad187062b0009820118c1b773a232e29b879a2faChristian MaederisSimpleArgTerm trm = case trm of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder QualVar vd -> not (isPatVarDecl vd)
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder QualOp {} -> True
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder ResolvedMixTerm n _ l _ -> placeCount n /= 0 || not (null l)
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder TupleTerm _ _ -> True
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder BracketTerm {} -> True
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian MaederhasRightQuant :: Term -> Bool
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian MaederhasRightQuant t = case t of
97ee7048e63953c5617342ce38c30cbcb35cc0beChristian Maeder QuantifiedTerm {} -> True
97ee7048e63953c5617342ce38c30cbcb35cc0beChristian Maeder LambdaTerm {} -> True
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder CaseTerm {} -> True
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder LetTerm Let _ _ _ -> True
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian Maeder ResolvedMixTerm n _ ts _ | endPlace n && placeCount n == length ts
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian Maeder -> hasRightQuant (last ts)
2dfc7b04f2db681992ca04175f2beb0f127c9844Christian Maeder ApplTerm (ResolvedMixTerm n _ [] _) t2 _ | endPlace n ->
07b72edb610ee53b4832d132e96b0a3d8423f8ebChristian Maeder TupleTerm ts _ | placeCount n == length ts -> hasRightQuant (last ts)
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder _ -> hasRightQuant t2
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder ApplTerm _ t2 _ -> hasRightQuant t2
b66eb6038bfbcd2fe520d87c151bb4f1f510e985Christian MaederzipArgs :: Id -> [Term] -> [Doc] -> [Doc]
588c0c022a0f4e129a89c3bc569daf6a835e182dChristian MaederzipArgs n ts ds = case (ts, ds) of
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder (t : r, d : s) -> let
07b72edb610ee53b4832d132e96b0a3d8423f8ebChristian Maeder p = parenTermDoc t d
_ -> error "printTermRec.foldApplTerm"