{-# LANGUAGE EmptyDataDecls, TypeFamilies #-}

module Feldspar.Compiler.Backend.C.Plugin.BlockProgramHandler where

import Data.List
import Feldspar.Transformation
import Feldspar.Compiler.Backend.C.CodeGeneration
import Feldspar.Compiler.Backend.C.Options
import Feldspar.Compiler.Error

-- ===========================================================================
--  == Type definition generator plugin
-- ===========================================================================

data BlockProgramHandler = BlockProgramHandler

instance Default [Declaration ()] where
    def = []

instance Combine [Declaration ()] where
    combine a b = a ++ b

instance Transformation BlockProgramHandler where
    type From BlockProgramHandler = ()
    type To BlockProgramHandler = ()
    type Down BlockProgramHandler = ()
    type Up BlockProgramHandler = [Declaration ()]
    type State BlockProgramHandler = ()

instance Transformable BlockProgramHandler Block where
        transform t s d b = tr
            { result = (result tr)
                { locals = (locals $ result tr) ++ up tr
                }
            , up = ([])
            }
            where
                tr = defaultTransform t s d b

instance Transformable BlockProgramHandler Program where
        transform t s d p =
            case result tr of
                BlockProgram b _ -> Result (blockBody b) () (locals b ++ up tr)
                _ -> tr
            where
                    tr = defaultTransform t s d p


instance Plugin BlockProgramHandler where
    type ExternalInfo BlockProgramHandler = ()
    executePlugin BlockProgramHandler externalInfo procedure = 
        result $ transform BlockProgramHandler ({-state-}) () procedure