Fixed many of the modules to use the new Polyplate-based Traversal system
This commit is contained in:
parent
a3bcb32937
commit
890e7ea9a6
|
@ -363,6 +363,28 @@ abbrevModeOfSpec s
|
||||||
A.RetypesExpr _ am _ _ -> am
|
A.RetypesExpr _ am _ _ -> am
|
||||||
_ -> A.Original
|
_ -> A.Original
|
||||||
|
|
||||||
|
-- | Resolve a datatype into its underlying type -- i.e. if it's a named data
|
||||||
|
-- type, then return the underlying real type. This will recurse.
|
||||||
|
underlyingType :: forall m. (CSMR m, Die m) => Meta -> A.Type -> m A.Type
|
||||||
|
underlyingType m = applyDepthM doType
|
||||||
|
where
|
||||||
|
doType :: A.Type -> m A.Type
|
||||||
|
-- This is fairly subtle: after resolving a user type, we have to recurse
|
||||||
|
-- on the resulting type.
|
||||||
|
doType t@(A.UserDataType _) = resolveUserType m t >>= underlyingType m
|
||||||
|
doType t = return t
|
||||||
|
|
||||||
|
-- | Like underlyingType, but only do the "outer layer": if you give this a
|
||||||
|
-- user type that's an array of user types, then you'll get back an array of
|
||||||
|
-- user types.
|
||||||
|
resolveUserType :: (CSMR m, Die m) => Meta -> A.Type -> m A.Type
|
||||||
|
resolveUserType m (A.UserDataType n)
|
||||||
|
= do st <- specTypeOfName n
|
||||||
|
case st of
|
||||||
|
A.DataType _ t -> resolveUserType m t
|
||||||
|
_ -> dieP m $ "Not a type name: " ++ show n
|
||||||
|
resolveUserType _ t = return t
|
||||||
|
|
||||||
-- | Add array dimensions to a type; if it's already an array it'll just add
|
-- | Add array dimensions to a type; if it's already an array it'll just add
|
||||||
-- the new dimensions to the existing array.
|
-- the new dimensions to the existing array.
|
||||||
addDimensions :: [A.Dimension] -> A.Type -> A.Type
|
addDimensions :: [A.Dimension] -> A.Type -> A.Type
|
||||||
|
|
|
@ -16,11 +16,13 @@ You should have received a copy of the GNU General Public License along
|
||||||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
-- | Traversal strategies over the AST and other data types.
|
-- | Traversal strategies over the AST and other data types. This is now mainly
|
||||||
|
-- a collection of extra Tock-specific utilities that go on top of Polyplate
|
||||||
module Traversal (
|
module Traversal (
|
||||||
TransformM, Transform
|
TransformM, Transform, TransformStructured
|
||||||
, CheckM, Check
|
, CheckM, Check
|
||||||
, ExtOpMP, ExtOpMS, ExtOpMSP, extOpMS
|
, ExtOpMP, ExtOpMS, ExtOpMSP, extOpMS
|
||||||
|
, applyBottomUpMS
|
||||||
, module Data.Generics.Polyplate
|
, module Data.Generics.Polyplate
|
||||||
, module Data.Generics.Polyplate.Schemes
|
, module Data.Generics.Polyplate.Schemes
|
||||||
) where
|
) where
|
||||||
|
@ -95,3 +97,13 @@ extOpMS ops (_, f)
|
||||||
`extOpM` (f :: A.Structured A.Alternative -> m (A.Structured A.Alternative))
|
`extOpM` (f :: A.Structured A.Alternative -> m (A.Structured A.Alternative))
|
||||||
`extOpM` (f :: A.Structured () -> m (A.Structured ()))
|
`extOpM` (f :: A.Structured () -> m (A.Structured ()))
|
||||||
|
|
||||||
|
applyBottomUpMS :: (PolyplateM t (ExtOpMSP BaseOp) () PassM) =>
|
||||||
|
(forall a. (Data a, PolyplateM (A.Structured a) () (ExtOpMSP BaseOp) PassM) =>
|
||||||
|
(A.Structured a -> PassM (A.Structured a)))
|
||||||
|
-> t -> PassM t
|
||||||
|
applyBottomUpMS f = makeRecurseM ops
|
||||||
|
where
|
||||||
|
ops = baseOp `extOpMS` (ops, makeBottomUpM ops f)
|
||||||
|
|
||||||
|
type TransformStructured ops
|
||||||
|
= (PolyplateM (A.Structured t) () ops PassM, Data t) => Transform (A.Structured t)
|
||||||
|
|
|
@ -31,18 +31,18 @@ import Traversal
|
||||||
import Types
|
import Types
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
simplifyComms :: [Pass]
|
simplifyComms :: [Pass A.AST]
|
||||||
simplifyComms =
|
simplifyComms =
|
||||||
[ outExprs
|
[ outExprs
|
||||||
, transformInputCase
|
, transformInputCase
|
||||||
, transformProtocolInput
|
, transformProtocolInput
|
||||||
]
|
]
|
||||||
|
|
||||||
outExprs :: Pass
|
outExprs :: PassOn A.Process
|
||||||
outExprs = pass "Define temporary variables for outputting expressions"
|
outExprs = pass "Define temporary variables for outputting expressions"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
||||||
[Prop.outExpressionRemoved]
|
[Prop.outExpressionRemoved]
|
||||||
(applyDepthM doProcess)
|
(applyBottomUpM doProcess)
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Output m c ois)
|
doProcess (A.Output m c ois)
|
||||||
|
@ -135,11 +135,11 @@ ALT
|
||||||
-- process D
|
-- process D
|
||||||
-}
|
-}
|
||||||
|
|
||||||
transformInputCase :: Pass
|
transformInputCase :: PassOn A.Process
|
||||||
transformInputCase = pass "Transform ? CASE statements/guards into plain CASE"
|
transformInputCase = pass "Transform ? CASE statements/guards into plain CASE"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
||||||
[Prop.inputCaseRemoved]
|
[Prop.inputCaseRemoved]
|
||||||
(applyDepthM doProcess)
|
(applyBottomUpM doProcess)
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Input m v (A.InputCase m' s))
|
doProcess (A.Input m v (A.InputCase m' s))
|
||||||
|
@ -182,11 +182,11 @@ transformInputCase = pass "Transform ? CASE statements/guards into plain CASE"
|
||||||
-- Leave other guards untouched.
|
-- Leave other guards untouched.
|
||||||
doAlternative m a = return $ A.Only m a
|
doAlternative m a = return $ A.Only m a
|
||||||
|
|
||||||
transformProtocolInput :: Pass
|
transformProtocolInput :: PassOn2 A.Process A.Alternative
|
||||||
transformProtocolInput = pass "Flatten sequential protocol inputs into multiple inputs"
|
transformProtocolInput = pass "Flatten sequential protocol inputs into multiple inputs"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.inputCaseRemoved])
|
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.inputCaseRemoved])
|
||||||
[Prop.seqInputsFlattened]
|
[Prop.seqInputsFlattened]
|
||||||
(applyDepthM2 doProcess doAlternative)
|
(applyBottomUpM2 doProcess doAlternative)
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Input m v (A.InputSimple m' iis@(_:_:_)))
|
doProcess (A.Input m v (A.InputSimple m' iis@(_:_:_)))
|
||||||
|
|
|
@ -35,7 +35,7 @@ import Traversal
|
||||||
import Types
|
import Types
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
simplifyExprs :: [Pass]
|
simplifyExprs :: [Pass A.AST]
|
||||||
simplifyExprs =
|
simplifyExprs =
|
||||||
[ functionsToProcs
|
[ functionsToProcs
|
||||||
, removeAfter
|
, removeAfter
|
||||||
|
@ -51,7 +51,7 @@ builtInOperatorFunction = (`elem` occamBuiltInOperatorFunctions) . A.nameName
|
||||||
|
|
||||||
|
|
||||||
-- | Convert FUNCTION declarations to PROCs.
|
-- | Convert FUNCTION declarations to PROCs.
|
||||||
functionsToProcs :: Pass
|
functionsToProcs :: PassOn A.Specification
|
||||||
functionsToProcs = pass "Convert FUNCTIONs to PROCs"
|
functionsToProcs = pass "Convert FUNCTIONs to PROCs"
|
||||||
(Prop.agg_namesDone ++ [Prop.expressionTypesChecked, Prop.parUsageChecked,
|
(Prop.agg_namesDone ++ [Prop.expressionTypesChecked, Prop.parUsageChecked,
|
||||||
Prop.functionTypesChecked])
|
Prop.functionTypesChecked])
|
||||||
|
@ -106,11 +106,11 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
|
||||||
|
|
||||||
-- | Convert AFTER expressions to the equivalent using MINUS (which is how the
|
-- | Convert AFTER expressions to the equivalent using MINUS (which is how the
|
||||||
-- occam 3 manual defines AFTER).
|
-- occam 3 manual defines AFTER).
|
||||||
removeAfter :: Pass
|
removeAfter :: PassOn A.Expression
|
||||||
removeAfter = pass "Convert AFTER to MINUS"
|
removeAfter = pass "Convert AFTER to MINUS"
|
||||||
[Prop.expressionTypesChecked]
|
[Prop.expressionTypesChecked]
|
||||||
[Prop.afterRemoved]
|
[Prop.afterRemoved]
|
||||||
(applyDepthM2 doExpression doExpressionList)
|
(applyDepthM doExpression)
|
||||||
where
|
where
|
||||||
doFunctionCall :: (Meta -> A.Name -> [A.Expression] -> a)
|
doFunctionCall :: (Meta -> A.Name -> [A.Expression] -> a)
|
||||||
-> Meta -> A.Name -> [A.Expression] -> PassM a
|
-> Meta -> A.Name -> [A.Expression] -> PassM a
|
||||||
|
@ -145,11 +145,11 @@ removeAfter = pass "Convert AFTER to MINUS"
|
||||||
|
|
||||||
-- | For array literals that include other arrays, burst them into their
|
-- | For array literals that include other arrays, burst them into their
|
||||||
-- elements.
|
-- elements.
|
||||||
expandArrayLiterals :: Pass
|
expandArrayLiterals :: PassOn A.ArrayElem
|
||||||
expandArrayLiterals = pass "Expand array literals"
|
expandArrayLiterals = pass "Expand array literals"
|
||||||
[Prop.expressionTypesChecked, Prop.processTypesChecked]
|
[Prop.expressionTypesChecked, Prop.processTypesChecked]
|
||||||
[Prop.arrayLiteralsExpanded]
|
[Prop.arrayLiteralsExpanded]
|
||||||
(applyDepthM doArrayElem)
|
(applyBottomUpM doArrayElem)
|
||||||
where
|
where
|
||||||
doArrayElem :: A.Structured A.Expression -> PassM (A.Structured A.Expression)
|
doArrayElem :: A.Structured A.Expression -> PassM (A.Structured A.Expression)
|
||||||
doArrayElem ae@(A.Only _ e)
|
doArrayElem ae@(A.Only _ e)
|
||||||
|
@ -189,13 +189,14 @@ expandArrayLiterals = pass "Expand array literals"
|
||||||
-- Therefore, we only need to pull up the counts for SEQ, PAR and ALT
|
-- Therefore, we only need to pull up the counts for SEQ, PAR and ALT
|
||||||
--
|
--
|
||||||
-- TODO for simplification, we could avoid pulling up replication counts that are known to be constants
|
-- TODO for simplification, we could avoid pulling up replication counts that are known to be constants
|
||||||
--
|
|
||||||
-- TODO we should also pull up the step counts
|
|
||||||
pullRepCounts :: Pass
|
pullRepCounts :: Pass
|
||||||
pullRepCounts = pass "Pull up replicator counts for SEQs, PARs and ALTs"
|
pullRepCounts = pass "Pull up replicator counts for SEQs, PARs and ALTs"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
(Prop.agg_namesDone ++ Prop.agg_typesDone)
|
||||||
[]
|
[]
|
||||||
(applyDepthM pullRepCountProc)
|
(applyDepthM2
|
||||||
|
(pullRepCount :: A.Structured A.Process -> PassM (A.Structured A.Process))
|
||||||
|
(pullRepCount :: A.Structured A.Alternative -> PassM (A.Structured A.Alternative))
|
||||||
|
)
|
||||||
where
|
where
|
||||||
pullRepCountStr :: Data a => Bool -> A.Structured a
|
pullRepCountStr :: Data a => Bool -> A.Structured a
|
||||||
-> StateT (A.Structured A.Process -> A.Structured A.Process)
|
-> StateT (A.Structured A.Process -> A.Structured A.Process)
|
||||||
|
@ -221,11 +222,11 @@ pullRepCounts = pass "Pull up replicator counts for SEQs, PARs and ALTs"
|
||||||
return $ A.Seq m $ spec $ A.Only m $ A.Par m p body'
|
return $ A.Seq m $ spec $ A.Only m $ A.Par m p body'
|
||||||
pullRepCountProc p = return p
|
pullRepCountProc p = return p
|
||||||
|
|
||||||
transformConstr :: Pass
|
transformConstr :: PassOnOps (ExtOpMSP BaseOp)
|
||||||
transformConstr = pass "Transform array constructors into initialisation code"
|
transformConstr = pass "Transform array constructors into initialisation code"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.subscriptsPulledUp])
|
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.subscriptsPulledUp])
|
||||||
[Prop.arrayConstructorsRemoved]
|
[Prop.arrayConstructorsRemoved]
|
||||||
(applyDepthSM doStructured)
|
(applyBottomUpMS doStructured)
|
||||||
where
|
where
|
||||||
-- For arrays, this takes a constructor expression:
|
-- For arrays, this takes a constructor expression:
|
||||||
-- VAL type name IS [i = rep | expr]:
|
-- VAL type name IS [i = rep | expr]:
|
||||||
|
@ -329,19 +330,26 @@ transformConstr = pass "Transform array constructors into initialisation code"
|
||||||
|
|
||||||
doStructured s = return s
|
doStructured s = return s
|
||||||
|
|
||||||
|
type PullUpOps = ExtOpMSP BaseOp
|
||||||
|
`ExtOpMP` A.Process
|
||||||
|
`ExtOpMP` A.Specification
|
||||||
|
`ExtOpMP` A.LiteralRepr
|
||||||
|
`ExtOpMP` A.Expression
|
||||||
|
`ExtOpMP` A.Variable
|
||||||
|
`ExtOpMP` A.ExpressionList
|
||||||
|
|
||||||
-- | Find things that need to be moved up to their enclosing Structured, and do
|
-- | Find things that need to be moved up to their enclosing Structured, and do
|
||||||
-- so.
|
-- so.
|
||||||
pullUp :: Bool -> Pass
|
pullUp :: Bool -> PassOnOps PullUpOps
|
||||||
pullUp pullUpArraysInsideRecords = pass "Pull up definitions"
|
pullUp pullUpArraysInsideRecords = pass "Pull up definitions"
|
||||||
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.functionsRemoved, Prop.seqInputsFlattened])
|
(Prop.agg_namesDone ++ Prop.agg_typesDone ++ [Prop.functionsRemoved, Prop.seqInputsFlattened])
|
||||||
[Prop.functionCallsRemoved, Prop.subscriptsPulledUp]
|
[Prop.functionCallsRemoved, Prop.subscriptsPulledUp]
|
||||||
recurse
|
recurse
|
||||||
where
|
where
|
||||||
ops :: Ops
|
ops :: PullUpOps
|
||||||
ops = baseOp
|
ops = baseOp
|
||||||
`extOpS` doStructured
|
`extOpS` doStructured
|
||||||
`extOp` doProcess
|
`extOp` doProcess
|
||||||
`extOp` doRepArray
|
|
||||||
`extOp` doSpecification
|
`extOp` doSpecification
|
||||||
`extOp` doLiteralRepr
|
`extOp` doLiteralRepr
|
||||||
`extOp` doExpression
|
`extOp` doExpression
|
||||||
|
@ -354,7 +362,7 @@ pullUp pullUpArraysInsideRecords = pass "Pull up definitions"
|
||||||
|
|
||||||
-- | When we encounter a Structured, create a new pulled items state,
|
-- | When we encounter a Structured, create a new pulled items state,
|
||||||
-- recurse over it, then apply whatever pulled items we found to it.
|
-- recurse over it, then apply whatever pulled items we found to it.
|
||||||
doStructured :: Data a => A.Structured a -> PassM (A.Structured a)
|
doStructured :: TransformStructured PullUpOps
|
||||||
doStructured s
|
doStructured s
|
||||||
= do pushPullContext
|
= do pushPullContext
|
||||||
-- Recurse over the body, then apply the pulled items to it
|
-- Recurse over the body, then apply the pulled items to it
|
||||||
|
|
|
@ -34,7 +34,7 @@ import Traversal
|
||||||
import Types
|
import Types
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
simplifyProcs :: [Pass]
|
simplifyProcs :: [Pass A.AST]
|
||||||
simplifyProcs =
|
simplifyProcs =
|
||||||
[ parsToProcs
|
[ parsToProcs
|
||||||
, removeParAssign
|
, removeParAssign
|
||||||
|
@ -42,11 +42,11 @@ simplifyProcs =
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Wrap the subprocesses of PARs in no-arg PROCs.
|
-- | Wrap the subprocesses of PARs in no-arg PROCs.
|
||||||
parsToProcs :: Pass
|
parsToProcs :: PassOn A.Process
|
||||||
parsToProcs = pass "Wrap PAR subprocesses in PROCs"
|
parsToProcs = pass "Wrap PAR subprocesses in PROCs"
|
||||||
[Prop.parUsageChecked]
|
[Prop.parUsageChecked]
|
||||||
[Prop.parsWrapped]
|
[Prop.parsWrapped]
|
||||||
(applyDepthM doProcess)
|
(applyBottomUpM doProcess)
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Par m pm s)
|
doProcess (A.Par m pm s)
|
||||||
|
@ -64,11 +64,11 @@ parsToProcs = pass "Wrap PAR subprocesses in PROCs"
|
||||||
return $ A.Spec m s (A.Only m (A.ProcCall m n []))
|
return $ A.Spec m s (A.Only m (A.ProcCall m n []))
|
||||||
|
|
||||||
-- | Turn parallel assignment into multiple single assignments through temporaries.
|
-- | Turn parallel assignment into multiple single assignments through temporaries.
|
||||||
removeParAssign :: Pass
|
removeParAssign :: PassOn A.Process
|
||||||
removeParAssign = pass "Remove parallel assignment"
|
removeParAssign = pass "Remove parallel assignment"
|
||||||
[Prop.parUsageChecked, Prop.functionsRemoved, Prop.functionCallsRemoved]
|
[Prop.parUsageChecked, Prop.functionsRemoved, Prop.functionCallsRemoved]
|
||||||
[Prop.assignParRemoved]
|
[Prop.assignParRemoved]
|
||||||
(applyDepthM doProcess)
|
(applyBottomUpM doProcess)
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Assign m vs@(_:_:_) (A.ExpressionList _ es))
|
doProcess (A.Assign m vs@(_:_:_) (A.ExpressionList _ es))
|
||||||
|
@ -81,14 +81,14 @@ removeParAssign = pass "Remove parallel assignment"
|
||||||
doProcess p = return p
|
doProcess p = return p
|
||||||
|
|
||||||
-- | Turn assignment of arrays and records into multiple assignments.
|
-- | Turn assignment of arrays and records into multiple assignments.
|
||||||
flattenAssign :: Pass
|
flattenAssign :: PassOnOps (ExtOpMSP BaseOp `ExtOpMP` A.Process)
|
||||||
flattenAssign = pass "Flatten assignment"
|
flattenAssign = pass "Flatten assignment"
|
||||||
(Prop.agg_typesDone ++ [Prop.assignParRemoved])
|
(Prop.agg_typesDone ++ [Prop.assignParRemoved])
|
||||||
[Prop.assignFlattened]
|
[Prop.assignFlattened]
|
||||||
(makeRecurse ops)
|
(makeRecurseM ops)
|
||||||
where
|
where
|
||||||
ops :: Ops
|
ops = baseOp `extOpMS` (ops, makeBottomUpM ops doStructured)
|
||||||
ops = extOpD (extOpSD baseOp ops doStructured) ops doProcess
|
`extOpM` makeBottomUpM ops doProcess
|
||||||
|
|
||||||
doProcess :: A.Process -> PassM A.Process
|
doProcess :: A.Process -> PassM A.Process
|
||||||
doProcess (A.Assign m [v] (A.ExpressionList m' [e]))
|
doProcess (A.Assign m [v] (A.ExpressionList m' [e]))
|
||||||
|
|
|
@ -37,7 +37,7 @@ import Traversal
|
||||||
import Types
|
import Types
|
||||||
import Utils
|
import Utils
|
||||||
|
|
||||||
unnest :: [Pass]
|
unnest :: [Pass A.AST]
|
||||||
unnest =
|
unnest =
|
||||||
[ removeFreeNames
|
[ removeFreeNames
|
||||||
, removeNesting
|
, removeNesting
|
||||||
|
@ -77,22 +77,12 @@ freeNamesIn = doGeneric
|
||||||
doSpecType st = doGeneric st
|
doSpecType st = doGeneric st
|
||||||
|
|
||||||
-- | Replace names.
|
-- | Replace names.
|
||||||
--
|
replaceNames :: Data t => [(A.Name, A.Name)] -> t -> t
|
||||||
-- This has to have extra cleverness due to a really nasty bug. Array types can
|
replaceNames map v = runIdentity $ applyDepthM doName v
|
||||||
-- have expressions as dimensions, and those expressions can contain free names
|
|
||||||
-- which are being replaced. This is fine, but when that happens we need to update
|
|
||||||
-- CompState so that the type has the replaced name, not the old name.
|
|
||||||
replaceNames :: Data t => [(A.Name, A.Name)] -> t -> PassM t
|
|
||||||
replaceNames map v = recurse v
|
|
||||||
where
|
where
|
||||||
smap = Map.fromList [(A.nameName f, t) | (f, t) <- map]
|
smap = Map.fromList [(A.nameName f, t) | (f, t) <- map]
|
||||||
|
|
||||||
ops :: Ops
|
doName :: A.Name -> Identity A.Name
|
||||||
ops = baseOp `extOp` doName `extOp` doSpecification
|
|
||||||
recurse :: Data a => Transform a
|
|
||||||
recurse = makeRecurse ops
|
|
||||||
|
|
||||||
doName :: Transform A.Name
|
|
||||||
doName n = return $ Map.findWithDefault n (A.nameName n) smap
|
doName n = return $ Map.findWithDefault n (A.nameName n) smap
|
||||||
|
|
||||||
doSpecification :: Transform A.Specification
|
doSpecification :: Transform A.Specification
|
||||||
|
@ -107,11 +97,11 @@ replaceNames map v = recurse v
|
||||||
return $ A.Specification m n' sp'
|
return $ A.Specification m n' sp'
|
||||||
|
|
||||||
-- | Turn free names in PROCs into arguments.
|
-- | Turn free names in PROCs into arguments.
|
||||||
removeFreeNames :: Pass
|
removeFreeNames :: PassOn2 A.Specification A.Process
|
||||||
removeFreeNames = pass "Convert free names to arguments"
|
removeFreeNames = pass "Convert free names to arguments"
|
||||||
[Prop.mainTagged, Prop.parsWrapped, Prop.functionCallsRemoved]
|
[Prop.mainTagged, Prop.parsWrapped, Prop.functionCallsRemoved]
|
||||||
[Prop.freeNamesToArgs]
|
[Prop.freeNamesToArgs]
|
||||||
(applyDepthM2 doSpecification doProcess)
|
(applyBottomUpM2 doSpecification doProcess)
|
||||||
where
|
where
|
||||||
doSpecification :: A.Specification -> PassM A.Specification
|
doSpecification :: A.Specification -> PassM A.Specification
|
||||||
doSpecification spec = case spec of
|
doSpecification spec = case spec of
|
||||||
|
@ -196,25 +186,26 @@ removeFreeNames = pass "Convert free names to arguments"
|
||||||
doProcess p = return p
|
doProcess p = return p
|
||||||
|
|
||||||
-- | Pull nested declarations to the top level.
|
-- | Pull nested declarations to the top level.
|
||||||
removeNesting :: Pass
|
removeNesting :: PassASTOnOps (ExtOpMSP BaseOp)
|
||||||
removeNesting = pass "Pull nested definitions to top level"
|
removeNesting = pass "Pull nested definitions to top level"
|
||||||
[Prop.freeNamesToArgs]
|
[Prop.freeNamesToArgs]
|
||||||
[Prop.nestedPulled]
|
[Prop.nestedPulled]
|
||||||
(passOnlyOnAST "removeNesting" $ \s ->
|
(passOnlyOnAST "removeNesting" $ \s ->
|
||||||
do pushPullContext
|
do pushPullContext
|
||||||
s' <- recurse s >>= applyPulled
|
s' <- (makeRecurse ops) s >>= applyPulled
|
||||||
popPullContext
|
popPullContext
|
||||||
return s')
|
return s')
|
||||||
where
|
where
|
||||||
ops :: Ops
|
ops :: ExtOpMSP BaseOp
|
||||||
ops = baseOp `extOpS` doStructured
|
ops = baseOp `extOpMS` (ops, doStructured)
|
||||||
|
|
||||||
recurse :: Recurse
|
|
||||||
recurse = makeRecurse ops
|
|
||||||
descend :: Descend
|
|
||||||
descend = makeDescend ops
|
|
||||||
|
|
||||||
doStructured :: Data t => Transform (A.Structured t)
|
recurse :: RecurseM PassM (ExtOpMSP BaseOp)
|
||||||
|
recurse = makeRecurseM ops
|
||||||
|
descend :: DescendM PassM (ExtOpMSP BaseOp)
|
||||||
|
descend = makeDescendM ops
|
||||||
|
|
||||||
|
doStructured :: TransformStructured (ExtOpMSP BaseOp)
|
||||||
doStructured s@(A.Spec m spec subS)
|
doStructured s@(A.Spec m spec subS)
|
||||||
= do spec'@(A.Specification _ n st) <- recurse spec
|
= do spec'@(A.Specification _ n st) <- recurse spec
|
||||||
isConst <- isConstantName n
|
isConst <- isConstantName n
|
||||||
|
|
Loading…
Reference in New Issue
Block a user