diff --git a/Main.hs b/Main.hs
index 4df1eea..2da9bad 100644
--- a/Main.hs
+++ b/Main.hs
@@ -24,7 +24,7 @@ import Control.Monad.Identity
import Control.Monad.State
import Control.Monad.Writer
import Data.Either
-import Data.Generics
+import Data.Generics (Data)
import Data.Maybe
import qualified Data.Set as Set
import List
@@ -459,6 +459,7 @@ compile mode fn (outHandles@(outHandle, _), headerName)
ModeLex -> liftIO $ hPutStr outHandle $ pshow lexed
ModeHTML -> liftIO $ hPutStr outHandle $ showTokens True lexed
ModeParse -> liftIO $ hPutStr outHandle $ pshow ast1
+{-
ModeFlowGraph ->
do procs <- findAllProcesses
let fs :: Data t => t -> PassM String
@@ -476,6 +477,7 @@ compile mode fn (outHandles@(outHandle, _), headerName)
= map (transformMaybe $ \(x,_,_) -> x) graphs
-- TODO: output each process to a separate file, rather than just taking the first:
liftIO $ hPutStr outHandle $ head $ map makeFlowGraphInstr (catMaybes graphsTyped)
+-}
ModeCompile ->
do progress "Passes:"
diff --git a/Makefile.am b/Makefile.am
index e3b1ba4..3f5eddc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
GHC_OPTS = \
- -fcontext-stack=200 \
+ -fcontext-stack=400 \
-fwarn-deprecations \
-fwarn-duplicate-exports \
-fwarn-incomplete-record-updates \
diff --git a/backends/AnalyseAsm.hs b/backends/AnalyseAsm.hs
index 4ebda6d..285c977 100644
--- a/backends/AnalyseAsm.hs
+++ b/backends/AnalyseAsm.hs
@@ -30,7 +30,7 @@ module AnalyseAsm (
import Control.Arrow
import Control.Monad.State
import Data.Char
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.List
import qualified Data.Map as Map
import Data.Maybe
diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs
index 187c002..e9ba248 100644
--- a/backends/GenerateC.hs
+++ b/backends/GenerateC.hs
@@ -41,7 +41,7 @@ module GenerateC
) where
import Data.Char
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import qualified Data.Map as Map
import Data.Maybe
@@ -63,6 +63,7 @@ import Pass
import qualified Properties as Prop
import ShowCode
import TLP
+import Traversal
import Types
import TypeSizes
import Utils
@@ -181,11 +182,11 @@ cgenTopLevel headerName s
= A.nameName n `elem` (csOriginalTopLevelProcs cs)
tellToHeader $ sequence_ $ map (call genForwardDeclaration)
- (listify isTopLevelSpec s)
+ (listifyDepth isTopLevelSpec s)
-- Things like lifted wrapper_procs we still need to forward-declare,
-- but we do it in the C file, not in the header:
sequence_ $ map (call genForwardDeclaration)
- (listify (not . isTopLevelSpec) s)
+ (listifyDepth (not . isTopLevelSpec) s)
tell ["#include \"", dropPath headerName, "\"\n"]
diff --git a/backends/GenerateCBased.hs b/backends/GenerateCBased.hs
index 690cdc6..1cee60b 100644
--- a/backends/GenerateCBased.hs
+++ b/backends/GenerateCBased.hs
@@ -22,7 +22,7 @@ module GenerateCBased where
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer hiding (tell)
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import System.IO
diff --git a/backends/GenerateCHP.hs b/backends/GenerateCHP.hs
index b2fcc6f..859a666 100644
--- a/backends/GenerateCHP.hs
+++ b/backends/GenerateCHP.hs
@@ -42,7 +42,7 @@ module GenerateCHP where
import Control.Monad.State
import Control.Monad.Trans
import Data.Char
-import Data.Generics
+import Data.Generics (Data, showConstr, toConstr)
import Data.List
import Data.Maybe
import System.IO
diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs
index 66f1a89..2917af0 100644
--- a/backends/GenerateCPPCSP.hs
+++ b/backends/GenerateCPPCSP.hs
@@ -32,7 +32,7 @@ module GenerateCPPCSP (cppcspPrereq, cppgenOps, generateCPPCSP, genCPPCSPPasses)
import Control.Monad.State
import Data.Char
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import Data.Maybe
import qualified Data.Set as Set
@@ -144,11 +144,11 @@ cppgenTopLevel headerName s
= A.nameName n `elem` (csOriginalTopLevelProcs cs)
tellToHeader $ sequence_ $ map (call genForwardDeclaration)
- (listify isTopLevelSpec s)
+ (listifyDepth isTopLevelSpec s)
-- Things like lifted wrapper_procs we still need to forward-declare,
-- but we do it in the C file, not in the header:
sequence_ $ map (call genForwardDeclaration)
- (listify (\sp@(A.Specification _ n _)
+ (listifyDepth (\sp@(A.Specification _ n _)
-> not (isTopLevelSpec sp)
&& A.nameName n `notElem` map fst (csExternals cs)) s)
diff --git a/backends/TLP.hs b/backends/TLP.hs
index 8e99cb9..0bcb824 100644
--- a/backends/TLP.hs
+++ b/backends/TLP.hs
@@ -20,7 +20,7 @@ with this program. If not, see .
module TLP where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.List
import Data.Maybe
diff --git a/checks/Check.hs b/checks/Check.hs
index 6f768fc..19b4666 100644
--- a/checks/Check.hs
+++ b/checks/Check.hs
@@ -25,7 +25,7 @@ module Check (checkInitVarPass, usageCheckPass, checkUnusedVar) where
import Control.Monad.Identity
import Control.Monad.State
import Control.Monad.Trans
-import Data.Generics
+import Data.Generics (Data)
import Data.Graph.Inductive hiding (mapSnd)
import Data.List hiding (union)
import qualified Data.Map as Map
@@ -104,8 +104,15 @@ followBK = map followBK'
(concat $ mapMaybe (flip Map.lookup m) (Set.toList $
next `Set.difference` prev))
where
- next = Set.fromList $ map Var $ listify (const True :: A.Variable -> Bool) bk
+ next = Set.fromList $ map Var $ concatMap allVarsInBK bk
+allVarsInBK :: BackgroundKnowledge -> [A.Variable]
+allVarsInBK (Equal a b) = listifyDepth (const True) a
+ ++ listifyDepth (const True) b
+allVarsInBK (LessThanOrEqual a b) = listifyDepth (const True) a
+ ++ listifyDepth (const True) b
+allVarsInBK (RepBoundsIncl v a b) = v : (listifyDepth (const True) a
+ ++ listifyDepth (const True) b)
data And a = And [a]
data Or a = Or [a]
@@ -268,7 +275,7 @@ addBK mp mp2 g nid n
makeMap :: And BackgroundKnowledge -> Map.Map Var (And BackgroundKnowledge)
makeMap (And bks) = Map.fromListWith mappend $ concat
- [zip (map Var $ listify (const True) bk) (repeat $ noAnd bk) | bk <- bks]
+ [zip (map Var $ allVarsInBK bk) (repeat $ noAnd bk) | bk <- bks]
convValues :: Or (Map.Map Var (And BackgroundKnowledge))
convValues = Or $ map (Map.fromListWith mappend) $
diff --git a/checks/CheckFramework.hs b/checks/CheckFramework.hs
index 65b371a..8cb6f1a 100644
--- a/checks/CheckFramework.hs
+++ b/checks/CheckFramework.hs
@@ -26,7 +26,7 @@ module CheckFramework (CheckOptM, CheckOptASTM, forAnyASTTopDown, forAnyASTStruc
import Control.Monad.Reader
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import Data.Graph.Inductive hiding (apply)
import Data.List
import qualified Data.Map as Map
@@ -486,7 +486,7 @@ runChecks (CheckOptM m) x = execStateT m (CheckOptData {ast = x, parItems = Noth
nextVarsTouched = Map.empty, flowGraphRootsTerms = Nothing, lastValidMeta = emptyMeta}) >>* ast
runChecksPass :: CheckOptM () -> Pass A.AST
-runChecksPass c = pass "" [] [] (mkM (runChecks c))
+runChecksPass c = pass "" [] [] (runChecks c)
--getParItems :: CheckOptM (ParItems ())
--getParItems = CheckOptM (\d -> Right (d, fromMaybe (generateParItems $ ast d) (parItems d)))
diff --git a/checks/UsageCheckAlgorithms.hs b/checks/UsageCheckAlgorithms.hs
index 58b16fb..67f1219 100644
--- a/checks/UsageCheckAlgorithms.hs
+++ b/checks/UsageCheckAlgorithms.hs
@@ -19,7 +19,7 @@ with this program. If not, see .
module UsageCheckAlgorithms (checkPar, findConstraints, findReachDef, joinCheckParFunctions) where
import Control.Monad
-import Data.Generics
+import Data.Generics (Data)
import Data.Graph.Inductive
import Data.List
import qualified Data.Map as Map
@@ -30,6 +30,7 @@ import qualified AST as A
import FlowAlgorithms
import FlowGraph
import Metadata
+import Traversal
import Types
import UsageCheckUtils
import Utils
@@ -203,7 +204,7 @@ findConstraints graph startNode
processNode (n, e) nodeVal curAgg = case fmap getNodeData $ lab graph n of
Just u ->
let overlapsWithWritten e = not $ null $ intersect
- (listify (const True) e)
+ (listifyDepth (const True) $ snd e)
[v | Var v <- Map.keys $ writtenVars $ nodeVars u]
valFilt = filter (not . overlapsWithWritten) $
nub $ nodeVal ++ (case e of
diff --git a/common/Errors.hs b/common/Errors.hs
index 008fafb..dea3bfa 100644
--- a/common/Errors.hs
+++ b/common/Errors.hs
@@ -23,7 +23,7 @@ module Errors (checkJust, Die(..),
import Control.Monad.Error
import Control.Monad.Trans
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.List
import System.IO
import System.IO.Error
diff --git a/common/EvalLiterals.hs b/common/EvalLiterals.hs
index f4ee0ac..eca05fd 100644
--- a/common/EvalLiterals.hs
+++ b/common/EvalLiterals.hs
@@ -23,7 +23,7 @@ import Control.Monad.Error
import Control.Monad.Identity
import Control.Monad.State
import Data.Char
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.Int
import Data.Maybe
import Data.Word
diff --git a/common/PrettyShow.hs b/common/PrettyShow.hs
index f3541de..3305d26 100644
--- a/common/PrettyShow.hs
+++ b/common/PrettyShow.hs
@@ -29,7 +29,7 @@ with this program. If not, see .
-- (via the 'extCode' function) to print out data, otherwise it acts
-- like pshow. Note that because pshowCode chooses the appropriate
-- language based on the 'csFrontend' in 'CompState', it is inside the CSM monad.
-module PrettyShow (pshow, pshowCode) where
+module PrettyShow (pshow) where
import Control.Monad.State
import Data.Generics
@@ -154,6 +154,7 @@ doAny extFunc = extFunc (
pshow :: Data a => a -> String
pshow x = render $ doAny id x
+{-
pshowCode :: (Data a, CSMR m) => a -> m String
pshowCode c = do st <- getCompState
case csFrontend st of
@@ -164,3 +165,4 @@ pshowCode c = do st <- getCompState
extOccam f = extCode f showOccam
extRain :: forall a. (Data a, Typeable a) => (a -> Doc) -> (a -> Doc)
extRain f = extCode f showRain
+-}
diff --git a/common/ShowCode.hs b/common/ShowCode.hs
index bbb80f3..85b24e7 100644
--- a/common/ShowCode.hs
+++ b/common/ShowCode.hs
@@ -33,11 +33,11 @@ with this program. If not, see .
-- My plan for testing was to take each of the cgtests, and parse it in to AST_A. Then print AST_A using this
-- module, and feed it back in to the parser to get AST_B. Then check if AST_A and AST_B are equal.
-module ShowCode (showCode, ShowOccam(..), showOccam, ShowRain(..), showRain, formatCode, extCode) where
+module ShowCode (showCode, ShowOccam(..), showOccam, ShowRain(..), showRain, formatCode) where
import Control.Monad.State
import Control.Monad.Writer
-import Data.Generics
+import Data.Generics (Data, gshow)
import Data.List
import qualified Data.Map as Map
import Text.PrettyPrint.HughesPJ hiding (space, colon, semi)
@@ -711,6 +711,7 @@ instance ShowRain a => ShowRain [a] where
-- ShowOccam\/ShowRain implementation. But since to add a type to the ShowOccam\/ShowRain
-- classes you have to provide a specific instance above anyway, I don't think that adding
-- one more line while you're at it is too bad.
+{-
extCode :: (Data b, Typeable b) => (b -> Doc) -> (forall a. (ShowOccam a, ShowRain a) => a -> String) -> (b -> Doc)
extCode q f = q
`extQ` (text . (f :: A.Expression -> String))
@@ -723,4 +724,4 @@ extCode q f = q
`extQ` (text . (f :: A.Variable -> String))
--TODO
-- `ext1Q` (text . (f :: (Data c, ShowOccam c) => A.Structured c -> String))
-
+-}
diff --git a/common/Types.hs b/common/Types.hs
index 3060699..1daf5c0 100644
--- a/common/Types.hs
+++ b/common/Types.hs
@@ -41,7 +41,7 @@ module Types
import Control.Monad.State
import Data.Char
-import Data.Generics
+import Data.Generics (Data)
import qualified Data.Map as Map
import Data.Maybe
import Data.List
diff --git a/data/CompState.hs b/data/CompState.hs
index beb4201..4785ccf 100644
--- a/data/CompState.hs
+++ b/data/CompState.hs
@@ -23,7 +23,7 @@ import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
diff --git a/data/Metadata.hs b/data/Metadata.hs
index 9a859e4..58718f5 100644
--- a/data/Metadata.hs
+++ b/data/Metadata.hs
@@ -21,7 +21,7 @@ module Metadata where
{-! global : Haskell2Xml !-}
-import Data.Generics
+import Data.Generics (Data, Typeable, listify)
import Data.List
import Numeric
import Text.Printf
diff --git a/flow/FlowGraph.hs b/flow/FlowGraph.hs
index a0dfdd6..7c8e701 100644
--- a/flow/FlowGraph.hs
+++ b/flow/FlowGraph.hs
@@ -46,7 +46,7 @@ module FlowGraph (AlterAST(..), EdgeLabel(..), FNode, FlowGraph, FlowGraph', Gra
import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import Data.Graph.Inductive hiding (run)
import Data.Maybe
diff --git a/flow/FlowUtils.hs b/flow/FlowUtils.hs
index a6dc333..bb06678 100644
--- a/flow/FlowUtils.hs
+++ b/flow/FlowUtils.hs
@@ -21,7 +21,7 @@ module FlowUtils where
import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.Graph.Inductive hiding (run)
import qualified AST as A
diff --git a/frontends/LexOccam.x b/frontends/LexOccam.x
index b7ce490..8860b0f 100644
--- a/frontends/LexOccam.x
+++ b/frontends/LexOccam.x
@@ -21,7 +21,7 @@ with this program. If not, see .
module LexOccam where
import Control.Monad.Error
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Errors
import Metadata
diff --git a/frontends/LexRain.x b/frontends/LexRain.x
index 8048b95..2fe4e20 100644
--- a/frontends/LexRain.x
+++ b/frontends/LexRain.x
@@ -20,7 +20,7 @@ with this program. If not, see .
-- | Lexically analyse Rain code.
module LexRain where
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Metadata
}
diff --git a/frontends/OccamPasses.hs b/frontends/OccamPasses.hs
index 9a72ebb..594046d 100644
--- a/frontends/OccamPasses.hs
+++ b/frontends/OccamPasses.hs
@@ -20,7 +20,7 @@ with this program. If not, see .
module OccamPasses (occamPasses, foldConstants, checkConstants) where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import qualified Data.Sequence as Seq
import qualified Data.Foldable as F
diff --git a/frontends/OccamTypes.hs b/frontends/OccamTypes.hs
index 528a60b..841d5b4 100644
--- a/frontends/OccamTypes.hs
+++ b/frontends/OccamTypes.hs
@@ -23,7 +23,7 @@ import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.State
import Data.Function (on)
-import Data.Generics
+import Data.Generics (Data)
import Data.IORef
import Data.List
import qualified Data.Map as Map
diff --git a/frontends/ParseRain.hs b/frontends/ParseRain.hs
index 3c422c2..ecd8fc0 100644
--- a/frontends/ParseRain.hs
+++ b/frontends/ParseRain.hs
@@ -21,7 +21,7 @@ module ParseRain where
import Control.Monad (liftM)
import Control.Monad.State (MonadState, liftIO, get, put)
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import Data.Maybe
import qualified IO
diff --git a/frontends/RainPasses.hs b/frontends/RainPasses.hs
index 208cad2..ece4a0b 100644
--- a/frontends/RainPasses.hs
+++ b/frontends/RainPasses.hs
@@ -20,7 +20,7 @@ with this program. If not, see .
module RainPasses where
import Control.Monad.State
-import Data.Generics
+import Data.Generics -- TODO change this module to use Polyplate
import Data.List
import qualified Data.Map as Map
import Data.Maybe
diff --git a/frontends/RainTypes.hs b/frontends/RainTypes.hs
index 5ba2673..79a5a2f 100644
--- a/frontends/RainTypes.hs
+++ b/frontends/RainTypes.hs
@@ -19,7 +19,7 @@ with this program. If not, see .
module RainTypes (constantFoldPass, performTypeUnification) where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data, showConstr, toConstr)
import Data.List
import qualified Data.Map as Map
import Data.Maybe
diff --git a/frontends/TypeUnification.hs b/frontends/TypeUnification.hs
index 05d3d0c..2a318c0 100644
--- a/frontends/TypeUnification.hs
+++ b/frontends/TypeUnification.hs
@@ -21,7 +21,7 @@ module TypeUnification where
import Control.Monad
import Control.Monad.State
import Control.Monad.Trans
-import Data.Generics
+import Data.Generics (Data, Typeable)
import qualified Data.Map as Map
import Data.Maybe
import Data.IORef
diff --git a/frontends/UnifyType.hs b/frontends/UnifyType.hs
index d777ff0..d56f9a1 100644
--- a/frontends/UnifyType.hs
+++ b/frontends/UnifyType.hs
@@ -18,7 +18,7 @@ with this program. If not, see .
module UnifyType where
-import Data.Generics
+import Data.Generics (Data, Typeable)
import Data.IORef
import qualified AST as A
diff --git a/pass/Pass.hs b/pass/Pass.hs
index 58bc81e..7e3ec41 100644
--- a/pass/Pass.hs
+++ b/pass/Pass.hs
@@ -22,7 +22,7 @@ module Pass where
import Control.Monad.Error
import Control.Monad.State
import Control.Monad.Writer
-import Data.Generics
+import Data.Generics (Constr, Data)
import Data.Generics.Polyplate
import Data.List
import Data.Ord
diff --git a/pass/Properties.hs b/pass/Properties.hs
index d05be71..a907d69 100644
--- a/pass/Properties.hs
+++ b/pass/Properties.hs
@@ -69,7 +69,7 @@ module Properties
where
import Control.Monad.Writer
-import Data.Generics
+import Data.Generics -- TODO stop this module using SYB
import Data.Int
import Data.List
import qualified Data.Map as Map
diff --git a/pass/Traversal.hs b/pass/Traversal.hs
index f443c88..f7ed0bb 100644
--- a/pass/Traversal.hs
+++ b/pass/Traversal.hs
@@ -22,13 +22,14 @@ module Traversal (
TransformM, Transform, TransformStructured, TransformStructured'
, CheckM, Check
, ExtOpMP, ExtOpMS, ExtOpMSP, extOpMS, PassOnStruct, PassASTOnStruct
- , applyBottomUpMS
+ , ExtOpQS, extOpQS
+ , applyBottomUpMS, ASTStructured
, module Data.Generics.Polyplate
, module Data.Generics.Polyplate.Schemes
) where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import Data.Generics.Polyplate
import Data.Generics.Polyplate.Schemes
@@ -68,6 +69,57 @@ type ExtOpMSP opT = ExtOpMS PassM opT
type PassOnStruct = PassOnOps (ExtOpMSP BaseOp)
type PassASTOnStruct = PassASTOnOps (ExtOpMSP BaseOp)
+class (PolyplateM (A.Structured a) () opsM m
+ ,PolyplateM (A.Structured a) opsM () m
+ ,PolyplateSpine (A.Structured a) opsQ () r
+ ,PolyplateSpine (A.Structured a) () opsQ r
+ ,Data a
+ ,Monad m
+ ) => ASTStructured a opsM m opsQ r
+
+instance (PolyplateM (A.Structured ()) () opsM m
+ ,PolyplateM (A.Structured ()) opsM () m
+ ,PolyplateSpine (A.Structured ()) opsQ () r
+ ,PolyplateSpine (A.Structured ()) () opsQ r
+ ,Monad m) => ASTStructured () opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.Alternative) () opsM m
+ ,PolyplateM (A.Structured A.Alternative) opsM () m
+ ,PolyplateSpine (A.Structured A.Alternative) opsQ () r
+ ,PolyplateSpine (A.Structured A.Alternative) () opsQ r
+ ,Monad m) => ASTStructured A.Alternative opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.Choice) () opsM m
+ ,PolyplateM (A.Structured A.Choice) opsM () m
+ ,PolyplateSpine (A.Structured A.Choice) opsQ () r
+ ,PolyplateSpine (A.Structured A.Choice) () opsQ r
+ ,Monad m) => ASTStructured A.Choice opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.ExpressionList) () opsM m
+ ,PolyplateM (A.Structured A.ExpressionList) opsM () m
+ ,PolyplateSpine (A.Structured A.ExpressionList) opsQ () r
+ ,PolyplateSpine (A.Structured A.ExpressionList) () opsQ r
+ ,Monad m) => ASTStructured A.ExpressionList opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.Option) () opsM m
+ ,PolyplateM (A.Structured A.Option) opsM () m
+ ,PolyplateSpine (A.Structured A.Option) opsQ () r
+ ,PolyplateSpine (A.Structured A.Option) () opsQ r
+ ,Monad m) => ASTStructured A.Option opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.Process) () opsM m
+ ,PolyplateM (A.Structured A.Process) opsM () m
+ ,PolyplateSpine (A.Structured A.Process) opsQ () r
+ ,PolyplateSpine (A.Structured A.Process) () opsQ r
+ ,Monad m) => ASTStructured A.Process opsM m opsQ r
+
+instance (PolyplateM (A.Structured A.Variant) () opsM m
+ ,PolyplateM (A.Structured A.Variant) opsM () m
+ ,PolyplateSpine (A.Structured A.Variant) opsQ () r
+ ,PolyplateSpine (A.Structured A.Variant) () opsQ r
+ ,Monad m) => ASTStructured A.Variant opsM m opsQ r
+
+
extOpMS :: forall m opT op0T.
(PolyplateM (A.Structured ()) () op0T m,
PolyplateM (A.Structured A.Alternative) () op0T m,
@@ -86,9 +138,7 @@ extOpMS :: forall m opT op0T.
opT ->
-- Pairing the next two arguments allows us to apply this function infix:
(op0T, -- just a type witness
- forall t. (Data t, PolyplateM (A.Structured t) () op0T m
- , PolyplateM (A.Structured t) op0T () m) =>
- A.Structured t -> m (A.Structured t)) ->
+ forall t. ASTStructured t op0T m () () => A.Structured t -> m (A.Structured t)) ->
ExtOpMS m opT
extOpMS ops (_, f)
= ops
@@ -100,6 +150,47 @@ extOpMS ops (_, f)
`extOpM` (f :: A.Structured A.Alternative -> m (A.Structured A.Alternative))
`extOpM` (f :: A.Structured () -> m (A.Structured ()))
+type ExtOpQS r opT =
+ (A.Structured () -> r,
+ (A.Structured A.Alternative -> r,
+ (A.Structured A.Choice -> r,
+ (A.Structured A.ExpressionList -> r,
+ (A.Structured A.Option -> r,
+ (A.Structured A.Process -> r,
+ (A.Structured A.Variant -> r,
+ opT)))))))
+
+extOpQS :: forall m opT op0T r.
+ (PolyplateSpine (A.Structured ()) () op0T r,
+ PolyplateSpine (A.Structured A.Alternative) () op0T r,
+ PolyplateSpine (A.Structured A.Choice) () op0T r,
+ PolyplateSpine (A.Structured A.ExpressionList) () op0T r,
+ PolyplateSpine (A.Structured A.Option) () op0T r,
+ PolyplateSpine (A.Structured A.Process) () op0T r,
+ PolyplateSpine (A.Structured A.Variant) () op0T r,
+ PolyplateSpine (A.Structured ()) op0T () r,
+ PolyplateSpine (A.Structured A.Alternative) op0T () r,
+ PolyplateSpine (A.Structured A.Choice) op0T () r,
+ PolyplateSpine (A.Structured A.ExpressionList) op0T () r,
+ PolyplateSpine (A.Structured A.Option) op0T () r,
+ PolyplateSpine (A.Structured A.Process) op0T () r,
+ PolyplateSpine (A.Structured A.Variant) op0T () r) =>
+ opT ->
+ -- Pairing the next two arguments allows us to apply this function infix:
+ (op0T, -- just a type witness
+ forall t. ASTStructured t () PassM op0T r => A.Structured t -> r) ->
+ ExtOpQS r opT
+extOpQS ops (_, f)
+ = ops
+ `extOpQ` (f :: A.Structured A.Variant -> r)
+ `extOpQ` (f :: A.Structured A.Process -> r)
+ `extOpQ` (f :: A.Structured A.Option -> r)
+ `extOpQ` (f :: A.Structured A.ExpressionList -> r)
+ `extOpQ` (f :: A.Structured A.Choice -> r)
+ `extOpQ` (f :: A.Structured A.Alternative -> r)
+ `extOpQ` (f :: A.Structured () -> r)
+
+
applyBottomUpMS :: (PolyplateM t (ExtOpMSP BaseOp) () PassM) =>
(forall a. (Data a, PolyplateM (A.Structured a) () (ExtOpMSP BaseOp) PassM) =>
(A.Structured a -> PassM (A.Structured a)))
diff --git a/transformations/ImplicitMobility.hs b/transformations/ImplicitMobility.hs
index 59c7eb1..8841acb 100644
--- a/transformations/ImplicitMobility.hs
+++ b/transformations/ImplicitMobility.hs
@@ -20,7 +20,7 @@ module ImplicitMobility (implicitMobility, mobiliseArrays, inferDeref) where
import Control.Monad
import Control.Monad.Trans
-import Data.Generics
+import Data.Generics (Data)
import Data.Graph.Inductive
import Data.Graph.Inductive.Query.DFS
import qualified Data.Map as Map
diff --git a/transformations/SimplifyAbbrevs.hs b/transformations/SimplifyAbbrevs.hs
index 4211a58..fece9c6 100644
--- a/transformations/SimplifyAbbrevs.hs
+++ b/transformations/SimplifyAbbrevs.hs
@@ -25,7 +25,7 @@ module SimplifyAbbrevs (
) where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import qualified Data.Map as Map
import qualified Data.Set as Set
diff --git a/transformations/SimplifyExprs.hs b/transformations/SimplifyExprs.hs
index c4cfff0..4b0a278 100644
--- a/transformations/SimplifyExprs.hs
+++ b/transformations/SimplifyExprs.hs
@@ -20,7 +20,7 @@ with this program. If not, see .
module SimplifyExprs where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import qualified Data.Map as Map
import qualified AST as A
@@ -86,17 +86,11 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
vpToSeq :: Meta -> A.Name -> [A.Variable] -> Either (A.Structured A.ExpressionList) A.Process -> A.Process
vpToSeq m n vs (Left el) = A.Seq m $ vpToSeq' el vs
- vpToSeq _ n vs (Right p) = subst p
+ vpToSeq _ n vs (Right p) = applyBottomUp doAssignSubst p
where
- subst :: Data t => t -> t
- subst = doGenericSubst `extT` doAssignSubst
-
- doGenericSubst :: Data t => t -> t
- doGenericSubst = gmapT subst `extT` (id :: String -> String) `extT` (id :: Meta -> Meta)
-
doAssignSubst :: A.Process -> A.Process
doAssignSubst ass@(A.Assign m [A.Variable _ dest] el) = if (A.nameName dest == A.nameName n) then (A.Assign m vs el) else ass
- doAssignSubst p = doGenericSubst p
+ doAssignSubst p = p
vpToSeq' :: A.Structured A.ExpressionList -> [A.Variable] -> A.Structured A.Process
diff --git a/transformations/SimplifyProcs.hs b/transformations/SimplifyProcs.hs
index 54837ae..5b4cf02 100644
--- a/transformations/SimplifyProcs.hs
+++ b/transformations/SimplifyProcs.hs
@@ -20,7 +20,7 @@ with this program. If not, see .
module SimplifyProcs (simplifyProcs, fixLowReplicators) where
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import qualified Data.Set as Set
import qualified AST as A
diff --git a/transformations/Unnest.hs b/transformations/Unnest.hs
index a9ba75f..9551fb8 100644
--- a/transformations/Unnest.hs
+++ b/transformations/Unnest.hs
@@ -21,10 +21,11 @@ module Unnest (unnest, removeNesting) where
import Control.Monad.Identity
import Control.Monad.State
-import Data.Generics
+import Data.Generics (Data)
import Data.List
import qualified Data.Map as Map
import Data.Maybe
+import Data.Tree
import qualified AST as A
import CompState
@@ -44,28 +45,37 @@ unnest =
]
type NameMap = Map.Map String A.Name
+type FreeNameOps = ExtOpQ NameMap (ExtOpQ NameMap (ExtOpQS NameMap BaseOp) A.Name) A.SpecType
-- | Get the set of free names within a block of code.
-freeNamesIn :: Data t => t -> NameMap
-freeNamesIn = doGeneric
- `extQ` (ignore :: String -> NameMap)
- `extQ` (ignore :: Meta -> NameMap)
- `extQ` doName `ext1Q` doStructured `extQ` doSpecType
+freeNamesIn :: PolyplateSpine t FreeNameOps () NameMap => t -> NameMap
+freeNamesIn = flattenTree . recurse
where
- doGeneric :: Data t => t -> NameMap
- doGeneric n = Map.unions $ gmapQ freeNamesIn n
+ flattenTree :: Tree (Maybe NameMap) -> NameMap
+ flattenTree = foldl Map.union Map.empty . catMaybes . flatten
+
+ ops :: FreeNameOps
+ ops = baseOp `extOpQS` (ops, doStructured) `extOpQ` doName `extOpQ` doSpecType
+ recurse :: PolyplateSpine t FreeNameOps () NameMap => t -> Tree (Maybe NameMap)
+ recurse = transformSpine ops ()
+ descend :: PolyplateSpine t () FreeNameOps NameMap => t -> Tree (Maybe NameMap)
+ descend = transformSpine () ops
+
ignore :: t -> NameMap
ignore s = Map.empty
doName :: A.Name -> NameMap
doName n = Map.singleton (A.nameName n) n
- doStructured :: Data a => A.Structured a -> NameMap
+ doStructured :: (Data a, PolyplateSpine (A.Structured a) () FreeNameOps NameMap
+ , PolyplateSpine (A.Structured a) FreeNameOps () NameMap)
+ => A.Structured a -> NameMap
doStructured (A.Spec _ spec s) = doSpec spec s
- doStructured s = doGeneric s
+ doStructured s = flattenTree $ descend s
- doSpec :: Data t => A.Specification -> t -> NameMap
+ doSpec :: (PolyplateSpine t () FreeNameOps NameMap
+ ,PolyplateSpine t FreeNameOps () NameMap) => A.Specification -> t -> NameMap
doSpec (A.Specification _ n st) child
= Map.union fns $ Map.delete (A.nameName n) $ freeNamesIn child
where
@@ -74,7 +84,7 @@ freeNamesIn = doGeneric
doSpecType :: A.SpecType -> NameMap
doSpecType (A.Proc _ _ fs p) = Map.difference (freeNamesIn p) (freeNamesIn fs)
doSpecType (A.Function _ _ _ fs vp) = Map.difference (freeNamesIn vp) (freeNamesIn fs)
- doSpecType st = doGeneric st
+ doSpecType st = flattenTree $ descend st
-- | Replace names.
--