module Curry.FlatCurry.Typed.Goodies
( module Curry.FlatCurry.Typed.Goodies
, module Curry.FlatCurry.Goodies
) where
import Curry.FlatCurry.Goodies ( Update
, trType, typeName, typeVisibility, typeParams
, typeConsDecls, typeSyn, isTypeSyn
, isDataTypeDecl, isExternalType, isPublicType
, updType, updTypeName, updTypeVisibility
, updTypeParams, updTypeConsDecls, updTypeSynonym
, updQNamesInType
, trCons, consName, consArity, consVisibility
, isPublicCons, consArgs, updCons, updConsName
, updConsArity, updConsVisibility, updConsArgs
, updQNamesInConsDecl
, tVarIndex, domain, range, tConsName, tConsArgs
, trTypeExpr, isTVar, isTCons, isFuncType
, updTVars, updTCons, updFuncTypes, argTypes
, typeArity, resultType, allVarsInTypeExpr
, allTypeCons, rnmAllVarsInTypeExpr
, updQNamesInTypeExpr
, trOp, opName, opFixity, opPrecedence, updOp
, updOpName, updOpFixity, updOpPrecedence
, trCombType, isCombTypeFuncCall
, isCombTypeFuncPartCall, isCombTypeConsCall
, isCombTypeConsPartCall
, isPublic
)
import Curry.FlatCurry.Typed.Type
trTProg :: (String -> [String] -> [TypeDecl] -> [TFuncDecl] -> [OpDecl] -> b)
-> TProg -> b
trTProg prog (TProg name imps types funcs ops) = prog name imps types funcs ops
tProgName :: TProg -> String
tProgName = trTProg (\name _ _ _ _ -> name)
tProgImports :: TProg -> [String]
tProgImports = trTProg (\_ imps _ _ _ -> imps)
tProgTypes :: TProg -> [TypeDecl]
tProgTypes = trTProg (\_ _ types _ _ -> types)
tProgTFuncs :: TProg -> [TFuncDecl]
tProgTFuncs = trTProg (\_ _ _ funcs _ -> funcs)
tProgOps :: TProg -> [OpDecl]
tProgOps = trTProg (\_ _ _ _ ops -> ops)
updTProg :: (String -> String) ->
([String] -> [String]) ->
([TypeDecl] -> [TypeDecl]) ->
([TFuncDecl] -> [TFuncDecl]) ->
([OpDecl] -> [OpDecl]) -> TProg -> TProg
updTProg fn fi ft ff fo = trTProg prog
where
prog name imps types funcs ops
= TProg (fn name) (fi imps) (ft types) (ff funcs) (fo ops)
updTProgName :: Update TProg String
updTProgName f = updTProg f id id id id
updTProgImports :: Update TProg [String]
updTProgImports f = updTProg id f id id id
updTProgTypes :: Update TProg [TypeDecl]
updTProgTypes f = updTProg id id f id id
updTProgTFuncs :: Update TProg [TFuncDecl]
updTProgTFuncs f = updTProg id id id f id
updTProgOps :: Update TProg [OpDecl]
updTProgOps = updTProg id id id id
allVarsInTProg :: TProg -> [(VarIndex, TypeExpr)]
allVarsInTProg = concatMap allVarsInTFunc . tProgTFuncs
updTProgTExps :: Update TProg TExpr
updTProgTExps = updTProgTFuncs . map . updTFuncBody
rnmAllVarsInTProg :: Update TProg VarIndex
rnmAllVarsInTProg = updTProgTFuncs . map . rnmAllVarsInTFunc
updQNamesInTProg :: Update TProg QName
updQNamesInTProg f = updTProg id id
(map (updQNamesInType f)) (map (updQNamesInTFunc f)) (map (updOpName f))
rnmTProg :: String -> TProg -> TProg
rnmTProg name p = updTProgName (const name) (updQNamesInTProg rnm p)
where
rnm (m, n) | m == tProgName p = (name, n)
| otherwise = (m, n)
trTFunc :: (QName -> Int -> Visibility -> TypeExpr -> TRule -> b) -> TFuncDecl -> b
trTFunc func (TFunc name arity vis t rule) = func name arity vis t rule
tFuncName :: TFuncDecl -> QName
tFuncName = trTFunc (\name _ _ _ _ -> name)
tFuncArity :: TFuncDecl -> Int
tFuncArity = trTFunc (\_ arity _ _ _ -> arity)
tFuncVisibility :: TFuncDecl -> Visibility
tFuncVisibility = trTFunc (\_ _ vis _ _ -> vis)
tFuncType :: TFuncDecl -> TypeExpr
tFuncType = trTFunc (\_ _ _ t _ -> t)
tFuncTRule :: TFuncDecl -> TRule
tFuncTRule = trTFunc (\_ _ _ _ rule -> rule)
updTFunc :: (QName -> QName) ->
(Int -> Int) ->
(Visibility -> Visibility) ->
(TypeExpr -> TypeExpr) ->
(TRule -> TRule) -> TFuncDecl -> TFuncDecl
updTFunc fn fa fv ft fr = trTFunc func
where
func name arity vis t rule
= TFunc (fn name) (fa arity) (fv vis) (ft t) (fr rule)
updTFuncName :: Update TFuncDecl QName
updTFuncName f = updTFunc f id id id id
updTFuncArity :: Update TFuncDecl Int
updTFuncArity f = updTFunc id f id id id
updTFuncVisibility :: Update TFuncDecl Visibility
updTFuncVisibility f = updTFunc id id f id id
updFuncType :: Update TFuncDecl TypeExpr
updFuncType f = updTFunc id id id f id
updTFuncTRule :: Update TFuncDecl TRule
updTFuncTRule = updTFunc id id id id
isPublicTFunc :: TFuncDecl -> Bool
isPublicTFunc = isPublic . tFuncVisibility
isExternal :: TFuncDecl -> Bool
isExternal = isTRuleExternal . tFuncTRule
allVarsInTFunc :: TFuncDecl -> [(VarIndex, TypeExpr)]
allVarsInTFunc = allVarsInTRule . tFuncTRule
tFuncArgs :: TFuncDecl -> [(VarIndex, TypeExpr)]
tFuncArgs = tRuleArgs . tFuncTRule
tFuncBody :: TFuncDecl -> TExpr
tFuncBody = tRuleBody . tFuncTRule
tFuncRHS :: TFuncDecl -> [TExpr]
tFuncRHS f | not (isExternal f) = orCase (tFuncBody f)
| otherwise = []
where
orCase e
| isTOr e = concatMap orCase (orExps e)
| isTCase e = concatMap (orCase . tBranchTExpr) (caseBranches e)
| otherwise = [e]
rnmAllVarsInTFunc :: Update TFuncDecl VarIndex
rnmAllVarsInTFunc = updTFunc id id id id . rnmAllVarsInTRule
updQNamesInTFunc :: Update TFuncDecl QName
updQNamesInTFunc f = updTFunc f id id (updQNamesInTypeExpr f) (updQNamesInTRule f)
updTFuncArgs :: Update TFuncDecl [(VarIndex, TypeExpr)]
updTFuncArgs = updTFuncTRule . updTRuleArgs
updTFuncBody :: Update TFuncDecl TExpr
updTFuncBody = updTFuncTRule . updTRuleBody
trTRule :: ([(VarIndex, TypeExpr)] -> TExpr -> b) -> (TypeExpr -> String -> b) -> TRule -> b
trTRule rule _ (TRule args e) = rule args e
trTRule _ ext (TExternal ty s) = ext ty s
tRuleArgs :: TRule -> [(VarIndex, TypeExpr)]
tRuleArgs = trTRule const undefined
tRuleBody :: TRule -> TExpr
tRuleBody = trTRule (\_ e -> e) undefined
tRuleExtDecl :: TRule -> String
tRuleExtDecl = trTRule undefined (\_ s -> s)
isTRuleExternal :: TRule -> Bool
isTRuleExternal = trTRule (\_ _ -> False) (\_ _ -> True)
updTRule :: (TypeExpr -> TypeExpr) ->
([(VarIndex, TypeExpr)] -> [(VarIndex, TypeExpr)]) ->
(TExpr -> TExpr) ->
(String -> String) -> TRule -> TRule
updTRule fannot fa fe fs = trTRule rule ext
where
rule args e = TRule (fa args) (fe e)
ext ty s = TExternal (fannot ty) (fs s)
updTRuleType :: Update TRule TypeExpr
updTRuleType f = updTRule f id id id
updTRuleArgs :: Update TRule [(VarIndex, TypeExpr)]
updTRuleArgs f = updTRule id f id id
updTRuleBody :: Update TRule TExpr
updTRuleBody f = updTRule id id f id
updTRuleExtDecl :: Update TRule String
updTRuleExtDecl = updTRule id id id
allVarsInTRule :: TRule -> [(VarIndex, TypeExpr)]
allVarsInTRule = trTRule (\args body -> args ++ allVars body) (\_ _ -> [])
rnmAllVarsInTRule :: Update TRule VarIndex
rnmAllVarsInTRule f = updTRule id (map (\(a, b) -> (f a, b))) (rnmAllVars f) id
updQNamesInTRule :: Update TRule QName
updQNamesInTRule = updTRuleBody . updQNames
varNr :: TExpr -> VarIndex
varNr (TVarE _ n) = n
varNr _ = error "Curry.FlatCurry.Typed.Goodies.varNr: no variable"
literal :: TExpr -> Literal
literal (TLit _ l) = l
literal _ = error "Curry.FlatCurry.Typed.Goodies.literal: no literal"
combType :: TExpr -> CombType
combType (TComb _ ct _ _) = ct
combType _ = error $ "Curry.FlatCurry.Typed.Goodies.combType: " ++
"no combined expression"
combName :: TExpr -> QName
combName (TComb _ _ name _) = name
combName _ = error $ "Curry.FlatCurry.Typed.Goodies.combName: " ++
"no combined expression"
combArgs :: TExpr -> [TExpr]
combArgs (TComb _ _ _ args) = args
combArgs _ = error $ "Curry.FlatCurry.Typed.Goodies.combArgs: " ++
"no combined expression"
missingCombArgs :: TExpr -> Int
missingCombArgs = missingArgs . combType
where
missingArgs :: CombType -> Int
missingArgs = trCombType 0 id 0 id
letBinds :: TExpr -> [((VarIndex, TypeExpr), TExpr)]
letBinds (TLet vs _) = vs
letBinds _ = error $ "Curry.FlatCurry.Typed.Goodies.letBinds: " ++
"no let expression"
letBody :: TExpr -> TExpr
letBody (TLet _ e) = e
letBody _ = error $ "Curry.FlatCurry.Typed.Goodies.letBody: " ++
"no let expression"
freeVars :: TExpr -> [(VarIndex, TypeExpr)]
freeVars (TFree vs _) = vs
freeVars _ = error $ "Curry.FlatCurry.Typed.Goodies.freeVars: " ++
"no declaration of free variables"
freeExpr :: TExpr -> TExpr
freeExpr (TFree _ e) = e
freeExpr _ = error $ "Curry.FlatCurry.Typed.Goodies.freeExpr: " ++
"no declaration of free variables"
orExps :: TExpr -> [TExpr]
orExps (TOr e1 e2) = [e1, e2]
orExps _ = error $ "Curry.FlatCurry.Typed.Goodies.orExps: " ++
"no or expression"
caseType :: TExpr -> CaseType
caseType (TCase ct _ _) = ct
caseType _ = error $ "Curry.FlatCurry.Typed.Goodies.caseType: " ++
"no case expression"
caseExpr :: TExpr -> TExpr
caseExpr (TCase _ e _) = e
caseExpr _ = error $ "Curry.FlatCurry.Typed.Goodies.caseExpr: " ++
"no case expression"
caseBranches :: TExpr -> [TBranchExpr]
caseBranches (TCase _ _ bs) = bs
caseBranches _ = error "Curry.FlatCurry.Typed.Goodies.caseBranches: no case expression"
isTVarE :: TExpr -> Bool
isTVarE e = case e of
TVarE _ _ -> True
_ -> False
isTLit :: TExpr -> Bool
isTLit e = case e of
TLit _ _ -> True
_ -> False
isTComb :: TExpr -> Bool
isTComb e = case e of
TComb _ _ _ _ -> True
_ -> False
isTLet :: TExpr -> Bool
isTLet e = case e of
TLet _ _ -> True
_ -> False
isTFree :: TExpr -> Bool
isTFree e = case e of
TFree _ _ -> True
_ -> False
isTOr :: TExpr -> Bool
isTOr e = case e of
TOr _ _ -> True
_ -> False
isTCase :: TExpr -> Bool
isTCase e = case e of
TCase _ _ _ -> True
_ -> False
trTExpr :: (TypeExpr -> VarIndex -> b)
-> (TypeExpr -> Literal -> b)
-> (TypeExpr -> CombType -> QName -> [b] -> b)
-> ([((VarIndex, TypeExpr), b)] -> b -> b)
-> ([(VarIndex, TypeExpr)] -> b -> b)
-> (b -> b -> b)
-> (CaseType -> b -> [c] -> b)
-> (TPattern -> b -> c)
-> (b -> TypeExpr -> b)
-> TExpr
-> b
trTExpr var lit comb lt fr oR cas branch typed expr = case expr of
TVarE ty n -> var ty n
TLit ty l -> lit ty l
TComb ty ct name args -> comb ty ct name (map f args)
TLet bs e -> lt (map (\(v, x) -> (v, f x)) bs) (f e)
TFree vs e -> fr vs (f e)
TOr e1 e2 -> oR (f e1) (f e2)
TCase ct e bs -> cas ct (f e) (map (\ (TBranch p e') -> branch p (f e')) bs)
TTyped e ty -> typed (f e) ty
where
f = trTExpr var lit comb lt fr oR cas branch typed
updVars :: (TypeExpr -> VarIndex -> TExpr) -> TExpr -> TExpr
updVars var = trTExpr var TLit TComb TLet TFree TOr TCase TBranch TTyped
updLiterals :: (TypeExpr -> Literal -> TExpr) -> TExpr -> TExpr
updLiterals lit = trTExpr TVarE lit TComb TLet TFree TOr TCase TBranch TTyped
updCombs :: (TypeExpr -> CombType -> QName -> [TExpr] -> TExpr) -> TExpr -> TExpr
updCombs comb = trTExpr TVarE TLit comb TLet TFree TOr TCase TBranch TTyped
updLets :: ([((VarIndex, TypeExpr), TExpr)] -> TExpr -> TExpr) -> TExpr -> TExpr
updLets lt = trTExpr TVarE TLit TComb lt TFree TOr TCase TBranch TTyped
updFrees :: ([(VarIndex, TypeExpr)] -> TExpr -> TExpr) -> TExpr -> TExpr
updFrees fr = trTExpr TVarE TLit TComb TLet fr TOr TCase TBranch TTyped
updOrs :: (TExpr -> TExpr -> TExpr) -> TExpr -> TExpr
updOrs oR = trTExpr TVarE TLit TComb TLet TFree oR TCase TBranch TTyped
updCases :: (CaseType -> TExpr -> [TBranchExpr] -> TExpr) -> TExpr -> TExpr
updCases cas = trTExpr TVarE TLit TComb TLet TFree TOr cas TBranch TTyped
updBranches :: (TPattern -> TExpr -> TBranchExpr) -> TExpr -> TExpr
updBranches branch = trTExpr TVarE TLit TComb TLet TFree TOr TCase branch TTyped
updTypeds :: (TExpr -> TypeExpr -> TExpr) -> TExpr -> TExpr
updTypeds = trTExpr TVarE TLit TComb TLet TFree TOr TCase TBranch
isFuncCall :: TExpr -> Bool
isFuncCall e = isTComb e && isCombTypeFuncCall (combType e)
isFuncPartCall :: TExpr -> Bool
isFuncPartCall e = isTComb e && isCombTypeFuncPartCall (combType e)
isConsCall :: TExpr -> Bool
isConsCall e = isTComb e && isCombTypeConsCall (combType e)
isConsPartCall :: TExpr -> Bool
isConsPartCall e = isTComb e && isCombTypeConsPartCall (combType e)
isGround :: TExpr -> Bool
isGround e
= case e of
TComb _ ConsCall _ args -> all isGround args
_ -> isTLit e
allVars :: TExpr -> [(VarIndex, TypeExpr)]
allVars e = trTExpr var lit comb lt fr (.) cas branch typ e []
where
var a v = (:) (v, a)
lit = const (const id)
comb _ _ _ = foldr (.) id
lt bs e' = e' . foldr (.) id (map (\(n,ns) -> (n:) . ns) bs)
fr vs e' = (vs++) . e'
cas _ e' bs = e' . foldr (.) id bs
branch pat e' = (args pat ++) . e'
typ = const
args pat | isConsPattern pat = tPatArgs pat
| otherwise = []
rnmAllVars :: Update TExpr VarIndex
rnmAllVars f = trTExpr var TLit TComb lt fr TOr TCase branch TTyped
where
var a = TVarE a . f
lt = TLet . map (\((n, b), e) -> ((f n, b), e))
fr = TFree . map (\(b, c) -> (f b, c))
branch = TBranch . updTPatArgs (map (\(a, b) -> (f a, b)))
updQNames :: Update TExpr QName
updQNames f = trTExpr TVarE TLit comb TLet TFree TOr TCase branch TTyped
where
comb ty ct name args = TComb ty ct (f name) args
branch = TBranch . updTPatCons f
trTBranch :: (TPattern -> TExpr -> b) -> TBranchExpr -> b
trTBranch branch (TBranch pat e) = branch pat e
tBranchTPattern :: TBranchExpr -> TPattern
tBranchTPattern = trTBranch const
tBranchTExpr :: TBranchExpr -> TExpr
tBranchTExpr = trTBranch (\_ e -> e)
updTBranch :: (TPattern -> TPattern) -> (TExpr -> TExpr) -> TBranchExpr -> TBranchExpr
updTBranch fp fe = trTBranch branch
where
branch pat e = TBranch (fp pat) (fe e)
updTBranchTPattern :: Update TBranchExpr TPattern
updTBranchTPattern f = updTBranch f id
updTBranchTExpr :: Update TBranchExpr TExpr
updTBranchTExpr = updTBranch id
trTPattern :: (TypeExpr -> QName -> [(VarIndex, TypeExpr)] -> b) -> (TypeExpr -> Literal -> b) -> TPattern -> b
trTPattern pattern _ (TPattern ty name args) = pattern ty name args
trTPattern _ lpattern (TLPattern a l) = lpattern a l
tPatCons :: TPattern -> QName
tPatCons = trTPattern (\_ name _ -> name) undefined
tPatArgs :: TPattern -> [(VarIndex, TypeExpr)]
tPatArgs = trTPattern (\_ _ args -> args) undefined
tPatLiteral :: TPattern -> Literal
tPatLiteral = trTPattern undefined (const id)
isConsPattern :: TPattern -> Bool
isConsPattern = trTPattern (\_ _ _ -> True) (\_ _ -> False)
updTPattern :: (TypeExpr -> TypeExpr) ->
(QName -> QName) ->
([(VarIndex, TypeExpr)] -> [(VarIndex, TypeExpr)]) ->
(Literal -> Literal) -> TPattern -> TPattern
updTPattern fannot fn fa fl = trTPattern pattern lpattern
where
pattern ty name args = TPattern (fannot ty) (fn name) (fa args)
lpattern ty l = TLPattern (fannot ty) (fl l)
updTPatType :: (TypeExpr -> TypeExpr) -> TPattern -> TPattern
updTPatType f = updTPattern f id id id
updTPatCons :: (QName -> QName) -> TPattern -> TPattern
updTPatCons f = updTPattern id f id id
updTPatArgs :: ([(VarIndex, TypeExpr)] -> [(VarIndex, TypeExpr)]) -> TPattern -> TPattern
updTPatArgs f = updTPattern id id f id
updTPatLiteral :: (Literal -> Literal) -> TPattern -> TPattern
updTPatLiteral = updTPattern id id id
tPatExpr :: TPattern -> TExpr
tPatExpr = trTPattern (\ty name -> TComb ty ConsCall name . map (uncurry (flip TVarE))) TLit