module Language.Fortran.Pretty where
import Language.Fortran
import Debug.Trace
import Data.List
pprint :: PrettyPrintable t => t -> String
pprint = let ?variant = DefaultPP in printMaster
data DefaultPP = DefaultPP
class PPVersion a
instance PPVersion DefaultPP
type PrettyPrintable t = PrintMaster t DefaultPP
class PrintMaster t v where
printMaster :: (?variant :: v) => t -> String
class PrintSlave t v where
printSlave :: (?variant :: v) => t -> String
class PrintIndSlave t v where
printIndSlave :: (?variant :: v) => Int -> t -> String
class PrintIndMaster t v where
printIndMaster :: (?variant :: v) => Int -> t -> String
instance (PrintMaster t DefaultPP) => PrintSlave t DefaultPP where
printSlave = printMaster
instance (PrintIndMaster t DefaultPP) => PrintIndSlave t DefaultPP where
printIndSlave = printIndMaster
instance PPVersion v => PrintSlave String v where
printSlave = id
instance PPVersion v => PrintMaster String v where
printMaster = id
instance (PPVersion v, PrintSlave (ProgUnit p) v) => PrintMaster [ProgUnit p] v where
printMaster xs = concat $ intersperse "\n" (map printSlave xs)
instance (PrintSlave (Arg p) v,
PrintSlave (BaseType p) v,
PrintSlave (Block p) v,
PrintSlave (Decl p) v,
PrintSlave (Fortran p) v,
PrintSlave (Implicit p) v,
PrintSlave (SubName p) v,
PrintSlave (VarName p) v,
PrintSlave (ProgUnit p) v,
PPVersion v) => PrintMaster (ProgUnit p) v where
printMaster (Sub _ _ (Just p) n a b) = printSlave p ++ " subroutine "++(printSlave n)++printSlave a++"\n"++
printSlave b++
"\nend subroutine "++(printSlave n)++"\n"
printMaster (Sub _ _ Nothing n a b) = "subroutine "++(printSlave n)++printSlave a++"\n"++
printSlave b++
"\nend subroutine "++(printSlave n)++"\n"
printMaster (Function _ _ (Just p) n a (Just r) b) = printSlave p ++ " function "++(printSlave n)++printSlave a++" result("++printSlave r++")\n"++
printSlave b++
"\nend function "++(printSlave n)++"\n"
printMaster (Function _ _ (Just p) n a Nothing b) = printSlave p ++ " function "++(printSlave n)++printSlave a++"\n"++
printSlave b++
"\nend function "++(printSlave n)++"\n"
printMaster (Function _ _ Nothing n a (Just r) b) = "function "++(printSlave n)++printSlave a++" result("++printSlave r++")\n"++
printSlave b++
"\nend function "++(printSlave n)++"\n"
printMaster (Function _ _ Nothing n a Nothing b) = "function "++(printSlave n)++printSlave a++"\n"++
printSlave b++
"\nend function "++(printSlave n)++"\n"
printMaster (Main _ _ n a b []) = "program "++(printSlave n) ++
(if not (isEmptyArg a) then (printSlave a) else ""++"\n") ++
printSlave b ++
"\nend program "++ (printSlave n) ++"\n"
printMaster (Main _ _ n a b ps) = "program "++(printSlave n) ++
(if not (isEmptyArg a) then (printSlave a) else ""++"\n") ++
printSlave b ++
"\ncontains\n" ++
(concatMap printSlave ps) ++
"\nend program "++(printSlave n)++"\n"
printMaster (Module _ _ n us i ds []) = "module "++(printSlave n)++"\n" ++
showUse us ++
printSlave i ++
printSlave ds ++
"end module " ++ (printSlave n)++"\n"
printMaster (Module _ _ n us i ds ps) = "module "++(printSlave n)++"\n" ++
showUse us ++
printSlave i ++
printSlave ds ++
"\ncontains\n" ++
concatMap printSlave ps ++
"end module " ++ (printSlave n)++"\n"
printMaster (BlockData _ _ n us i ds) = "block data " ++ (printSlave n) ++ "\n" ++
showUse us ++
printSlave i ++
printSlave ds ++
"end block data " ++ (printSlave n)++"\n"
printMaster (Prog _ _ p) = printSlave p
printMaster (NullProg _ _) = ""
printMaster (IncludeProg _ _ ds Nothing) = printSlave ds
printMaster (IncludeProg _ _ ds (Just f)) = printSlave ds ++ "\n" ++ printSlave f
instance (PrintSlave (Fortran p) v, PrintSlave (Decl p) v, PrintSlave (Implicit p) v, PPVersion v) =>
PrintMaster (Block p) v where
printMaster (Block _ (UseBlock us _) i sp ds f) = showUse us++printSlave i++(printSlave ds)++printSlave f
instance (PrintSlave (Expr p) v) => PrintMaster (DataForm p) v where
printMaster (Data _ ds) = "data "++(concat (intersperse "\n" (map show_data ds)))
instance (Indentor (Decl p),
PrintSlave (Arg p) v,
PrintSlave (ArgList p) v,
PrintSlave (Attr p) v,
PrintSlave (BinOp p) v,
PrintSlave (Decl p) v,
PrintSlave (DataForm p) v,
PrintSlave (Expr p) v,
PrintSlave (GSpec p) v,
PrintSlave (Implicit p) v,
PrintSlave (InterfaceSpec p) v,
PrintSlave (MeasureUnitSpec p) v,
PrintSlave (SubName p) v,
PrintSlave (UnaryOp p) v,
PrintSlave (VarName p) v,
PrintSlave (Type p) v,
PPVersion v) => PrintMaster (Decl p) v where
printMaster x@(Decl _ _ vs t) = (indR x 1)++printSlave t++" :: "++asSeq id (map showDV vs)++"\n"
printMaster (Namelist _ ns) = ind 1++"namelist "++show_namelist ns++"\n"
printMaster (DataDecl _ ds) = ind 1++ (printSlave ds) ++"\n"
printMaster t@(Equivalence _ _ vs) = (indR t 1)++"equivlance ("++(concat (intersperse "," (map printMaster vs))) ++ ")\n"
printMaster (AttrStmt _ p gs) = ind 1++printSlave p ++ " (" ++asSeq id (map showDV gs) ++ ") \n"
printMaster (AccessStmt _ p []) = ind 1++printSlave p ++ "\n"
printMaster (AccessStmt _ p gs) = ind 1++printSlave p ++ " :: " ++ (concat . intersperse ", " . map printSlave) gs++"\n"
printMaster (ExternalStmt _ xs) = ind 1++"external :: " ++ (concat (intersperse "," xs)) ++ "\n"
printMaster (Interface _ (Just g) is) = ind 1 ++ "interface " ++ printSlave g ++ printMasterInterfaceSpecs is ++ ind 1 ++ "end interface" ++ printSlave g ++ "\n"
printMaster (Common _ _ name exps) = ind 1++"common " ++ (case name of
Just n -> "/" ++ n ++ "/ "
Nothing -> "") ++ (concat (intersperse "," (map printMaster exps))) ++ "\n"
printMaster (Interface _ Nothing is) = ind 1 ++ "interface " ++ printMasterInterfaceSpecs is ++ ind 1 ++ "end interface\n"
printMaster (DerivedTypeDef _ _ n as ps ds) = ind 1 ++ "type " ++ printMasterList as ++ " :: " ++ printSlave n ++ "\n" ++ (concat (intersperse "\n" (map (printSlave) ps))) ++ (if (length ps > 0) then "\n" else "") ++ (concatMap (((ind 2) ++) . printSlave) ds) ++ ind 1 ++ "end type " ++ printSlave n ++ "\n\n"
printMaster (MeasureUnitDef _ _ ds) = ind 1 ++ "unit :: " ++ (concat . intersperse ", " . map showDU) ds ++ "\n"
printMaster (Include _ i) = "include "++printSlave i
printMaster (DSeq _ d d') = printSlave d++printSlave d'
printMaster (NullDecl _ _) = ""
printMasterInterfaceSpecs xs = concat $ intersperse "\n" (map printMaster xs)
show_namelist ((x,xs):[]) = "/" ++ printSlave x ++ "/" ++ (concat (intersperse ", " (map printSlave xs)))
show_namelist ((x,xs):ys) = "/" ++ printSlave x ++ "/" ++ (concat (intersperse ", " (map printSlave xs))) ++ "," ++ show_namelist ys
show_data ((xs,ys)) = "/" ++ printSlave xs ++ "/" ++ printSlave ys
showDV (v, NullExpr _ _, Just n) = (printMaster v) ++ "*" ++ show n
showDV (v, NullExpr _ _, Nothing) = printMaster v
showDV (v,e,Nothing) = printMaster v++" = "++printMaster e
showDV (v,e,Just n) = (printMaster v) ++ "*" ++ show n ++ " = "++(printMaster e)
showDU (name,spec) = printMaster name++" = "++printMaster spec
instance (PrintSlave (ArgList p) v,
PrintSlave (BinOp p) v,
PrintSlave (UnaryOp p) v,
PrintSlave (BaseType p) v,
PrintSlave (Expr p) v,
PrintSlave (MeasureUnitSpec p) v,
PrintSlave (VarName p) v,
PPVersion v) => PrintMaster (Type p) v where
printMaster (BaseType _ bt as (NullExpr _ _) (NullExpr _ _)) = printSlave bt++printMasterList as
printMaster (BaseType _ bt as (NullExpr _ _) e') = printSlave bt++" (len="++printSlave e'++")"++printMasterList as
printMaster (BaseType _ bt as e (NullExpr _ _)) = printSlave bt++" (kind="++printSlave e++")"++printMasterList as
printMaster (BaseType _ bt as e e') = printSlave bt++" (len="++printSlave e'++"kind="++printSlave e++")"++printMasterList as
printMaster (ArrayT _ [] bt as (NullExpr _ _) (NullExpr _ _)) = printSlave bt++printMasterList as
printMaster (ArrayT _ [] bt as (NullExpr _ _) e') = printSlave bt++" (len="++printSlave e'++")"++printMasterList as
printMaster (ArrayT _ [] bt as e (NullExpr _ _)) = printSlave bt++" (kind="++printSlave e++")"++printMasterList as
printMaster (ArrayT _ [] bt as e e') = printSlave bt++" (len="++printSlave e'++"kind="++printSlave e++")"++printMasterList as
printMaster (ArrayT _ rs bt as (NullExpr _ _) (NullExpr _ _)) = printSlave bt++" , dimension ("++showRanges rs++")"++printMasterList as
printMaster (ArrayT _ rs bt as (NullExpr _ _) e') = printSlave bt++" (len="++printSlave e'++")"++" , dimension ("++showRanges rs++")"++printMasterList as
printMaster (ArrayT _ rs bt as e (NullExpr _ _)) = printSlave bt++" (kind="++printSlave e++")"++" , dimension ("++showRanges rs++")"++printMasterList as
printMaster (ArrayT _ rs bt as e e') = printSlave bt++" (len="++printSlave e'++"kind="++printSlave e++")"++" , dimension ("++showRanges rs++")"++printMasterList as
instance (PrintSlave (ArgList p) v, PrintSlave (BinOp p) v, PrintSlave (Expr p) v, PrintSlave (UnaryOp p) v,
PrintSlave (VarName p) v,
PrintSlave (MeasureUnitSpec p) v, PPVersion v) => PrintMaster (Attr p) v where --new
printMaster (Allocatable _) = "allocatable "
printMaster (Parameter _) = "parameter "
printMaster (External _) = "external "
printMaster (Intent _ (In _)) = "intent(in) "
printMaster (Intent _ (Out _)) = "intent(out) "
printMaster (Intent _ (InOut _)) = "intent(inout) "
printMaster (Intrinsic _) = "intrinsic "
printMaster (Optional _) = "optional "
printMaster (Pointer _) = "pointer "
printMaster (Save _) = "save "
printMaster (Target _) = "target "
printMaster (Volatile _) = "volatile "
printMaster (Public _) = "public "
printMaster (Private _) = "private "
printMaster (Sequence _) = "sequence "
printMaster (Dimension _ r) = "dimension (" ++ (showRanges r) ++ ")"
printMaster (MeasureUnit _ u) = "unit("++printSlave u++")"
instance (PPVersion v) => PrintMaster (MeasureUnitSpec p) v where
printMaster (UnitProduct _ units) = showUnits units
printMaster (UnitQuotient _ units1 units2) = showUnits units1++" / "++showUnits units2
printMaster (UnitNone _) = ""
instance (PPVersion v) => PrintMaster (Fraction p) v where
printMaster (IntegerConst _ s) = "**"++printSlave s
printMaster (FractionConst _ p q) = "**("++printSlave p++"/"++printSlave q++")"
printMaster (NullFraction _) = ""
instance (PrintSlave (Arg p) v, PrintSlave (BinOp p) v, PrintSlave (Expr p) v, PPVersion v) => PrintMaster (GSpec p) v where
printMaster (GName _ s) = printSlave s
printMaster (GOper _ op) = "operator("++printSlave op++")"
printMaster (GAssg _) = "assignment(=)"
instance (PrintSlave (Arg p) v, PrintSlave (Decl p) v, PrintSlave (Implicit p) v,
PrintSlave (SubName p) v, PPVersion v) => PrintMaster (InterfaceSpec p) v where
printMaster (FunctionInterface _ s as us i ds) = (ind 1)++ "function " ++ printSlave s ++ printSlave as ++ showUse us ++ printSlave i ++ printSlave ds ++ "\nend function " ++ printSlave s
printMaster (SubroutineInterface _ s as us i ds) = (ind 1)++ "subroutine " ++ printSlave s ++ printSlave as ++ showUse us ++ printSlave i ++ printSlave ds ++ "\nend subroutine " ++ printSlave s
printMaster (ModuleProcedure _ ss) = (ind 2) ++ "module procedure " ++ concat (intersperse ", " (map (printSlave) ss))
instance (PPVersion v, PrintMaster (Uses p) v) => PrintMaster (UseBlock p) v where
printMaster (UseBlock uses _) = printMaster uses
instance (PPVersion v) => PrintMaster (Uses p) v where
printMaster u = showUse u
instance (PrintSlave (SubName p) v, PPVersion v) => PrintMaster (BaseType p) v where
printMaster (Integer _) = "integer"
printMaster (Real _) = "real"
printMaster (DoublePrecision _) = "double precision"
printMaster (Character _) = "character"
printMaster (Logical _) = "logical"
printMaster (DerivedType _ s) = "type ("++printSlave s++")"
printMaster (SomeType _) = error "sometype not valid in output source file"
instance (PrintSlave (ArgList p) v,
PrintSlave (BinOp p) v,
PrintSlave (Expr p) v,
PrintSlave (UnaryOp p) v,
PrintSlave (VarName p) v,
PPVersion v) => PrintMaster (Expr p) v where
printMaster (Con _ _ i) = i
printMaster (ConL _ _ m s) = m:("\'" ++ s ++ "\'")
printMaster (ConS _ _ s) = s
printMaster (Var _ _ vs) = showPartRefList vs
printMaster (Bin _ _ bop e@(Bin _ _ op _ _ ) e'@(Bin _ _ op' _ _)) = checkPrec bop op (paren) (printSlave e)++printSlave bop++ checkPrec bop op' (paren) (printSlave e')
printMaster (Bin _ _ bop e@(Bin _ _ op _ _) e') = checkPrec bop op (paren) (printSlave e)++printSlave bop++printSlave e'
printMaster (Bin _ _ bop e e'@(Bin _ _ op' _ _)) = printSlave e++printSlave bop++checkPrec bop op' (paren) (printSlave e')
printMaster (Bin _ _ bop e e') = printSlave e++printSlave bop++printSlave e'
printMaster (Unary _ _ uop e) = "("++printSlave uop++printSlave e++")"
printMaster (CallExpr _ _ s as) = printSlave s ++ printSlave as
printMaster (Null _ _) = "NULL()"
printMaster (NullExpr _ _) = ""
printMaster (ESeq _ _ (NullExpr _ _) e) = printSlave e
printMaster (ESeq _ _ e (NullExpr _ _)) = printSlave e
printMaster (ESeq _ _ e e') = printSlave e++","++printSlave e'
printMaster (Bound _ _ e e') = printSlave e++":"++printSlave e'
printMaster (Sqrt _ _ e) = "sqrt("++printSlave e++")"
printMaster (ArrayCon _ _ es) = "(\\" ++ concat (intersperse ", " (map (printSlave) es)) ++ "\\)"
printMaster (AssgExpr _ _ v e) = v ++ "=" ++ printSlave e
instance (PrintIndMaster (Fortran p) v, PPVersion v) => PrintMaster (Fortran p) v where
printMaster = printIndMaster 1
instance (PrintSlave (ArgName p) v, PPVersion v) => PrintMaster (Arg p) v where
printMaster (Arg _ vs _) = "("++ printSlave vs ++")"
instance (PrintSlave (Expr p) v, PPVersion v) => PrintMaster (ArgList p) v where
printMaster (ArgList _ es) = "("++printSlave es++")"
instance PPVersion v => PrintMaster (BinOp p) v where
printMaster (Plus _) ="+"
printMaster (Minus _) ="-"
printMaster (Mul _) ="*"
printMaster (Div _) ="/"
printMaster (Or _) =".or."
printMaster (And _) =".and."
printMaster (Concat _) ="//"
printMaster (Power _) ="**"
printMaster (RelEQ _) ="=="
printMaster (RelNE _) ="/="
printMaster (RelLT _) ="<"
printMaster (RelLE _) ="<="
printMaster (RelGT _) =">"
printMaster (RelGE _) =">="
instance PPVersion v => PrintMaster (UnaryOp p) v where
printMaster (UMinus _) = "-"
printMaster (Not _) = ".not."
instance PPVersion v => PrintMaster (VarName p) v where
printMaster (VarName _ v) = v
instance (PrintSlave (VarName p) v, PrintSlave (ArgName p) v, PPVersion v) => PrintMaster (ArgName p) v where
printMaster (ArgName _ a) = a
printMaster (ASeq _ (NullArg _) (NullArg _)) = ""
printMaster (ASeq _ (NullArg _) a') = printSlave a'
printMaster (ASeq _ a (NullArg _)) = printSlave a
printMaster (ASeq _ a a') = printSlave a++","++printSlave a'
printMaster (NullArg _) = ""
instance PPVersion v => PrintMaster (SubName p) v where
printMaster (SubName _ n) = n
printMaster (NullSubName _) = error "subroutine needs a name"
instance PPVersion v => PrintMaster ( Implicit p) v where
printMaster (ImplicitNone _) = " implicit none\n"
printMaster (ImplicitNull _) = ""
instance (PrintSlave (Expr p) v, PPVersion v) => PrintMaster (Spec p) v where
printMaster (Access _ s) = "access = " ++ printSlave s
printMaster (Action _ s) = "action = "++printSlave s
printMaster (Advance _ s) = "advance = "++printSlave s
printMaster (Blank _ s) = "blank = "++printSlave s
printMaster (Delim _ s) = "delim = "++printSlave s
printMaster (Direct _ s) = "direct = "++printSlave s
printMaster (End _ s) = "end = "++printSlave s
printMaster (Eor _ s) = "eor = "++printSlave s
printMaster (Err _ s) = "err = "++printSlave s
printMaster (Exist _ s) = "exist = "++printSlave s
printMaster (File _ s) = "file = "++printSlave s
printMaster (FMT _ s) = "fmt = "++printSlave s
printMaster (Form _ s) = "form = "++printSlave s
printMaster (Formatted _ s) = "formatted = "++printSlave s
printMaster (Unformatted _ s) = "unformatted = "++printSlave s
printMaster (IOLength _ s) = "iolength = "++printSlave s
printMaster (IOStat _ s) = "iostat = "++printSlave s
printMaster (Opened _ s) = "opened = "++printSlave s
printMaster (Name _ s) = "name = "++printSlave s
printMaster (Named _ s) = "named = "++printSlave s
printMaster (NextRec _ s) = "nextrec = "++printSlave s
printMaster (NML _ s) = "nml = "++printSlave s
printMaster (NoSpec _ s) = printSlave s
printMaster (Floating _ s1 s2) = printSlave s1 ++ "F" ++ printSlave s2
printMaster (Number _ s) = "number = "++printSlave s
printMaster (Pad _ s) = "pad = "++printSlave s
printMaster (Position _ s) = "position = "++printSlave s
printMaster (Read _ s) = "read = "++printSlave s
printMaster (ReadWrite _ s) = "readwrite = "++printSlave s
printMaster (WriteSp _ s) = "write = "++printSlave s
printMaster (Rec _ s) = "rec = "++printSlave s
printMaster (Recl _ s) = "recl = "++printSlave s
printMaster (Sequential _ s) = "sequential = "++printSlave s
printMaster (Size _ s) = "size = "++printSlave s
printMaster (Status _ s) = "status = "++printSlave s
printMaster (StringLit _ s) = "'" ++ s ++ "'"
printMaster (Unit _ s) = "unit = "++printSlave s
printMaster (Delimiter _) = "/"
showElseIf i (e,f) = (ind i)++"else if ("++printSlave e++") then\n"++(ind (i+1))++printSlave f++"\n"
showForall [] = "error"
showForall ((s,e,e',NullExpr _ _):[]) = s++"="++printSlave e++":"++printSlave e'
showForall ((s,e,e',e''):[]) = s++"="++printSlave e++":"++printSlave e'++"; "++printSlave e''
showForall ((s,e,e',NullExpr _ _):is) = s++"="++printSlave e++":"++printSlave e'++", "++showForall is
showForall ((s,e,e',e''):is) = s++"="++printSlave e++":"++printSlave e'++"; "++printSlave e''++", "++showForall is
showUse :: Uses p -> String
showUse (UseNil _) = ""
showUse (Uses _ (Use n []) us _) = ((ind 1)++"use "++n++"\n") ++ (showUse us)
showUse (Uses _ (Use n renames) us _) = ((ind 1)++"use "++n++", " ++
(concat $ intersperse ", " (map (\(a, b) -> a ++ " => " ++ b) renames)) ++
"\n") ++ (showUse us)
showUse (Uses _ (UseOnly n renames) us _) = ((ind 1)++"use "++n++", only: " ++
(concat $ intersperse ", " (map showOnly renames)) ++
"\n") ++ (showUse us)
where
showOnly (a, Just b) = a ++ " => " ++ b
showOnly (a, Nothing) = a
isEmptyArg (Arg _ as _) = and (isEmptyArgName as)
isEmptyArgName (ASeq _ a a') = isEmptyArgName a ++ isEmptyArgName a'
isEmptyArgName (ArgName _ a) = [False]
isEmptyArgName (NullArg _) = [True]
paren :: String -> String
paren s = "(" ++ s ++ ")"
checkPrec :: BinOp p -> BinOp p -> (a -> a) -> a -> a
checkPrec pop cop f s = if opPrec pop >= opPrec cop then f s else s
opPrec :: BinOp p -> Int
opPrec (Or _) = 0
opPrec (And _) = 1
opPrec (RelEQ _) = 2
opPrec (RelNE _) = 2
opPrec (RelLT _) = 2
opPrec (RelLE _) = 2
opPrec (RelGT _) = 2
opPrec (RelGE _) = 2
opPrec (Concat _) = 3
opPrec (Plus _) = 4
opPrec (Minus _) = 4
opPrec (Mul _) = 5
opPrec (Div _) = 5
opPrec (Power _) = 6
class Indentor t where
indR :: t -> Int -> String
instance Indentor (p ()) where
indR t i = ind i
instance (Indentor (Fortran p),
PrintSlave (VarName p) v,
PrintSlave (Expr p) v,
PrintSlave (UnaryOp p) v,
PrintSlave (BinOp p) v,
PrintSlave (ArgList p) v,
PrintIndSlave (Fortran p) v,
PrintSlave (DataForm p) v,
PrintSlave (Fortran p) v, PrintSlave (Spec p) v, PPVersion v) => PrintIndMaster (Fortran p) v where
printIndMaster i t@(Assg _ _ v e) = (indR t i)++printSlave v++" = "++printSlave e
printIndMaster i t@(DoWhile _ _ e f) = (indR t i)++"do while (" ++ printSlave e ++ ")\n" ++
printIndSlave (i+1) f ++ "\n" ++ (indR t i) ++ "end do"
printIndMaster i t@(For _ _ (VarName _ "") e e' e'' f) = (indR t i)++"do \n"++
(printIndSlave (i+1) f)++"\n"++(indR t i)++"end do"
printIndMaster i t@(For _ _ v e e' e'' f) = (indR t i)++"do"++" "++printSlave v++" = "++printSlave e++", "++
printSlave e'++", "++printSlave e''++"\n"++
(printIndSlave (i+1) f)++"\n"++(indR t i)++"end do"
printIndMaster i t@(FSeq _ _ f f') = printIndSlave i f++"\n"++printIndSlave i f'
printIndMaster i t@(If _ _ e f [] Nothing) = (indR t i)++"if ("++printSlave e++") then\n"
++(printIndSlave (i+1) f)++"\n"
++(indR t i)++"end if"
printIndMaster i t@(If _ _ e f [] (Just f')) = (indR t i)++"if ("++printSlave e++") then\n"
++(printIndSlave (i+1) f)++"\n"
++(indR t i)++"else\n"
++(printIndSlave (i+1) f')++"\n"
++(indR t i)++"end if"
printIndMaster i t@(If _ _ e f elsif Nothing) = (indR t i)++"if ("++printSlave e++") then\n"
++(printIndSlave (i+1) f)++"\n"
++concat (map (showElseIf i) elsif)
++(indR t i)++"end if"
printIndMaster i t@(If _ _ e f elsif (Just f')) = (indR t i)++"if ("++printSlave e++") then\n"
++(printIndSlave (i+1) f)++"\n"
++concat (map (showElseIf i) elsif)
++(indR t i)++"else\n"
++(printIndSlave (i+1) f')++"\n"
++(indR t i)++"end if"
printIndMaster i t@(Allocate _ _ a (NullExpr _ _)) = (indR t i)++"allocate (" ++ printSlave a ++ ")"
printIndMaster i t@(Allocate _ _ a s) = (indR t i)++"allocate ("++ printSlave a ++ ", STAT = "++printSlave s++ ")"
printIndMaster i t@(Backspace _ _ ss) = (indR t i)++"backspace "++asTuple printSlave ss++"\n"
printIndMaster i t@(Call _ _ sub al) = indR t i++"call "++printSlave sub++printSlave al
printIndMaster i t@(Open _ _ s) = (indR t i)++"open "++asTuple printSlave s++"\n"
printIndMaster i t@(Close _ _ ss) = (indR t i)++"close "++asTuple printSlave ss++"\n"
printIndMaster i t@(Continue _ _) = (indR t i)++"continue"++"\n"
printIndMaster i t@(Cycle _ _ s) = (indR t i)++"cycle "++printSlave s++"\n"
printIndMaster i t@(DataStmt _ _ d) = (indR t i)++(printSlave d)++"\n"
printIndMaster i t@(Deallocate _ _ es e) = (indR t i)++"deallocate "++asTuple printSlave es++printSlave e++"\n"
printIndMaster i t@(Endfile _ _ ss) = (indR t i)++"endfile "++asTuple printSlave ss++"\n"
printIndMaster i t@(Exit _ _ s) = (indR t i)++"exit "++printSlave s
printIndMaster i t@(Format _ _ es) = (indR t i)++"format " ++ (asTuple printSlave es)
printIndMaster i t@(Forall _ _ (is, (NullExpr _ _)) f) = (indR t i)++"forall ("++showForall is++") "++printSlave f
printIndMaster i t@(Forall _ _ (is,e) f) = (indR t i)++"forall ("++showForall is++","++printSlave e++") "++printSlave f
printIndMaster i t@(Goto _ _ s) = (indR t i)++"goto "++printSlave s
printIndMaster i t@(Nullify _ _ es) = (indR t i)++"nullify "++asTuple printSlave es++"\n"
printIndMaster i t@(Inquire _ _ ss es) = (indR t i)++"inquire "++asTuple printSlave ss++" "++(concat (intersperse "," (map printSlave es)))++"\n"
printIndMaster i t@(Pause _ _ s) = (indR t i)++"pause "++ show s ++ "\n"
printIndMaster i t@(Rewind _ _ ss) = (indR t i)++"rewind "++asTuple printSlave ss++"\n"
printIndMaster i t@(Stop _ _ e) = (indR t i)++"stop "++printSlave e++"\n"
printIndMaster i t@(Where _ _ e f Nothing) = (indR t i)++"where ("++printSlave e++") "++printSlave f
printIndMaster i t@(Where _ _ e f (Just f')) = (indR t i)++"where ("++printSlave e++") "++(printIndSlave (i + 1) f)++"\n"++(indR t i)++"elsewhere\n" ++ (indR t i) ++ (printIndSlave (i + 1) f') ++ "\n" ++ (indR t i) ++ "end where"
printIndMaster i t@(Write _ _ ss es) = (indR t i)++"write "++asTuple printSlave ss++" "++(concat (intersperse "," (map printSlave es)))++"\n"
printIndMaster i t@(PointerAssg _ _ e e') = (indR t i)++printSlave e++" => "++printSlave e'++"\n"
printIndMaster i t@(Return _ _ e) = (indR t i)++"return "++printSlave e++"\n"
printIndMaster i t@(Label _ _ s f) = s++" "++printSlave f
printIndMaster i t@(Print _ _ e []) = (indR t i)++("print ")++printSlave e++("\n")
printIndMaster i t@(Print _ _ e es) = (indR t i)++("print ")++printSlave e++", "++(concat (intersperse "," (map printSlave es)))++("\n")
printIndMaster i t@(ReadS _ _ ss es) = (indR t i)++("read ")++(asTuple printSlave ss)++" "++(concat (intersperse "," (map printSlave es)))++("\n")
printIndMaster i t@(NullStmt _ _) = ""
showNQ :: Show a => a -> String
showNQ = filter ('"'/=) . show
ind = indent 3
indent i l = take (i*l) (repeat ' ')
printList sep f xs = sep!!0++concat (intersperse (sep!!1) (map f xs))++sep!!2
asTuple = printList ["(",",",")"]
asSeq = printList ["",",",""]
asList = printList ["[",",","]"]
asSet = printList ["{",",","}"]
asLisp = printList ["("," ",")"]
asPlain f xs = if null xs then "" else printList [" "," ",""] f xs
asPlain' f xs = if null xs then "" else printList [""," ",""] f xs
asCases l = printList ["\n"++ind++" ","\n"++ind++" | ",""] where ind = indent 4 l
asDefs n = printList ["\n"++n,"\n"++n,"\n"]
asParagraphs = printList ["\n","\n\n","\n"]
optTuple :: (?variant :: v, PPVersion v, PrintSlave (UnaryOp p) v, PrintMaster (Expr p) v) => [Expr p] -> String
optTuple [] = ""
optTuple xs = asTuple printMaster xs
showUnits :: (PPVersion v, ?variant :: v, PrintMaster (Fraction p) v) => [(MeasureUnit, Fraction p)] -> String
showUnits units
| null units = "1"
| otherwise = printList [""," ",""] (\(unit, f) -> unit++printMaster f) units
printMasterList :: (PPVersion v, ?variant :: v, PrintMaster a v) => [a] -> String
printMasterList = concat . map (", "++) . map (printMaster)
showBounds :: (PPVersion v, ?variant :: v, PrintMaster (Expr p) v) => (Expr p,Expr p) -> String
showBounds (NullExpr _ _, NullExpr _ _) = ":"
showBounds (NullExpr _ _, e) = printMaster e
showBounds (e1,e2) = printMaster e1++":"++printMaster e2
showRanges :: (PPVersion v, ?variant :: v, PrintMaster (Expr p) v) => [(Expr p, Expr p)] -> String
showRanges = asSeq showBounds
showPartRefList :: (PPVersion v, ?variant :: v, PrintSlave (VarName p) v,
PrintSlave (UnaryOp p) v, PrintMaster (Expr p) v) => [(VarName p,[Expr p])] -> String
showPartRefList [] = ""
showPartRefList ((v,es):[]) = printSlave v ++ optTuple es
showPartRefList ((v,es):xs) = printSlave v ++ optTuple es ++ "%" ++ showPartRefList xs