Reusable functions for translation from the (non-recursive) base structure to Stratego.
module BaseStruct2Stratego2 where import StrategoAST2 import BaseSyntax -- non-recursive base syntax structure import PrettyPrint(pp) import UniqueNames(orig,Orig(G)) import TypedIds(IdTy(..),idTy) import TiDefinedNames(definedTypeName) import DefinedNames(contextSize) import TiNames(superName) import Parentheses transId x = case orig x of G m n _ -> pp m++"."++pp n _ -> pp x transL lit = case lit of HsInt i -> hInt i HsChar c -> hChar [c] HsString s -> hString s -- desugar into list of characters? HsFrac x -> hFrac x transPId i = case i of HsVar x -> varPat x HsCon c -> ConstrPat (c,[]) transP trId trP p = case mapPI trId trP p of HsPId i -> transPId i HsPLit _ lit -> litPat (transL lit) -- new {- old HsPLit _ (HsInt _ i) -> litPat i HsPLit _ (HsChar c) -> charLitPat c HsPLit _ (HsString s) -> stringLitPat s -- other literals... -} -- HsPSucc _ n l -> ... HsPInfixApp x op y -> ConstrPat (op,[x,y]) HsPApp c ps -> ConstrPat (c,ps) HsPTuple s ps -> tuplePat ps HsPList s ps -> plist ps HsPParen p -> p -- HsPRec HsPAsPat x p -> AsPattern (x,p) HsPWildCard -> WildCard HsPIrrPat p -> twiddlePat p _ -> not_supported "Pattern" p transD trId trE trP trDs trT trC trTp d = case d of HsClassDecl loc c tp fd ds -> defs (transClassDecl tp) HsInstDecl loc (Just n) c t ds -> onedef (transInstDecl n c t ds) _ -> case mapDI trId trE trP trDs trT trC trTp d of HsPatBind loc p rhs ds -> onedef (HDef (p, hlet ds (transRhs rhs))) HsFunBind _ [HsMatch _ f ps rhs ds] -> onedef (HDef (varPat f,habs ps (hlet ds (transRhs rhs)))) HsTypeDecl loc tp t -> onedef (tSyn tp t) HsDataDecl loc c tp cons ds -> onedef (tData tp (map transCon cons)) HsNewTypeDecl loc c tp con ds -> onedef (tNew tp (transCon con)) _ -> [ignored (pp d)] where onedef d = [def d] defs = map def transRhs (HsBody e) = e transRhs (HsGuard triples) = foldr guard nomatch triples where guard (loc,guard,body) therest = HIte(guard,body,therest) transCon con = case con of HsConDecl loc _ _ c args -> dCons c (map transConArg args) HsRecDecl loc _ _ c args -> dCons c [a'|(fs,a)<-args,let a'=transConArg a,f<-fs] transConArg arg = case arg of HsBangedType t -> (Strict,t) HsUnBangedType t -> (Lazy,t)
Classes are translated to tuple types. The methods are translated to tuple field selector functions.
transClassDecl tp =
case idTy cn of
Class cnt ms ->
[selector i (superName cn (i+1)) | i<-[0..cnt-1]] ++
zipWith selector [cnt..] ms
where
arity = cnt+length ms
selector i m = HDef (varPat m',habs1 (tpat i) ze)
where
m' = transId m
tpat i = tuplePat [pick j|j<-[0..arity-1]]
where pick j = if j==i then zp else WildCard
where
cn = definedTypeName tp
Instances are translated into tuple definitons...
transInstDecl n ctx inst ds =
case idTy cn of
Class cnt ms ->
HDef (varPat n',
habs (map varPat dicts) (hTuple (map findDef ms')))
where
ms' = map (transId . superName cn) [1..cnt]++map transId ms
ds' = trDs ds
arity = cnt+length ms
n' = transId n
dicts = ["d"++show i|i<-[1..contextSize ctx]]
findDef m =
case [ e | (HDef (VarPat (P m'),e))<-ds',m'==m] of
[e] -> foldl happ e (map hVar dicts)
where
cn = definedTypeName inst
transEId i =
case i of
HsVar x -> hVar x
HsCon c -> HCon (c,[])
transE trId trE trP trDs trT trC e =
case mapEI trId trE trP trDs trT trC e of
HsId i -> transEId i
HsApp x y -> x `happ` y
HsLit _ lit -> hLit (transL lit) -- new
{- old
HsLit _ (HsInt _ i) -> hLit i
HsLit _ (HsChar c) -> hCharLit c
HsLit _ (HsString s) -> hStringLit s
-}
-- other literals...
HsInfixApp x (HsVar op) z -> hVar op `happ` x `happ` z
HsInfixApp x (HsCon c) z -> HCon (c,[x,z]) -- !! constructor arity?
HsNegApp _ x -> hVar "Prelude.negate" `happ` x
HsLambda ps e -> habs ps e
HsLet ds e -> hlet ds e
HsIf x y z -> HIte (x, y, z)
HsCase e alts -> HCase (e,map transAlt alts)
HsTuple xs -> hTuple xs
HsList xs -> hlist xs
HsParen x -> x
HsLeftSection x (HsVar op) -> hleftsection x op
HsRightSection (HsVar op) y -> hrightsection op y
HsLeftSection x (HsCon c) -> hconleftsection x c
HsRightSection (HsCon c) y -> hconrightsection c y
-- The following removed by the type checker too...
HsEnumFrom e1 -> hVar "Prelude.enumFrom" `happ` e1
HsEnumFromTo e1 e2 -> hVar "Prelude.enumFromTo" `happ` e1 `happ` e2
HsEnumFromThen e1 e2 ->
hVar "Prelude.enumFromThen" `happ` e1 `happ` e2
HsEnumFromThenTo e1 e2 e3 ->
hVar "Prelude.enumFromThenTo" `happ` e1 `happ` e2 `happ` e3
HsExpTypeSig _ e c t -> e -- !!
_ -> hVar (not_supported_msg "Expression" e) -- !!
where
transAlt alt =
case alt of
HsAlt loc pat rhs _ -> HBranch (pat,transRhs rhs) -- !!!
--_ -> not_supported "Case branch" "'where' clauses"
where
transRhs (HsBody e) = [nonGuarded e]
transRhs (HsGuard gdrhss) = [Guarded (g,e)|(_,g,e)<-gdrhss]
transT trId trT t =
case mapTI trId trT t of
HsTyFun t1 t2 -> TArrow (t1,t2)
HsTyApp t1 t2 -> tApp t1 t2
HsTyVar a -> tVar a
HsTyCon c -> tConst c
_ -> not_supported "Type" t
transTp trId trTp trTa t =
case t of
HsTyApp t1 t2 -> (c,vs++[trTa t2])
where (c,vs) = trTp t1
HsTyCon c -> (trId c,[])
_ -> not_supported "LHS in type decl" t
transTa trId t =
case t of
HsTyVar a -> trId a
_ -> not_supported "Type parameter in LHS of type decl" t
not_supported s x = error $ not_supported_msg s x
not_supported_msg s x = s++" not supported (yet): "++pp x