{- | Module : ./CSL/Fold.hs Description : folding functions for CSL terms and commands Copyright : (c) Ewaryst.Schulz, DFKI 2010 License : GPLv2 or higher, see LICENSE.txt Maintainer : Ewaryst.Schulz@dfki.de Stability : provisional Portability : portable folding functions for CSL terms and commands -} module CSL.Fold where import Common.Id import CSL.AS_BASIC_CSL (EXPRESSION (..), CMD (..), OpDecl, EXTPARAM , APInt, APFloat, OPID) data Record a b = Record { Record a b -> CMD -> OpDecl -> b -> a foldAss :: CMD -> OpDecl -> b -> a , Record a b -> CMD -> String -> [b] -> a foldCmd :: CMD -> String -> [b] -> a , Record a b -> CMD -> [a] -> a foldSequence :: CMD -> [a] -> a , Record a b -> CMD -> [(b, [a])] -> a foldCond :: CMD -> [(b, [a])] -> a , Record a b -> CMD -> b -> [a] -> a foldRepeat :: CMD -> b -> [a] -> a , Record a b -> EXPRESSION -> Token -> b foldVar :: EXPRESSION -> Token -> b , Record a b -> EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b foldOp :: EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b , Record a b -> EXPRESSION -> [b] -> Range -> b foldList :: EXPRESSION -> [b] -> Range -> b , Record a b -> EXPRESSION -> Double -> Double -> Range -> b foldInterval :: EXPRESSION -> Double -> Double -> Range -> b , Record a b -> EXPRESSION -> APInt -> Range -> b foldInt :: EXPRESSION -> APInt -> Range -> b , Record a b -> EXPRESSION -> APFloat -> Range -> b foldRat :: EXPRESSION -> APFloat -> Range -> b } {- | Produces an error with given message on all entries. Use this if you overwrite only the EXPRESSION part and you do not use the CMD part anyway , e.g., if you use the record in foldTerm -} emptyRecord :: String -> Record a b emptyRecord :: String -> Record a b emptyRecord s :: String s = Record :: forall a b. (CMD -> OpDecl -> b -> a) -> (CMD -> String -> [b] -> a) -> (CMD -> [a] -> a) -> (CMD -> [(b, [a])] -> a) -> (CMD -> b -> [a] -> a) -> (EXPRESSION -> Token -> b) -> (EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b) -> (EXPRESSION -> [b] -> Range -> b) -> (EXPRESSION -> Double -> Double -> Range -> b) -> (EXPRESSION -> APInt -> Range -> b) -> (EXPRESSION -> APFloat -> Range -> b) -> Record a b Record { foldAss :: CMD -> OpDecl -> b -> a foldAss = String -> CMD -> OpDecl -> b -> a forall a. HasCallStack => String -> a error String s , foldCmd :: CMD -> String -> [b] -> a foldCmd = String -> CMD -> String -> [b] -> a forall a. HasCallStack => String -> a error String s , foldSequence :: CMD -> [a] -> a foldSequence = String -> CMD -> [a] -> a forall a. HasCallStack => String -> a error String s , foldCond :: CMD -> [(b, [a])] -> a foldCond = String -> CMD -> [(b, [a])] -> a forall a. HasCallStack => String -> a error String s , foldRepeat :: CMD -> b -> [a] -> a foldRepeat = String -> CMD -> b -> [a] -> a forall a. HasCallStack => String -> a error String s , foldVar :: EXPRESSION -> Token -> b foldVar = String -> EXPRESSION -> Token -> b forall a. HasCallStack => String -> a error String s , foldOp :: EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b foldOp = String -> EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b forall a. HasCallStack => String -> a error String s , foldList :: EXPRESSION -> [b] -> Range -> b foldList = String -> EXPRESSION -> [b] -> Range -> b forall a. HasCallStack => String -> a error String s , foldInterval :: EXPRESSION -> Double -> Double -> Range -> b foldInterval = String -> EXPRESSION -> Double -> Double -> Range -> b forall a. HasCallStack => String -> a error String s , foldInt :: EXPRESSION -> APInt -> Range -> b foldInt = String -> EXPRESSION -> APInt -> Range -> b forall a. HasCallStack => String -> a error String s , foldRat :: EXPRESSION -> APFloat -> Range -> b foldRat = String -> EXPRESSION -> APFloat -> Range -> b forall a. HasCallStack => String -> a error String s } -- | The identity transformation idRecord :: Record CMD EXPRESSION idRecord :: Record CMD EXPRESSION idRecord = Record :: forall a b. (CMD -> OpDecl -> b -> a) -> (CMD -> String -> [b] -> a) -> (CMD -> [a] -> a) -> (CMD -> [(b, [a])] -> a) -> (CMD -> b -> [a] -> a) -> (EXPRESSION -> Token -> b) -> (EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b) -> (EXPRESSION -> [b] -> Range -> b) -> (EXPRESSION -> Double -> Double -> Range -> b) -> (EXPRESSION -> APInt -> Range -> b) -> (EXPRESSION -> APFloat -> Range -> b) -> Record a b Record { foldAss :: CMD -> OpDecl -> EXPRESSION -> CMD foldAss = \ v :: CMD v _ _ -> CMD v , foldCmd :: CMD -> String -> [EXPRESSION] -> CMD foldCmd = \ v :: CMD v _ _ -> CMD v , foldSequence :: CMD -> [CMD] -> CMD foldSequence = CMD -> [CMD] -> CMD forall a b. a -> b -> a const , foldCond :: CMD -> [(EXPRESSION, [CMD])] -> CMD foldCond = CMD -> [(EXPRESSION, [CMD])] -> CMD forall a b. a -> b -> a const , foldRepeat :: CMD -> EXPRESSION -> [CMD] -> CMD foldRepeat = \ v :: CMD v _ _ -> CMD v , foldVar :: EXPRESSION -> Token -> EXPRESSION foldVar = EXPRESSION -> Token -> EXPRESSION forall a b. a -> b -> a const , foldOp :: EXPRESSION -> OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION foldOp = \ v :: EXPRESSION v _ _ _ _ -> EXPRESSION v , foldList :: EXPRESSION -> [EXPRESSION] -> Range -> EXPRESSION foldList = \ v :: EXPRESSION v _ _ -> EXPRESSION v , foldInterval :: EXPRESSION -> Double -> Double -> Range -> EXPRESSION foldInterval = \ v :: EXPRESSION v _ _ _ -> EXPRESSION v , foldInt :: EXPRESSION -> APInt -> Range -> EXPRESSION foldInt = \ v :: EXPRESSION v _ _ -> EXPRESSION v , foldRat :: EXPRESSION -> APFloat -> Range -> EXPRESSION foldRat = \ v :: EXPRESSION v _ _ -> EXPRESSION v } {- | Passes the transformation through the CMD part and is the identity on the EXPRESSION part -} passRecord :: Record CMD EXPRESSION passRecord :: Record CMD EXPRESSION passRecord = Record CMD EXPRESSION idRecord { foldAss :: CMD -> OpDecl -> EXPRESSION -> CMD foldAss = (OpDecl -> EXPRESSION -> CMD) -> CMD -> OpDecl -> EXPRESSION -> CMD forall a b. a -> b -> a const OpDecl -> EXPRESSION -> CMD Ass , foldCmd :: CMD -> String -> [EXPRESSION] -> CMD foldCmd = (String -> [EXPRESSION] -> CMD) -> CMD -> String -> [EXPRESSION] -> CMD forall a b. a -> b -> a const String -> [EXPRESSION] -> CMD Cmd , foldSequence :: CMD -> [CMD] -> CMD foldSequence = ([CMD] -> CMD) -> CMD -> [CMD] -> CMD forall a b. a -> b -> a const [CMD] -> CMD Sequence , foldCond :: CMD -> [(EXPRESSION, [CMD])] -> CMD foldCond = ([(EXPRESSION, [CMD])] -> CMD) -> CMD -> [(EXPRESSION, [CMD])] -> CMD forall a b. a -> b -> a const [(EXPRESSION, [CMD])] -> CMD Cond , foldRepeat :: CMD -> EXPRESSION -> [CMD] -> CMD foldRepeat = (EXPRESSION -> [CMD] -> CMD) -> CMD -> EXPRESSION -> [CMD] -> CMD forall a b. a -> b -> a const EXPRESSION -> [CMD] -> CMD Repeat } -- | Passes the transformation through both, the CMD and the EXPRESSION part passAllRecord :: Record CMD EXPRESSION passAllRecord :: Record CMD EXPRESSION passAllRecord = Record CMD EXPRESSION passRecord { foldVar :: EXPRESSION -> Token -> EXPRESSION foldVar = (Token -> EXPRESSION) -> EXPRESSION -> Token -> EXPRESSION forall a b. a -> b -> a const Token -> EXPRESSION Var , foldOp :: EXPRESSION -> OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION foldOp = (OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION) -> EXPRESSION -> OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION forall a b. a -> b -> a const OPID -> [EXTPARAM] -> [EXPRESSION] -> Range -> EXPRESSION Op , foldList :: EXPRESSION -> [EXPRESSION] -> Range -> EXPRESSION foldList = ([EXPRESSION] -> Range -> EXPRESSION) -> EXPRESSION -> [EXPRESSION] -> Range -> EXPRESSION forall a b. a -> b -> a const [EXPRESSION] -> Range -> EXPRESSION List , foldInterval :: EXPRESSION -> Double -> Double -> Range -> EXPRESSION foldInterval = (Double -> Double -> Range -> EXPRESSION) -> EXPRESSION -> Double -> Double -> Range -> EXPRESSION forall a b. a -> b -> a const Double -> Double -> Range -> EXPRESSION Interval , foldInt :: EXPRESSION -> APInt -> Range -> EXPRESSION foldInt = (APInt -> Range -> EXPRESSION) -> EXPRESSION -> APInt -> Range -> EXPRESSION forall a b. a -> b -> a const APInt -> Range -> EXPRESSION Int , foldRat :: EXPRESSION -> APFloat -> Range -> EXPRESSION foldRat = (APFloat -> Range -> EXPRESSION) -> EXPRESSION -> APFloat -> Range -> EXPRESSION forall a b. a -> b -> a const APFloat -> Range -> EXPRESSION Rat } {- | Passes the transformation through the 'CMD' part by concatenating the processed list from left to right and identity on expression part -} listCMDRecord :: Record [a] EXPRESSION listCMDRecord :: Record [a] EXPRESSION listCMDRecord = Record CMD EXPRESSION idRecord { foldAss :: CMD -> OpDecl -> EXPRESSION -> [a] foldAss = \ _ _ _ -> [] , foldCmd :: CMD -> String -> [EXPRESSION] -> [a] foldCmd = \ _ _ _ -> [] , foldSequence :: CMD -> [[a]] -> [a] foldSequence = ([[a]] -> [a]) -> CMD -> [[a]] -> [a] forall a b. a -> b -> a const [[a]] -> [a] forall (t :: * -> *) a. Foldable t => t [a] -> [a] concat , foldCond :: CMD -> [(EXPRESSION, [[a]])] -> [a] foldCond = \ _ -> [[a]] -> [a] forall (t :: * -> *) a. Foldable t => t [a] -> [a] concat ([[a]] -> [a]) -> ([(EXPRESSION, [[a]])] -> [[a]]) -> [(EXPRESSION, [[a]])] -> [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . ((EXPRESSION, [[a]]) -> [[a]]) -> [(EXPRESSION, [[a]])] -> [[a]] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (EXPRESSION, [[a]]) -> [[a]] forall a b. (a, b) -> b snd , foldRepeat :: CMD -> EXPRESSION -> [[a]] -> [a] foldRepeat = \ _ _ -> [[a]] -> [a] forall (t :: * -> *) a. Foldable t => t [a] -> [a] concat } {- | Returns the first constant on the CMD part and the second on the EXPRESSION part -} constRecord :: a -> b -> Record a b constRecord :: a -> b -> Record a b constRecord a :: a a b :: b b = Record :: forall a b. (CMD -> OpDecl -> b -> a) -> (CMD -> String -> [b] -> a) -> (CMD -> [a] -> a) -> (CMD -> [(b, [a])] -> a) -> (CMD -> b -> [a] -> a) -> (EXPRESSION -> Token -> b) -> (EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b) -> (EXPRESSION -> [b] -> Range -> b) -> (EXPRESSION -> Double -> Double -> Range -> b) -> (EXPRESSION -> APInt -> Range -> b) -> (EXPRESSION -> APFloat -> Range -> b) -> Record a b Record { foldAss :: CMD -> OpDecl -> b -> a foldAss = \ _ _ _ -> a a , foldCmd :: CMD -> String -> [b] -> a foldCmd = \ _ _ _ -> a a , foldSequence :: CMD -> [a] -> a foldSequence = \ _ _ -> a a , foldCond :: CMD -> [(b, [a])] -> a foldCond = \ _ _ -> a a , foldRepeat :: CMD -> b -> [a] -> a foldRepeat = \ _ _ _ -> a a , foldVar :: EXPRESSION -> Token -> b foldVar = \ _ _ -> b b , foldOp :: EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b foldOp = \ _ _ _ _ _ -> b b , foldList :: EXPRESSION -> [b] -> Range -> b foldList = \ _ _ _ -> b b , foldInterval :: EXPRESSION -> Double -> Double -> Range -> b foldInterval = \ _ _ _ _ -> b b , foldInt :: EXPRESSION -> APInt -> Range -> b foldInt = \ _ _ _ -> b b , foldRat :: EXPRESSION -> APFloat -> Range -> b foldRat = \ _ _ _ -> b b } foldCMD :: Record a b -> CMD -> a foldCMD :: Record a b -> CMD -> a foldCMD r :: Record a b r f :: CMD f = case CMD f of Ass c :: OpDecl c def :: EXPRESSION def -> Record a b -> CMD -> OpDecl -> b -> a forall a b. Record a b -> CMD -> OpDecl -> b -> a foldAss Record a b r CMD f OpDecl c (b -> a) -> b -> a forall a b. (a -> b) -> a -> b $ Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r EXPRESSION def Cmd s :: String s l :: [EXPRESSION] l -> Record a b -> CMD -> String -> [b] -> a forall a b. Record a b -> CMD -> String -> [b] -> a foldCmd Record a b r CMD f String s ([b] -> a) -> [b] -> a forall a b. (a -> b) -> a -> b $ (EXPRESSION -> b) -> [EXPRESSION] -> [b] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r) [EXPRESSION] l Sequence l :: [CMD] l -> Record a b -> CMD -> [a] -> a forall a b. Record a b -> CMD -> [a] -> a foldSequence Record a b r CMD f ([a] -> a) -> [a] -> a forall a b. (a -> b) -> a -> b $ (CMD -> a) -> [CMD] -> [a] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> CMD -> a forall a b. Record a b -> CMD -> a foldCMD Record a b r) [CMD] l Cond l :: [(EXPRESSION, [CMD])] l -> Record a b -> CMD -> [(b, [a])] -> a forall a b. Record a b -> CMD -> [(b, [a])] -> a foldCond Record a b r CMD f ([(b, [a])] -> a) -> [(b, [a])] -> a forall a b. (a -> b) -> a -> b $ ((EXPRESSION, [CMD]) -> (b, [a])) -> [(EXPRESSION, [CMD])] -> [(b, [a])] forall a b. (a -> b) -> [a] -> [b] map (EXPRESSION, [CMD]) -> (b, [a]) cf [(EXPRESSION, [CMD])] l where cf :: (EXPRESSION, [CMD]) -> (b, [a]) cf (x :: EXPRESSION x, y :: [CMD] y) = (Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r EXPRESSION x, (CMD -> a) -> [CMD] -> [a] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> CMD -> a forall a b. Record a b -> CMD -> a foldCMD Record a b r) [CMD] y) Repeat c :: EXPRESSION c l :: [CMD] l -> Record a b -> CMD -> b -> [a] -> a forall a b. Record a b -> CMD -> b -> [a] -> a foldRepeat Record a b r CMD f (Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r EXPRESSION c) ([a] -> a) -> [a] -> a forall a b. (a -> b) -> a -> b $ (CMD -> a) -> [CMD] -> [a] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> CMD -> a forall a b. Record a b -> CMD -> a foldCMD Record a b r) [CMD] l foldTerm :: Record a b -> EXPRESSION -> b foldTerm :: Record a b -> EXPRESSION -> b foldTerm r :: Record a b r t :: EXPRESSION t = case EXPRESSION t of Var tok :: Token tok -> Record a b -> EXPRESSION -> Token -> b forall a b. Record a b -> EXPRESSION -> Token -> b foldVar Record a b r EXPRESSION t Token tok Op s :: OPID s epl :: [EXTPARAM] epl al :: [EXPRESSION] al rg :: Range rg -> Record a b -> EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b forall a b. Record a b -> EXPRESSION -> OPID -> [EXTPARAM] -> [b] -> Range -> b foldOp Record a b r EXPRESSION t OPID s [EXTPARAM] epl ((EXPRESSION -> b) -> [EXPRESSION] -> [b] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r) [EXPRESSION] al) Range rg List l :: [EXPRESSION] l rg :: Range rg -> Record a b -> EXPRESSION -> [b] -> Range -> b forall a b. Record a b -> EXPRESSION -> [b] -> Range -> b foldList Record a b r EXPRESSION t ((EXPRESSION -> b) -> [EXPRESSION] -> [b] forall a b. (a -> b) -> [a] -> [b] map (Record a b -> EXPRESSION -> b forall a b. Record a b -> EXPRESSION -> b foldTerm Record a b r) [EXPRESSION] l) Range rg Interval from :: Double from to :: Double to rg :: Range rg -> Record a b -> EXPRESSION -> Double -> Double -> Range -> b forall a b. Record a b -> EXPRESSION -> Double -> Double -> Range -> b foldInterval Record a b r EXPRESSION t Double from Double to Range rg Int i :: APInt i rg :: Range rg -> Record a b -> EXPRESSION -> APInt -> Range -> b forall a b. Record a b -> EXPRESSION -> APInt -> Range -> b foldInt Record a b r EXPRESSION t APInt i Range rg Rat f :: APFloat f rg :: Range rg -> Record a b -> EXPRESSION -> APFloat -> Range -> b forall a b. Record a b -> EXPRESSION -> APFloat -> Range -> b foldRat Record a b r EXPRESSION t APFloat f Range rg