c797f343be2f3619bb1f5569753166ec49d27bdbChristian MaederDescription : print the abstract syntax so that it can be re-parsed
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003
c797f343be2f3619bb1f5569753166ec49d27bdbChristian MaederLicense : GPLv2 or higher, see LICENSE.txt
c797f343be2f3619bb1f5569753166ec49d27bdbChristian MaederMaintainer : Christian.Maeder@dfki.de
c797f343be2f3619bb1f5569753166ec49d27bdbChristian MaederStability : experimental
f3a94a197960e548ecd6520bb768cb0d547457bbChristian MaederPortability : portable
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maederprinting data types of the abstract syntax
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maederimport qualified Data.Set as Set
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder-- | short cut for: if b then empty else d
8b9fda012e5ee53b7b2320c0638896a0ff6e99f3Christian MaedernoPrint :: Bool -> Doc -> Doc
8b9fda012e5ee53b7b2320c0638896a0ff6e99f3Christian MaedernoPrint b d = if b then empty else d
8b9fda012e5ee53b7b2320c0638896a0ff6e99f3Christian MaedernoNullPrint :: [a] -> Doc -> Doc
b190f5c7cf3ddda73724efe5ce82b9585ed76be1Christian MaedernoNullPrint = noPrint . null
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian MaedersemiDs :: Pretty a => [a] -> Doc
04dada28736b4a237745e92063d8bdd49a362debChristian MaedersemiDs = fsep . punctuate semi . map pretty
b190f5c7cf3ddda73724efe5ce82b9585ed76be1Christian MaedersemiAnnoted :: Pretty a => [Annoted a] -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaedersemiAnnoted = vcat . map (printSemiAnno pretty True)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty Variance where
b190f5c7cf3ddda73724efe5ce82b9585ed76be1Christian Maeder pretty = sidDoc . mkSimpleId . show
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty a => Pretty (AnyKind a) where
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder pretty knd = case knd of
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder ClassKind ci -> pretty ci
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder FunKind v k1 k2 _ -> fsep
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder [ pretty v <> (case k1 of
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder FunKind {} -> parens
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder _ -> id) (pretty k1)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder , funArrow, pretty k2]
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaedervarOfTypeArg :: TypeArg -> Id
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaedervarOfTypeArg (TypeArg i _ _ _ _ _ _) = i
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maederinstance Pretty TypePattern where
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder pretty tp = case tp of
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder TypePattern name@(Id ts cs _) args _ ->
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder let ds = map (pretty . varOfTypeArg) args in
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder if placeCount name == length args then
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder let (ras, dts) = mapAccumL ( \ l t -> if isPlace t then
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder x : r -> (r, x)
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder _ -> error "Pretty TypePattern"
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder else (l, printTypeToken t)) ds ts
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder in fsep $ dts ++ (if null cs then [] else
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder [brackets $ sepByCommas $ map printTypeId cs])
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder else printTypeId name <+> fsep ds
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder TypePatternToken t -> printTypeToken t
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder MixfixTypePattern ts -> fsep $ map pretty ts
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder BracketTypePattern k l _ -> bracket k $ ppWithCommas l
f4741f6b7da52b5417899c8fcbe4349b920b006eChristian Maeder TypePatternArg t _ -> parens $ pretty t
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder-- | put proper brackets around a document
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maederbracket :: BracketKind -> Doc -> Doc
f4741f6b7da52b5417899c8fcbe4349b920b006eChristian Maederbracket b = case b of
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder Parens -> parens
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder Squares -> brackets
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder Braces -> specBraces
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder NoBrackets -> id
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder-- | print a 'Kind' plus a preceding colon (or nothing)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintKind :: Kind -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintKind k = noPrint (k == universe) $ printVarKind NonVar (VarKind k)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder-- | print the kind of a variable with its variance and a preceding colon
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintVarKind :: Variance -> VarKind -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintVarKind e vk = case vk of
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder Downset t -> less <+> pretty t
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder VarKind k -> colon <+> pretty e <> pretty k
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder MissingKind -> empty
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederdata TypePrec = Outfix | Prefix | Lazyfix | ProdInfix | FunInfix | Absfix
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder deriving (Eq, Ord)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederparenPrec :: TypePrec -> (TypePrec, Doc) -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederparenPrec p1 (p2, d) = if p2 < p1 then d else parens d
15bb922b665fcd44c6230a1202785d0c7890e90cChristian MaederprintTypeToken :: Token -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintTypeToken t = let
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder l = ("*", cross) : map ( \ (a, d) -> (show a, d) )
462ec4b2fa3e0e788eb60dcb4aebc518298f342cChristian Maeder [ (FunArr, funArrow)
f4741f6b7da52b5417899c8fcbe4349b920b006eChristian Maeder , (PFunArr, pfun)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder , (ContFunArr, cfun)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder , (PContFunArr, pcfun) ]
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder in case lookup (tokStr t) l of
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder _ -> pretty t
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintTypeId :: Id -> Doc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederprintTypeId (Id ts cs _) = let (toks, pls) = splitMixToken ts in
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder fcat $ map printTypeToken toks
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder ++ (if null cs then [] else [brackets $ sepByCommas $ map printTypeId cs])
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder ++ map printTypeToken pls
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian MaedertoMixType :: Type -> (TypePrec, Doc)
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaedertoMixType typ = case typ of
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder TypeName name _ _ -> (Outfix, printTypeId name)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder TypeToken tt -> (Outfix, printTypeToken tt)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder TypeAbs v t _ ->
04dada28736b4a237745e92063d8bdd49a362debChristian Maeder (Absfix, sep [ lambda <+> pretty v, bullet <+> snd (toMixType t)])
04dada28736b4a237745e92063d8bdd49a362debChristian Maeder ExpandedType t1 _ -> toMixType t1 -- here we print the unexpanded type
15bb922b665fcd44c6230a1202785d0c7890e90cChristian Maeder BracketType k l _ ->
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder (Outfix, bracket k $ sepByCommas $ map (snd . toMixType) l)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder KindedType t kind _ -> (Lazyfix, sep
04dada28736b4a237745e92063d8bdd49a362debChristian Maeder [ parenPrec Lazyfix $ toMixType t
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder , colon <+> printList0 (Set.toList kind)])
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder MixfixType ts -> (Prefix, fsep $ map (snd . toMixType) ts)
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder TypeAppl t1 t2 -> let
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder (topTy, tyArgs) = getTypeApplAux False typ
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder aArgs = (Prefix, sep [ parenPrec ProdInfix $ toMixType t1
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder , parenPrec Prefix $ toMixType t2 ])
76fa667489c5e0868ac68de9f0253ac10f73d0b5Christian Maeder in case topTy of
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder TypeName name@(Id ts cs _) _k _i ->
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder case map toMixType tyArgs of
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder [dArg] -> case ts of
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder [e] | name == lazyTypeId ->
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder (Lazyfix, pretty e <+> parenPrec Lazyfix dArg)
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder [e1, e2, e3] | not (isPlace e1) && isPlace e2
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder && not (isPlace e3) && null cs ->
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder (Outfix, fsep [pretty e1, snd dArg, pretty e3])
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder [dArg1, dArg2] -> case ts of
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder [_, e2, _] | isInfix name && null cs ->
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder if tokStr e2 == prodS then
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder (ProdInfix, fsep
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder [ parenPrec ProdInfix dArg1
15bb922b665fcd44c6230a1202785d0c7890e90cChristian Maeder , cross, parenPrec ProdInfix dArg2])
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder else -- assume fun type
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder (FunInfix, fsep
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder [ parenPrec FunInfix dArg1
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder , printTypeToken e2, snd dArg2])
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder dArgs -> if isProductIdWithArgs name $ length tyArgs then
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder (ProdInfix, fsep $ punctuate (space <> cross) $
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder map (parenPrec ProdInfix) dArgs) else aArgs
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maederinstance Pretty Type where
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder pretty = snd . toMixType
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian MaederprintTypeScheme :: PolyId -> TypeScheme -> Doc
e76e6a43f51438215737d6fc176c89da05bb86daChristian MaederprintTypeScheme (PolyId _ tys _) (TypeScheme vs t _) =
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder let tdoc = pretty t in
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder if null vs || not (null tys) then tdoc else
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder fsep [forallDoc, semiDs vs, bullet <+> tdoc]
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder-- no curried notation for bound variables
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty TypeScheme where
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder pretty = printTypeScheme (PolyId applId [] nullRange)
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maederinstance Pretty Partiality where
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder pretty p = case p of
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder Partial -> quMarkD
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maeder Total -> empty
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty Quantifier where
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maeder pretty q = case q of
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maeder Universal -> forallDoc
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maeder Existential -> exists
962d5c684e2b86d1f9c556c096b426e10cc74026Christian Maeder Unique -> unique
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty TypeQual where
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder pretty q = case q of
b984ff0ba75221f64451c1e69b3977967d4e99a1Christian Maeder OfType -> colon
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder AsType -> text asS
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder InType -> inDoc
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder Inferred -> colon
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maederinstance Pretty Term where
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder pretty = printTerm . rmSomeTypes
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederisSimpleTerm :: Term -> Bool
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian MaederisSimpleTerm trm = case trm of
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder QualVar _ -> True
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder QualOp {} -> True
6cca02cb6a5ae882d887a879f8b7a71941c3715cChristian Maeder ResolvedMixTerm {} -> True
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder ApplTerm {} -> True
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder TupleTerm _ _ -> True
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder TermToken _ -> True
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder BracketTerm {} -> True
15bb922b665fcd44c6230a1202785d0c7890e90cChristian Maeder-- | used only to produce CASL applications
15bb922b665fcd44c6230a1202785d0c7890e90cChristian MaederisSimpleArgTerm :: Term -> Bool
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian MaederisSimpleArgTerm trm = case trm of
_ -> error "printTermRec.foldApplTerm"