{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wno-orphans #-} {- | Module : Language.Egison.PrettyPrint Licence : MIT This module contains pretty printing for Egison syntax -} module Language.Egison.Pretty ( prettyTopExprs , prettyStr , showTSV ) where import Data.Foldable (toList) import Data.List (intercalate) import Prettyprinter import Prettyprinter.Render.String (renderString) import Text.Show.Unicode (ushow) import Language.Egison.AST import Language.Egison.Data import Language.Egison.IExpr hiding (TIPatternNode(..)) import Language.Egison.IExpr (TIPatternNode(..)) import qualified Language.Egison.Type.Types as Types import Language.Egison.Type.Pretty (prettyTypeScheme) -- -- Pretty printing for Non-S syntax -- prettyTopExprs :: [TopExpr] -> Doc [TopExpr] prettyTopExprs exprs = vsep $ punctuate line (map pretty exprs) instance Pretty TopExpr where pretty (Define x (LambdaExpr args body)) = hsep (pretty "def" : pretty x : map pretty' args) <+> indentBlock (pretty ":=") [pretty body] pretty (Define x expr) = pretty "def" <+> pretty x <+> indentBlock (pretty ":=") [pretty expr] pretty (Test expr) = pretty expr pretty (LoadFile file) = pretty "loadFile" <+> pretty (show file) pretty (Load lib) = pretty "load" <+> pretty (show lib) pretty (PatternInductiveDecl typeName typeParams constructors) = let typeParamsDoc = if null typeParams then emptyDoc else hsep (map pretty typeParams) constructorsDoc = vsep $ map (\(PatternConstructor name args) -> pretty "|" <+> pretty name <+> hsep (map pretty args)) constructors in pretty "inductive" <+> pretty "pattern" <+> pretty typeName <+> typeParamsDoc <+> pretty ":=" <+> constructorsDoc pretty (PatternFunctionDecl name typeParams params retType body) = let typeParamsDoc = if null typeParams then emptyDoc else braces (hsep $ punctuate (pretty ",") (map pretty typeParams)) paramsDoc = hsep $ map (\(pname, ptype) -> parens (pretty pname <+> pretty ":" <+> pretty ptype)) params in pretty "def" <+> pretty "pattern" <+> pretty name <+> typeParamsDoc <+> paramsDoc <+> pretty ":" <+> pretty retType <+> pretty ":=" <+> pretty body pretty (DeclareSymbol names mTypeExpr) = let namesDoc = hsep $ punctuate (pretty ",") (map pretty names) typeDoc = case mTypeExpr of Just typeExpr -> pretty ":" <+> pretty typeExpr Nothing -> emptyDoc in pretty "declare" <+> pretty "symbol" <+> namesDoc <+> typeDoc pretty _ = error "Unsupported topexpr" instance Pretty ConstantExpr where pretty (CharExpr x) = viaShow x pretty (StringExpr x) = pretty (ushow x) pretty (BoolExpr x) = pretty x pretty (IntegerExpr x) = pretty x pretty (FloatExpr x) = pretty x pretty SomethingExpr = pretty "something" pretty UndefinedExpr = pretty "undefined" instance Pretty Expr where pretty (ConstantExpr c) = pretty c -- Use |viaShow| to correctly handle escaped characters pretty (VarExpr x) = pretty x pretty FreshVarExpr = pretty "#" pretty (IndexedExpr True e indices) = pretty' e <> cat (map pretty indices) pretty (IndexedExpr False e indices) = pretty' e <> pretty "..." <> cat (map pretty indices) pretty (SubrefsExpr b e1 e2) = applyLike [pretty "subrefs" <> (if b then pretty "!" else emptyDoc), pretty' e1, pretty' e2] pretty (SuprefsExpr b e1 e2) = applyLike [pretty "suprefs" <> (if b then pretty "!" else emptyDoc), pretty' e1, pretty' e2] pretty (UserrefsExpr b e1 e2) = applyLike [pretty "userRefs" <> (if b then pretty "!" else emptyDoc), pretty' e1, pretty' e2] pretty (TupleExpr xs) = tupled (map pretty xs) pretty (CollectionExpr xs) | length xs < 20 = list (map pretty xs) | otherwise = pretty "[" <> align (fillSepAtom (punctuate comma (map pretty xs))) <> pretty "]" pretty (HashExpr xs) = listoid "{|" "|}" (map (\(x, y) -> tupled [pretty x, pretty y]) xs) pretty (VectorExpr xs) = listoid "[|" "|]" (map pretty xs) pretty (LambdaExpr xs e) = lambdaLike (pretty "\\") (map pretty xs) (pretty "->") (pretty e) pretty (MemoizedLambdaExpr xs e) = lambdaLike (pretty "memoizedLambda ") (map pretty xs) (pretty "->") (pretty e) pretty (TypedMemoizedLambdaExpr params retType e) = lambdaLike (pretty "memoizedLambda ") (map pretty params) (pretty ":" <+> pretty retType <+> pretty "->") (pretty e) pretty (CambdaExpr x e) = indentBlock (pretty "cambda" <+> pretty x <+> pretty "->") [pretty e] pretty (PatternFunctionExpr xs p) = lambdaLike (pretty "\\") (map pretty xs) (pretty "=>") (pretty p) pretty (IfExpr x y z) = indentBlock (pretty "if" <+> pretty x) [pretty "then" <+> pretty y, pretty "else" <+> pretty z] pretty (LetRecExpr bindings body) = hang 1 (pretty "let" <+> align (vsep (map pretty bindings)) <> hardline <> pretty "in" <+> align (pretty body)) pretty (WithSymbolsExpr xs e) = indentBlock (pretty "withSymbols" <+> list (map pretty xs)) [pretty e] pretty (MatchExpr BFSMode tgt matcher clauses) = nest 2 (pretty "match" <+> pretty tgt <+> prettyMatch matcher clauses) pretty (MatchExpr DFSMode tgt matcher clauses) = nest 2 (pretty "matchDFS" <+> pretty tgt <+> prettyMatch matcher clauses) pretty (MatchAllExpr BFSMode tgt matcher clauses) = nest 2 (pretty "matchAll" <+> pretty tgt <+> prettyMatch matcher clauses) pretty (MatchAllExpr DFSMode tgt matcher clauses) = nest 2 (pretty "matchAllDFS" <+> pretty tgt <+> prettyMatch matcher clauses) pretty (MatchLambdaExpr matcher clauses) = nest 2 (pretty "\\match" <+> prettyMatch matcher clauses) pretty (MatchAllLambdaExpr matcher clauses) = nest 2 (pretty "\\matchAll" <+> prettyMatch matcher clauses) pretty (MatcherExpr patDefs) = nest 2 (pretty "matcher" <> hardline <> align (vsep (map prettyPatDef patDefs))) where prettyPatDef (PatternDef pppat expr body) = nest 2 (pipe <+> pretty pppat <+> pretty "as" <+> group (pretty expr) <+> pretty "with" <> hardline <> align (vsep (map prettyPatBody body))) prettyPatBody (pdpat, expr) = indentBlock (pipe <+> align (pretty pdpat) <+> pretty "->") [pretty expr] pretty (AlgebraicDataMatcherExpr patDefs) = nest 2 (pretty "algebraicDataMatcher" <> hardline <> align (vsep (map prettyPatDef patDefs))) where prettyPatDef (name, exprs) = pipe <+> hsep (pretty name : map pretty exprs) pretty (QuoteExpr e) = squote <> pretty' e pretty (QuoteSymbolExpr e) = pretty '`' <> pretty' e pretty (PrefixExpr op x@(ConstantExpr (IntegerExpr _))) = pretty op <> pretty x pretty (PrefixExpr op x) | isAtomOrApp x = pretty op <+> pretty x | otherwise = pretty op <+> parens (pretty x) -- (x1 op' x2) op y pretty (InfixExpr op x@(InfixExpr op' _ _) y) = if priority op > priority op' || priority op == priority op' && assoc op == InfixR then parens (pretty x) <+> pretty op <> infixRight (pretty'' y) else pretty x <+> pretty op <> infixRight (pretty'' y) -- x op (y1 op' y2) pretty (InfixExpr op x y@(InfixExpr op' _ _)) = if priority op > priority op' || priority op == priority op' && assoc op == InfixL then pretty'' x <+> pretty op <> infixRight (parens (pretty y)) else pretty'' x <+> pretty op <> infixRight (pretty y) pretty (InfixExpr op x y) = pretty'' x <+> pretty op <> infixRight (pretty'' y) pretty (SectionExpr op Nothing Nothing) = parens (pretty op) pretty (SectionExpr op (Just x) Nothing) = parens (pretty x <+> pretty op) pretty (SectionExpr op Nothing (Just x)) = parens (pretty op <+> pretty x) pretty (DoExpr [] y) = pretty "do" <+> pretty y pretty (DoExpr xs (ApplyExpr (VarExpr "return") [])) = pretty "do" <+> align (hsepHard (map prettyDoBinds xs)) pretty (DoExpr xs y) = pretty "do" <+> align (hsepHard (map prettyDoBinds xs ++ [pretty y])) pretty (SeqExpr e1 e2) = applyLike [pretty "seq", pretty' e1, pretty' e2] pretty (ApplyExpr x ys) = applyLike (map pretty' (x : ys)) pretty (AnonParamFuncExpr n e) = pretty n <> pretty '#' <> pretty' e pretty (AnonParamExpr n) = pretty '$' <> pretty n pretty (GenerateTensorExpr gen shape) = applyLike [pretty "generateTensor", pretty' gen, pretty' shape] pretty (TensorExpr e1 e2) = applyLike [pretty "tensor", pretty' e1, pretty' e2] pretty (TensorContractExpr e1) = applyLike [pretty "contract", pretty' e1] pretty (TensorMapExpr e1 e2) = applyLike [pretty "tensorMap", pretty' e1, pretty' e2] pretty (TensorMap2Expr e1 e2 e3) = applyLike [pretty "tensorMap2", pretty' e1, pretty' e2, pretty' e3] pretty (TransposeExpr e1 e2) = applyLike [pretty "transpose", pretty' e1, pretty' e2] pretty (FlipIndicesExpr _) = error "unreachable" pretty (FunctionExpr xs) = pretty "function" <+> tupled (map pretty xs) pretty p = pretty (show p) instance (Pretty a, Complex a) => Pretty (Arg a) where pretty (Arg x) = pretty x pretty (InvertedArg x) = pretty "!" <> pretty' x instance Pretty ArgPattern where pretty APWildCard = pretty "_" pretty (APPatVar x) = pretty x pretty (APInductivePat x args) = applyLike (pretty x : map pretty' args) pretty (APTuplePat args) = tupled (map pretty args) pretty APEmptyPat = pretty "[]" pretty (APConsPat arg1 arg2) = pretty'' arg1 <+> pretty "::" <+> pretty'' arg2 pretty (APSnocPat arg1 arg2) = pretty'' arg1 <+> pretty "*:" <+> pretty' arg2 instance Pretty VarWithIndices where pretty (VarWithIndices xs is) = pretty xs <> hcat (map pretty is) instance Pretty VarIndex where pretty (VSubscript x) = pretty ('_' : x) pretty (VSuperscript x) = pretty ('~' : x) pretty (VSymmScripts xs) = pretty '[' <> hcat (map pretty xs) <> pretty ']' pretty (VAntiSymmScripts xs) = pretty '{' <> hcat (map pretty xs) <> pretty '}' instance Pretty BindingExpr where pretty (Bind (PDPatVar f) (LambdaExpr args body)) = hsep (pretty f : map pretty' args) <+> indentBlock (pretty ":=") [pretty body] pretty (Bind pat expr) = pretty pat <+> pretty ":=" <+> align (pretty expr) pretty (BindWithIndices var expr) = pretty var <+> pretty ":=" <+> align (pretty expr) pretty (BindWithType typedVar expr) = let constraints = typedVarConstraints typedVar constraintsDoc = if null constraints then mempty else pretty "{" <> hsep (punctuate (pretty ",") (map pretty constraints)) <> pretty "}" <> space in hsep (pretty (typedVarName typedVar) : [constraintsDoc | not (null constraints)] ++ map pretty (typedVarParams typedVar)) <+> pretty ":" <+> pretty (typedVarRetType typedVar) <+> pretty ":=" <+> align (pretty expr) instance Pretty TypedParam where pretty (TPVar name ty) = parens (pretty name <+> pretty ":" <+> pretty ty) pretty (TPInvertedVar name ty) = parens (pretty "!" <+> pretty name <+> pretty ":" <+> pretty ty) pretty (TPTuple elems) = parens (hsep (punctuate comma (map pretty elems))) pretty (TPWildcard ty) = parens (pretty "_" <+> pretty ":" <+> pretty ty) pretty (TPUntypedVar name) = pretty name pretty TPUntypedWildcard = pretty "_" instance Pretty TypeExpr where pretty TEInt = pretty "Integer" pretty TEMathExpr = pretty "MathExpr" pretty TEFloat = pretty "Float" pretty TEBool = pretty "Bool" pretty TEChar = pretty "Char" pretty TEString = pretty "String" pretty (TEVar v) = pretty v pretty (TEList t) = brackets (pretty t) pretty (TETuple []) = pretty "()" pretty (TETuple ts) = parens (hsep (punctuate comma (map pretty ts))) pretty (TEFun t1 t2) = pretty t1 <+> pretty "->" <+> pretty t2 pretty (TEMatcher t) = pretty "Matcher" <+> pretty t pretty (TEPattern t) = pretty "Pattern" <+> pretty t pretty (TEIO t) = pretty "IO" <+> pretty t pretty (TETensor t) = pretty "Tensor" <+> pretty t pretty (TEApp t args) = hsep (pretty t : map pretty args) instance Pretty ConstraintExpr where pretty (ConstraintExpr cls types) = hsep (pretty cls : map pretty types) instance {-# OVERLAPPING #-} Pretty MatchClause where pretty (pat, expr) = pipe <+> align (pretty pat) <+> indentBlock (pretty "->") [pretty expr] instance {-# OVERLAPPING #-} Pretty (IndexExpr String) where -- for 'VarWithIndices' pretty (Superscript s) = pretty ("~" ++ s) pretty (Subscript s) = pretty ("_" ++ s) pretty (SupSubscript s) = pretty ("~_" ++ s) pretty (Userscript i) = pretty ("|" ++ show i) pretty _ = undefined instance (Pretty a, Complex a) => Pretty (IndexExpr a) where pretty (Subscript i) = pretty '_' <> pretty' i pretty (Superscript i) = pretty '~' <> pretty' i pretty (SupSubscript i) = pretty "~_" <> pretty' i pretty (MultiSubscript i j) = pretty '_' <> pretty' i <> pretty "..._" <> pretty' j pretty (MultiSuperscript i j) = pretty '~' <> pretty' i <> pretty "...~" <> pretty' j pretty (Userscript i) = pretty '|' <> pretty' i instance Pretty Pattern where pretty WildCard = pretty "_" pretty (PatVar x) = pretty "$" <> pretty x pretty (ValuePat v) = pretty "#" <> pretty' v pretty (PredPat v) = pretty "?" <> pretty' v pretty (IndexedPat p indices) = pretty p <> hcat (map (\i -> pretty '_' <> pretty' i) indices) pretty (LetPat binds pat) = pretty "let" <+> align (vsep (map pretty binds)) <+> pretty "in" <+> pretty pat -- (p11 op' p12) op p2 pretty (InfixPat op p1@(InfixPat op' _ _) p2) = if priority op > priority op' || priority op == priority op' && assoc op == InfixR then parens (pretty p1) <+> pretty (repr op) <+> pretty'' p2 else pretty p1 <+> pretty (repr op) <+> pretty'' p2 -- p1 op (p21 op' p22) pretty (InfixPat op p1 p2@(InfixPat op' _ _)) = if priority op > priority op' || priority op == priority op' && assoc op == InfixL then pretty'' p1 <+> pretty (repr op) <+> parens (pretty p2) else pretty'' p1 <+> pretty (repr op) <+> pretty p2 pretty (InfixPat op p1 p2) = pretty'' p1 <+> pretty (repr op) <+> pretty'' p2 pretty (NotPat pat) = pretty "!" <> pretty' pat pretty (TuplePat pats) = tupled $ map pretty pats pretty (InductivePat "nil" []) = pretty "[]" pretty (InductivePat "::" [p, InductivePat "nil" []]) = pretty "[" <> pretty p <> pretty "]" pretty (InductivePat ctor xs) = hsep (pretty ctor : map pretty' xs) pretty (LoopPat i range p1 p2) = hang 2 (pretty "loop" <+> pretty '$' <> pretty i <+> pretty range <> flatAlt (hardline <> group (pretty' p1) <> hardline <> group (pretty' p2)) (space <> pretty' p1 <+> pretty' p2)) pretty ContPat = pretty "..." pretty (PApplyPat fn ps) = applyLike (pretty' fn : map pretty' ps) pretty (VarPat x) = pretty ('~' : x) pretty SeqNilPat = pretty "{}" pretty (SeqConsPat p1 p2) = listoid "{" "}" (f p1 p2) where f p1 SeqNilPat = [pretty p1] f p1 (SeqConsPat p2 p3) = pretty p1 : f p2 p3 f p1 p2 = [pretty p1, pretty p2] pretty LaterPatVar = pretty "@" pretty (DApplyPat p ps) = applyLike (map pretty' (p : ps)) pretty e = pretty (show e) instance {-# OVERLAPPING #-} Pretty LoopRange where pretty (LoopRange from (ApplyExpr (VarExpr "from") [ApplyExpr (VarExpr "i.-") [_, ConstantExpr (IntegerExpr 1)]]) pat) = tupled [pretty from, pretty pat] pretty (LoopRange from to pat) = tupled [pretty from, pretty to, pretty pat] instance Pretty PrimitivePatPattern where pretty PPWildCard = pretty "_" pretty PPPatVar = pretty "$" pretty (PPValuePat x) = pretty ('#' : '$' : x) pretty (PPInductivePat x pppats) = hsep (pretty x : map pretty pppats) pretty (PPTuplePat pppats) = tupled (map pretty pppats) instance Pretty PrimitiveDataPattern where pretty PDWildCard = pretty "_" pretty (PDPatVar x) = pretty x pretty (PDInductivePat x pdpats) = applyLike (pretty x : map pretty' pdpats) pretty (PDTuplePat pdpats) = tupled (map pretty pdpats) pretty PDEmptyPat = pretty "[]" pretty (PDConsPat pdp1 pdp2) = pretty'' pdp1 <+> pretty "::" <+> pretty'' pdp2 pretty (PDSnocPat pdp1 pdp2) = pretty'' pdp1 <+> pretty "*:" <+> pretty' pdp2 pretty (PDConstantPat expr) = pretty expr instance Pretty Op where pretty op | isWedge op = pretty ("!" ++ repr op) | otherwise = pretty (repr op) instance Pretty IExpr where pretty (IConstantExpr c) = pretty c pretty (IVarExpr name) = pretty name pretty (IIndexedExpr override expr indices) = pretty' expr <> (if override then pretty "..." else emptyDoc) <> hcat (map prettyIndex indices) where prettyIndex (Sub e) = pretty "_" <> prettyIndexExpr e prettyIndex (Sup e) = pretty "~" <> prettyIndexExpr e prettyIndex (SupSub e) = pretty "~_" <> prettyIndexExpr e prettyIndex (User e) = pretty "|" <> prettyIndexExpr e prettyIndex (DF _ _) = emptyDoc prettyIndex (MultiSub _ _ _) = pretty "_..." prettyIndex (MultiSup _ _ _) = pretty "~..." prettyIndexExpr e = if isAtom e then pretty e else parens (pretty e) pretty (ISubrefsExpr override expr subExpr) = pretty' expr <> (if override then pretty "..." else emptyDoc) <> pretty "._" <> prettyRefExpr subExpr pretty (ISuprefsExpr override expr supExpr) = pretty' expr <> (if override then pretty "..." else emptyDoc) <> pretty ".~" <> prettyRefExpr supExpr pretty (IUserrefsExpr override expr userExpr) = pretty' expr <> (if override then pretty "..." else emptyDoc) <> pretty ".|" <> prettyRefExpr userExpr pretty (IInductiveDataExpr name args) | null args = pretty name | otherwise = applyLike (pretty name : map pretty' args) pretty (ITupleExpr []) = pretty "(" <> pretty ")" pretty (ITupleExpr xs) = tupled (map pretty xs) pretty (ICollectionExpr xs) = list (map pretty xs) pretty (IConsExpr x xs) = pretty'' x <+> pretty "::" <+> pretty'' xs pretty (IJoinExpr x xs) = pretty'' x <+> pretty "++" <+> pretty'' xs pretty (IHashExpr pairs) = pretty "{|" <+> hsep (punctuate comma (map prettyPair pairs)) <+> pretty "|}" where prettyPair (k, v) = parens (pretty k <> comma <+> pretty v) pretty (IVectorExpr xs) = pretty "[|" <+> hsep (punctuate comma (map pretty xs)) <+> pretty "|]" pretty (ILambdaExpr _mVar params body) = lambdaLike (pretty "\\") (map prettyVar params) (pretty "->") (pretty body) where prettyVar (Var name []) = pretty name prettyVar v = pretty (show v) -- fallback for complex vars pretty (IMemoizedLambdaExpr xs e) = lambdaLike (pretty "memoizedLambda") (map pretty xs) (pretty "->") (pretty e) pretty (ICambdaExpr x e) = indentBlock (pretty "cambda" <+> pretty x <+> pretty "->") [pretty e] pretty (IIfExpr cond thenE elseE) = indentBlock (pretty "if" <+> pretty cond) [pretty "then" <+> pretty thenE, pretty "else" <+> pretty elseE] pretty (ILetRecExpr bindings body) = hang 1 (pretty "let" <+> align (vsep (map prettyIBinding bindings)) <> hardline <> pretty "in" <+> align (pretty body)) pretty (ILetExpr bindings body) = hang 1 (pretty "let" <+> align (vsep (map prettyIBinding bindings)) <> hardline <> pretty "in" <+> align (pretty body)) pretty (IWithSymbolsExpr xs e) = indentBlock (pretty "withSymbols" <+> list (map pretty xs)) [pretty e] pretty (IMatchExpr BFSMode tgt matcher clauses) = nest 2 (pretty "match" <+> pretty tgt <+> prettyIMatch matcher clauses) pretty (IMatchExpr DFSMode tgt matcher clauses) = nest 2 (pretty "matchDFS" <+> pretty tgt <+> prettyIMatch matcher clauses) pretty (IMatchAllExpr BFSMode tgt matcher clauses) = nest 2 (pretty "matchAll" <+> pretty tgt <+> prettyIMatch matcher clauses) pretty (IMatchAllExpr DFSMode tgt matcher clauses) = nest 2 (pretty "matchAllDFS" <+> pretty tgt <+> prettyIMatch matcher clauses) pretty (IMatcherExpr patDefs) = nest 2 (pretty "matcher" <> hardline <> align (vsep (map prettyIPatDef patDefs))) where prettyIPatDef (pppat, expr, body) = nest 2 (pipe <+> pretty pppat <+> pretty "as" <+> group (pretty expr) <+> pretty "with" <> hardline <> align (vsep (map prettyIPatBody body))) prettyIPatBody (pdpat, expr) = indentBlock (pipe <+> align (pretty pdpat) <+> pretty "->") [pretty expr] pretty (IQuoteExpr e) = squote <> pretty' e pretty (IQuoteSymbolExpr e) = pretty '`' <> pretty' e pretty (IWedgeApplyExpr op args) = applyLike (pretty' op : map pretty' args) pretty (IDoExpr [] y) = pretty "do" <+> pretty y pretty (IDoExpr xs y) = pretty "do" <+> align (hsepHard (map prettyIDoBinds xs ++ [pretty y])) pretty (ISeqExpr e1 e2) = applyLike [pretty "seq", pretty' e1, pretty' e2] pretty (IApplyExpr fn args) = applyLike (map pretty' (fn : args)) pretty (IGenerateTensorExpr gen shape) = applyLike [pretty "generateTensor", pretty' gen, pretty' shape] pretty (ITensorExpr e1 e2) = applyLike [pretty "tensor", pretty' e1, pretty' e2] pretty (ITensorContractExpr e1) = applyLike [pretty "contract", pretty' e1] pretty (ITensorMapExpr e1 e2) = applyLike [pretty "tensorMap", pretty' e1, pretty' e2] pretty (ITensorMap2Expr e1 e2 e3) = applyLike [pretty "tensorMap2", pretty' e1, pretty' e2, pretty' e3] pretty (ITensorMap2WedgeExpr e1 e2 e3) = applyLike [pretty "tensorMap2Wedge", pretty' e1, pretty' e2, pretty' e3] pretty (ITransposeExpr e1 e2) = applyLike [pretty "transpose", pretty' e1, pretty' e2] pretty (IFlipIndicesExpr e) = applyLike [pretty "flipIndices", pretty' e] pretty (IFunctionExpr xs) = pretty "function" <+> tupled (map pretty xs) prettyRefExpr :: IExpr -> Doc ann prettyRefExpr e = if isAtom e then pretty e else parens (pretty e) prettyIBinding :: IBindingExpr -> Doc ann prettyIBinding (pdpat, expr) = pretty pdpat <+> pretty ":=" <+> align (pretty expr) prettyIDoBinds :: IBindingExpr -> Doc ann prettyIDoBinds (pdpat, expr) = pretty pdpat <+> pretty "<-" <+> pretty expr prettyIMatch :: IExpr -> [IMatchClause] -> Doc ann prettyIMatch matcher clauses = pretty "as" <+> pretty matcher <+> pretty "with" <> hardline <> indent 2 (vsep (map prettyIClause clauses)) where prettyIClause (pat, body) = indentBlock (pipe <+> pretty pat <+> pretty "->") [pretty body] instance Complex IExpr where isAtom (IConstantExpr (IntegerExpr i)) | i < 0 = False isAtom (IConstantExpr _) = True isAtom (IVarExpr _) = True isAtom ITupleExpr{} = True isAtom ICollectionExpr{} = True isAtom IHashExpr{} = True isAtom IVectorExpr{} = True isAtom IMatcherExpr{} = True isAtom (IIndexedExpr _ e _) = isAtom e isAtom (IInductiveDataExpr _ []) = True isAtom _ = False isAtomOrApp (IApplyExpr _ _) = True isAtomOrApp (IInductiveDataExpr _ (_:_)) = True isAtomOrApp e = isAtom e isInfix _ = False -- IExpr doesn't have infix expressions (they're desugared) instance Pretty IPrimitiveDataPattern where pretty (PDPatVar (Var name [])) = pretty name pretty (PDPatVar var) = pretty (show var) pretty PDWildCard = pretty "_" pretty (PDInductivePat name []) = pretty name pretty (PDInductivePat name pats) = applyLike (pretty name : map pretty pats) pretty (PDTuplePat pats) = tupled (map pretty pats) pretty PDEmptyPat = pretty "[]" pretty (PDConsPat pat1 pat2) = pretty pat1 <+> pretty "::" <+> pretty pat2 pretty (PDSnocPat pat1 pat2) = pretty pat1 <+> pretty "*:" <+> pretty pat2 pretty (PDConstantPat c) = pretty c -- MathExpr primitive patterns pretty (PDDivPat p1 p2) = applyLike [pretty "Div", pretty p1, pretty p2] pretty (PDPlusPat p) = applyLike [pretty "Plus", pretty p] pretty (PDTermPat p1 p2) = applyLike [pretty "Term", pretty p1, pretty p2] pretty (PDSymbolPat p1 p2) = applyLike [pretty "Symbol", pretty p1, pretty p2] pretty (PDApply1Pat p1 p2) = applyLike [pretty "Apply1", pretty p1, pretty p2] pretty (PDApply2Pat p1 p2 p3) = applyLike [pretty "Apply2", pretty p1, pretty p2, pretty p3] pretty (PDApply3Pat p1 p2 p3 p4) = applyLike [pretty "Apply3", pretty p1, pretty p2, pretty p3, pretty p4] pretty (PDApply4Pat p1 p2 p3 p4 p5) = applyLike [pretty "Apply4", pretty p1, pretty p2, pretty p3, pretty p4, pretty p5] pretty (PDQuotePat p) = applyLike [pretty "Quote", pretty p] pretty (PDFunctionPat p1 p2) = applyLike [pretty "Function", pretty p1, pretty p2] pretty (PDSubPat p) = applyLike [pretty "Sub", pretty p] pretty (PDSupPat p) = applyLike [pretty "Sup", pretty p] pretty (PDUserPat p) = applyLike [pretty "User", pretty p] instance Pretty IPattern where pretty IWildCard = pretty "_" pretty (IPatVar name) = pretty "~" <> pretty name -- IPatVar is VarPat (~x, pattern variable reference) pretty (IValuePat expr) = pretty "#" <> pretty' expr pretty (IPredPat expr) = pretty "?" <> pretty' expr pretty (IIndexedPat pat indices) = pretty' pat <> hcat (map prettyIndex indices) where prettyIndex e = if isAtom e then pretty e else parens (pretty e) pretty (ILetPat bindings pat) = pretty "let" <+> align (vsep (map prettyIBinding bindings)) <+> pretty "in" <+> pretty pat pretty (INotPat pat) = pretty "!" <> pretty' pat pretty (IAndPat pat1 pat2) = pretty' pat1 <+> pretty "&" <+> pretty' pat2 pretty (IOrPat pat1 pat2) = pretty' pat1 <+> pretty "|" <+> pretty' pat2 pretty (IForallPat var pat) = pretty "forall" <+> pretty var <+> pretty pat pretty (ITuplePat pats) = tupled (map pretty pats) pretty (IInductivePat name []) = pretty name pretty (IInductivePat name pats) = applyLike (pretty name : map pretty' pats) pretty (ILoopPat var (ILoopRange start end pat) bodyPat restPat) = pretty "loop" <+> pretty "$" <> pretty var <+> tupled [pretty start, pretty end, pretty pat] <+> pretty' bodyPat <+> pretty' restPat pretty IContPat = pretty "..." pretty (IPApplyPat expr pats) = applyLike (pretty' expr : map pretty' pats) pretty (IVarPat name) = pretty "$" <> pretty name -- IVarPat is PatVar ($x, new binding) pretty (IInductiveOrPApplyPat name pats) | null pats = pretty name | otherwise = applyLike (pretty name : map pretty' pats) pretty ISeqNilPat = pretty "{}" pretty (ISeqConsPat p1 p2) = listoid "{" "}" (f p1 p2) where f p1 ISeqNilPat = [pretty p1] f p1 (ISeqConsPat p2 p3) = pretty p1 : f p2 p3 f p1 p2 = [pretty p1, pretty p2] pretty ILaterPatVar = pretty "@" pretty (IDApplyPat pat pats) = applyLike (pretty' pat : map pretty' pats) instance Complex IPattern where isAtom IWildCard = True isAtom (IPatVar _) = True isAtom (ITuplePat _) = True isAtom (IInductivePat _ []) = True isAtom ISeqNilPat = True isAtom _ = False isAtomOrApp (IPApplyPat _ _) = True isAtomOrApp (IInductiveOrPApplyPat _ (_:_)) = True isAtomOrApp (IInductivePat _ (_:_)) = True isAtomOrApp pat = isAtom pat isInfix _ = False -- Pretty print for TIPattern (use existing prettyPatternWithType) instance Pretty TIPattern where pretty = prettyPatternWithType instance Complex TIPattern where isAtom (TIPattern _ TIWildCard) = True isAtom (TIPattern _ (TIVarPat _)) = True isAtom (TIPattern _ (TITuplePat _)) = True isAtom (TIPattern _ (TIInductivePat _ [])) = True isAtom (TIPattern _ TISeqNilPat) = True isAtom _ = False isAtomOrApp (TIPattern _ (TIPApplyPat _ _)) = True isAtomOrApp (TIPattern _ (TIInductiveOrPApplyPat _ (_:_))) = True isAtomOrApp (TIPattern _ (TIInductivePat _ (_:_))) = True isAtomOrApp pat = isAtom pat isInfix _ = False -- Pretty print for ITopExpr instance Pretty ITopExpr where pretty (IDefine var iexpr) = pretty "def" <+> prettyVar var <+> indentBlock (pretty ":=") [pretty iexpr] pretty (IDefineMany bindings) = vsep (map prettyDefineMany bindings) where prettyDefineMany (var, iexpr) = pretty "def" <+> prettyVar var <+> pretty ":=" <+> pretty iexpr pretty (ITest iexpr) = pretty iexpr pretty (IExecute iexpr) = pretty "execute" <+> pretty iexpr pretty (ILoadFile path) = pretty "loadFile" <+> pretty (show path) pretty (ILoad lib) = pretty "load" <+> pretty (show lib) pretty (IDeclareSymbol names mType) = let namesDoc = hsep $ punctuate (pretty ",") (map pretty names) typeDoc = case mType of Just ty -> pretty ":" <+> prettyTypeDoc ty Nothing -> emptyDoc in pretty "declare" <+> pretty "symbol" <+> namesDoc <+> typeDoc pretty (IPatternFunctionDecl name tyVars params retType body) = let tyVarsDoc = if null tyVars then emptyDoc else pretty "{" <> hsep (punctuate (pretty ",") (map prettyTyVar tyVars)) <> pretty "}" paramsDoc = hsep (map prettyParam params) retTypeDoc = prettyTypeDoc retType in pretty "def" <+> pretty "pattern" <+> pretty name <+> tyVarsDoc <+> paramsDoc <+> pretty ":" <+> retTypeDoc <+> indentBlock (pretty ":=") [pretty body] where prettyTyVar (Types.TyVar v) = pretty v prettyParam (pname, pty) = pretty "(" <> pretty pname <+> pretty ":" <+> prettyTypeDoc pty <> pretty ")" -- Pretty print for TIExpr and TITopExpr instance Pretty TIExpr where pretty tiexpr = prettyTIExprWithType tiexpr -- Pretty print TIExpr with type annotations for all subexpressions prettyTIExprWithType :: TIExpr -> Doc ann prettyTIExprWithType tiexpr = let (Types.Forall _ constraints ty) = tiScheme tiexpr constraintDoc = prettyConstraintsDoc constraints in parens (prettyTIExprNode (tiExprNode tiexpr) <+> pretty ":" <+> constraintDoc <> prettyTypeDoc ty) -- Pretty print pattern with type annotations (recursive) prettyPatternWithType :: TIPattern -> Doc ann prettyPatternWithType (TIPattern (Types.Forall _ constraints ty) node) = let constraintDoc = prettyConstraintsDoc constraints in parens (prettyTIPatternNode node <+> pretty ":" <+> constraintDoc <> prettyTypeDoc ty) -- Pretty print pattern node recursively prettyTIPatternNode :: TIPatternNode -> Doc ann prettyTIPatternNode node = case node of TIWildCard -> pretty "_" TIPatVar name -> pretty "~" <> pretty name -- TIPatVar is VarPat (~x, pattern variable reference) TIValuePat expr -> pretty "#" <> prettyTIExprWithType expr TIPredPat expr -> pretty "?" <> prettyTIExprWithType expr TIIndexedPat pat exprs -> prettyPatternWithType pat <> hcat (map prettyIndexExpr exprs) where prettyIndexExpr e = pretty "_" <> prettyTIExprWithType e TILetPat bindings pat -> pretty "let" <+> hsep (map prettyBinding bindings) <+> pretty "in" <+> prettyPatternWithType pat where prettyBinding (p, e) = pretty p <+> pretty ":=" <+> prettyTIExprWithType e TINotPat pat -> pretty "!" <> prettyPatternWithType pat TIAndPat p1 p2 -> prettyPatternWithType p1 <+> pretty "&" <+> prettyPatternWithType p2 TIOrPat p1 p2 -> prettyPatternWithType p1 <+> pretty "|" <+> prettyPatternWithType p2 TIForallPat p1 p2 -> pretty "forall" <+> prettyPatternWithType p1 <+> prettyPatternWithType p2 TITuplePat pats -> tupled (map prettyPatternWithType pats) TIInductivePat name pats -> pretty name <+> hsep (map prettyPatternWithType pats) TILoopPat var (TILoopRange start end pat) p1 p2 -> pretty "loop" <+> pretty "$" <> pretty var <+> tupled [prettyTIExprWithType start, prettyTIExprWithType end, prettyPatternWithType pat] <+> prettyPatternWithType p1 <+> prettyPatternWithType p2 TIContPat -> pretty "..." TIPApplyPat func pats -> prettyTIExprWithType func <+> hsep (map prettyPatternWithType pats) TIVarPat name -> pretty "$" <> pretty name -- TIVarPat is PatVar ($x, new binding) TIInductiveOrPApplyPat name pats -> pretty name <+> hsep (map prettyPatternWithType pats) TISeqNilPat -> pretty "{}" TISeqConsPat p1 p2 -> listoid "{" "}" (f p1 p2) where f p1 (TIPattern _ TISeqNilPat) = [prettyPatternWithType p1] f p1 (TIPattern _ (TISeqConsPat p2 p3)) = prettyPatternWithType p1 : f p2 p3 f p1 p2 = [prettyPatternWithType p1, prettyPatternWithType p2] TILaterPatVar -> pretty "@" TIDApplyPat pat pats -> prettyPatternWithType pat <+> hsep (map prettyPatternWithType pats) -- Pretty print TIExprNode recursively prettyTIExprNode :: TIExprNode -> Doc ann prettyTIExprNode node = case node of TIConstantExpr c -> pretty c TIVarExpr name -> pretty name TILambdaExpr _ params body -> pretty "\\" <> hsep (map prettyVar params) <+> pretty "->" <+> prettyTIExprWithType body TIApplyExpr func args -> prettyTIExprWithType func <+> hsep (map prettyTIExprWithType args) TITupleExpr exprs -> tupled (map prettyTIExprWithType exprs) TICollectionExpr exprs -> brackets (hsep $ punctuate comma (map prettyTIExprWithType exprs)) TIConsExpr h t -> prettyTIExprWithType h <+> pretty "::" <+> prettyTIExprWithType t TIJoinExpr l r -> prettyTIExprWithType l <+> pretty "++" <+> prettyTIExprWithType r TIIfExpr cond thenE elseE -> pretty "if" <+> prettyTIExprWithType cond <+> pretty "then" <+> prettyTIExprWithType thenE <+> pretty "else" <+> prettyTIExprWithType elseE TILetExpr bindings body -> pretty "let" <+> vsep (map prettyBinding bindings) <+> pretty "in" <+> prettyTIExprWithType body where prettyBinding (pat, expr) = pretty pat <+> pretty ":=" <+> prettyTIExprWithType expr TITensorMapExpr func tensor -> pretty "tensorMap" <+> prettyTIExprWithType func <+> prettyTIExprWithType tensor TITensorMap2Expr func t1 t2 -> pretty "tensorMap2" <+> prettyTIExprWithType func <+> prettyTIExprWithType t1 <+> prettyTIExprWithType t2 TITensorMap2WedgeExpr func t1 t2 -> pretty "tensorMap2Wedge" <+> prettyTIExprWithType func <+> prettyTIExprWithType t1 <+> prettyTIExprWithType t2 TITensorContractExpr tensor -> pretty "contract" <+> prettyTIExprWithType tensor TITensorExpr shape elems -> pretty "tensor" <+> prettyTIExprWithType shape <+> prettyTIExprWithType elems TIGenerateTensorExpr func shape -> pretty "generateTensor" <+> prettyTIExprWithType func <+> prettyTIExprWithType shape TITransposeExpr perm tensor -> pretty "transpose" <+> prettyTIExprWithType perm <+> prettyTIExprWithType tensor TIFlipIndicesExpr tensor -> pretty "flipIndices" <+> prettyTIExprWithType tensor TIVectorExpr exprs -> pretty "[|" <+> hsep (punctuate comma (map prettyTIExprWithType exprs)) <+> pretty "|]" TIHashExpr pairs -> pretty "{|" <+> hsep (punctuate comma (map prettyPair pairs)) <+> pretty "|}" where prettyPair (k, v) = parens (prettyTIExprWithType k <> comma <+> prettyTIExprWithType v) TISeqExpr e1 e2 -> prettyTIExprWithType e1 <> pretty ";" <+> prettyTIExprWithType e2 TIMemoizedLambdaExpr params body -> pretty "memoizedLambda" <+> hsep (map pretty params) <+> pretty "->" <+> prettyTIExprWithType body TICambdaExpr param body -> pretty "cambda" <+> pretty param <+> pretty "->" <+> prettyTIExprWithType body TIWithSymbolsExpr syms body -> pretty "withSymbols" <+> list (map pretty syms) <+> prettyTIExprWithType body TIDoExpr bindings body -> pretty "do" <+> vsep (map prettyBinding bindings) <+> prettyTIExprWithType body where prettyBinding (pat, expr) = pretty pat <+> pretty "<-" <+> prettyTIExprWithType expr TIMatchExpr _mode target matcher clauses -> pretty "match" <+> prettyTIExprWithType target <+> pretty "as" <+> prettyTIExprWithType matcher <+> pretty "with" <+> vsep (map prettyClause clauses) where prettyClause (tipat, body) = pretty "|" <+> prettyPatternWithType tipat <+> pretty "->" <+> prettyTIExprWithType body TIMatchAllExpr _mode target matcher clauses -> pretty "matchAll" <+> prettyTIExprWithType target <+> pretty "as" <+> prettyTIExprWithType matcher <+> pretty "with" <+> vsep (map prettyClause clauses) where prettyClause (tipat, body) = pretty "|" <+> prettyPatternWithType tipat <+> pretty "->" <+> prettyTIExprWithType body TIInductiveDataExpr name exprs -> pretty name <+> hsep (map prettyTIExprWithType exprs) TIQuoteExpr e -> squote <> prettyTIExprWithType e TIQuoteSymbolExpr e -> pretty '`' <> prettyTIExprWithType e TISubrefsExpr _ base ref -> pretty "subrefs" <+> prettyTIExprWithType base <+> prettyTIExprWithType ref TISuprefsExpr _ base ref -> pretty "suprefs" <+> prettyTIExprWithType base <+> prettyTIExprWithType ref TIUserrefsExpr _ base ref -> pretty "userrefs" <+> prettyTIExprWithType base <+> prettyTIExprWithType ref TIWedgeApplyExpr func args -> pretty "!" <+> prettyTIExprWithType func <+> hsep (map prettyTIExprWithType args) TIIndexedExpr _ base indices -> prettyTIExprWithType base <> hcat (map prettyIndex indices) where prettyIndex (Sub e) = pretty "_" <> pretty e prettyIndex (Sup e) = pretty "~" <> pretty e prettyIndex (SupSub e) = pretty "~_" <> pretty e prettyIndex (User e) = pretty "|" <> pretty e prettyIndex (MultiSub e1 n e2) = pretty "_..." <> pretty e1 <> pretty n <> pretty e2 prettyIndex (MultiSup e1 n e2) = pretty "~..." <> pretty e1 <> pretty n <> pretty e2 prettyIndex (DF _i1 _i2) = emptyDoc TIFunctionExpr names -> pretty "function" <+> hsep (map pretty names) TILetRecExpr bindings body -> pretty "let" <+> vsep (map prettyBinding bindings) <+> pretty "in" <+> prettyTIExprWithType body where prettyBinding (pat, expr) = pretty pat <+> pretty ":=" <+> prettyTIExprWithType expr TIMatcherExpr patDefs -> pretty "matcher" <+> vsep (map prettyPatDef patDefs) where prettyPatDef (pat, expr, _bindings) = pretty pat <+> pretty "->" <+> prettyTIExprWithType expr instance Pretty TITopExpr where pretty (TIDefine scheme var tiexpr) = let typeStr = prettyTypeScheme scheme in pretty "def" <+> prettyVar var <+> pretty ":" <+> pretty typeStr <+> indentBlock (pretty ":=") [pretty tiexpr] pretty (TITest tiexpr) = pretty tiexpr pretty (TIExecute tiexpr) = pretty "execute" <+> pretty tiexpr pretty (TILoadFile path) = pretty "loadFile" <+> pretty (show path) pretty (TILoad lib) = pretty "load" <+> pretty (show lib) pretty (TIDefineMany bindings) = vsep (map prettyBinding bindings) where prettyBinding (var, tiexpr) = prettyVar var <+> pretty ":=" <+> pretty tiexpr pretty (TIDeclareSymbol names ty) = let namesDoc = hsep $ punctuate (pretty ",") (map pretty names) in pretty "declare" <+> pretty "symbol" <+> namesDoc <+> pretty ":" <+> prettyTypeDoc ty pretty (TIPatternFunctionDecl name typeScheme params retType body) = let typeStr = prettyTypeScheme typeScheme paramsDoc = hsep (map prettyParam params) retTypeDoc = prettyTypeDoc retType in pretty "def" <+> pretty "pattern" <+> pretty name <+> pretty ":" <+> pretty typeStr <+> paramsDoc <+> pretty ":" <+> retTypeDoc <+> indentBlock (pretty ":=") [pretty body] where prettyParam (pname, pty) = pretty "(" <> pretty pname <+> pretty ":" <+> prettyTypeDoc pty <> pretty ")" -- Helper function to pretty print Var prettyVar :: Var -> Doc ann prettyVar (Var name []) = pretty name prettyVar (Var name indices) = pretty name <> hcat (map prettyVarIndex indices) where prettyVarIndex (Sub Nothing) = pretty "_" prettyVarIndex (Sub (Just v)) = pretty "_" <> prettyVar v prettyVarIndex (Sup Nothing) = pretty "~" prettyVarIndex (Sup (Just v)) = pretty "~" <> prettyVar v prettyVarIndex (SupSub Nothing) = pretty "~_" prettyVarIndex (SupSub (Just v)) = pretty "~_" <> prettyVar v prettyVarIndex (User Nothing) = pretty "|" prettyVarIndex (User (Just v)) = pretty "|" <> prettyVar v prettyVarIndex (MultiSub _ _ _) = pretty "_..." prettyVarIndex (MultiSup _ _ _) = pretty "~..." prettyVarIndex (DF _ _) = emptyDoc -- Helper function to pretty print constraints as Doc prettyConstraintsDoc :: [Types.Constraint] -> Doc ann prettyConstraintsDoc [] = emptyDoc prettyConstraintsDoc [c] = pretty "{" <> prettyConstraintDoc c <> pretty "}" <> space prettyConstraintsDoc cs = pretty "{" <> hsep (punctuate comma (map prettyConstraintDoc cs)) <> pretty "}" <> space -- Helper function to pretty print a single constraint as Doc prettyConstraintDoc :: Types.Constraint -> Doc ann prettyConstraintDoc (Types.Constraint className tyArg) = pretty className <+> prettyTypeDoc tyArg -- Helper function to pretty print Type as Doc prettyTypeDoc :: Types.Type -> Doc ann prettyTypeDoc Types.TInt = pretty "Integer" prettyTypeDoc Types.TFloat = pretty "Float" prettyTypeDoc Types.TBool = pretty "Bool" prettyTypeDoc Types.TChar = pretty "Char" prettyTypeDoc Types.TString = pretty "String" prettyTypeDoc (Types.TTuple []) = pretty "()" prettyTypeDoc (Types.TVar (Types.TyVar v)) = pretty v prettyTypeDoc (Types.TFun t1 t2) = prettyTypeArg t1 <+> pretty "->" <+> prettyTypeDoc t2 where prettyTypeArg t@(Types.TFun _ _) = parens (prettyTypeDoc t) prettyTypeArg t = prettyTypeDoc t prettyTypeDoc (Types.TTuple ts) = tupled (map prettyTypeDoc ts) prettyTypeDoc (Types.TCollection t) = brackets (prettyTypeDoc t) prettyTypeDoc (Types.THash k v) = pretty "Hash" <+> prettyTypeDoc k <+> prettyHashValueTypeDoc v where -- Hash value types need parentheses if they are function types prettyHashValueTypeDoc t@(Types.TFun _ _) = parens (prettyTypeDoc t) prettyHashValueTypeDoc t = prettyTypeDoc t prettyTypeDoc (Types.TMatcher t) = pretty "Matcher" <+> prettyTypeDoc t prettyTypeDoc (Types.TIO t) = pretty "IO" <+> prettyTypeDoc t prettyTypeDoc (Types.TIORef t) = pretty "IORef" <+> prettyTypeDoc t prettyTypeDoc (Types.TTensor t) = pretty "Tensor" <+> prettyTypeDoc t prettyTypeDoc (Types.TInductive name []) = pretty name prettyTypeDoc (Types.TInductive name ts) = hsep (pretty name : map prettyTypeDoc ts) prettyTypeDoc Types.TAny = pretty "_" prettyTypeDoc Types.TPort = pretty "Port" prettyTypeDoc Types.TMathExpr = pretty "MathExpr" prettyTypeDoc Types.TPolyExpr = pretty "PolyExpr" prettyTypeDoc Types.TTermExpr = pretty "TermExpr" prettyTypeDoc Types.TSymbolExpr = pretty "SymbolExpr" prettyTypeDoc Types.TIndexExpr = pretty "IndexExpr" class Complex a where isAtom :: a -> Bool isAtomOrApp :: a -> Bool isInfix :: a -> Bool instance Complex Expr where isAtom (ConstantExpr (IntegerExpr i)) | i < 0 = False isAtom PrefixExpr{} = False isAtom InfixExpr{} = False isAtom (ApplyExpr _ []) = True isAtom ApplyExpr{} = False isAtom LambdaExpr{} = False isAtom MemoizedLambdaExpr{} = False isAtom TypedMemoizedLambdaExpr{} = False isAtom CambdaExpr{} = False isAtom PatternFunctionExpr{} = False isAtom IfExpr{} = False isAtom LetRecExpr{} = False isAtom SubrefsExpr{} = False isAtom SuprefsExpr{} = False isAtom UserrefsExpr{} = False isAtom WithSymbolsExpr{} = False isAtom MatchExpr{} = False isAtom MatchAllExpr{} = False isAtom MatchLambdaExpr{} = False isAtom MatchAllLambdaExpr{} = False isAtom MatcherExpr{} = False isAtom AlgebraicDataMatcherExpr{} = False isAtom GenerateTensorExpr{} = False isAtom TensorExpr{} = False isAtom FunctionExpr{} = False isAtom TensorContractExpr{} = False isAtom TensorMapExpr{} = False isAtom TensorMap2Expr{} = False isAtom TransposeExpr{} = False isAtom _ = True isAtomOrApp ApplyExpr{} = True isAtomOrApp e = isAtom e isInfix InfixExpr{} = True isInfix _ = False instance Complex a => Complex (Arg a) where isAtom (Arg x) = isAtom x isAtom _ = True isAtomOrApp = isAtom isInfix _ = False instance Complex ArgPattern where isAtom (APInductivePat _ []) = True isAtom APInductivePat{} = False isAtom APConsPat{} = False isAtom APSnocPat{} = False isAtom _ = True isAtomOrApp = isAtom isInfix _ = False instance Complex Pattern where isAtom LetPat{} = False isAtom (InductivePat _ []) = True isAtom (InductivePat _ _) = False isAtom InfixPat{} = False isAtom LoopPat{} = False isAtom (PApplyPat _ []) = True isAtom (PApplyPat _ _) = False isAtom _ = True isAtomOrApp PApplyPat{} = True isAtomOrApp InductivePat{} = True isAtomOrApp e = isAtom e isInfix InfixPat{} = True isInfix _ = False instance Complex PrimitiveDataPattern where isAtom (PDInductivePat _ []) = True isAtom (PDInductivePat _ _) = False isAtom PDConsPat{} = False isAtom PDSnocPat{} = False isAtom _ = True isAtomOrApp PDInductivePat{} = True isAtomOrApp PDSnocPat{} = True isAtomOrApp e = isAtom e isInfix PDConsPat{} = True isInfix _ = False pretty' :: (Pretty a, Complex a) => a -> Doc ann pretty' x | isAtom x = pretty x | otherwise = parens $ pretty x pretty'' :: (Pretty a, Complex a) => a -> Doc ann pretty'' x | isAtomOrApp x || isInfix x = pretty x | otherwise = parens $ pretty x -- Display "hoge" instead of "() := hoge" prettyDoBinds :: BindingExpr -> Doc ann prettyDoBinds (Bind (PDTuplePat []) expr) = pretty expr prettyDoBinds bind = pretty "let" <+> pretty bind prettyMatch :: Expr -> [MatchClause] -> Doc ann prettyMatch matcher clauses = pretty "as" <> group (flatAlt (hardline <> pretty matcher) (space <> pretty matcher) <+> pretty "with") <> hardline <> align (vsep (map pretty clauses)) listoid :: String -> String -> [Doc ann] -> Doc ann listoid lp rp elems = encloseSep (pretty lp) (pretty rp) (comma <> space) elems -- Just like |fillSep|, but does not break the atomicity of grouped Docs fillSepAtom :: [Doc ann] -> Doc ann fillSepAtom [] = emptyDoc fillSepAtom [x] = x fillSepAtom (x:xs) = x <> fillSepAtom' xs where fillSepAtom' [] = emptyDoc fillSepAtom' (x:xs) = group (flatAlt (hardline <> x) (space <> x)) <> fillSepAtom' xs indentBlock :: Doc ann -> [Doc ann] -> Doc ann indentBlock header bodies = group (nest 2 (header <> flatAlt (hardline <> hsepHard bodies) (space <> hsep bodies))) hsepHard :: [Doc ann] -> Doc ann hsepHard = concatWith (\x y -> x <> hardline <> y) lambdaLike :: Doc ann -> [Doc ann] -> Doc ann -> Doc ann -> Doc ann lambdaLike start [] arrow body = indentBlock (start <> pretty "()" <+> arrow) [body] lambdaLike start args arrow body = indentBlock (start <> hsep args <+> arrow) [body] applyLike :: [Doc ann] -> Doc ann applyLike = hang 2 . sep . map group -- Tests if the argument can be printed in a single line, and if not, -- inserts a line break before printing it. -- This is useful for nicely printing infix expressions. infixRight :: Doc ann -> Doc ann infixRight p = group (flatAlt (hardline <> p) (space <> p)) showTSV :: EgisonValue -> String showTSV (Tuple (val:vals)) = foldl (\r x -> r ++ "\t" ++ x) (show val) (map show vals) showTSV (Collection vals) = intercalate "\t" (map show (toList vals)) showTSV val = show val -- -- Pretty printer for error messages -- prettyStr :: Pretty a => a -> String prettyStr = renderString . layoutPretty (LayoutOptions Unbounded) . pretty