module Curry.FlatCurry.Annotated.Goodies
( module Curry.FlatCurry.Annotated.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.Annotated.Type
trAProg :: (String -> [String] -> [TypeDecl] -> [AFuncDecl a] -> [OpDecl] -> b)
-> AProg a -> b
trAProg prog (AProg name imps types funcs ops) = prog name imps types funcs ops
aProgName :: AProg a -> String
aProgName = trAProg (\name _ _ _ _ -> name)
aProgImports :: AProg a -> [String]
aProgImports = trAProg (\_ imps _ _ _ -> imps)
aProgTypes :: AProg a -> [TypeDecl]
aProgTypes = trAProg (\_ _ types _ _ -> types)
aProgAFuncs :: AProg a -> [AFuncDecl a]
aProgAFuncs = trAProg (\_ _ _ funcs _ -> funcs)
aProgOps :: AProg a -> [OpDecl]
aProgOps = trAProg (\_ _ _ _ ops -> ops)
updAProg :: (String -> String) ->
([String] -> [String]) ->
([TypeDecl] -> [TypeDecl]) ->
([AFuncDecl a] -> [AFuncDecl a]) ->
([OpDecl] -> [OpDecl]) -> AProg a -> AProg a
updAProg fn fi ft ff fo = trAProg prog
where
prog name imps types funcs ops
= AProg (fn name) (fi imps) (ft types) (ff funcs) (fo ops)
updAProgName :: Update (AProg a) String
updAProgName f = updAProg f id id id id
updAProgImports :: Update (AProg a) [String]
updAProgImports f = updAProg id f id id id
updAProgTypes :: Update (AProg a) [TypeDecl]
updAProgTypes f = updAProg id id f id id
updAProgAFuncs :: Update (AProg a) [AFuncDecl a]
updAProgAFuncs f = updAProg id id id f id
updAProgOps :: Update (AProg a) [OpDecl]
updAProgOps = updAProg id id id id
allVarsInAProg :: AProg a -> [(VarIndex, a)]
allVarsInAProg = concatMap allVarsInAFunc . aProgAFuncs
updAProgAExps :: Update (AProg a) (AExpr a)
updAProgAExps = updAProgAFuncs . map . updAFuncBody
rnmAllVarsInAProg :: Update (AProg a) VarIndex
rnmAllVarsInAProg = updAProgAFuncs . map . rnmAllVarsInAFunc
updQNamesInAProg :: Update (AProg a) QName
updQNamesInAProg f = updAProg id id
(map (updQNamesInType f)) (map (updQNamesInAFunc f)) (map (updOpName f))
rnmAProg :: String -> AProg a -> AProg a
rnmAProg name p = updAProgName (const name) (updQNamesInAProg rnm p)
where
rnm (m, n) | m == aProgName p = (name, n)
| otherwise = (m, n)
trAFunc :: (QName -> Int -> Visibility -> TypeExpr -> ARule a -> b) -> AFuncDecl a -> b
trAFunc func (AFunc name arity vis t rule) = func name arity vis t rule
aFuncName :: AFuncDecl a -> QName
aFuncName = trAFunc (\name _ _ _ _ -> name)
aFuncArity :: AFuncDecl a -> Int
aFuncArity = trAFunc (\_ arity _ _ _ -> arity)
aFuncVisibility :: AFuncDecl a -> Visibility
aFuncVisibility = trAFunc (\_ _ vis _ _ -> vis)
aFuncType :: AFuncDecl a -> TypeExpr
aFuncType = trAFunc (\_ _ _ t _ -> t)
aFuncARule :: AFuncDecl a -> ARule a
aFuncARule = trAFunc (\_ _ _ _ rule -> rule)
updAFunc :: (QName -> QName) ->
(Int -> Int) ->
(Visibility -> Visibility) ->
(TypeExpr -> TypeExpr) ->
(ARule a -> ARule a) -> AFuncDecl a -> AFuncDecl a
updAFunc fn fa fv ft fr = trAFunc func
where
func name arity vis t rule
= AFunc (fn name) (fa arity) (fv vis) (ft t) (fr rule)
updAFuncName :: Update (AFuncDecl a) QName
updAFuncName f = updAFunc f id id id id
updAFuncArity :: Update (AFuncDecl a) Int
updAFuncArity f = updAFunc id f id id id
updAFuncVisibility :: Update (AFuncDecl a) Visibility
updAFuncVisibility f = updAFunc id id f id id
updFuncType :: Update (AFuncDecl a) TypeExpr
updFuncType f = updAFunc id id id f id
updAFuncARule :: Update (AFuncDecl a) (ARule a)
updAFuncARule = updAFunc id id id id
isPublicAFunc :: AFuncDecl a -> Bool
isPublicAFunc = isPublic . aFuncVisibility
isExternal :: AFuncDecl a -> Bool
isExternal = isARuleExternal . aFuncARule
allVarsInAFunc :: AFuncDecl a -> [(VarIndex, a)]
allVarsInAFunc = allVarsInARule . aFuncARule
aFuncArgs :: AFuncDecl a -> [(VarIndex, a)]
aFuncArgs = aRuleArgs . aFuncARule
aFuncBody :: AFuncDecl a -> AExpr a
aFuncBody = aRuleBody . aFuncARule
aFuncRHS :: AFuncDecl a -> [AExpr a]
aFuncRHS f | not (isExternal f) = orCase (aFuncBody f)
| otherwise = []
where
orCase e
| isAOr e = concatMap orCase (orExps e)
| isACase e = concatMap orCase (map aBranchAExpr (caseBranches e))
| otherwise = [e]
rnmAllVarsInAFunc :: Update (AFuncDecl a) VarIndex
rnmAllVarsInAFunc = updAFunc id id id id . rnmAllVarsInARule
updQNamesInAFunc :: Update (AFuncDecl a) QName
updQNamesInAFunc f = updAFunc f id id (updQNamesInTypeExpr f) (updQNamesInARule f)
updAFuncArgs :: Update (AFuncDecl a) [(VarIndex, a)]
updAFuncArgs = updAFuncARule . updARuleArgs
updAFuncBody :: Update (AFuncDecl a) (AExpr a)
updAFuncBody = updAFuncARule . updARuleBody
trARule :: (a -> [(VarIndex, a)] -> AExpr a -> b) -> (a -> String -> b) -> ARule a -> b
trARule rule _ (ARule a args e) = rule a args e
trARule _ ext (AExternal a s) = ext a s
aRuleAnnot :: ARule a -> a
aRuleAnnot = trARule (\a _ _ -> a) (\a _ -> a)
aRuleArgs :: ARule a -> [(VarIndex, a)]
aRuleArgs = trARule (\_ args _ -> args) undefined
aRuleBody :: ARule a -> AExpr a
aRuleBody = trARule (\_ _ e -> e) undefined
aRuleExtDecl :: ARule a -> String
aRuleExtDecl = trARule undefined (\_ s -> s)
isARuleExternal :: ARule a -> Bool
isARuleExternal = trARule (\_ _ _ -> False) (\_ _ -> True)
updARule :: (a -> b) ->
([(VarIndex, a)] -> [(VarIndex, b)]) ->
(AExpr a -> AExpr b) ->
(String -> String) -> ARule a -> ARule b
updARule fannot fa fe fs = trARule rule ext
where
rule a args e = ARule (fannot a) (fa args) (fe e)
ext a s = AExternal (fannot a) (fs s)
updARuleAnnot :: Update (ARule a) a
updARuleAnnot f = updARule f id id id
updARuleArgs :: Update (ARule a) [(VarIndex, a)]
updARuleArgs f = updARule id f id id
updARuleBody :: Update (ARule a) (AExpr a)
updARuleBody f = updARule id id f id
updARuleExtDecl :: Update (ARule a) String
updARuleExtDecl f = updARule id id id f
allVarsInARule :: ARule a -> [(VarIndex, a)]
allVarsInARule = trARule (\_ args body -> args ++ allVars body) (\_ _ -> [])
rnmAllVarsInARule :: Update (ARule a) VarIndex
rnmAllVarsInARule f = updARule id (map (\(a, b) -> (f a, b))) (rnmAllVars f) id
updQNamesInARule :: Update (ARule a) QName
updQNamesInARule = updARuleBody . updQNames
annot :: AExpr a -> a
annot (AVar a _ ) = a
annot (ALit a _ ) = a
annot (AComb a _ _ _) = a
annot (ALet a _ _ ) = a
annot (AFree a _ _ ) = a
annot (AOr a _ _ ) = a
annot (ACase a _ _ _) = a
annot (ATyped a _ _ ) = a
varNr :: AExpr a -> VarIndex
varNr (AVar _ n) = n
varNr _ = error "Curry.FlatCurry.Annotated.Goodies.varNr: no variable"
literal :: AExpr a -> Literal
literal (ALit _ l) = l
literal _ = error "Curry.FlatCurry.Annotated.Goodies.literal: no literal"
combType :: AExpr a -> CombType
combType (AComb _ ct _ _) = ct
combType _ = error $ "Curry.FlatCurry.Annotated.Goodies.combType: " ++
"no combined expression"
combName :: AExpr a -> (QName, a)
combName (AComb _ _ name _) = name
combName _ = error $ "Curry.FlatCurry.Annotated.Goodies.combName: " ++
"no combined expression"
combArgs :: AExpr a -> [AExpr a]
combArgs (AComb _ _ _ args) = args
combArgs _ = error $ "Curry.FlatCurry.Annotated.Goodies.combArgs: " ++
"no combined expression"
missingCombArgs :: AExpr a -> Int
missingCombArgs = missingArgs . combType
where
missingArgs :: CombType -> Int
missingArgs = trCombType 0 id 0 id
letBinds :: AExpr a -> [((VarIndex, a), AExpr a)]
letBinds (ALet _ vs _) = vs
letBinds _ = error $ "Curry.FlatCurry.Annotated.Goodies.letBinds: " ++
"no let expression"
letBody :: AExpr a -> AExpr a
letBody (ALet _ _ e) = e
letBody _ = error $ "Curry.FlatCurry.Annotated.Goodies.letBody: " ++
"no let expression"
freeVars :: AExpr a -> [(VarIndex, a)]
freeVars (AFree _ vs _) = vs
freeVars _ = error $ "Curry.FlatCurry.Annotated.Goodies.freeVars: " ++
"no declaration of free variables"
freeExpr :: AExpr a -> AExpr a
freeExpr (AFree _ _ e) = e
freeExpr _ = error $ "Curry.FlatCurry.Annotated.Goodies.freeExpr: " ++
"no declaration of free variables"
orExps :: AExpr a -> [AExpr a]
orExps (AOr _ e1 e2) = [e1, e2]
orExps _ = error $ "Curry.FlatCurry.Annotated.Goodies.orExps: " ++
"no or expression"
caseType :: AExpr a -> CaseType
caseType (ACase _ ct _ _) = ct
caseType _ = error $ "Curry.FlatCurry.Annotated.Goodies.caseType: " ++
"no case expression"
caseExpr :: AExpr a -> AExpr a
caseExpr (ACase _ _ e _) = e
caseExpr _ = error $ "Curry.FlatCurry.Annotated.Goodies.caseExpr: " ++
"no case expression"
caseBranches :: AExpr a -> [ABranchExpr a]
caseBranches (ACase _ _ _ bs) = bs
caseBranches _ = error
"Curry.FlatCurry.Annotated.Goodies.caseBranches: no case expression"
isAVar :: AExpr a -> Bool
isAVar e = case e of
AVar _ _ -> True
_ -> False
isALit :: AExpr a -> Bool
isALit e = case e of
ALit _ _ -> True
_ -> False
isAComb :: AExpr a -> Bool
isAComb e = case e of
AComb _ _ _ _ -> True
_ -> False
isALet :: AExpr a -> Bool
isALet e = case e of
ALet _ _ _ -> True
_ -> False
isAFree :: AExpr a -> Bool
isAFree e = case e of
AFree _ _ _ -> True
_ -> False
isAOr :: AExpr a -> Bool
isAOr e = case e of
AOr _ _ _ -> True
_ -> False
isACase :: AExpr a -> Bool
isACase e = case e of
ACase _ _ _ _ -> True
_ -> False
trAExpr :: (a -> VarIndex -> b)
-> (a -> Literal -> b)
-> (a -> CombType -> (QName, a) -> [b] -> b)
-> (a -> [((VarIndex, a), b)] -> b -> b)
-> (a -> [(VarIndex, a)] -> b -> b)
-> (a -> b -> b -> b)
-> (a -> CaseType -> b -> [c] -> b)
-> (APattern a -> b -> c)
-> (a -> b -> TypeExpr -> b)
-> AExpr a
-> b
trAExpr var lit comb lt fr oR cas branch typed expr = case expr of
AVar a n -> var a n
ALit a l -> lit a l
AComb a ct name args -> comb a ct name (map f args)
ALet a bs e -> lt a (map (\(v, x) -> (v, f x)) bs) (f e)
AFree a vs e -> fr a vs (f e)
AOr a e1 e2 -> oR a (f e1) (f e2)
ACase a ct e bs -> cas a ct (f e) (map (\ (ABranch p e') -> branch p (f e')) bs)
ATyped a e ty -> typed a (f e) ty
where
f = trAExpr var lit comb lt fr oR cas branch typed
updVars :: (a -> VarIndex -> AExpr a) -> AExpr a -> AExpr a
updVars var = trAExpr var ALit AComb ALet AFree AOr ACase ABranch ATyped
updLiterals :: (a -> Literal -> AExpr a) -> AExpr a -> AExpr a
updLiterals lit = trAExpr AVar lit AComb ALet AFree AOr ACase ABranch ATyped
updCombs :: (a -> CombType -> (QName, a) -> [AExpr a] -> AExpr a) -> AExpr a -> AExpr a
updCombs comb = trAExpr AVar ALit comb ALet AFree AOr ACase ABranch ATyped
updLets :: (a -> [((VarIndex, a), AExpr a)] -> AExpr a -> AExpr a) -> AExpr a -> AExpr a
updLets lt = trAExpr AVar ALit AComb lt AFree AOr ACase ABranch ATyped
updFrees :: (a -> [(VarIndex, a)] -> AExpr a -> AExpr a) -> AExpr a -> AExpr a
updFrees fr = trAExpr AVar ALit AComb ALet fr AOr ACase ABranch ATyped
updOrs :: (a -> AExpr a -> AExpr a -> AExpr a) -> AExpr a -> AExpr a
updOrs oR = trAExpr AVar ALit AComb ALet AFree oR ACase ABranch ATyped
updCases :: (a -> CaseType -> AExpr a -> [ABranchExpr a] -> AExpr a) -> AExpr a -> AExpr a
updCases cas = trAExpr AVar ALit AComb ALet AFree AOr cas ABranch ATyped
updBranches :: (APattern a -> AExpr a -> ABranchExpr a) -> AExpr a -> AExpr a
updBranches branch = trAExpr AVar ALit AComb ALet AFree AOr ACase branch ATyped
updTypeds :: (a -> AExpr a -> TypeExpr -> AExpr a) -> AExpr a -> AExpr a
updTypeds = trAExpr AVar ALit AComb ALet AFree AOr ACase ABranch
isFuncCall :: AExpr a -> Bool
isFuncCall e = isAComb e && isCombTypeFuncCall (combType e)
isFuncPartCall :: AExpr a -> Bool
isFuncPartCall e = isAComb e && isCombTypeFuncPartCall (combType e)
isConsCall :: AExpr a -> Bool
isConsCall e = isAComb e && isCombTypeConsCall (combType e)
isConsPartCall :: AExpr a -> Bool
isConsPartCall e = isAComb e && isCombTypeConsPartCall (combType e)
isGround :: AExpr a -> Bool
isGround e
= case e of
AComb _ ConsCall _ args -> all isGround args
_ -> isALit e
allVars :: AExpr a -> [(VarIndex, a)]
allVars e = trAExpr var lit comb lt fr (const (.)) 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 = aPatArgs pat
| otherwise = []
rnmAllVars :: Update (AExpr a) VarIndex
rnmAllVars f = trAExpr var ALit AComb lt fr AOr ACase branch ATyped
where
var a = AVar a . f
lt a = ALet a . map (\((n, b), e) -> ((f n, b), e))
fr a = AFree a . map (\(b, c) -> (f b, c))
branch = ABranch . updAPatArgs (map (\(a, b) -> (f a, b)))
updQNames :: Update (AExpr a) QName
updQNames f = trAExpr AVar ALit comb ALet AFree AOr ACase branch ATyped
where
comb a ct (name, a') args = AComb a ct (f name, a') args
branch = ABranch . updAPatCons (\(q, a) -> (f q, a))
trABranch :: (APattern a -> AExpr a -> b) -> ABranchExpr a -> b
trABranch branch (ABranch pat e) = branch pat e
aBranchAPattern :: ABranchExpr a -> APattern a
aBranchAPattern = trABranch (\pat _ -> pat)
aBranchAExpr :: ABranchExpr a -> AExpr a
aBranchAExpr = trABranch (\_ e -> e)
updABranch :: (APattern a -> APattern a) -> (AExpr a -> AExpr a) -> ABranchExpr a -> ABranchExpr a
updABranch fp fe = trABranch branch
where
branch pat e = ABranch (fp pat) (fe e)
updABranchAPattern :: Update (ABranchExpr a) (APattern a)
updABranchAPattern f = updABranch f id
updABranchAExpr :: Update (ABranchExpr a) (AExpr a)
updABranchAExpr = updABranch id
trAPattern :: (a -> (QName, a) -> [(VarIndex, a)] -> b) -> (a -> Literal -> b) -> APattern a -> b
trAPattern pattern _ (APattern a name args) = pattern a name args
trAPattern _ lpattern (ALPattern a l) = lpattern a l
aPatAnnot :: APattern a -> a
aPatAnnot = trAPattern (\a _ _ -> a) (\a _ -> a)
aPatCons :: APattern a -> (QName, a)
aPatCons = trAPattern (\_ name _ -> name) undefined
aPatArgs :: APattern a -> [(VarIndex, a)]
aPatArgs = trAPattern (\_ _ args -> args) undefined
aPatLiteral :: APattern a -> Literal
aPatLiteral = trAPattern undefined (const id)
isConsPattern :: APattern a -> Bool
isConsPattern = trAPattern (\_ _ _ -> True) (\_ _ -> False)
updAPattern :: (a -> a) ->
((QName, a) -> (QName, a)) ->
([(VarIndex, a)] -> [(VarIndex, a)]) ->
(Literal -> Literal) -> APattern a -> APattern a
updAPattern fannot fn fa fl = trAPattern pattern lpattern
where
pattern a name args = APattern (fannot a) (fn name) (fa args)
lpattern a l = ALPattern (fannot a) (fl l)
updAPatAnnot :: (a -> a) -> APattern a -> APattern a
updAPatAnnot f = updAPattern f id id id
updAPatCons :: ((QName, a) -> (QName, a)) -> APattern a -> APattern a
updAPatCons f = updAPattern id f id id
updAPatArgs :: ([(VarIndex, a)] -> [(VarIndex, a)]) -> APattern a -> APattern a
updAPatArgs f = updAPattern id id f id
updAPatLiteral :: (Literal -> Literal) -> APattern a -> APattern a
updAPatLiteral f = updAPattern id id id f
aPatExpr :: APattern a -> AExpr a
aPatExpr = trAPattern (\a name -> AComb a ConsCall name . map (uncurry (flip AVar))) ALit