{- - Copyright (c) 2009-2010, ERICSSON AB All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of the ERICSSON AB nor the names of its - contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -} {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-} module Feldspar.Compiler.Transformation.GraphUtils ( tupleWalk , tupleZip , tupleZipList , replaceVars ) where import Feldspar.Core.Graph import Feldspar.Core.Types import Data.List -- replaceVars [(var,fun)] ndhier ---- replace the variable (or the variables of the same node ----- if the list part is empty) according to the "fun" class RepVars a where replaceVars:: [(Variable, Variable -> Variable)] -> a -> a instance RepVars (Node, [Hierarchy]) where replaceVars chLs (node, hs) = (replaceVars chLs node, map (replaceVars chLs) hs) instance RepVars Hierarchy where replaceVars chLs (Hierarchy ndHrs) = Hierarchy (map (replaceVars chLs) ndHrs) instance RepVars Node where replaceVars chLs (node@(Node {input = nInp, function = nFunc})) = node{input= replaceVars chLs nInp, function = replaceVars chLs nFunc} instance RepVars (Tuple Source) where replaceVars chLs (One (Constant x)) = One (Constant x) replaceVars chLs (One (Variable x)) = One (Variable (replaceVars chLs x)) replaceVars chLs (Tup tls) = Tup (map (replaceVars chLs) tls) instance RepVars Variable where replaceVars chLs (nId, ls) = case find (\((v,_),_) -> v == nId) chLs of Nothing -> (nId, ls) Just ((v,vls),tr) -> case vls of [] -> tr (nId, ls) _ -> if (vls == ls) then (tr (nId,ls)) else (nId,ls) instance RepVars Function where replaceVars chLs (NoInline str ifc) = (NoInline str (replaceVars chLs ifc)) replaceVars chLs (Parallel ifc) = (Parallel (replaceVars chLs ifc)) replaceVars chLs (IfThenElse ifc1 ifc2) = (IfThenElse (replaceVars chLs ifc1) (replaceVars chLs ifc2)) replaceVars chLs (While ifc1 ifc2) = (While (replaceVars chLs ifc1) (replaceVars chLs ifc2)) replaceVars chLs fun = fun instance RepVars Interface where replaceVars chLs ifc@ (Interface {interfaceOutput = ifOut}) = ifc{interfaceOutput = replaceVars chLs ifOut} -- The 'tupleWalk' function walks through a tuple, applies the given -- function to every leaf (while provides information about the place of -- the leaf) and puts the results in a list. tupleWalk :: ([Int] -> a -> b) -> Tuple a -> [b] tupleWalk = tupleWalk' [] where tupleWalk' :: [Int] -> ([Int] -> a -> b) -> Tuple a -> [b] tupleWalk' p f (One x) = [f p x] tupleWalk' p f (Tup xs) = concatMap ff $ zip xs [0..] where ff (x,idx) = tupleWalk' (p ++ [idx]) f x -- Zips to tuples of the same structure. tupleZip :: (Tuple a, Tuple b) -> Tuple (a,b) tupleZip (One x, One y) = One (x,y) tupleZip (Tup xs, Tup ys) = Tup (map tupleZip $ zip xs ys) tupleZip _ = error "Error: Tuples with different structure are zipped." -- Zips the "leafs" to list of tuples. tupleZipList :: (Tuple a, Tuple b) -> [(a,b)] tupleZipList (One x, One y) = [(x,y)] tupleZipList (Tup xs, Tup ys) = concatMap tupleZipList $ zip xs ys tupleZipList _ = error "Error: Tuples with different structure are zipped."