{- - 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 TypeFamilies, FlexibleContexts, Rank2Types #-} module Feldspar.Compiler.PluginArchitecture ( module Feldspar.Compiler.PluginArchitecture, module Feldspar.Compiler.Imperative.Representation, module Feldspar.Compiler.Imperative.Semantics, module Feldspar.Compiler.PluginArchitecture.DefaultConvert ) where import Feldspar.Compiler.Imperative.Representation import Feldspar.Compiler.Imperative.Semantics import Feldspar.Compiler.PluginArchitecture.DefaultConvert -- ================================================================================================================================== -- == Plugin class -- ================================================================================================================================== type Walker t construction = (TransformationPhase t) => t -> Downwards t -> construction (From t) -> (construction (To t), Upwards t) class (TransformationPhase t) => Plugin t where type ExternalInfo t executePlugin :: t -> ExternalInfo t -> Procedure (From t) -> Procedure (To t) class (SemanticInfo (From t), SemanticInfo (To t) , ConvertAllInfos (From t) (To t) , Combine (Upwards t), Default (Upwards t)) => TransformationPhase t where type From t type To t type Downwards t type Upwards t executeTransformationPhase :: Walker t Procedure executeTransformationPhase = walkProcedure -- ================================================================================================================================== -- == Node Transformers specification -- ================================================================================================================================== downwardsProcedure :: t -> Downwards t -> Procedure (From t) -> Downwards t transformProcedure :: t -> Downwards t -> Procedure (From t) -> InfosFromProcedureParts t -> Procedure (To t) upwardsProcedure :: t -> Downwards t -> Procedure (From t) -> InfosFromProcedureParts t -> Procedure (To t) -> Upwards t downwardsBlock :: t -> Downwards t -> Block (From t) -> Downwards t transformBlock :: t -> Downwards t -> Block (From t) -> InfosFromBlockParts t -> Block (To t) upwardsBlock :: t -> Downwards t -> Block (From t) -> InfosFromBlockParts t -> Block (To t) -> Upwards t downwardsProgram :: t -> Downwards t -> Program (From t) -> Downwards t transformProgram :: t -> Downwards t -> Program (From t) -> InfosFromProgramParts t -> Program (To t) upwardsProgram :: t -> Downwards t -> Program (From t) -> InfosFromProgramParts t -> Program (To t) -> Upwards t transformEmpty :: t -> Downwards t -> Empty (From t) -> ProgramConstruction (To t) upwardsEmpty :: t -> Downwards t -> Empty (From t) -> ProgramConstruction (To t) -> Upwards t downwardsPrimitive :: t -> Downwards t -> Primitive (From t) -> Downwards t transformPrimitive :: t -> Downwards t -> Primitive (From t) -> InfosFromPrimitiveParts t -> ProgramConstruction (To t) upwardsPrimitive :: t -> Downwards t -> Primitive (From t) -> InfosFromPrimitiveParts t -> ProgramConstruction (To t) -> Upwards t downwardsSequence :: t -> Downwards t -> Sequence (From t) -> Downwards t transformSequence :: t -> Downwards t -> Sequence (From t) -> InfosFromSequenceParts t -> ProgramConstruction (To t) upwardsSequence :: t -> Downwards t -> Sequence (From t) -> InfosFromSequenceParts t -> ProgramConstruction (To t) -> Upwards t downwardsBranch :: t -> Downwards t -> Branch (From t) -> Downwards t transformBranch :: t -> Downwards t -> Branch (From t) -> InfosFromBranchParts t -> ProgramConstruction (To t) upwardsBranch :: t -> Downwards t -> Branch (From t) -> InfosFromBranchParts t -> ProgramConstruction (To t) -> Upwards t downwardsSequentialLoop :: t -> Downwards t -> SequentialLoop (From t) -> Downwards t transformSequentialLoop :: t -> Downwards t -> SequentialLoop (From t) -> InfosFromSequentialLoopParts t -> ProgramConstruction (To t) upwardsSequentialLoop :: t -> Downwards t -> SequentialLoop (From t) -> InfosFromSequentialLoopParts t -> ProgramConstruction (To t) -> Upwards t downwardsParallelLoop :: t -> Downwards t -> ParallelLoop (From t) -> Downwards t transformParallelLoop :: t -> Downwards t -> ParallelLoop (From t) -> InfosFromParallelLoopParts t -> ProgramConstruction (To t) upwardsParallelLoop :: t -> Downwards t -> ParallelLoop (From t) -> InfosFromParallelLoopParts t -> ProgramConstruction (To t) -> Upwards t downwardsFormalParameter :: t -> Downwards t -> FormalParameter (From t) -> Downwards t transformFormalParameter :: t -> Downwards t -> FormalParameter (From t) -> InfosFromFormalParameterParts t -> FormalParameter (To t) upwardsFormalParameter :: t -> Downwards t -> FormalParameter (From t) -> InfosFromFormalParameterParts t -> FormalParameter (To t) -> Upwards t downwardsLocalDeclaration :: t -> Downwards t -> LocalDeclaration (From t) -> Downwards t transformLocalDeclaration :: t -> Downwards t -> LocalDeclaration (From t) -> InfosFromLocalDeclarationParts t -> LocalDeclaration (To t) upwardsLocalDeclaration :: t -> Downwards t -> LocalDeclaration (From t) -> InfosFromLocalDeclarationParts t -> LocalDeclaration (To t) -> Upwards t downwardsAssignment :: t -> Downwards t -> Assignment (From t) -> Downwards t transformAssignment :: t -> Downwards t -> Assignment (From t) -> InfosFromAssignmentParts t -> Instruction (To t) upwardsAssignment :: t -> Downwards t -> Assignment (From t) -> InfosFromAssignmentParts t -> Instruction (To t) -> Upwards t downwardsProcedureCall :: t -> Downwards t -> ProcedureCall (From t) -> Downwards t transformProcedureCall :: t -> Downwards t -> ProcedureCall (From t) -> InfosFromProcedureCallParts t -> Instruction (To t) upwardsProcedureCall :: t -> Downwards t -> ProcedureCall (From t) -> InfosFromProcedureCallParts t -> Instruction (To t) -> Upwards t downwardsInputActualParameter :: t -> Downwards t -> InputActualParameterType (From t) -> Downwards t transformInputActualParameter :: t -> Downwards t -> InputActualParameterType (From t) -> InfosFromInputActualParameterParts t -> ActualParameter (To t) upwardsInputActualParameter :: t -> Downwards t -> InputActualParameterType (From t) -> InfosFromInputActualParameterParts t -> ActualParameter (To t) -> Upwards t downwardsOutputActualParameter :: t -> Downwards t -> OutputActualParameterType (From t) -> Downwards t transformOutputActualParameter :: t -> Downwards t -> OutputActualParameterType (From t) -> InfosFromOutputActualParameterParts t -> ActualParameter (To t) upwardsOutputActualParameter :: t -> Downwards t -> OutputActualParameterType (From t) -> InfosFromOutputActualParameterParts t -> ActualParameter (To t) -> Upwards t downwardsVariableInLeftValue :: t -> Downwards t -> VariableInLeftValue (From t) -> Downwards t transformVariableInLeftValue :: t -> Downwards t -> VariableInLeftValue (From t) -> InfosFromVariableLeftValueParts t -> LeftValue (To t) upwardsVariableInLeftValue :: t -> Downwards t -> VariableInLeftValue (From t) -> InfosFromVariableLeftValueParts t -> LeftValue (To t) -> Upwards t downwardsArrayElemReference :: t -> Downwards t -> ArrayElemReference (From t) -> Downwards t transformArrayElemReference :: t -> Downwards t -> ArrayElemReference (From t) -> InfosFromArrayElemReferenceParts t -> LeftValue (To t) upwardsArrayElemReference :: t -> Downwards t -> ArrayElemReference (From t) -> InfosFromArrayElemReferenceParts t -> LeftValue (To t) -> Upwards t downwardsLeftValueExpression :: t -> Downwards t -> LeftValueInExpression (From t) -> Downwards t transformLeftValueExpression :: t -> Downwards t -> LeftValueInExpression (From t) -> InfosFromLeftValueExpressionParts t -> Expression (To t) upwardsLeftValueExpression :: t -> Downwards t -> LeftValueInExpression (From t) -> InfosFromLeftValueExpressionParts t -> Expression (To t) -> Upwards t downwardsFunctionCall :: t -> Downwards t -> FunctionCall (From t) -> Downwards t transformFunctionCall :: t -> Downwards t -> FunctionCall (From t) -> InfosFromFunctionCallParts t -> Expression (To t) upwardsFunctionCall :: t -> Downwards t -> FunctionCall (From t) -> InfosFromFunctionCallParts t -> Expression (To t) -> Upwards t transformIntConstant :: t -> Downwards t -> IntConstantType (From t) -> Constant (To t) upwardsIntConstant :: t -> Downwards t -> IntConstantType (From t) -> Constant (To t) -> Upwards t transformFloatConstant :: t -> Downwards t -> FloatConstantType (From t) -> Constant (To t) upwardsFloatConstant :: t -> Downwards t -> FloatConstantType (From t) -> Constant (To t) -> Upwards t transformBoolConstant :: t -> Downwards t -> BoolConstantType (From t) -> Constant (To t) upwardsBoolConstant :: t -> Downwards t -> BoolConstantType (From t) -> Constant (To t) -> Upwards t downwardsArrayConstant :: t -> Downwards t -> ArrayConstantType (From t) -> Downwards t transformArrayConstant :: t -> Downwards t -> ArrayConstantType (From t) -> InfosFromArrayConstantParts t -> Constant (To t) upwardsArrayConstant :: t -> Downwards t -> ArrayConstantType (From t) -> InfosFromArrayConstantParts t -> Constant (To t) -> Upwards t transformVariable :: t -> Downwards t -> Variable (From t) -> Variable (To t) upwardsVariable :: t -> Downwards t -> Variable (From t) -> Variable (To t) -> Upwards t -- ================================================================================================================================== -- == Node Transformer defaults -- ================================================================================================================================== downwardsProcedure self = const transformProcedure self fromAbove originalProcedure fromBelow = originalProcedure { inParameters = recursivelyTransformedInParameters fromBelow, outParameters = recursivelyTransformedOutParameters fromBelow, procedureBody = recursivelyTransformedProcedureBody fromBelow, procedureSemInf = convert $ procedureSemInf originalProcedure } upwardsProcedure self fromAbove originalProcedure fromBelow transformedProcedure = foldl combine (upwardsInfoFromProcedureBody fromBelow) ((upwardsInfoFromInParameters fromBelow)++(upwardsInfoFromOutParameters fromBelow)) downwardsBlock self = const transformBlock self fromAbove originalBlock fromBelow = Block { blockData = recursivelyTransformedBlockData fromBelow, blockSemInf = convert $ blockSemInf originalBlock } upwardsBlock self fromAbove originalBlock fromBelow transformedBlock = foldl combine (upwardsInfoFromBlockInstructions fromBelow) (upwardsInfoFromBlockDeclarations fromBelow) downwardsProgram self = const transformProgram self fromAbove originalProgram fromBelow = Program { programConstruction = recursivelyTransformedProgramConstruction fromBelow, programSemInf = convert $ programSemInf originalProgram } upwardsProgram self fromAbove originalProgram fromBelow transformedProgram = upwardsInfoFromProgramConstruction fromBelow transformEmpty self fromAbove originalEmpty = EmptyProgram $ Empty { emptySemInf = convert $ emptySemInf originalEmpty } upwardsEmpty self fromAbove originalEmpty transformedEmpty = defaultValue downwardsPrimitive self = const transformPrimitive self fromAbove originalPrimitive fromBelow = PrimitiveProgram $ Primitive { primitiveInstruction = recursivelyTransformedPrimitiveInstruction fromBelow, primitiveSemInf = convert $ primitiveSemInf originalPrimitive } upwardsPrimitive self fromAbove originalPrimitive fromBelow transformedPrimitive = upwardsInfoFromPrimitiveInstruction fromBelow downwardsSequence self = const transformSequence self fromAbove originalSequence fromBelow = SequenceProgram $ Sequence { sequenceProgramList = recursivelyTransformedSequenceProgramList fromBelow, sequenceSemInf = convert $ sequenceSemInf originalSequence } upwardsSequence self fromAbove originalSequence fromBelow transformedSequence = case ul of [] -> defaultValue otherwise -> foldl combine (head ul) (tail ul) where ul = upwardsInfoFromSequenceProgramList fromBelow downwardsBranch self = const transformBranch self fromAbove originalBranch fromBelow = BranchProgram $ Branch { branchData = recursivelyTransformedBranchData fromBelow, branchSemInf = convert $ branchSemInf originalBranch } upwardsBranch self fromAbove originalBranch fromBelow transformedBranch = foldl combine (upwardsInfoFromBranchConditionVariable fromBelow) [upwardsInfoFromThenBlock fromBelow, upwardsInfoFromElseBlock fromBelow] downwardsSequentialLoop self = const transformSequentialLoop self fromAbove originalSequentialLoop fromBelow = SequentialLoopProgram $ SequentialLoop { sequentialLoopData = recursivelyTransformedSequentialLoopData fromBelow, sequentialLoopSemInf = convert $ sequentialLoopSemInf originalSequentialLoop } upwardsSequentialLoop self fromAbove originalSequentialLoop fromBelow transformedSequentialLoop = foldl combine (upwardsInfoFromSequentialLoopConditionVariable fromBelow) [upwardsInfoFromSequentialLoopConditionCalculation fromBelow, upwardsInfoFromSequentialLoopCore fromBelow] downwardsParallelLoop self = const transformParallelLoop self fromAbove originalParallelLoop fromBelow = ParallelLoopProgram $ ParallelLoop { parallelLoopData = recursivelyTransformedParallelLoopData fromBelow, parallelLoopSemInf = convert $ parallelLoopSemInf originalParallelLoop } upwardsParallelLoop self fromAbove originalParallelLoop fromBelow transformedParallelLoop = foldl combine (upwardsInfoFromParallelLoopConditionVariable fromBelow) [upwardsInfoFromNumberOfIterations fromBelow, upwardsInfoFromParallelLoopCore fromBelow] downwardsFormalParameter self = const transformFormalParameter self fromAbove originalFormalParameter fromBelow = FormalParameter { formalParameterVariable = recursivelyTransformedFormalParameterVariable fromBelow, formalParameterSemInf = convert $ formalParameterSemInf originalFormalParameter } upwardsFormalParameter self fromAbove originalFormalParameter fromBelow transformedFormalParameter = upwardsInfoFromFormalParameterVariable fromBelow downwardsLocalDeclaration self = const transformLocalDeclaration self fromAbove originalLocalDeclaration fromBelow = LocalDeclaration { localDeclarationData = recursivelyTransformedLocalDeclarationData fromBelow, localDeclarationSemInf = convert $ localDeclarationSemInf originalLocalDeclaration } upwardsLocalDeclaration self fromAbove originalLocalDeclaration fromBelow transformedLocalDeclaration = case (upwardsInfoFromLocalInitValue fromBelow) of Nothing -> (upwardsInfoFromLocalVariable fromBelow) Just justUpFromLocalInitValue -> combine (upwardsInfoFromLocalVariable fromBelow) justUpFromLocalInitValue downwardsAssignment self = const transformAssignment self fromAbove originalAssignment fromBelow = AssignmentInstruction $ Assignment { assignmentData = recursivelyTransformedAssignmentData fromBelow, assignmentSemInf = convert $ assignmentSemInf originalAssignment } upwardsAssignment self fromAbove originalAssignment fromBelow transformedAssignment = combine (upwardsInfoFromAssignmentLhs fromBelow) (upwardsInfoFromAssignmentRhs fromBelow) downwardsProcedureCall self = const transformProcedureCall self fromAbove originalProcedureCall fromBelow = ProcedureCallInstruction $ ProcedureCall { procedureCallData = recursivelyTransformedProcedureCallData fromBelow, procedureCallSemInf = convert $ procedureCallSemInf originalProcedureCall } upwardsProcedureCall self fromAbove originalProcedureCall fromBelow transformedProcedureCall = case ul of [] -> defaultValue otherwise -> foldl combine (head ul) (tail ul) where ul = upwardsInfoFromActualParametersOfProcedureToCall fromBelow downwardsInputActualParameter self = const transformInputActualParameter self fromAbove originalInputActualParameter fromBelow = InputActualParameter $ InputActualParameterType { inputActualParameterExpression = recursivelyTransformedInputActualParameterExpression fromBelow, inputActualParameterSemInf = convert $ inputActualParameterSemInf originalInputActualParameter } upwardsInputActualParameter self fromAbove originalInputActualParameter fromBelow transformedInputActualParameter = upwardsInfoFromInputActualParameter fromBelow downwardsOutputActualParameter self = const transformOutputActualParameter self fromAbove originalOutputActualParameter fromBelow = OutputActualParameter $ OutputActualParameterType { outputActualParameterLeftValue = recursivelyTransformedOutputActualParameterLeftValue fromBelow, outputActualParameterSemInf = convert $ outputActualParameterSemInf originalOutputActualParameter } upwardsOutputActualParameter self fromAbove originalOutputActualParameter fromBelow transformedOutputActualParameter = upwardsInfoFromOutputActualParameterLeftValue fromBelow downwardsVariableInLeftValue self = const transformVariableInLeftValue self fromAbove originalVariableInLeftValue fromBelow = VariableLeftValue $ VariableInLeftValue { variableLeftValueContents = recursivelyTransformedVariableLeftValueContents fromBelow, variableLeftValueSemInf = convert $ variableLeftValueSemInf originalVariableInLeftValue } upwardsVariableInLeftValue self fromAbove originalVariableInLeftValue fromBelow transformedVariableInLeftValue = upwardsInfoFromVariableLeftValueContents fromBelow downwardsArrayElemReference self = const transformArrayElemReference self fromAbove originalArrayElemReference fromBelow = ArrayElemReferenceLeftValue $ ArrayElemReference { arrayElemReferenceData = recursivelyTransformedArrayElemReferenceData fromBelow, arrayElemReferenceSemInf = convert $ arrayElemReferenceSemInf originalArrayElemReference } upwardsArrayElemReference self fromAbove originalArrayElemReference fromBelow transformedArrayElemReference = combine (upwardsInfoFromArrayName fromBelow) (upwardsInfoFromArrayIndex fromBelow) downwardsLeftValueExpression self = const transformLeftValueExpression self fromAbove originalLeftValueExpression fromBelow = LeftValueExpression $ LeftValueInExpression { leftValueExpressionContents = recursivelyTransformedLeftValueExpressionContents fromBelow, leftValueExpressionSemInf = convert $ leftValueExpressionSemInf originalLeftValueExpression } upwardsLeftValueExpression self fromAbove originalLeftValueExpression fromBelow transformedLeftValueExpression = upwardsInfoFromLeftValueExpressionContents fromBelow downwardsFunctionCall self = const transformFunctionCall self fromAbove originalFunctionCall fromBelow = FunctionCallExpression $ FunctionCall { functionCallData = recursivelyTransformedFunctionCallData fromBelow, functionCallSemInf = convert $ functionCallSemInf originalFunctionCall } upwardsFunctionCall self fromAbove originalFunctionCall fromBelow transformedFunctionCall = case ul of [] -> defaultValue otherwise -> foldl combine (head ul) (tail ul) where ul = upwardsInfoFromActualParametersOfFunctionToCall fromBelow transformIntConstant self fromAbove originalIntConstant = IntConstant originalIntConstant { intConstantSemInf = convert $ intConstantSemInf originalIntConstant } upwardsIntConstant self fromAbove originalIntConstant transformedIntConstant = defaultValue transformFloatConstant self fromAbove originalFloatConstant = FloatConstant originalFloatConstant { floatConstantSemInf = convert $ floatConstantSemInf originalFloatConstant } upwardsFloatConstant self fromAbove originalFloatConstant transformedFloatConstant = defaultValue transformBoolConstant self fromAbove originalBoolConstant = BoolConstant originalBoolConstant { boolConstantSemInf = convert $ boolConstantSemInf originalBoolConstant } upwardsBoolConstant self fromAbove originalBoolConstant transformedBoolConstant = defaultValue downwardsArrayConstant self = const transformArrayConstant self fromAbove originalArrayConstant fromBelow = ArrayConstant $ ArrayConstantType { arrayConstantValue = recursivelyTransformedArrayConstantValue fromBelow, arrayConstantSemInf = convert $ arrayConstantSemInf originalArrayConstant } upwardsArrayConstant self fromAbove originalArrayConstant fromBelow transformedArrayConstant = case ul of [] -> defaultValue otherwise -> foldl combine (head ul) (tail ul) where ul = upwardsInfoFromConstantList fromBelow transformVariable self fromAbove originalVariable = originalVariable { variableSemInf = convert $ variableSemInf originalVariable } upwardsVariable self fromAbove originalVariable transformedVariable = defaultValue -- ================================================================================================================================== -- == Walker defaults -- ================================================================================================================================== walkProcedure :: Walker t Procedure walkProcedure selfpointer fromAbove construction = (transformedProcedure, toAbove) where toBelow = downwardsProcedure selfpointer fromAbove construction transformedInParameters = map (walkFormalParameter selfpointer toBelow) $ inParameters construction transformedOutParameters = map (walkFormalParameter selfpointer toBelow) $ outParameters construction transformedProcedureBody = (walkBlock selfpointer toBelow) $ procedureBody construction fromBelow = InfosFromProcedureParts { recursivelyTransformedInParameters = map fst transformedInParameters, upwardsInfoFromInParameters = map snd transformedInParameters, recursivelyTransformedOutParameters = map fst transformedOutParameters, upwardsInfoFromOutParameters = map snd transformedOutParameters, recursivelyTransformedProcedureBody = fst transformedProcedureBody, upwardsInfoFromProcedureBody = snd transformedProcedureBody } transformedProcedure = transformProcedure selfpointer fromAbove construction fromBelow toAbove = upwardsProcedure selfpointer fromAbove construction fromBelow transformedProcedure walkFormalParameter :: Walker t FormalParameter walkFormalParameter selfpointer fromAbove p = (transformedFormalParameter, toAbove) where toBelow = downwardsFormalParameter selfpointer fromAbove p transformedVariable = walkVariable selfpointer toBelow (formalParameterVariable p) fromBelow = InfosFromFormalParameterParts { recursivelyTransformedFormalParameterVariable = fst transformedVariable, upwardsInfoFromFormalParameterVariable = snd transformedVariable } transformedFormalParameter = transformFormalParameter selfpointer fromAbove p fromBelow toAbove = upwardsFormalParameter selfpointer fromAbove p fromBelow transformedFormalParameter walkBlock :: Walker t Block walkBlock selfpointer fromAbove block = (transformedBlock, toAbove) where toBelow = downwardsBlock selfpointer fromAbove block transformedLocalDeclarations = map (walkLocalDeclaration selfpointer toBelow) $ blockDeclarations $ blockData block transformedProgram = walkProgram selfpointer toBelow $ blockInstructions $ blockData block fromBelow = InfosFromBlockParts { recursivelyTransformedBlockData = BlockData { blockDeclarations = map fst transformedLocalDeclarations, blockInstructions = fst transformedProgram }, upwardsInfoFromBlockDeclarations = map snd transformedLocalDeclarations, upwardsInfoFromBlockInstructions = snd transformedProgram } transformedBlock = transformBlock selfpointer fromAbove block fromBelow toAbove = upwardsBlock selfpointer fromAbove block fromBelow transformedBlock walkProgram :: Walker t Program walkProgram selfpointer fromAbove program = (transformedProgram, toAbove) where toBelow = downwardsProgram selfpointer fromAbove program transformedProgramConstruction = case programConstruction program of EmptyProgram empty -> walkEmpty selfpointer toBelow empty PrimitiveProgram primitive -> walkPrimitive selfpointer toBelow primitive SequenceProgram sequence -> walkSequence selfpointer toBelow sequence BranchProgram branch -> walkBranch selfpointer toBelow branch SequentialLoopProgram sequentialLoop -> walkSequentialLoop selfpointer toBelow sequentialLoop ParallelLoopProgram parallelLoop -> walkParallelLoop selfpointer toBelow parallelLoop fromBelow = InfosFromProgramParts { recursivelyTransformedProgramConstruction = fst transformedProgramConstruction, upwardsInfoFromProgramConstruction = snd transformedProgramConstruction } transformedProgram = transformProgram selfpointer fromAbove program fromBelow toAbove = upwardsProgram selfpointer fromAbove program fromBelow transformedProgram walkEmpty :: (TransformationPhase t) => t -> Downwards t -> Empty (From t) -> (ProgramConstruction (To t), Upwards t) walkEmpty selfpointer fromAbove empty = (transformedEmpty, toAbove) where transformedEmpty = transformEmpty selfpointer fromAbove empty toAbove = upwardsEmpty selfpointer fromAbove empty transformedEmpty walkPrimitive :: (TransformationPhase t) => t -> Downwards t -> Primitive (From t) -> (ProgramConstruction (To t), Upwards t) walkPrimitive selfpointer fromAbove primitive = (transformedPrimitive, toAbove) where toBelow = downwardsPrimitive selfpointer fromAbove primitive transformedPrimitiveInstruction = walkInstruction selfpointer toBelow (primitiveInstruction primitive) fromBelow = InfosFromPrimitiveParts { recursivelyTransformedPrimitiveInstruction = fst transformedPrimitiveInstruction, upwardsInfoFromPrimitiveInstruction = snd transformedPrimitiveInstruction } transformedPrimitive = transformPrimitive selfpointer fromAbove primitive fromBelow toAbove = upwardsPrimitive selfpointer fromAbove primitive fromBelow transformedPrimitive walkSequence :: (TransformationPhase t) => t -> Downwards t -> Sequence (From t) -> (ProgramConstruction (To t), Upwards t) walkSequence selfpointer fromAbove sequence = (transformedSequence, toAbove) where toBelow = downwardsSequence selfpointer fromAbove sequence transformedProgramList = map (walkProgram selfpointer toBelow) (sequenceProgramList sequence) fromBelow = InfosFromSequenceParts { recursivelyTransformedSequenceProgramList = map fst transformedProgramList, upwardsInfoFromSequenceProgramList = map snd transformedProgramList } transformedSequence = transformSequence selfpointer fromAbove sequence fromBelow toAbove = upwardsSequence selfpointer fromAbove sequence fromBelow transformedSequence walkBranch :: (TransformationPhase t) => t -> Downwards t -> Branch (From t) -> (ProgramConstruction (To t), Upwards t) walkBranch selfpointer fromAbove branch = (transformedBranch, toAbove) where toBelow = downwardsBranch selfpointer fromAbove branch transformedBranchConditionVariable = walkVariable selfpointer toBelow (branchConditionVariable $ branchData branch) transformedThenBlock = walkBlock selfpointer toBelow (thenBlock $ branchData branch) transformedElseBlock = walkBlock selfpointer toBelow (elseBlock $ branchData branch) fromBelow = InfosFromBranchParts { recursivelyTransformedBranchData = BranchData { branchConditionVariable = fst transformedBranchConditionVariable, thenBlock = fst transformedThenBlock, elseBlock = fst transformedElseBlock }, upwardsInfoFromBranchConditionVariable = snd transformedBranchConditionVariable, upwardsInfoFromThenBlock = snd transformedThenBlock, upwardsInfoFromElseBlock = snd transformedElseBlock } transformedBranch = transformBranch selfpointer fromAbove branch fromBelow toAbove = upwardsBranch selfpointer fromAbove branch fromBelow transformedBranch walkSequentialLoop :: (TransformationPhase t) => t -> Downwards t -> SequentialLoop (From t) -> (ProgramConstruction (To t), Upwards t) walkSequentialLoop selfpointer fromAbove loop = (transformedSequentialLoop, toAbove) where toBelow = downwardsSequentialLoop selfpointer fromAbove loop transformedLoopConditionVariable = walkExpression selfpointer toBelow (sequentialLoopCondition $ sequentialLoopData loop) transformedConditionCalculation = walkBlock selfpointer toBelow (conditionCalculation $ sequentialLoopData loop) transformedSequentialLoopCore = walkBlock selfpointer toBelow (sequentialLoopCore $ sequentialLoopData loop) fromBelow = InfosFromSequentialLoopParts { recursivelyTransformedSequentialLoopData = SequentialLoopData { sequentialLoopCondition = fst transformedLoopConditionVariable, conditionCalculation = fst transformedConditionCalculation, sequentialLoopCore = fst transformedSequentialLoopCore }, upwardsInfoFromSequentialLoopConditionVariable = snd transformedLoopConditionVariable, upwardsInfoFromSequentialLoopConditionCalculation = snd transformedConditionCalculation, upwardsInfoFromSequentialLoopCore = snd transformedSequentialLoopCore } transformedSequentialLoop = transformSequentialLoop selfpointer fromAbove loop fromBelow toAbove = upwardsSequentialLoop selfpointer fromAbove loop fromBelow transformedSequentialLoop walkParallelLoop :: (TransformationPhase t) => t -> Downwards t -> ParallelLoop (From t) -> (ProgramConstruction (To t), Upwards t) walkParallelLoop selfpointer fromAbove loop = (transformedParallelLoop, toAbove) where toBelow = downwardsParallelLoop selfpointer fromAbove loop transformedParallelLoopConditionVariable = walkVariable selfpointer toBelow (parallelLoopConditionVariable $ parallelLoopData loop) transformedNumberOfIterations = walkExpression selfpointer toBelow (numberOfIterations $ parallelLoopData loop) transformedParallelLoopCore = walkBlock selfpointer toBelow (parallelLoopCore $ parallelLoopData loop) fromBelow = InfosFromParallelLoopParts { recursivelyTransformedParallelLoopData = ParallelLoopData { parallelLoopConditionVariable = fst transformedParallelLoopConditionVariable, numberOfIterations = fst transformedNumberOfIterations, parallelLoopStep = parallelLoopStep $ parallelLoopData loop, parallelLoopCore = fst transformedParallelLoopCore }, upwardsInfoFromParallelLoopConditionVariable = snd transformedParallelLoopConditionVariable, upwardsInfoFromNumberOfIterations = snd transformedNumberOfIterations, upwardsInfoFromParallelLoopCore = snd transformedParallelLoopCore } transformedParallelLoop = transformParallelLoop selfpointer fromAbove loop fromBelow toAbove = upwardsParallelLoop selfpointer fromAbove loop fromBelow transformedParallelLoop walkLocalDeclaration :: Walker t LocalDeclaration walkLocalDeclaration selfpointer fromAbove local = (transformedLocalDeclaration, toAbove) where toBelow = downwardsLocalDeclaration selfpointer fromAbove local transformedLocalVariable = walkVariable selfpointer toBelow (localVariable $ localDeclarationData local) transformedLocalInitValue = case localInitValue $ localDeclarationData local of Nothing -> (Nothing, Nothing) Just localInitExpression -> (Just (fst transformedLocalInitExpression), Just (snd transformedLocalInitExpression)) where transformedLocalInitExpression = walkExpression selfpointer toBelow localInitExpression fromBelow = InfosFromLocalDeclarationParts { recursivelyTransformedLocalDeclarationData = LocalDeclarationData { localVariable = fst transformedLocalVariable, localInitValue = fst transformedLocalInitValue }, upwardsInfoFromLocalVariable = snd transformedLocalVariable, upwardsInfoFromLocalInitValue = snd transformedLocalInitValue } transformedLocalDeclaration = transformLocalDeclaration selfpointer fromAbove local fromBelow toAbove = upwardsLocalDeclaration selfpointer fromAbove local fromBelow transformedLocalDeclaration walkExpression :: Walker t Expression walkExpression selfpointer fromAbove expression = case expression of LeftValueExpression leftValueExpression -> (transformedLeftValueExpression, toAbove) where toBelow = downwardsLeftValueExpression selfpointer fromAbove leftValueExpression transformedLeftValueExpressionContents = walkLeftValue selfpointer toBelow (leftValueExpressionContents leftValueExpression) fromBelow = InfosFromLeftValueExpressionParts { recursivelyTransformedLeftValueExpressionContents = fst transformedLeftValueExpressionContents, upwardsInfoFromLeftValueExpressionContents = snd transformedLeftValueExpressionContents } transformedLeftValueExpression = transformLeftValueExpression selfpointer fromAbove leftValueExpression fromBelow toAbove = upwardsLeftValueExpression selfpointer fromAbove leftValueExpression fromBelow transformedLeftValueExpression ConstantExpression constant -> ((ConstantExpression $ fst transformedConstant), snd transformedConstant) where toBelow = fromAbove -- calculations are done in WalkConstant, used only in the ArrayConstant branch transformedConstant = walkConstant selfpointer toBelow constant FunctionCallExpression functionCall -> (transformedFunctionCallExpression, toAbove) where toBelow = downwardsFunctionCall selfpointer fromAbove functionCall transformedActualParametersOfFunctionToCall = map (walkExpression selfpointer toBelow) (actualParametersOfFunctionToCall $ functionCallData functionCall) fromBelow = InfosFromFunctionCallParts { recursivelyTransformedFunctionCallData = (functionCallData functionCall) { actualParametersOfFunctionToCall = map fst transformedActualParametersOfFunctionToCall }, upwardsInfoFromActualParametersOfFunctionToCall = map snd transformedActualParametersOfFunctionToCall } transformedFunctionCallExpression = transformFunctionCall selfpointer fromAbove functionCall fromBelow toAbove = upwardsFunctionCall selfpointer fromAbove functionCall fromBelow transformedFunctionCallExpression walkConstant :: Walker t Constant walkConstant selfpointer fromAbove constant = case constant of IntConstant intConstant -> (transformedIntConstant, toAbove) where transformedIntConstant = transformIntConstant selfpointer fromAbove intConstant toAbove = upwardsIntConstant selfpointer fromAbove intConstant transformedIntConstant FloatConstant floatConstant -> (transformedFloatConstant, toAbove) where transformedFloatConstant = transformFloatConstant selfpointer fromAbove floatConstant toAbove = upwardsFloatConstant selfpointer fromAbove floatConstant transformedFloatConstant BoolConstant boolConstant -> (transformedBoolConstant, toAbove) where transformedBoolConstant = transformBoolConstant selfpointer fromAbove boolConstant toAbove = upwardsBoolConstant selfpointer fromAbove boolConstant transformedBoolConstant ArrayConstant arrayConstant -> (transformedArrayConstant, toAbove) where toBelow = downwardsArrayConstant selfpointer fromAbove arrayConstant transformedConstantList = map (walkConstant selfpointer toBelow) (arrayConstantValue arrayConstant) fromBelow = InfosFromArrayConstantParts { recursivelyTransformedArrayConstantValue = map fst transformedConstantList, upwardsInfoFromConstantList = map snd transformedConstantList } transformedArrayConstant = transformArrayConstant selfpointer fromAbove arrayConstant fromBelow toAbove = upwardsArrayConstant selfpointer fromAbove arrayConstant fromBelow transformedArrayConstant walkLeftValue :: Walker t LeftValue walkLeftValue selfpointer fromAbove leftValue = case leftValue of VariableLeftValue lvt -> (transformedVariableLeftValue, toAbove) where toBelow = downwardsVariableInLeftValue selfpointer fromAbove lvt transformedVariableLeftValueContents = walkVariable selfpointer toBelow (variableLeftValueContents lvt) fromBelow = InfosFromVariableLeftValueParts { recursivelyTransformedVariableLeftValueContents = fst transformedVariableLeftValueContents, upwardsInfoFromVariableLeftValueContents = snd transformedVariableLeftValueContents } transformedVariableLeftValue = transformVariableInLeftValue selfpointer fromAbove lvt fromBelow toAbove = upwardsVariableInLeftValue selfpointer fromAbove lvt fromBelow transformedVariableLeftValue ArrayElemReferenceLeftValue arrayElemReference -> (transformedArrayElemReference, toAbove) where toBelow = downwardsArrayElemReference selfpointer fromAbove arrayElemReference transformedArrayName = walkLeftValue selfpointer toBelow (arrayName $ arrayElemReferenceData arrayElemReference) transformedArrayIndex = walkExpression selfpointer toBelow (arrayIndex $ arrayElemReferenceData arrayElemReference) fromBelow = InfosFromArrayElemReferenceParts { recursivelyTransformedArrayElemReferenceData = ArrayElemReferenceData { arrayName = fst transformedArrayName, arrayIndex = fst transformedArrayIndex }, upwardsInfoFromArrayName = snd transformedArrayName, upwardsInfoFromArrayIndex = snd transformedArrayIndex } transformedArrayElemReference = transformArrayElemReference selfpointer fromAbove arrayElemReference fromBelow toAbove = upwardsArrayElemReference selfpointer fromAbove arrayElemReference fromBelow transformedArrayElemReference walkActualParameter :: Walker t ActualParameter walkActualParameter selfpointer fromAbove actualParameter = case actualParameter of InputActualParameter input -> (transformedInputActualParameter, toAbove) where toBelow = downwardsInputActualParameter selfpointer fromAbove input transformedInputActualParameterExpression = walkExpression selfpointer toBelow (inputActualParameterExpression input) fromBelow = InfosFromInputActualParameterParts { recursivelyTransformedInputActualParameterExpression = fst transformedInputActualParameterExpression, upwardsInfoFromInputActualParameter = snd transformedInputActualParameterExpression } transformedInputActualParameter = transformInputActualParameter selfpointer fromAbove input fromBelow toAbove = upwardsInputActualParameter selfpointer fromAbove input fromBelow transformedInputActualParameter OutputActualParameter output -> (transformedOutputActualParameter, toAbove) where toBelow = downwardsOutputActualParameter selfpointer fromAbove output transformedOutputActualParameterLeftValue = walkLeftValue selfpointer toBelow (outputActualParameterLeftValue output) fromBelow = InfosFromOutputActualParameterParts { recursivelyTransformedOutputActualParameterLeftValue = fst transformedOutputActualParameterLeftValue, upwardsInfoFromOutputActualParameterLeftValue = snd transformedOutputActualParameterLeftValue } transformedOutputActualParameter = transformOutputActualParameter selfpointer fromAbove output fromBelow toAbove = upwardsOutputActualParameter selfpointer fromAbove output fromBelow transformedOutputActualParameter walkInstruction :: Walker t Instruction walkInstruction selfpointer fromAbove instruction = case instruction of AssignmentInstruction assignment -> (transformedAssignment, toAbove) where toBelow = downwardsAssignment selfpointer fromAbove assignment transformedAssignmentLhs = walkLeftValue selfpointer toBelow (assignmentLhs $ assignmentData assignment) transformedAssignmentRhs = walkExpression selfpointer toBelow (assignmentRhs $ assignmentData assignment) fromBelow = InfosFromAssignmentParts { recursivelyTransformedAssignmentData = AssignmentData { assignmentLhs = fst transformedAssignmentLhs, assignmentRhs = fst transformedAssignmentRhs }, upwardsInfoFromAssignmentLhs = snd transformedAssignmentLhs, upwardsInfoFromAssignmentRhs = snd transformedAssignmentRhs } transformedAssignment = transformAssignment selfpointer fromAbove assignment fromBelow toAbove = upwardsAssignment selfpointer fromAbove assignment fromBelow transformedAssignment ProcedureCallInstruction procedureCall -> (transformedProcedureCall, toAbove) where toBelow = downwardsProcedureCall selfpointer fromAbove procedureCall transformedActualParametersOfProcedureToCall = map (walkActualParameter selfpointer toBelow) (actualParametersOfProcedureToCall $ procedureCallData procedureCall) fromBelow = InfosFromProcedureCallParts { recursivelyTransformedProcedureCallData = (procedureCallData procedureCall) { actualParametersOfProcedureToCall = map fst transformedActualParametersOfProcedureToCall }, upwardsInfoFromActualParametersOfProcedureToCall = map snd transformedActualParametersOfProcedureToCall } transformedProcedureCall = transformProcedureCall selfpointer fromAbove procedureCall fromBelow toAbove = upwardsProcedureCall selfpointer fromAbove procedureCall fromBelow transformedProcedureCall walkVariable :: Walker t Variable walkVariable selfpointer fromAbove v = (transformedVariable, toAbove) where transformedVariable = transformVariable selfpointer fromAbove v toAbove = upwardsVariable selfpointer fromAbove v transformedVariable -- ================================================================================================================================== -- == Upwards infos -- ================================================================================================================================== data (TransformationPhase t) => InfosFromProcedureParts t = InfosFromProcedureParts { recursivelyTransformedInParameters :: [FormalParameter (To t)], upwardsInfoFromInParameters :: [Upwards t], recursivelyTransformedOutParameters :: [FormalParameter (To t)], upwardsInfoFromOutParameters :: [Upwards t], recursivelyTransformedProcedureBody :: Block (To t), upwardsInfoFromProcedureBody :: Upwards t } data (TransformationPhase t) => InfosFromBlockParts t = InfosFromBlockParts { recursivelyTransformedBlockData :: BlockData (To t), upwardsInfoFromBlockDeclarations :: [Upwards t], upwardsInfoFromBlockInstructions :: Upwards t } data (TransformationPhase t) => InfosFromProgramParts t = InfosFromProgramParts { recursivelyTransformedProgramConstruction :: ProgramConstruction (To t), upwardsInfoFromProgramConstruction :: Upwards t } data (TransformationPhase t) => InfosFromPrimitiveParts t = InfosFromPrimitiveParts { recursivelyTransformedPrimitiveInstruction :: Instruction (To t), upwardsInfoFromPrimitiveInstruction :: Upwards t } data (TransformationPhase t) => InfosFromSequenceParts t = InfosFromSequenceParts { recursivelyTransformedSequenceProgramList :: [Program (To t)], upwardsInfoFromSequenceProgramList :: [Upwards t] } data (TransformationPhase t) => InfosFromBranchParts t = InfosFromBranchParts { recursivelyTransformedBranchData :: BranchData (To t), upwardsInfoFromBranchConditionVariable :: Upwards t, upwardsInfoFromThenBlock :: Upwards t, upwardsInfoFromElseBlock :: Upwards t } data (TransformationPhase t) => InfosFromSequentialLoopParts t = InfosFromSequentialLoopParts { recursivelyTransformedSequentialLoopData :: SequentialLoopData (To t), upwardsInfoFromSequentialLoopConditionVariable :: Upwards t, upwardsInfoFromSequentialLoopConditionCalculation :: Upwards t, upwardsInfoFromSequentialLoopCore :: Upwards t } data (TransformationPhase t) => InfosFromParallelLoopParts t = InfosFromParallelLoopParts { recursivelyTransformedParallelLoopData :: ParallelLoopData (To t), upwardsInfoFromParallelLoopConditionVariable :: Upwards t, upwardsInfoFromNumberOfIterations :: Upwards t, upwardsInfoFromParallelLoopCore :: Upwards t } data (TransformationPhase t) => InfosFromFormalParameterParts t = InfosFromFormalParameterParts { recursivelyTransformedFormalParameterVariable :: Variable (To t), upwardsInfoFromFormalParameterVariable :: Upwards t } data (TransformationPhase t) => InfosFromLocalDeclarationParts t = InfosFromLocalDeclarationParts { recursivelyTransformedLocalDeclarationData :: LocalDeclarationData (To t), upwardsInfoFromLocalVariable :: Upwards t, upwardsInfoFromLocalInitValue :: Maybe (Upwards t) } data (TransformationPhase t) => InfosFromAssignmentParts t = InfosFromAssignmentParts { recursivelyTransformedAssignmentData :: AssignmentData (To t), upwardsInfoFromAssignmentLhs :: Upwards t, upwardsInfoFromAssignmentRhs :: Upwards t } data (TransformationPhase t) => InfosFromProcedureCallParts t = InfosFromProcedureCallParts { recursivelyTransformedProcedureCallData :: ProcedureCallData (To t), upwardsInfoFromActualParametersOfProcedureToCall :: [Upwards t] } data (TransformationPhase t) => InfosFromInputActualParameterParts t = InfosFromInputActualParameterParts { recursivelyTransformedInputActualParameterExpression :: Expression (To t), upwardsInfoFromInputActualParameter :: Upwards t } data (TransformationPhase t) => InfosFromOutputActualParameterParts t = InfosFromOutputActualParameterParts { recursivelyTransformedOutputActualParameterLeftValue :: LeftValue (To t), upwardsInfoFromOutputActualParameterLeftValue :: Upwards t } data (TransformationPhase t) => InfosFromArrayElemReferenceParts t = InfosFromArrayElemReferenceParts { recursivelyTransformedArrayElemReferenceData :: ArrayElemReferenceData (To t), upwardsInfoFromArrayName :: Upwards t, upwardsInfoFromArrayIndex :: Upwards t } data (TransformationPhase t) => InfosFromVariableLeftValueParts t = InfosFromVariableLeftValueParts { recursivelyTransformedVariableLeftValueContents :: Variable (To t), upwardsInfoFromVariableLeftValueContents :: Upwards t } data (TransformationPhase t) => InfosFromLeftValueExpressionParts t = InfosFromLeftValueExpressionParts { recursivelyTransformedLeftValueExpressionContents :: LeftValue (To t), upwardsInfoFromLeftValueExpressionContents :: Upwards t } data (TransformationPhase t) => InfosFromFunctionCallParts t = InfosFromFunctionCallParts { recursivelyTransformedFunctionCallData :: FunctionCallData (To t), upwardsInfoFromActualParametersOfFunctionToCall :: [Upwards t] } data (TransformationPhase t) => InfosFromArrayConstantParts t = InfosFromArrayConstantParts { recursivelyTransformedArrayConstantValue :: [Constant (To t)], upwardsInfoFromConstantList :: [Upwards t] }