From 8cfb989c9cf23f83fa5b9c5aa21c7e113da224eb Mon Sep 17 00:00:00 2001 From: hallgren Date: Tue, 14 Apr 2015 12:44:14 +0000 Subject: Translating linearization functions to Haskell: move Haskell AST and pretty printer to GF.Haskell For further separation of pretty printing concerns from conversion concerns, the Haskell AST and pretty printer has been moved to its own module, GF.Haskell, also allowing it to be reused in other places where Haskell code is generated. --- src/compiler/GF/Haskell.hs | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/compiler/GF/Haskell.hs (limited to 'src/compiler/GF/Haskell.hs') diff --git a/src/compiler/GF/Haskell.hs b/src/compiler/GF/Haskell.hs new file mode 100644 index 000000000..55613c95c --- /dev/null +++ b/src/compiler/GF/Haskell.hs @@ -0,0 +1,146 @@ +-- | Abstract syntax and a pretty printer for a subset of Haskell +{-# LANGUAGE DeriveFunctor #-} +module GF.Haskell where +import GF.Infra.Ident(Ident,identS) +import GF.Text.Pretty + +-- | Top-level declarations +data Dec = Comment String + | Type (ConAp Ident) Ty + | Data (ConAp Ident) [ConAp Ty] Deriving + | Class [ConAp Ident] (ConAp Ident) FunDeps [(Ident,Ty)] + | Instance [Ty] Ty [(Lhs,Exp)] + | TypeSig Ident Ty + | Eqn Lhs Exp + +-- | A type constructor applied to some arguments +data ConAp a = ConAp Ident [a] deriving Functor +conap0 n = ConAp n [] +tsyn0 = Type . conap0 + +type Deriving = [Const] +type FunDeps = [([Ident],[Ident])] +type Lhs = (Ident,[Pat]) +lhs0 s = (identS s,[]) + +-- | Type expressions +data Ty = TId Ident | TAp Ty Ty | Fun Ty Ty | ListT Ty + +-- | Expressions +data Exp = Var Ident | Const Const | Ap Exp Exp | Op Exp Const Exp + | List [Exp] | Pair Exp Exp + | Lets [(Ident,Exp)] Exp | LambdaCase [(Pat,Exp)] +type Const = String + +-- | Patterns +data Pat = WildP | VarP Ident | Lit String | ConP Ident [Pat] | AsP Ident Pat + +tvar = TId +tcon0 = TId +tcon c = foldl TAp (TId c) + +let1 x xe e = Lets [(x,xe)] e +single x = List [x] + +plusplus (List ts1) (List ts2) = List (ts1++ts2) +plusplus (List [t]) t2 = Op t ":" t2 +plusplus t1 t2 = Op t1 "++" t2 + +-- | Pretty print atomically (i.e. wrap it in parentheses if necessary) +class Pretty a => PPA a where ppA :: a -> Doc + +instance PPA Ident where ppA = pp + +instance Pretty Dec where + ppList = vcat + pp d = + case d of + Comment s -> pp s + Type lhs rhs -> hang ("type"<+>lhs<+>"=") 4 rhs + Data lhs cons ds -> + hang ("data"<+>lhs) 4 + (sep (zipWith (<+>) ("=":repeat "|") cons++ + ["deriving"<+>parens (punctuate "," ds)|not (null ds)])) + Class ctx cls fds sigs -> + hang ("class"<+>sep [ppctx ctx,pp cls]<+>ppfds fds <+>"where") 4 + (vcat (map ppSig sigs)) + Instance ctx inst eqns -> + hang ("instance"<+>sep [ppctx ctx,pp inst]<+>"where") 4 + (vcat (map ppEqn eqns)) + TypeSig f ty -> hang (f<+>"::") 4 ty + Eqn lhs rhs -> ppEqn (lhs,rhs) + where + ppctx ctx = case ctx of + [] -> empty + [p] -> p <+> "=>" + ps -> parens (fsep (punctuate "," ps)) <+> "=>" + + ppfds [] = empty + ppfds fds = "|"<+>fsep (punctuate "," [hsep as<+>"->"<+>bs|(as,bs)<-fds]) + + ppEqn ((f,ps),e) = hang (f<+>fsep (map ppA ps)<+>"=") 4 e + + ppSig (f,ty) = f<+>"::"<+>ty + +instance PPA a => Pretty (ConAp a) where + pp (ConAp c as) = c<+>fsep (map ppA as) + +instance Pretty Ty where + pp = ppT + where + ppT t = case flatFun t of t:ts -> sep (ppB t:["->"<+>ppB t|t<-ts]) + ppB t = case flatTAp t of t:ts -> ppA t<+>sep (map ppA ts) + + flatFun (Fun t1 t2) = t1:flatFun t2 -- right associative + flatFun t = [t] + + flatTAp (TAp t1 t2) = flatTAp t1++[t2] -- left associative + flatTAp t = [t] + +instance PPA Ty where + ppA t = + case t of + TId c -> pp c + ListT t -> brackets t + _ -> parens t + +instance Pretty Exp where + pp = ppT + where + ppT e = + case e of + Op e1 op e2 -> hang (ppB e1<+>op) 2 (ppB e2) + Lets bs e -> sep ["let"<+>vcat [hang (x<+>"=") 2 xe|(x,xe)<-bs], + "in" <+>e] + LambdaCase alts -> hang "\\case" 4 (vcat [p<+>"->"<+>e|(p,e)<-alts]) + _ -> ppB e + + ppB e = case flatAp e of f:as -> hang (ppA f) 2 (sep (map ppA as)) + + flatAp (Ap t1 t2) = flatAp t1++[t2] -- left associative + flatAp t = [t] + +instance PPA Exp where + ppA e = + case e of + Var x -> pp x + Const n -> pp n + Pair e1 e2 -> parens (e1<>","<>e2) + List es -> brackets (fsep (punctuate "," es)) + _ -> parens e + +instance Pretty Pat where + pp p = + case p of + ConP c ps -> c<+>fsep (map ppA ps) + _ -> ppA p + +instance PPA Pat where + ppA p = + case p of + WildP -> pp "_" + VarP x -> pp x + Lit s -> pp s + ConP c [] -> pp c + AsP x p -> x<>"@"<>parens p + _ -> parens p -- cgit v1.2.3