feldspar-compiler-0.7: lib/Feldspar/Transformation/Framework.hs
--
-- Copyright (c) 2009-2011, 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 RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Feldspar.Transformation.Framework where
import Feldspar.Compiler.Error
transformationError :: String -> a
transformationError = handleError "PluginArch/TransformationFramework" InternalError
-- ===========
-- == Utils ==
-- ===========
class Default t where
def :: t
def = transformationError "Default value requested."
class Combine t where
combine :: t -> t -> t
combine = transformationError "Default combination function used."
instance Default () where
def = ()
instance Default [a] where
def = []
instance Default Int where
def = 0
instance (Default a, Default b) => Default (a,b) where
def = (def, def)
instance (Default a, Default b, Default c) => Default (a,b,c) where
def = (def, def, def)
instance Combine () where
combine _ _ = ()
instance Combine String where
combine s1 s2 = s1 ++ s2
instance Combine Int where
combine i1 i2 = i1 + i2
instance (Combine a, Combine b)
=> Combine (a,b) where
combine (x,y) (v,w) = (combine x v, combine y w)
-- =============================
-- == TransformationFramework ==
-- =============================
class (Default (Up t), Combine (Up t))
=> Transformation t where
type From t
type To t
type State t
type Down t
type Up t
data Result t s
= Result
{ result :: s (To t)
, state :: State t
, up :: Up t
}
deriving instance (Transformation t, Show (s (To t)), Show (State t), Show (Up t)) => Show (Result t s)
data Result1 t s a
= Result1
{ result1 :: s (a (To t))
, state1 :: State t
, up1 :: Up t
}
deriving instance (Transformation t, Show (s (b (To t))), Show (State t), Show (Up t)) => Show (Result1 t s b)
-- The following classes used to have `Transformation t` as super-class, but
-- this resulted in looping dictionaries (at run time) after switching to
-- GHC-7.4. This may or may not be related to the following (unconfirmed) bug:
--
-- http://hackage.haskell.org/trac/ghc/ticket/5913
--
-- The constraint `Transformation t` has currently been moved to the relevant
-- instances.
class Transformable t s where
transform :: t -> State t -> Down t -> s (From t) -> Result t s
class Transformable1 t s a where
transform1 :: t -> State t -> Down t -> s (a (From t)) -> Result1 t s a
class DefaultTransformable t s where
defaultTransform :: t -> State t -> Down t -> s (From t) -> Result t s
class DefaultTransformable1 t s a where
defaultTransform1 :: t -> State t -> Down t -> s (a (From t)) -> Result1 t s a
instance (DefaultTransformable t s)
=> Transformable t s where
transform = defaultTransform
instance (DefaultTransformable1 t s a)
=> Transformable1 t s a where
transform1 = defaultTransform1