diff --git a/fco2/Main.hs b/fco2/Main.hs index 9bc6aea..83c9941 100644 --- a/fco2/Main.hs +++ b/fco2/Main.hs @@ -10,12 +10,14 @@ import Pass import PrettyShow import Parse import SimplifyExprs +import SimplifyProcs import Unnest import GenerateC passes :: [(String, Pass)] passes = [ ("Simplify expressions", simplifyExprs) + , ("Simplify processes", simplifyProcs) , ("Flatten nested declarations", unnest) ] diff --git a/fco2/Makefile b/fco2/Makefile index df317b8..bbca891 100644 --- a/fco2/Makefile +++ b/fco2/Makefile @@ -14,6 +14,7 @@ sources = \ Pass.hs \ PrettyShow.hs \ SimplifyExprs.hs \ + SimplifyProcs.hs \ Types.hs \ Unnest.hs diff --git a/fco2/SimplifyProcs.hs b/fco2/SimplifyProcs.hs new file mode 100644 index 0000000..4d1d012 --- /dev/null +++ b/fco2/SimplifyProcs.hs @@ -0,0 +1,39 @@ +-- | Simplify processes. +module SimplifyProcs (simplifyProcs) where + +import Control.Monad.State +import Data.Generics +import qualified Data.Map as Map +import Data.Maybe + +import qualified AST as A +import Metadata +import ParseState +import Types +import Pass + +simplifyProcs :: A.Process -> PassM A.Process +simplifyProcs p + = parsToProcs p + +-- | Wrap the subprocesses of PARs in no-arg PROCs. +parsToProcs :: Data t => t -> PassM t +parsToProcs = doGeneric `extM` doProcess + where + doGeneric :: Data t => t -> PassM t + doGeneric = gmapM parsToProcs + + doProcess :: A.Process -> PassM A.Process + doProcess (A.Par m pm ps) + = do ps' <- mapM parsToProcs ps + procs <- mapM (makeNonceProc m) ps' + let calls = [A.ProcSpec m s (A.ProcCall m n []) | s@(A.Specification m n _) <- procs] + return $ A.Par m pm calls + doProcess (A.ParRep m pm rep p) + = do p' <- parsToProcs p + rep' <- parsToProcs rep + s@(A.Specification _ n _) <- makeNonceProc m p' + let call = A.ProcSpec m s (A.ProcCall m n []) + return $ A.ParRep m pm rep' call + doProcess p = doGeneric p + diff --git a/fco2/Unnest.hs b/fco2/Unnest.hs index 39856d4..9bd8d26 100644 --- a/fco2/Unnest.hs +++ b/fco2/Unnest.hs @@ -14,32 +14,10 @@ import Pass unnest :: A.Process -> PassM A.Process unnest p - = parsToProcs p - >>= removeFreeNames + = removeFreeNames p >>= removeNesting >>= removeNoSpecs --- | Wrap the subprocesses of PARs in no-arg PROCs. -parsToProcs :: Data t => t -> PassM t -parsToProcs = doGeneric `extM` doProcess - where - doGeneric :: Data t => t -> PassM t - doGeneric = gmapM parsToProcs - - doProcess :: A.Process -> PassM A.Process - doProcess (A.Par m pm ps) - = do ps' <- mapM parsToProcs ps - procs <- mapM (makeNonceProc m) ps' - let calls = [A.ProcSpec m s (A.ProcCall m n []) | s@(A.Specification m n _) <- procs] - return $ A.Par m pm calls - doProcess (A.ParRep m pm rep p) - = do p' <- parsToProcs p - rep' <- parsToProcs rep - s@(A.Specification _ n _) <- makeNonceProc m p' - let call = A.ProcSpec m s (A.ProcCall m n []) - return $ A.ParRep m pm rep' call - doProcess p = doGeneric p - type NameMap = Map.Map String A.Name -- | Get the set of free names within a block of code.