From edc3a7e910edb5a57c35161c918991f7e65b41ee Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 28 Jan 2008 17:21:13 +0000 Subject: [PATCH] Removed the die function (that has no source position) and as far as possible replaced all its uses with dieP and a valid position --- Main.hs | 4 +- backends/GenerateC.hs | 38 +++++++------- backends/GenerateCPPCSP.hs | 12 ++--- backends/GenerateCTest.hs | 36 ++++++------- backends/TLP.hs | 25 ++++----- checks/Check.hs | 8 +-- common/CompState.hs | 6 +-- common/Errors.hs | 10 ++-- common/EvalConstants.hs | 8 +-- common/EvalLiterals.hs | 2 +- common/Types.hs | 48 ++++++++--------- frontends/ParseOccam.hs | 88 ++++++++++++++++---------------- frontends/RainPasses.hs | 4 +- transformations/SimplifyExprs.hs | 4 +- transformations/SimplifyProcs.hs | 2 +- transformations/SimplifyTypes.hs | 3 +- transformations/Unnest.hs | 2 +- 17 files changed, 149 insertions(+), 151 deletions(-) diff --git a/Main.hs b/Main.hs index a8cdb5a..50364f7 100644 --- a/Main.hs +++ b/Main.hs @@ -158,7 +158,7 @@ instance Die (StateT [FilePath] PassM) where compileFull :: String -> StateT [FilePath] PassM () compileFull fn = do optsPS <- lift get destBin <- case csOutputFile optsPS of - "-" -> die "Must specify an output file when using full-compile mode" + "-" -> dieReport (Nothing, "Must specify an output file when using full-compile mode") file -> return file -- First, compile the code into C/C++: @@ -213,7 +213,7 @@ compileFull fn = do optsPS <- lift get exitCode <- liftIO $ waitForProcess p case exitCode of ExitSuccess -> return () - ExitFailure n -> die $ "Command \"" ++ cmd ++ "\" failed, exiting with code: " ++ show n + ExitFailure n -> dieReport (Nothing, "Command \"" ++ cmd ++ "\" failed, exiting with code: " ++ show n) -- | Picks out the handle from the options and passes it to the function: useOutputOptions :: (Handle -> PassM ()) -> PassM () diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 4454f61..701ac62 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -91,7 +91,7 @@ data GenOps = GenOps { -- | Generates the number of bytes in a fixed size type, fails if a free dimension is present and is not allowed. -- The Either parameter is either an array variable (to use the _sizes array of) or a boolean specifying -- wheter or not one free dimension is allowed (True <=> allowed). - genBytesIn :: GenOps -> A.Type -> Either Bool A.Variable -> CGen (), + genBytesIn :: GenOps -> Meta -> A.Type -> Either Bool A.Variable -> CGen (), -- | Generates a case statement over the given expression with the structured as the body. genCase :: GenOps -> Meta -> A.Expression -> A.Structured -> CGen (), genCheckedConversion :: GenOps -> Meta -> A.Type -> A.Type -> CGen () -> CGen (), @@ -428,15 +428,15 @@ indexOfFreeDimensions = (mapMaybe indexOfFreeDimensions') . (zip [0..]) -- | Generate the number of bytes in a type. -cgenBytesIn :: GenOps -> A.Type -> Either Bool A.Variable -> CGen () -cgenBytesIn ops t v +cgenBytesIn :: GenOps -> Meta -> A.Type -> Either Bool A.Variable -> CGen () +cgenBytesIn ops m t v = do case (t, v) of (A.Array ds _, Left freeDimensionAllowed) -> case (length (indexOfFreeDimensions ds), freeDimensionAllowed) of (0,_) -> return () - (1,False) -> die "genBytesIn type with unknown dimension, when unknown dimensions are not allowed" + (1,False) -> dieP m "genBytesIn type with unknown dimension, when unknown dimensions are not allowed" (1,True) -> return () - (_,_) -> die "genBytesIn type with more than one free dimension" + (_,_) -> dieP m "genBytesIn type with more than one free dimension" _ -> return () genBytesIn' ops t where @@ -458,7 +458,7 @@ cgenBytesIn ops t v genBytesIn' ops t = case call getScalarType ops t of Just s -> tell ["sizeof(", s, ")"] - Nothing -> dieC $ formatCode "genBytesIn' %" t + Nothing -> diePC m $ formatCode "genBytesIn' %" t genBytesInArrayDim :: (A.Dimension,Int) -> CGen () genBytesInArrayDim (A.Dimension n, _) = tell [show n, "*"] @@ -875,7 +875,7 @@ cgenExpression _ (A.False m) = tell ["false"] cgenExpression ops (A.IntrinsicFunctionCall m s es) = call genIntrinsicFunction ops m s es --cgenExpression ops (A.SubscriptedExpr m s e) --cgenExpression ops (A.BytesInExpr m e) -cgenExpression ops (A.BytesInType m t) = call genBytesIn ops t (Left False) +cgenExpression ops (A.BytesInType m t) = call genBytesIn ops m t (Left False) --cgenExpression ops (A.OffsetOf m t n) --cgenExpression ops (A.ExprConstr {}) cgenExpression ops (A.AllocMobile m t me) = call genAllocMobile ops m t me @@ -975,10 +975,10 @@ cgenInputItem ops c (A.InCounted m cv av) tell [","] fst $ abbrevVariable ops A.Abbrev t av tell [","] - subT <- trivialSubscriptType t + subT <- trivialSubscriptType m t call genVariable ops cv tell ["*"] - call genBytesIn ops subT (Right av) + call genBytesIn ops m subT (Right av) tell [");"] cgenInputItem ops c (A.InVariable m v) = do t <- typeOfVariable v @@ -996,7 +996,7 @@ cgenInputItem ops c (A.InVariable m v) tell [","] rhs tell [","] - call genBytesIn ops t (Right v) + call genBytesIn ops m t (Right v) tell [");"] cgenOutputItem :: GenOps -> A.Variable -> A.OutputItem -> CGen () @@ -1010,10 +1010,10 @@ cgenOutputItem ops c (A.OutCounted m ce ae) tell [","] fst $ abbrevVariable ops A.Abbrev t v tell [","] - subT <- trivialSubscriptType t + subT <- trivialSubscriptType m t call genExpression ops ce tell ["*"] - call genBytesIn ops subT (Right v) + call genBytesIn ops m subT (Right v) tell [");"] cgenOutputItem ops c (A.OutExpression m e) = do t <- typeOfExpression e @@ -1030,7 +1030,7 @@ cgenOutputItem ops c (A.OutExpression m e) tell [","] fst $ abbrevVariable ops A.Abbrev t v tell [","] - call genBytesIn ops t (Right v) + call genBytesIn ops m t (Right v) tell [");"] --}}} @@ -1162,9 +1162,9 @@ cgenRetypeSizes :: GenOps -> Meta -> A.Type -> A.Name -> A.Type -> A.Variable -> cgenRetypeSizes _ _ (A.Chan {}) _ (A.Chan {}) _ = return () cgenRetypeSizes ops m destT destN srcT srcV = let size = do tell ["occam_check_retype("] - call genBytesIn ops srcT (Right srcV) + call genBytesIn ops m srcT (Right srcV) tell [","] - call genBytesIn ops destT (Left True) + call genBytesIn ops m destT (Left True) tell [","] genMeta m tell [")"] in @@ -1188,7 +1188,7 @@ cgenRetypeSizes ops m destT destN srcT srcV case free of Just _ -> size Nothing -> - die "genRetypeSizes expecting free dimension" + dieP m "genRetypeSizes expecting free dimension" A.Dimension n -> tell [show n] | d <- destDS] call genArraySize ops False (genLeftB >> seqComma dims >> genRightB) destN @@ -1271,13 +1271,13 @@ cdeclareArraySizes ops t name -- | Generate a C literal to initialise an _sizes array with, where all the -- dimensions are fixed. cgenArraySizesLiteral :: GenOps -> A.Name -> A.Type -> CGen () -cgenArraySizesLiteral ops _ (A.Array ds _) +cgenArraySizesLiteral ops n (A.Array ds _) = genLeftB >> seqComma dims >> genRightB where dims :: [CGen ()] dims = [case d of A.Dimension n -> tell [show n] - _ -> die "unknown dimension in array type" + _ -> dieP (findMeta n) "unknown dimension in array type" | d <- ds] -- | Initialise an item being declared. @@ -1858,7 +1858,7 @@ cgenAssert ops m e --{{{ mobiles cgenAllocMobile :: GenOps -> Meta -> A.Type -> Maybe A.Expression -> CGen() -cgenAllocMobile ops m (A.Mobile t) Nothing = tell ["malloc("] >> call genBytesIn ops t (Left False) >> tell [")"] +cgenAllocMobile ops m (A.Mobile t) Nothing = tell ["malloc("] >> call genBytesIn ops m t (Left False) >> tell [")"] --TODO add a pass, just for C, that pulls out the initialisation expressions for mobiles -- into a subsequent assignment cgenAllocMobile ops _ _ _ = call genMissing ops "Mobile allocation with initialising-expression" diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs index a146b36..9767ec1 100644 --- a/backends/GenerateCPPCSP.hs +++ b/backends/GenerateCPPCSP.hs @@ -314,14 +314,14 @@ cppgenInputItem ops c dest do call genVariable ops cv tell ["*"] t <- typeOfVariable av - subT <- trivialSubscriptType t - call genBytesIn ops subT (Right av) + subT <- trivialSubscriptType m t + call genBytesIn ops m subT (Right av) ) (A.InVariable m v) -> do ct <- typeOfVariable c t <- typeOfVariable v case (byteArrayChan ct,t) of - (True,_)-> recvBytes v (call genBytesIn ops t (Right v)) + (True,_)-> recvBytes v (call genBytesIn ops m t (Right v)) (False,A.Array {}) -> do tell ["tockRecvArray("] chan' tell [","] @@ -578,7 +578,7 @@ cppgenArraySizesLiteral ops n t@(A.Array ds _) = dims :: [CGen ()] dims = [case d of A.Dimension n -> tell [show n] - _ -> die "unknown dimension in array type" + _ -> dieP (findMeta n) "unknown dimension in array type" | d <- ds] -- | Changed because we initialise channels and arrays differently in C++ @@ -1093,9 +1093,9 @@ cppgenRetypeSizes _ _ (A.Chan {}) _ (A.Chan {}) _ = return () cppgenRetypeSizes ops m destT destN srcT srcV = let checkSize = do tell ["if(occam_check_retype("] - call genBytesIn ops srcT (Right srcV) + call genBytesIn ops m srcT (Right srcV) tell [","] - call genBytesIn ops destT (Left True) + call genBytesIn ops m destT (Left True) tell [","] genMeta m tell [")!=1){"] diff --git a/backends/GenerateCTest.hs b/backends/GenerateCTest.hs index 6530c3b..d146f6f 100644 --- a/backends/GenerateCTest.hs +++ b/backends/GenerateCTest.hs @@ -706,8 +706,8 @@ testRetypeSizes = TestList rep search replace str = subRegex (mkRegex search) str replace - showBytesInParams _ t (Right _) = tell ["$(" ++ show t ++ " Right)"] - showBytesInParams _ t v = tell ["$(" ++ show t ++ " " ++ show v ++ ")"] + showBytesInParams _ _ t (Right _) = tell ["$(" ++ show t ++ " Right)"] + showBytesInParams _ _ t v = tell ["$(" ++ show t ++ " " ++ show v ++ ")"] showArrSize _ _ sz _ = tell ["^("] >> sz >> tell [")"] over ops = ops {genBytesIn = showBytesInParams, genStop = override2 at, genArraySize = showArrSize} @@ -969,7 +969,7 @@ testInput = TestList -- defineName chanOut $ simpleDefDecl "cIn" (A.Chan A.DirInput (A.ChanAttributes False False) $ A.UserProtocol foo) overInputItemCase ops = ops {genInputItem = override2 caret} - over ops = ops {genBytesIn = (\_ t _ -> tell ["^(",show t,")"]) , genArraySubscript = override3 dollar} + over ops = ops {genBytesIn = (\_ _ t _ -> tell ["^(",show t,")"]) , genArraySubscript = override3 dollar} testOutput :: Test testOutput = TestList @@ -1054,33 +1054,33 @@ testOutput = TestList defineName chanOut $ simpleDefDecl "cOut" (A.Chan A.DirOutput (A.ChanAttributes False False) $ A.UserProtocol foo) overOutput ops = ops {genOutput = override2 caret} overOutputItem ops = ops {genOutputItem = override2 caret} - over ops = ops {genBytesIn = override2 caret} + over ops = ops {genBytesIn = override3 caret} testBytesIn :: Test testBytesIn = TestList [ - testBothSame "testBytesIn 0" "sizeof(int)" (tcall2 genBytesIn A.Int undefined) - ,testBothSame "testBytesIn 1" "sizeof(foo)" (tcall2 genBytesIn (A.Record foo) undefined) - ,testBoth "testBytesIn 2" "sizeof(Channel)" "sizeof(csp::One2OneChannel)" (tcall2 genBytesIn (A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) undefined) - ,testBoth "testBytesIn 3" "sizeof(Channel*)" "sizeof(csp::Chanin)" (tcall2 genBytesIn (A.Chan A.DirInput (A.ChanAttributes False False) A.Int) undefined) + testBothSame "testBytesIn 0" "sizeof(int)" (tcall3 genBytesIn undefined A.Int undefined) + ,testBothSame "testBytesIn 1" "sizeof(foo)" (tcall3 genBytesIn undefined (A.Record foo) undefined) + ,testBoth "testBytesIn 2" "sizeof(Channel)" "sizeof(csp::One2OneChannel)" (tcall3 genBytesIn undefined (A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) undefined) + ,testBoth "testBytesIn 3" "sizeof(Channel*)" "sizeof(csp::Chanin)" (tcall3 genBytesIn undefined (A.Chan A.DirInput (A.ChanAttributes False False) A.Int) undefined) --Array with a single known dimension: - ,testBothSame "testBytesIn 100" "5*sizeof(int)" (tcall2 genBytesIn (A.Array [A.Dimension 5] A.Int) (Left False)) + ,testBothSame "testBytesIn 100" "5*sizeof(int)" (tcall3 genBytesIn undefined (A.Array [A.Dimension 5] A.Int) (Left False)) --single unknown dimension, no variable, no free dimension allowed: - ,testBothFail "testBytesIn 101a" (tcall2 genBytesIn (A.Array [A.UnknownDimension] A.Int) (Left False)) + ,testBothFail "testBytesIn 101a" (tcall3 genBytesIn undefined (A.Array [A.UnknownDimension] A.Int) (Left False)) --single unknown dimension, no variable, free dimension allowed: - ,testBothSame "testBytesIn 101b" "sizeof(int)" (tcall2 genBytesIn (A.Array [A.UnknownDimension] A.Int) (Left True)) + ,testBothSame "testBytesIn 101b" "sizeof(int)" (tcall3 genBytesIn undefined (A.Array [A.UnknownDimension] A.Int) (Left True)) --single unknown dimension, with variable: - ,testBothSame "testBytesIn 102" "$(@0)*sizeof(int)" ((tcall2 genBytesIn (A.Array [A.UnknownDimension] A.Int) (Right undefined)) . over) + ,testBothSame "testBytesIn 102" "$(@0)*sizeof(int)" ((tcall3 genBytesIn undefined (A.Array [A.UnknownDimension] A.Int) (Right undefined)) . over) --Array with all known dimensions: - ,testBothSame "testBytesIn 200" "7*6*5*sizeof(int)" (tcall2 genBytesIn (A.Array [A.Dimension 5,A.Dimension 6, A.Dimension 7] A.Int) (Left False)) + ,testBothSame "testBytesIn 200" "7*6*5*sizeof(int)" (tcall3 genBytesIn undefined (A.Array [A.Dimension 5,A.Dimension 6, A.Dimension 7] A.Int) (Left False)) --single unknown dimension, no variable, no free dimension allowed: - ,testBothFail "testBytesIn 201a" (tcall2 genBytesIn (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Left False)) + ,testBothFail "testBytesIn 201a" (tcall3 genBytesIn undefined (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Left False)) --single unknown dimension, no variable, free dimension allowed: - ,testBothSame "testBytesIn 201b" "6*5*sizeof(int)" (tcall2 genBytesIn (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Left True)) + ,testBothSame "testBytesIn 201b" "6*5*sizeof(int)" (tcall3 genBytesIn undefined (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Left True)) --single unknown dimension, with variable: - ,testBothSame "testBytesIn 202" "$(@2)*6*5*sizeof(int)" ((tcall2 genBytesIn (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Right undefined)) . over) + ,testBothSame "testBytesIn 202" "$(@2)*6*5*sizeof(int)" ((tcall3 genBytesIn undefined (A.Array [A.Dimension 5,A.Dimension 6,A.UnknownDimension] A.Int) (Right undefined)) . over) ] where @@ -1096,8 +1096,8 @@ testMobile = TestList ((tcall2 genClearMobile emptyMeta undefined) . over) ] where - showBytesInParams _ t (Right _) = tell ["#(" ++ show t ++ " Right)"] - showBytesInParams _ t v = tell ["#(" ++ show t ++ " " ++ show v ++ ")"] + showBytesInParams _ _ t (Right _) = tell ["#(" ++ show t ++ " Right)"] + showBytesInParams _ _ t v = tell ["#(" ++ show t ++ " " ++ show v ++ ")"] over ops = ops {genBytesIn = showBytesInParams, genType = (\_ t -> tell [show t]), genExpression = override1 dollar, genVariable = override1 at} ---Returns the list of tests: diff --git a/backends/TLP.hs b/backends/TLP.hs index 83711ca..e4effd2 100644 --- a/backends/TLP.hs +++ b/backends/TLP.hs @@ -27,6 +27,7 @@ import Data.Maybe import qualified AST as A import CompState import Errors +import Metadata import Types data TLPChannel = TLPIn | TLPOut | TLPError @@ -37,28 +38,28 @@ data TLPChannel = TLPIn | TLPOut | TLPError tlpInterface :: (CSM m, Die m) => m ( A.Name, [(A.Direction, TLPChannel)] ) tlpInterface = do ps <- get - when (null $ csMainLocals ps) (die "No main process found") + when (null $ csMainLocals ps) (dieReport (Nothing,"No main process found")) let mainName = snd $ head $ csMainLocals ps st <- specTypeOfName mainName - formals <- case st of - A.Proc _ _ fs _ -> return fs - _ -> die "Last definition is not a PROC" - chans <- mapM tlpChannel formals - when ((nub (map snd chans)) /= (map snd chans)) $ die "Channels used more than once in TLP" + (m,formals) <- case st of + A.Proc m _ fs _ -> return (m,fs) + _ -> dieP (findMeta mainName) "Last definition is not a PROC" + chans <- mapM (tlpChannel m) formals + when ((nub (map snd chans)) /= (map snd chans)) $ dieP (findMeta mainName) "Channels used more than once in TLP" return (mainName, chans) where - tlpChannel :: (CSM m, Die m) => A.Formal -> m (A.Direction, TLPChannel) - tlpChannel (A.Formal _ (A.Chan dir _ _) n) + tlpChannel :: (CSM m, Die m) => Meta -> A.Formal -> m (A.Direction, TLPChannel) + tlpChannel m (A.Formal _ (A.Chan dir _ _) n) = do def <- lookupName n let origN = A.ndOrigName def case lookup origN tlpChanNames of Just c -> if (dir == A.DirUnknown || dir == (tlpDir c)) then return (dir,c) - else die $ "TLP formal " ++ show n ++ " has wrong direction for its name" - _ -> die $ "TLP formal " ++ show n ++ " has unrecognised name" - tlpChannel (A.Formal _ _ n) - = die $ "TLP formal " ++ show n ++ " has unrecognised type" + else dieP m $ "TLP formal " ++ show n ++ " has wrong direction for its name" + _ -> dieP m $ "TLP formal " ++ show n ++ " has unrecognised name" + tlpChannel m (A.Formal _ _ n) + = dieP m $ "TLP formal " ++ show n ++ " has unrecognised type" tlpDir :: TLPChannel -> A.Direction tlpDir TLPIn = A.DirInput diff --git a/checks/Check.hs b/checks/Check.hs index 5008bc7..a665578 100644 --- a/checks/Check.hs +++ b/checks/Check.hs @@ -43,7 +43,7 @@ import UsageCheckUtils usageCheckPass :: Pass usageCheckPass t = do g' <- buildFlowGraph labelFunctions t g <- case g' of - Left err -> die err + Left err -> dieP (findMeta t) err Right g -> return g sequence_ $ checkPar checkArrayUsage g return t @@ -186,10 +186,10 @@ showCodeExSet (NormalSet s) return $ "{" ++ concat (intersperse ", " ss) ++ "}" -- | Checks that no variable is used uninitialised. That is, it checks that every variable is written to before it is read. -checkInitVar :: forall m. (Monad m, Die m, CSM m) => FlowGraph m (Maybe Decl, Vars) -> Node -> m () -checkInitVar graph startNode +checkInitVar :: forall m. (Monad m, Die m, CSM m) => Meta -> FlowGraph m (Maybe Decl, Vars) -> Node -> m () +checkInitVar m graph startNode = do vwb <- case flowAlgorithm graphFuncs (nodes graph) startNode of - Left err -> die $ "Error building control-flow graph: " ++ err + Left err -> dieP m $ "Error building control-flow graph: " ++ err Right x -> return x -- vwb is a map from Node to a set of Vars that have been written by that point -- Now we check that for every variable read in each node, it has already been written to by then diff --git a/common/CompState.hs b/common/CompState.hs index 8a29bf8..f520a8c 100644 --- a/common/CompState.hs +++ b/common/CompState.hs @@ -124,7 +124,7 @@ defineName n nd -- | Find the definition of a name. lookupName :: (CSM m, Die m) => A.Name -> m A.NameDef -lookupName n = lookupNameOrError n (die $ "cannot find name " ++ A.nameName n) +lookupName n = lookupNameOrError n (dieP (findMeta n) $ "cannot find name " ++ A.nameName n) lookupNameOrError :: CSM m => A.Name -> m A.NameDef -> m A.NameDef lookupNameOrError n err @@ -253,8 +253,8 @@ makeNonceVariable s m t nt am diePC :: (CSM m, Die m) => Meta -> m String -> m a diePC m str = str >>= (dieP m) -dieC :: (CSM m, Die m) => m String -> m a -dieC str = str >>= die +--dieC :: (CSM m, Die m) => m String -> m a +--dieC str = str >>= die throwErrorC :: (CSM m,MonadError ErrorReport m) => (Maybe Meta,m String) -> m a throwErrorC (m,str) = str >>= ((curry throwError) m) diff --git a/common/Errors.hs b/common/Errors.hs index 3be3195..ea63d90 100644 --- a/common/Errors.hs +++ b/common/Errors.hs @@ -17,7 +17,7 @@ with this program. If not, see . -} -- | Error handling and reporting. -module Errors where +module Errors (checkJust, Die, dieInternal, dieIO, dieP, dieReport, ErrorReport) where import Control.Monad.Error import Control.Monad.Trans @@ -35,10 +35,6 @@ instance Error ErrorReport where class Monad m => Die m where dieReport :: ErrorReport -> m a - -- | Fail, giving an error message. - die :: String -> m a - die s = dieReport (Nothing, s) - -- | Fail, giving a position and an error message. dieP :: Die m => Meta -> String -> m a dieP m s = dieReport (Just m,s) @@ -90,6 +86,6 @@ dieInternal :: Monad m => ErrorReport -> m a dieInternal (m,s) = error $ "\n\n" ++ (maybe "" show m) ++ "Internal error: " ++ s -- | Extract a value from a Maybe type, dying with the given error if it's Nothing. -checkJust :: Die m => String -> Maybe t -> m t +checkJust :: Die m => ErrorReport -> Maybe t -> m t checkJust _ (Just v) = return v -checkJust err _ = die err +checkJust err _ = dieReport err diff --git a/common/EvalConstants.hs b/common/EvalConstants.hs index 3dbe55c..0dc1fcc 100644 --- a/common/EvalConstants.hs +++ b/common/EvalConstants.hs @@ -136,7 +136,7 @@ evalExpression (A.MostNeg _ A.Int32) = return $ OccInt32 minBound evalExpression (A.MostPos _ A.Int64) = return $ OccInt64 maxBound evalExpression (A.MostNeg _ A.Int64) = return $ OccInt64 minBound evalExpression (A.SizeExpr m e) - = do t <- typeOfExpression e >>= underlyingType + = do t <- typeOfExpression e >>= underlyingType m case t of A.Array (A.Dimension n:_) _ -> return $ OccInt (fromIntegral n) _ -> @@ -145,7 +145,7 @@ evalExpression (A.SizeExpr m e) OccArray vs -> return $ OccInt (fromIntegral $ length vs) _ -> throwError (Just m, "size of non-constant expression " ++ show e ++ " used") evalExpression (A.SizeVariable m v) - = do t <- typeOfVariable v >>= underlyingType + = do t <- typeOfVariable v >>= underlyingType m case t of A.Array (A.Dimension n:_) _ -> return $ OccInt (fromIntegral n) _ -> throwError (Just m, "size of non-fixed-size variable " ++ show v ++ " used") @@ -155,12 +155,12 @@ evalExpression (A.True _) = return $ OccBool True evalExpression (A.False _) = return $ OccBool False evalExpression (A.SubscriptedExpr _ sub e) = evalExpression e >>= evalSubscript sub evalExpression (A.BytesInExpr m e) - = do b <- typeOfExpression e >>= underlyingType >>= bytesInType + = do b <- typeOfExpression e >>= underlyingType m >>= bytesInType case b of BIJust n -> return $ OccInt (fromIntegral $ n) _ -> throwError (Just m, "BYTESIN non-constant-size expression " ++ show e ++ " used") evalExpression (A.BytesInType m t) - = do b <- underlyingType t >>= bytesInType + = do b <- underlyingType m t >>= bytesInType case b of BIJust n -> return $ OccInt (fromIntegral $ n) _ -> throwErrorC (Just m, formatCode "BYTESIN non-constant-size type % used" t) diff --git a/common/EvalLiterals.hs b/common/EvalLiterals.hs index 0708454..98bfe11 100644 --- a/common/EvalLiterals.hs +++ b/common/EvalLiterals.hs @@ -82,7 +82,7 @@ evalIntExpression e case runEvaluator ps (evalSimpleExpression e) of Left (m,err) -> dieReport (m,"cannot evaluate expression: " ++ err) Right (OccInt val) -> return $ fromIntegral val - Right _ -> die "expression is not of INT type" + Right _ -> dieP (findMeta e) "expression is not of INT type" -- | Evaluate a byte literal. evalByte :: (CSM m, Die m) => String -> m Char diff --git a/common/Types.hs b/common/Types.hs index 68aca9e..f66a732 100644 --- a/common/Types.hs +++ b/common/Types.hs @@ -65,7 +65,7 @@ typeOfName n t <- typeOfSpec st case t of Just t' -> return t' - Nothing -> die $ "cannot type name " ++ show st + Nothing -> dieP (findMeta n) $ "cannot type name " ++ show st typeOfSpec :: (CSM m, Die m) => A.SpecType -> m (Maybe A.Type) typeOfSpec st @@ -113,7 +113,7 @@ recordFields m _ = dieP m "not record type" typeOfRecordField :: (CSM m, Die m) => Meta -> A.Type -> A.Name -> m A.Type typeOfRecordField m t field = do fs <- recordFields m t - checkJust "unknown record field" $ lookup field fs + checkJust (Just m, "unknown record field") $ lookup field fs -- | Apply a plain subscript to a type. plainSubscriptType :: (CSM m, Die m) => Meta -> A.Expression -> A.Type -> m A.Type @@ -135,7 +135,7 @@ plainSubscriptType m _ t = diePC m $ formatCode "subscript of non-array type: %" -- subscripted. subscriptType :: (CSM m, Die m) => A.Subscript -> A.Type -> m A.Type subscriptType sub t@(A.UserDataType _) - = resolveUserType t >>= subscriptType sub + = resolveUserType (findMeta sub) t >>= subscriptType sub subscriptType (A.SubscriptFromFor m base count) t = sliceType m base count t subscriptType (A.SubscriptFrom m base) (A.Array (d:ds) t) @@ -161,8 +161,8 @@ unsubscriptType (A.SubscriptFrom _ _) t = return $ removeFixedDimension t unsubscriptType (A.SubscriptFor _ _) t = return $ removeFixedDimension t -unsubscriptType (A.SubscriptField _ _) t - = die $ "unsubscript of record type (but we can't tell which one)" +unsubscriptType (A.SubscriptField m _) t + = dieP m $ "unsubscript of record type (but we can't tell which one)" unsubscriptType (A.Subscript _ sub) t = return $ addDimensions [A.UnknownDimension] t @@ -170,10 +170,10 @@ unsubscriptType (A.Subscript _ sub) t -- subscriptType with constant 0 as a subscript, but without the checking. -- This is used for the couple of cases where we know it's safe and don't want -- the usage check. -trivialSubscriptType :: (CSM m, Die m) => A.Type -> m A.Type -trivialSubscriptType (A.Array [d] t) = return t -trivialSubscriptType (A.Array (d:ds) t) = return $ A.Array ds t -trivialSubscriptType t = dieC $ formatCode "not plain array type: %" t +trivialSubscriptType :: (CSM m, Die m) => Meta -> A.Type -> m A.Type +trivialSubscriptType _ (A.Array [d] t) = return t +trivialSubscriptType _ (A.Array (d:ds) t) = return $ A.Array ds t +trivialSubscriptType m t = diePC m $ formatCode "not plain array type: %" t -- | Gets the 'A.Type' of a 'A.Variable' by looking at the types recorded in the 'CompState'. typeOfVariable :: (CSM m, Die m) => A.Variable -> m A.Type @@ -184,12 +184,12 @@ typeOfVariable (A.DerefVariable m v) = do t <- typeOfVariable v case t of (A.Mobile innerT) -> return innerT - _ -> die $ "Tried to dereference a non-mobile variable: " ++ show v + _ -> dieP m $ "Tried to dereference a non-mobile variable: " ++ show v typeOfVariable (A.DirectedVariable m dir v) = do t <- typeOfVariable v case t of (A.Chan A.DirUnknown attr innerT) -> return (A.Chan dir attr innerT) - _ -> die $ "Used specifier on something that was not a directionless channel: " ++ show v + _ -> dieP m $ "Used specifier on something that was not a directionless channel: " ++ show v -- | Get the abbreviation mode of a variable. abbrevModeOfVariable :: (CSM m, Die m) => A.Variable -> m A.AbbrevMode @@ -245,7 +245,7 @@ typeOfExpression e A.True m -> return A.Bool A.False m -> return A.Bool A.FunctionCall m n es -> liftM head $ returnTypesOfFunction n - A.IntrinsicFunctionCall _ s _ -> liftM head $ returnTypesOfIntrinsic s + A.IntrinsicFunctionCall m s _ -> liftM head $ returnTypesOfIntrinsic m s A.SubscriptedExpr m s e -> typeOfExpression e >>= subscriptType s A.BytesInExpr m e -> return A.Int @@ -274,14 +274,14 @@ returnTypesOfFunction n -- If it's not defined as a function, it might have been converted to a proc. _ -> do ps <- get - checkJust "not defined as a function" $ + checkJust (Just $ findMeta n, "not defined as a function") $ Map.lookup (A.nameName n) (csFunctionReturns ps) -returnTypesOfIntrinsic :: (CSM m, Die m) => String -> m [A.Type] -returnTypesOfIntrinsic s +returnTypesOfIntrinsic :: (CSM m, Die m) => Meta -> String -> m [A.Type] +returnTypesOfIntrinsic m s = case lookup s intrinsicFunctions of Just (rts, _) -> return rts - Nothing -> die $ "unknown intrinsic function " ++ s + Nothing -> dieP m $ "unknown intrinsic function " ++ s -- | Get the items in a channel's protocol (for typechecking). -- Returns Left if it's a simple protocol, Right if it's tagged. @@ -309,25 +309,25 @@ abbrevModeOfSpec s -- | 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 :: (CSM m, Die m) => A.Type -> m A.Type -underlyingType = everywhereM (mkM underlyingType') +underlyingType :: (CSM m, Die m) => Meta -> A.Type -> m A.Type +underlyingType m = everywhereM (mkM underlyingType') where underlyingType' :: (CSM m, Die m) => A.Type -> m A.Type underlyingType' t@(A.UserDataType _) - = resolveUserType t >>= underlyingType + = resolveUserType m t >>= underlyingType m underlyingType' (A.Array ds t) = return $ addDimensions ds t underlyingType' 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 :: (CSM m, Die m) => A.Type -> m A.Type -resolveUserType (A.UserDataType n) +resolveUserType :: (CSM 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 t - _ -> die $ "not a type name " ++ show n -resolveUserType t = return t + 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 -- the new dimensions to the existing array. diff --git a/frontends/ParseOccam.hs b/frontends/ParseOccam.hs index 6976459..b6aa073 100644 --- a/frontends/ParseOccam.hs +++ b/frontends/ParseOccam.hs @@ -252,7 +252,7 @@ postSubscripts t postSubscript :: A.Type -> OccParser A.Subscript postSubscript t = do m <- md - t' <- resolveUserType t + t' <- resolveUserType m t case t' of A.Record _ -> do f <- tryXV sLeft fieldName @@ -269,7 +269,7 @@ maybeSliced inner subscripter typer = do m <- md (v, ff1) <- tryXVV sLeft inner fromOrFor - t <- typer v >>= underlyingType + t <- typer v >>= underlyingType m case t of (A.Array _ _) -> return () _ -> dieP m $ "slice of non-array type " ++ showOccam t @@ -361,22 +361,22 @@ areValidDimensions (d1:ds1) (d2:ds2) areValidDimensions _ _ = False -- | Check that a type we've inferred matches the type we expected. -matchType :: A.Type -> A.Type -> OccParser () -matchType et rt +matchType :: Meta -> A.Type -> A.Type -> OccParser () +matchType m et rt = case (et, rt) of ((A.Array ds t), (A.Array ds' t')) -> if areValidDimensions ds ds' - then matchType t t' + then matchType m t t' else bad _ -> if rt == et then return () else bad where bad :: OccParser () - bad = die $ "type mismatch (got " ++ showOccam rt ++ "; expected " ++ showOccam et ++ ")" + bad = dieP m $ "type mismatch (got " ++ showOccam rt ++ "; expected " ++ showOccam et ++ ")" -- | Check that two lists of types match (for example, for parallel assignment). -matchTypes :: [A.Type] -> [A.Type] -> OccParser () -matchTypes ets rts - = sequence_ [matchType et rt | (et, rt) <- zip ets rts] +matchTypes :: Meta -> [A.Type] -> [A.Type] -> OccParser () +matchTypes m ets rts + = sequence_ [matchType m et rt | (et, rt) <- zip ets rts] -- | Parse a production inside a particular type context. inTypeContext :: Maybe A.Type -> OccParser a -> OccParser a @@ -589,7 +589,7 @@ portType -- | Can a literal of type rawT be used as a value of type wantT? isValidLiteralType :: Meta -> A.Type -> A.Type -> OccParser Bool isValidLiteralType m rawT wantT - = do underT <- resolveUserType wantT + = do underT <- resolveUserType m wantT case (rawT, underT) of -- We don't yet know what type we want -- so assume it's OK for now. (_, A.Any) -> return True @@ -606,8 +606,8 @@ isValidLiteralType m rawT wantT -- We can't just look at all the dimensions because this -- might be an array of a record type, or similar. if isValidDimension d2 d1 - then do rawT' <- trivialSubscriptType rawT - underT' <- trivialSubscriptType underT + then do rawT' <- trivialSubscriptType m rawT + underT' <- trivialSubscriptType m underT isValidLiteralType m rawT' underT' else return False _ -> return $ rawT == wantT @@ -629,14 +629,14 @@ applyDimensions _ t = t -- | Convert a raw array element literal into its real form. makeArrayElem :: A.Type -> A.ArrayElem -> OccParser A.ArrayElem makeArrayElem t@(A.Array _ _) (A.ArrayElemArray aes) - = do elemT <- trivialSubscriptType t + = do elemT <- trivialSubscriptType (findMeta aes) t liftM A.ArrayElemArray $ mapM (makeArrayElem elemT) aes -makeArrayElem _ (A.ArrayElemArray _) - = die $ "unexpected nested array literal" +makeArrayElem _ (A.ArrayElemArray es) + = dieP (findMeta es) $ "unexpected nested array literal" -- A nested array literal that's still of array type (i.e. it's not a -- record inside the array) -- collapse it. -makeArrayElem t@(A.Array _ _) (A.ArrayElemExpr (A.Literal _ _ (A.ArrayLiteral _ aes))) - = do elemT <- trivialSubscriptType t +makeArrayElem t@(A.Array _ _) (A.ArrayElemExpr (A.Literal _ _ (A.ArrayLiteral m aes))) + = do elemT <- trivialSubscriptType m t liftM A.ArrayElemArray $ mapM (makeArrayElem elemT) aes makeArrayElem t (A.ArrayElemExpr e) = liftM A.ArrayElemExpr $ makeLiteral e t @@ -647,7 +647,7 @@ makeArrayElem t (A.ArrayElemExpr e) makeLiteral :: A.Expression -> A.Type -> OccParser A.Expression -- A literal. makeLiteral x@(A.Literal m t lr) wantT - = do underT <- resolveUserType wantT + = do underT <- resolveUserType m wantT typesOK <- isValidLiteralType m t wantT when (not typesOK) $ @@ -656,7 +656,7 @@ makeLiteral x@(A.Literal m t lr) wantT case (underT, lr) of -- An array literal. (A.Array _ _, A.ArrayLiteral ml aes) -> - do elemT <- trivialSubscriptType underT + do elemT <- trivialSubscriptType ml underT aes' <- mapM (makeArrayElem elemT) aes return $ A.Literal m (applyDimensions t wantT) (A.ArrayLiteral ml aes') -- A record literal -- which we need to convert from the raw @@ -681,7 +681,7 @@ makeLiteral (A.SubscriptedExpr m sub e) wantT -- check it's the right type. makeLiteral e wantT = do t <- typeOfExpression e - matchType wantT t + matchType (findMeta e) wantT t return e --}}} @@ -876,7 +876,7 @@ associativeOpExpression tl <- typeOfExpression l r <- associativeOpExpression <|> operand tr <- typeOfExpression r - matchType tl tr + matchType m tl tr return $ A.Dyadic m o l r "associative operator expression" @@ -896,7 +896,7 @@ expressionOfType :: A.Type -> OccParser A.Expression expressionOfType wantT = do e <- inTypeContext (Just wantT) expression t <- typeOfExpression e - matchType wantT t + matchType (findMeta e) wantT t return e intExpr = expressionOfType A.Int "integer expression" @@ -916,7 +916,7 @@ operandOfType :: A.Type -> OccParser A.Expression operandOfType wantT = do o <- inTypeContext (Just wantT) operand t <- typeOfExpression o - matchType wantT t + matchType (findMeta o) wantT t return o --}}} --{{{ functions @@ -955,7 +955,7 @@ functionMulti types as <- functionActuals fs sRightR rts <- returnTypesOfFunction n - matchTypes types rts + matchTypes m types rts return $ A.FunctionCallList m n as "multi-valued function call" --}}} @@ -1041,10 +1041,10 @@ conversion :: OccParser A.Expression conversion = do m <- md t <- dataType - baseT <- underlyingType t + baseT <- underlyingType m t (c, o) <- conversionMode ot <- typeOfExpression o - baseOT <- underlyingType ot + baseOT <- underlyingType m ot c <- case (isPreciseConversion baseOT baseT, c) of (False, A.DefaultConversion) -> dieP m "imprecise conversion must specify ROUND or TRUNC" @@ -1102,7 +1102,7 @@ variableOfType :: A.Type -> OccParser A.Variable variableOfType wantT = do v <- variable t <- typeOfVariable v - matchType wantT t + matchType (findMeta v) wantT t return v channel :: OccParser A.Variable @@ -1120,7 +1120,7 @@ channelOfType :: A.Type -> OccParser A.Variable channelOfType wantT = do c <- channel t <- typeOfVariable c - matchType wantT t + matchType (findMeta c) wantT t return c timer :: OccParser A.Variable @@ -1149,7 +1149,7 @@ portOfType :: A.Type -> OccParser A.Variable portOfType wantT = do p <- port t <- typeOfVariable p - matchType wantT t + matchType (findMeta p) wantT t return p --}}} --{{{ protocols @@ -1269,7 +1269,7 @@ isAbbrev newName oldVar sColon eol t <- typeOfVariable v - matchType s t + matchType m s t return $ A.Specification m n $ A.Is m A.Abbrev s v "IS abbreviation" @@ -1291,7 +1291,7 @@ chanArrayAbbrev n <- newChannelName sIS sLeft - ct <- trivialSubscriptType s + ct <- trivialSubscriptType m s case ct of A.Chan {} -> return (ct, s, n) _ -> pzero) @@ -1356,7 +1356,7 @@ retypesAbbrev sColon eol origT <- typeOfVariable v - checkRetypes origT s + checkRetypes m origT s return $ A.Specification m n $ A.Retypes m A.Abbrev s v <|> do m <- md (s, n) <- tryVVX channelSpecifier newChannelName retypesReshapes @@ -1364,7 +1364,7 @@ retypesAbbrev sColon eol origT <- typeOfVariable c - checkRetypes origT s + checkRetypes m origT s return $ A.Specification m n $ A.Retypes m A.Abbrev s c <|> do m <- md (s, n) <- tryXVVX sVAL dataSpecifier newVariableName retypesReshapes @@ -1372,24 +1372,24 @@ retypesAbbrev sColon eol origT <- typeOfExpression e - checkRetypes origT s + checkRetypes m origT s return $ A.Specification m n $ A.RetypesExpr m A.ValAbbrev s e "RETYPES/RESHAPES abbreviation" -- | Check that a RETYPES\/RESHAPES is safe. -checkRetypes :: A.Type -> A.Type -> OccParser () +checkRetypes :: Meta -> A.Type -> A.Type -> OccParser () -- Retyping channels is always "safe". -checkRetypes (A.Chan {}) (A.Chan {}) = return () -checkRetypes fromT toT +checkRetypes _ (A.Chan {}) (A.Chan {}) = return () +checkRetypes m fromT toT = do bf <- bytesInType fromT bt <- bytesInType toT case (bf, bt) of (BIJust a, BIJust b) -> - when (a /= b) $ die "size mismatch in RETYPES" + when (a /= b) $ dieP m "size mismatch in RETYPES" (BIJust a, BIOneFree b _) -> - when (not ((b <= a) && (a `mod` b == 0))) $ die "size mismatch in RETYPES" + when (not ((b <= a) && (a `mod` b == 0))) $ dieP m "size mismatch in RETYPES" (_, BIManyFree) -> - die "multiple free dimensions in RETYPES/RESHAPES type" + dieP m "multiple free dimensions in RETYPES/RESHAPES type" -- Otherwise we have to do a runtime check. _ -> return () @@ -1600,7 +1600,7 @@ taggedList :: [(A.Name, [A.Type])] -> OccParser (A.Process -> A.Variant) taggedList nts = do m <- md tag <- tagName - ts <- checkJust "unknown tag in protocol" $ lookup tag nts + ts <- checkJust (Just m, "unknown tag in protocol") $ lookup tag nts is <- sequence [sSemi >> inputItem t | t <- ts] return $ A.Variant m tag is "tagged list" @@ -1679,7 +1679,7 @@ channelOutput return $ A.Output m c os Right nts -> do tag <- tagName - ts <- checkJust "unknown tag in protocol" $ lookup tag nts + ts <- checkJust (Just m, "unknown tag in protocol") $ lookup tag nts os <- sequence [sSemi >> outputItem t | t <- ts] eol return $ A.OutputCase m c tag os @@ -1755,7 +1755,7 @@ caseProcess sCASE sel <- expression t <- typeOfExpression sel - t' <- underlyingType t + t' <- underlyingType m t when (not $ isCaseableType t') $ dieP m "case selector has non-CASEable type" eol os <- maybeIndentedList m "empty CASE" (caseOption t) @@ -1972,7 +1972,7 @@ sourceFile runTockParser :: [Token] -> OccParser t -> CompState -> PassM t runTockParser toks prod cs = do case runParser prod cs "" toks of - Left err -> die $ "Parse error: " ++ show err + Left err -> dieReport (Nothing, "Parse error: " ++ show err) Right r -> return r -- | Parse an occam program. diff --git a/frontends/RainPasses.hs b/frontends/RainPasses.hs index 9514ace..9c9b1ef 100644 --- a/frontends/RainPasses.hs +++ b/frontends/RainPasses.hs @@ -167,7 +167,7 @@ transformEachRange :: Data t => t -> PassM t transformEachRange = everywhereM (mkM transformEachRange') where transformEachRange' :: A.Structured -> PassM A.Structured - transformEachRange' s@(A.Rep {}) + transformEachRange' s@(A.Rep m _ _) = case getMatchedItems patt s of Left _ -> return s --Doesn't match, return the original Right items -> @@ -192,7 +192,7 @@ transformEachRange = everywhereM (mkM transformEachRange') castOrDie :: (Typeable b) => String -> Items -> PassM b castOrDie key items = case castADI (Map.lookup key items) of Just y -> return y - Nothing -> die "Internal error in transformEachRange" + Nothing -> dieP m "Internal error in transformEachRange" transformEachRange' s = return s -- | A pass that changes all the 'A.ForEach' replicators in the AST into 'A.For' replicators. diff --git a/transformations/SimplifyExprs.hs b/transformations/SimplifyExprs.hs index c00d456..5592519 100644 --- a/transformations/SimplifyExprs.hs +++ b/transformations/SimplifyExprs.hs @@ -114,8 +114,8 @@ expandArrayLiterals = doGeneric `extM` doArrayElem expand :: [A.Dimension] -> A.Expression -> PassM A.ArrayElem expand [] e = return $ A.ArrayElemExpr e - expand (A.UnknownDimension:_) _ - = die "array literal containing non-literal array of unknown size" + expand (A.UnknownDimension:_) e + = dieP (findMeta e) "array literal containing non-literal array of unknown size" expand (A.Dimension n:ds) e = liftM A.ArrayElemArray $ sequence [expand ds (A.SubscriptedExpr m (A.Subscript m $ makeConstant m i) e) | i <- [0 .. (n - 1)]] where m = findMeta e diff --git a/transformations/SimplifyProcs.hs b/transformations/SimplifyProcs.hs index fb236da..9fd1034 100644 --- a/transformations/SimplifyProcs.hs +++ b/transformations/SimplifyProcs.hs @@ -127,7 +127,7 @@ flattenAssign = doGeneric `extM` doProcess let zero = A.Literal m A.Int $ A.IntLiteral m "0" let rep = A.For m counter zero (A.SizeVariable m srcV) - itemT <- trivialSubscriptType t + itemT <- trivialSubscriptType m t let sub = A.Subscript m (A.ExprVariable m (A.Variable m counter)) inner <- assign m itemT diff --git a/transformations/SimplifyTypes.hs b/transformations/SimplifyTypes.hs index 0f1da96..a0ab7bb 100644 --- a/transformations/SimplifyTypes.hs +++ b/transformations/SimplifyTypes.hs @@ -23,6 +23,7 @@ import Control.Monad.State import Data.Generics import qualified AST as A +import Metadata import Pass import Types @@ -43,7 +44,7 @@ resolveNamedTypes = doGeneric `extM` doType doGeneric = makeGeneric resolveNamedTypes doType :: A.Type -> PassM A.Type - doType t@(A.UserDataType _) = underlyingType t + doType t@(A.UserDataType _) = underlyingType emptyMeta t doType t = doGeneric t -- | Resolve named types in CompState. diff --git a/transformations/Unnest.hs b/transformations/Unnest.hs index 3984139..46e8cc3 100644 --- a/transformations/Unnest.hs +++ b/transformations/Unnest.hs @@ -112,7 +112,7 @@ removeFreeNames = doGeneric `extM` doSpecification `extM` doProcess -- we know it's not going to be moved by removeNesting, so anything -- that it had in scope originally will still be in scope. ps <- get - when (null $ csMainLocals ps) (die "No main process found") + when (null $ csMainLocals ps) (dieReport (Nothing,"No main process found")) let isTLP = (snd $ head $ csMainLocals ps) == n -- Figure out the free names.