module Curry.FlatCurry.Tools ( -- operations on programs: progName, progImports, progTypes, progFuncs, progOps, updProg, updProgName, updProgImports, updProgTypes, updProgFuncs, updProgOps, updProgExps, rnmAllVarsProg, allVarsProg, updQNamesProg, rnmProg, -- operations on type declarations: updQNamesType,allConstructors,consQName, consArity, isTypeSyn, isDataTypeDecl, isPublicType, isPublicCons,typeQName,isExternalType, -- operations on functions: funcName, funcArity, funcVisibility, funcType, funcRule, updFunc, updFuncName, updFuncArity, updFuncVisibility, updFuncType, updFuncRule, funcArgs, funcBody, funcRHS, isExternal, isCombFunc, updFuncArgs, updFuncBody, incVarsFunc, rnmAllVarsFunc, allVarsFunc, updQNamesFunc, -- operations on function-rules: isRuleExternal, ruleArgs, ruleBody, updRule, updRuleArgs, updRuleBody, rnmAllVarsRule, allVarsRule, updQNamesRule, -- operations on type-expressions: isTypeVar, isFuncType, isTypeCons, typeConsName, argTypes, resultType, isIOType,typeArity, allTVars, rnmAllVarsTypeExpr, allTypeCons, -- operations on expressions: isVar, varNr, isLit, isComb, isFree, isOr, isCase, isLet, isGround, literal, combType, exprFromFreeDecl, orExps, isFuncCall, isPartCall, isConsCall, combFunc, combCons, combArgs, missingFuncArgs, hasName, caseBranches, rnmAllVars, allVars, mapVar, mapLit, mapComb, mapFree, mapOr, mapCase, mapLet, -- operations on combination-types isCombFuncCall, isCombPartCall, isCombConsCall, missingArgs, -- operations on branch-expressions branchPattern, branchExpr, isConsPattern, updBranch, updBranchPattern, updBranchExpr, patCons, patArgs, patLiteral, patExpr, rnmAllVarsBranch, allVarsBranch, rnmAllVarsPat, allVarsPat, -- operations on OpDecls opName ) where import Data.Maybe import Data.Char import Data.List import Curry.FlatCurry.Type infixr 5 -:- -- variant of zipWith for lists of same length zipWith' _ [] [] = [] zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys -- auxiliary functions ------------------------------------------------------- x -:- xs = Comb ConsCall ("Prelude",":") [x,xs] nil = Comb ConsCall ("Prelude","[]") [] char_ :: Char -> Expr char_ c = Lit (Charc c) int_ :: Integer -> Expr int_ n = Lit (Intc n) float_ :: Double -> Expr float_ f = Lit (Floatc f) list_ :: [Expr] -> Expr list_ [] = nil list_ (x:xs) = x -:- list_ xs string_ :: String -> Expr string_ = list_ . map char_ -- Prog ---------------------------------------------------------------------- updProg fn fi ft ff fo (Prog name imps types funcs ops) = Prog (fn name) (fi imps) (ft types) (ff funcs) (fo ops) --- get name from program progName :: Prog -> String progName (Prog name _ _ _ _) = name --- update name of program updProgName :: (String -> String) -> Prog -> Prog updProgName f = updProg f id id id id --- get imports from program progImports :: Prog -> [String] progImports (Prog _ imps _ _ _) = imps --- update imports of program updProgImports :: ([String] -> [String]) -> Prog -> Prog updProgImports f = updProg id f id id id --- get type declarations from program progTypes :: Prog -> [TypeDecl] progTypes (Prog _ _ types _ _) = types --- update type declarations of program updProgTypes :: ([TypeDecl] -> [TypeDecl]) -> Prog -> Prog updProgTypes f = updProg id id f id id --- get functions from program progFuncs :: Prog -> [FuncDecl] progFuncs (Prog _ _ _ funcs _) = funcs --- update functions of program updProgFuncs :: ([FuncDecl] -> [FuncDecl]) -> Prog -> Prog updProgFuncs f = updProg id id id f id --- get infix operators from program progOps :: Prog -> [OpDecl] progOps (Prog _ _ _ _ ops) = ops --- update infix operators of program updProgOps :: ([OpDecl] -> [OpDecl]) -> Prog -> Prog updProgOps f = updProg id id id id f --- lift transformation on expressions to program updProgExps :: (Expr -> Expr) -> Prog -> Prog updProgExps = updProgFuncs . map . updFuncBody --- rename programs variables rnmAllVarsProg :: (Int -> Int) -> Prog -> Prog rnmAllVarsProg = updProgFuncs . map . rnmAllVarsFunc --- get all program variables (also from patterns) allVarsProg :: Prog -> [Int] allVarsProg = concatMap allVarsFunc . progFuncs --- update all qualified names in program updQNamesProg :: (QName -> QName) -> Prog -> Prog updQNamesProg f = updProg id id (map (updQNamesType f)) (map (updQNamesFunc f)) (map (\ (Op name fix prec) -> Op (f name) fix prec)) rnmProg :: String -> Prog -> Prog rnmProg name p = updProgName (const name) (updQNamesProg rnm p) where rnm (mod,n) | mod==progName p = (name,n) | otherwise = (mod,n) -- TypeDecl ------------------------------------------------------------------ --- select all constructors in a type declaration allConstructors :: TypeDecl -> [ConsDecl] allConstructors (TypeSyn _ _ _ _) = [] allConstructors (Type _ _ _ cs) = cs --- select name of constructor consQName :: ConsDecl -> QName consQName (Cons n _ _ _) = n consArity :: ConsDecl -> Int consArity (Cons _ a _ _) = a --- update all qualified names in type declaration updQNamesType :: (QName -> QName) -> TypeDecl -> TypeDecl updQNamesType f (Type name vis vars decls) = Type (f name) vis vars (map (updQNamesConsDecl f) decls) updQNamesType f (TypeSyn name vis vars t) = TypeSyn (f name) vis vars (updQNamesTypeExpr f t) --- update all qualified names in constructor declaration updQNamesConsDecl :: (QName -> QName) -> ConsDecl -> ConsDecl updQNamesConsDecl f (Cons name arity vis args) = Cons (f name) arity vis (map (updQNamesTypeExpr f) args) isDataTypeDecl :: TypeDecl -> Bool isDataTypeDecl (TypeSyn _ _ _ _) = False isDataTypeDecl (Type _ _ _ cs) = not (null cs) isExternalType :: TypeDecl -> Bool isExternalType (TypeSyn _ _ _ _) = False isExternalType (Type _ _ _ cs) = null cs isTypeSyn :: TypeDecl -> Bool isTypeSyn (Type _ _ _ _) = False isTypeSyn (TypeSyn _ _ _ _) = True isPublicType :: TypeDecl -> Bool isPublicType (Type _ vis _ _) = vis==Public isPublicType (TypeSyn _ vis _ _) = vis==Public isPublicCons :: ConsDecl -> Bool isPublicCons (Cons _ _ vis _) = vis==Public typeQName :: TypeDecl -> QName typeQName (TypeSyn n _ _ _) = n typeQName (Type n _ _ _) = n -- FuncDecl ------------------------------------------------------------------ updFunc fn fa fv ft fr (Func name arity vis t rule) = Func (fn name) (fa arity) (fv vis) (ft t) (fr rule) --- get name of function funcName :: FuncDecl -> QName funcName (Func name _ _ _ _) = name --- update name of function updFuncName :: (QName -> QName) -> FuncDecl -> FuncDecl updFuncName f = updFunc f id id id id --- get arity of function funcArity :: FuncDecl -> Int funcArity (Func _ arity _ _ _) = arity --- update arity of function updFuncArity :: (Int -> Int) -> FuncDecl -> FuncDecl updFuncArity f = updFunc id f id id id --- get visibility of function funcVisibility :: FuncDecl -> Visibility funcVisibility (Func _ _ vis _ _) = vis --- is function public? isPublicFunc :: FuncDecl -> Bool isPublicFunc (Func _ _ vis _ _) = vis==Public --- update visibility of function updFuncVisibility :: (Visibility -> Visibility) -> FuncDecl -> FuncDecl updFuncVisibility f = updFunc id id f id id --- get type of function funcType :: FuncDecl -> TypeExpr funcType (Func _ _ _ t _) = t --- update type of function updFuncType :: (TypeExpr -> TypeExpr) -> FuncDecl -> FuncDecl updFuncType f = updFunc id id id f id --- get rule of function funcRule :: FuncDecl -> Rule funcRule (Func _ _ _ _ rule) = rule --- update rule of function updFuncRule :: (Rule -> Rule) -> FuncDecl -> FuncDecl updFuncRule f = updFunc id id id id f --- update all qualified names in function updQNamesFunc :: (QName -> QName) -> FuncDecl -> FuncDecl updQNamesFunc f = updFunc f id id (updQNamesTypeExpr f) (updQNamesRule f) -- shortcuts --- get arguments of function, if not externally defined funcArgs :: FuncDecl -> Maybe [Int] funcArgs = ruleArgs . funcRule --- update arguments of function, if not externally defined updFuncArgs :: ([Int] -> [Int]) -> FuncDecl -> FuncDecl updFuncArgs = updFuncRule . updRuleArgs --- get body of function, if not externally defined funcBody :: FuncDecl -> Maybe Expr funcBody = ruleBody . funcRule --- update body of function, if not externally defined updFuncBody :: (Expr -> Expr) -> FuncDecl -> FuncDecl updFuncBody = updFuncRule . updRuleBody --- get right-hand-sides of function (body without leading case and or nodes) funcRHS :: FuncDecl -> Maybe [Expr] funcRHS = maybe Nothing (Just . unwrapCaseOr) . funcBody where unwrapCaseOr e | isCase e = concatMap unwrapCaseOr (map branchExpr (caseBranches e)) | isOr e = concatMap unwrapCaseOr (orExps e) | otherwise = [e] --- is function externally defined? isExternal :: FuncDecl -> Bool isExternal = isRuleExternal . funcRule --- is expression e an application of function f? --- @*param f - function declaration --- @*param e - expression isCombFunc :: FuncDecl -> Expr -> Bool isCombFunc = hasName . funcName -- auxiliary functions ------------------------------------------------------- --- increment all variable names in function incVarsFunc :: Int -> FuncDecl -> FuncDecl incVarsFunc m = rnmAllVarsFunc (m+) --- rename all variables in function rnmAllVarsFunc :: (Int -> Int) -> FuncDecl -> FuncDecl rnmAllVarsFunc f (Func name arity vis t rule) = Func name arity vis t (rnmAllVarsRule f rule) --- get variable names in a function declaration allVarsFunc :: FuncDecl -> [Int] allVarsFunc = allVarsRule . funcRule -- Rule ---------------------------------------------------------------------- updRule fa fe _ (Rule args exp) = Rule (fa args) (fe exp) updRule _ _ f (External s) = External (f s) --- is rule an external declaration? isRuleExternal :: Rule -> Bool isRuleExternal (Rule _ _) = False isRuleExternal (External _) = True --- get rules arguments if it's not external ruleArgs :: Rule -> Maybe [Int] ruleArgs (Rule args _) = Just args ruleArgs (External _) = Nothing --- update rules arguments updRuleArgs :: ([Int] -> [Int]) -> Rule -> Rule updRuleArgs f = updRule f id id --- get rules body if it's not external ruleBody :: Rule -> Maybe Expr ruleBody (Rule _ exp) = Just exp ruleBody (External _) = Nothing --- update rules body updRuleBody :: (Expr -> Expr) -> Rule -> Rule updRuleBody f = updRule id f id --- get rules external declaration ruleExtDecl :: Rule -> Maybe String ruleExtDecl (Rule _ _ ) = Nothing ruleExtDecl (External s) = Just s --- update rules external declaration updRuleExtDecl :: (String -> String) -> Rule -> Rule updRuleExtDecl f = updRule id id f --- update all qualified names in rule updQNamesRule :: (QName -> QName) -> Rule -> Rule updQNamesRule = updRuleBody . updQNames -- auxiliary functions ------------------------------------------------------- --- rename all variables in rule rnmAllVarsRule :: (Int -> Int) -> Rule -> Rule rnmAllVarsRule f (Rule args body) = Rule (map f args) (rnmAllVars f body) rnmAllVarsRule _ (External s) = External s --- get variable names in a functions rule allVarsRule :: Rule -> [Int] allVarsRule (Rule args body) = args ++ allVars body -- TypeExpr ------------------------------------------------------------------ --- is type expression a type variable? isTypeVar :: TypeExpr -> Bool isTypeVar t = case t of TVar _ -> True _ -> False --- is type expression a functional type? isFuncType :: TypeExpr -> Bool isFuncType t = case t of FuncType _ _ -> True _ -> False --- compute number of arguments by function type typeArity :: TypeExpr -> Int typeArity (TVar _) = 0 typeArity (TCons _ _) = 0 typeArity (FuncType _ t2) = 1+typeArity t2 --- is type expression a type constructor? isTypeCons :: TypeExpr -> Bool isTypeCons t = case t of TCons _ _ -> True _ -> False --- is root type constructor IO? isIOType :: TypeExpr -> Bool isIOType t = typeConsName t==Just ("Prelude","IO") --- get name if type expression is type constructor typeConsName :: TypeExpr -> Maybe QName typeConsName t | isTypeCons t = let TCons name _ = t in Just name | otherwise = Nothing --- get argument types from functional type argTypes :: TypeExpr -> [TypeExpr] argTypes t = case t of FuncType dom ran -> dom : argTypes ran _ -> [] --- get result type from (nested) functional type resultType :: TypeExpr -> TypeExpr resultType t = case t of FuncType _ ran -> resultType ran _ -> t --- rename variables in type declaration rnmAllVarsTypeExpr :: (Int -> Int) -> TypeExpr -> TypeExpr rnmAllVarsTypeExpr f (TVar n) = TVar (f n) rnmAllVarsTypeExpr f (TCons name args) = TCons name (map (rnmAllVarsTypeExpr f) args) rnmAllVarsTypeExpr f (FuncType dom ran) = FuncType (rnmAllVarsTypeExpr f dom) (rnmAllVarsTypeExpr f ran) allTVars (TVar n) = [n] allTVars (TCons _ args) = concatMap allTVars args allTVars (FuncType t1 t2) = concatMap allTVars [t1,t2] --- yield the list of all contained type constructors allTypeCons :: TypeExpr -> [QName] allTypeCons (TVar _) = [] allTypeCons (TCons name args) = name : concatMap allTypeCons args allTypeCons (FuncType t1 t2) = allTypeCons t1 ++ allTypeCons t2 --- update all qualified names in type expression updQNamesTypeExpr :: (QName -> QName) -> TypeExpr -> TypeExpr updQNamesTypeExpr _ (TVar n) = TVar n updQNamesTypeExpr f (FuncType dom ran) = FuncType (updQNamesTypeExpr f dom) (updQNamesTypeExpr f ran) updQNamesTypeExpr f (TCons name args) = TCons (f name) (map (updQNamesTypeExpr f) args) -- Expr ---------------------------------------------------------------------- --- is expression a variable? isVar :: Expr -> Bool isVar e = case e of Var _ -> True _ -> False --- get internal number of variable varNr :: Expr -> Int varNr (Var n) = n --- is expression a literal expression? isLit :: Expr -> Bool isLit e = case e of Lit _ -> True _ -> False --- is expression combined? isComb :: Expr -> Bool isComb e = case e of Comb _ _ _ -> True _ -> False --- is expression a declaration of free variables? isFree :: Expr -> Bool isFree e = case e of Free _ _ -> True _ -> False --- is expression an or-expression? isOr :: Expr -> Bool isOr e = case e of Or _ _ -> True _ -> False --- is expression a case expression? isCase :: Expr -> Bool isCase e = case e of Case _ _ _ -> True _ -> False --- is expression a let expression? isLet :: Expr -> Bool isLet e = case e of Let _ _ -> True _ -> False --- is expression fully evaluated? isGround :: Expr -> Bool isGround exp = case exp of Comb ConsCall _ args -> all isGround args _ -> isLit exp --- get literal if expression is literal expression literal :: Expr -> Maybe Literal literal e = case e of Lit l -> Just l _ -> Nothing --- get combination type if expression is a combined expression combType :: Expr -> Maybe CombType combType e = case e of Comb ct _ _ -> Just ct _ -> Nothing --- get expression from declaration of free variables exprFromFreeDecl :: Expr -> Expr exprFromFreeDecl (Free _ e) = e --- get expressions from or-expression orExps :: Expr -> [Expr] orExps (Or e1 e2) = [e1,e2] -- shortcuts --- is expression a call of a function where all arguments are provided? isFuncCall :: Expr -> Bool isFuncCall e = maybe False isCombFuncCall (combType e) --- is expression a partial call? isPartCall :: Expr -> Bool isPartCall e = maybe False isCombPartCall (combType e) --- is expression a call of a constructor? isConsCall :: Expr -> Bool isConsCall e = maybe False isCombConsCall (combType e) --- get name of function if expression is a (maybe partial) function call combFunc :: Expr -> Maybe QName combFunc e | isFuncCall e || isPartCall e = let Comb _ name _ = e in Just name | otherwise = Nothing --- get name of constructor if expression is a constructor call combCons :: Expr -> Maybe QName combCons e | isConsCall e = let Comb _ name _ = e in Just name | otherwise = Nothing --- get arguments if expression is combined combArgs :: Expr -> Maybe [Expr] combArgs e | isComb e = let Comb _ _ args = e in Just args | otherwise = Nothing --- get number of missing function arguments if expression is combined missingFuncArgs :: Expr -> Maybe Int missingFuncArgs e = combType e >>= Just . missingArgs --- is expression a combined expression with given name? hasName :: QName -> Expr -> Bool hasName name (Comb _ name' _) = name==name' --- get branch expressions from case expression caseBranches :: Expr -> [BranchExpr] caseBranches (Case _ _ bs) = bs -- auxiliary functions --- rename all variables (even in patterns) in expression rnmAllVars :: (Int -> Int) -> Expr -> Expr rnmAllVars f (Var n) = Var (f n) rnmAllVars _ (Lit l) = Lit l rnmAllVars f (Comb ct name args) = Comb ct name (map (rnmAllVars f) args) rnmAllVars f (Free vs e) = Free (map f vs) (rnmAllVars f e) rnmAllVars f (Or e1 e2) = Or (rnmAllVars f e1) (rnmAllVars f e2) rnmAllVars f (Case ct e bs) = Case ct (rnmAllVars f e) (map (rnmAllVarsBranch f) bs) rnmAllVars f (Let bs e) = Let (map (\ (n,e') -> (f n,rnmAllVars f e')) bs) (rnmAllVars f e) --- get all variables (even in patterns) in expression allVars :: Expr -> [Int] allVars (Var n) = [n] allVars (Lit _) = [] allVars (Comb _ _ args) = concatMap allVars args allVars (Free vs e) = vs ++ allVars e allVars (Or e1 e2) = allVars e1 ++ allVars e2 allVars (Case _ e bs) = allVars e ++ concatMap allVarsBranch bs allVars (Let bs e) = concatMap (\ (n,e') -> n:allVars e') bs ++ allVars e --- map all variables in given expression mapVar :: (Expr -> Expr) -> Expr -> Expr mapVar f (Var n) = f (Var n) mapVar _ (Lit l) = Lit l mapVar f (Comb ct name args) = Comb ct name (map (mapVar f) args) mapVar f (Free vs e) = Free vs (mapVar f e) mapVar f (Or e1 e2) = Or (mapVar f e1) (mapVar f e2) mapVar f (Case ct e bs) = Case ct (mapVar f e) (map (updBranchExpr (mapVar f)) bs) mapVar f (Let bs e) = Let (map (\ (n,e') -> (n,mapVar f e')) bs) (mapVar f e) --- map all literals in given expression mapLit :: (Expr -> Expr) -> Expr -> Expr mapLit _ (Var n) = Var n mapLit f (Lit l) = f (Lit l) mapLit f (Comb ct name args) = Comb ct name (map (mapLit f) args) mapLit f (Free vs e) = Free vs (mapLit f e) mapLit f (Or e1 e2) = Or (mapLit f e1) (mapLit f e2) mapLit f (Case ct e bs) = Case ct (mapLit f e) (map (updBranchExpr (mapLit f)) bs) mapLit f (Let bs e) = Let (map (\ (n,e') -> (n,mapLit f e')) bs) (mapLit f e) --- map all combined expressions in given expression mapComb :: (Expr -> Expr) -> Expr -> Expr mapComb _ (Var n) = Var n mapComb _ (Lit l) = Lit l mapComb f (Comb ct name args) = f (Comb ct name (map (mapComb f) args)) mapComb f (Free vs e) = Free vs (mapComb f e) mapComb f (Or e1 e2) = Or (mapComb f e1) (mapComb f e2) mapComb f (Case ct e bs) = Case ct (mapComb f e) (map (updBranchExpr (mapComb f)) bs) mapComb f (Let bs e) = Let (map (\ (n,e') -> (n,mapComb f e')) bs) (mapComb f e) --- map all free declarations in given expression mapFree :: (Expr -> Expr) -> Expr -> Expr mapFree _ (Var n) = Var n mapFree _ (Lit l) = Lit l mapFree f (Comb ct name args) = Comb ct name (map (mapFree f) args) mapFree f (Free vs e) = f (Free vs (mapFree f e)) mapFree f (Or e1 e2) = Or (mapFree f e1) (mapFree f e2) mapFree f (Case ct e bs) = Case ct (mapFree f e) (map (updBranchExpr (mapFree f)) bs) mapFree f (Let bs e) = Let (map (\ (n,e') -> (n,mapFree f e')) bs) (mapFree f e) --- map all or expressions in given expression mapOr :: (Expr -> Expr) -> Expr -> Expr mapOr _ (Var n) = Var n mapOr _ (Lit l) = Lit l mapOr f (Comb ct name args) = Comb ct name (map (mapOr f) args) mapOr f (Free vs e) = Free vs (mapOr f e) mapOr f (Or e1 e2) = f (Or (mapOr f e1) (mapOr f e2)) mapOr f (Case ct e bs) = Case ct (mapOr f e) (map (updBranchExpr (mapOr f)) bs) mapOr f (Let bs e) = Let (map (\ (n,e') -> (n,mapOr f e')) bs) (mapOr f e) --- map all case expressions in given expression mapCase :: (Expr -> Expr) -> Expr -> Expr mapCase _ (Var n) = Var n mapCase _ (Lit l) = Lit l mapCase f (Comb ct name args) = Comb ct name (map (mapCase f) args) mapCase f (Free vs e) = Free vs (mapCase f e) mapCase f (Or e1 e2) = Or (mapCase f e1) (mapCase f e2) mapCase f (Case ct e bs) = f (Case ct (mapCase f e) (map (updBranchExpr (mapCase f)) bs)) mapCase f (Let bs e) = Let (map (\ (n,e') -> (n,mapCase f e')) bs) (mapCase f e) --- map all let expressions in given expression mapLet :: (Expr -> Expr) -> Expr -> Expr mapLet _ (Var n) = Var n mapLet _ (Lit l) = Lit l mapLet f (Comb ct name args) = Comb ct name (map (mapLet f) args) mapLet f (Free vs e) = Free vs (mapLet f e) mapLet f (Or e1 e2) = Or (mapLet f e1) (mapLet f e2) mapLet f (Case ct e bs) = Case ct (mapLet f e) (map (updBranchExpr (mapLet f)) bs) mapLet f (Let bs e) = f (Let (map (\ (n,e') -> (n,mapLet f e')) bs) (mapLet f e)) --- update all qualified names in expression updQNames :: (QName -> QName) -> Expr -> Expr updQNames f = mapComb (\ (Comb ct name args) -> Comb ct (f name) args) . mapCase (\ (Case ct e bs) -> Case ct e (map (updBranchPattern (updPatCons f)) bs)) -- CombType ------------------------------------------------------------------ --- is combination type FuncCall? isCombFuncCall :: CombType -> Bool isCombFuncCall ct = case ct of FuncCall -> True _ -> False --- is combination type PartCall? isCombPartCall :: CombType -> Bool isCombPartCall ct = case ct of FuncPartCall _ -> True ConsPartCall _ -> True _ -> False --- is combination type ConsCall? isCombConsCall :: CombType -> Bool isCombConsCall ct = case ct of ConsCall -> True _ -> False --- get number of missing args from combination type missingArgs :: CombType -> Int missingArgs FuncCall = 0 missingArgs (FuncPartCall n) = n missingArgs (ConsPartCall n) = n missingArgs ConsCall = 0 -- ConsCalls need not be fully applied (?) -- BranchExpr ---------------------------------------------------------------- updBranch fp fe (Branch pat exp) = Branch (fp pat) (fe exp) --- get pattern from branch expression branchPattern :: BranchExpr -> Pattern branchPattern (Branch pat _) = pat --- update pattern of branch expression updBranchPattern :: (Pattern -> Pattern) -> BranchExpr -> BranchExpr updBranchPattern f = updBranch f id --- get expression from branch expression branchExpr :: BranchExpr -> Expr branchExpr (Branch _ e) = e --- update expression of branch expression updBranchExpr :: (Expr -> Expr) -> BranchExpr -> BranchExpr updBranchExpr f = updBranch id f --- is pattern a constructor pattern? isConsPattern :: Pattern -> Bool isConsPattern (Pattern _ _) = True isConsPattern (LPattern _) = False updPattern fn fa _ (Pattern name args) = Pattern (fn name) (fa args) updPattern _ _ f (LPattern l) = LPattern (f l) --- get name if pattern is a constructor pattern patCons :: Pattern -> Maybe QName patCons (Pattern name _) = Just name patCons (LPattern _) = Nothing --- update constructors name of pattern updPatCons :: (QName -> QName) -> Pattern -> Pattern updPatCons f = updPattern f id id --- get arguments if pattern is a constructor pattern patArgs :: Pattern -> Maybe [Int] patArgs (Pattern _ args) = Just args patArgs (LPattern _) = Nothing updPatArgs :: ([Int] -> [Int]) -> Pattern -> Pattern updPatArgs f = updPattern id f id --- get literal if pattern is a literal pattern patLiteral :: Pattern -> Maybe Literal patLiteral (Pattern _ _) = Nothing patLiteral (LPattern l) = Just l --- update literal of pattern updPatLiteral :: (Literal -> Literal) -> Pattern -> Pattern updPatLiteral f = updPattern id id f --- build expression from pattern patExpr :: Pattern -> Expr patExpr (Pattern name args) = Comb ConsCall name (map Var args) patExpr (LPattern l) = Lit l -- auxiliary functions ------------------------------------------------------- --- rename all variables in branch expression rnmAllVarsBranch :: (Int -> Int) -> BranchExpr -> BranchExpr rnmAllVarsBranch f (Branch pat e) = Branch (rnmAllVarsPat f pat) (rnmAllVars f e) --- flatten all variables in branch expression allVarsBranch :: BranchExpr -> [Int] allVarsBranch (Branch pat e) = allVarsPat pat ++ allVars e --- rename variables in pattern rnmAllVarsPat :: (Int -> Int) -> Pattern -> Pattern rnmAllVarsPat f (Pattern name args) = Pattern name (map f args) rnmAllVarsPat _ (LPattern l) = LPattern l --- flatten pattern variables allVarsPat :: Pattern -> [Int] allVarsPat = maybe [] id . patArgs -- opDecls ------------------------------ opName (Op name _ _) = name