Changed FUNCTIONs and PROCs to have optional bodies, and put all the externals into the AST (without bodies)

This may seem like an odd change, but it simplifies the logic a lot.  I kept having problems with passes not operating on externals (e.g. functions-to-procs, adding array sizes, constant folding in array dimensions) and adding a special case every time to also process the externals was getting silly.

Putting the externals in the AST therefore made sense, but I didn't want to just add dummy bodies as this would cause them to throw up errors (e.g. in the type-checking for functions).  So I turned the bodies into a Maybe type, and that has worked out well.

I also stopped storing the formals in csExternals (since they are now in csNames, and the tree), which streamlined that nicely, and stopped me having to keep them up to date.
This commit is contained in:
Neil Brown 2009-04-04 14:56:35 +00:00
parent 2a321d7910
commit e457d82f0c
25 changed files with 115 additions and 122 deletions

View File

@ -234,14 +234,6 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays"
\t -> do pushPullContext \t -> do pushPullContext
t' <- recurse t >>= applyPulled t' <- recurse t >>= applyPulled
popPullContext popPullContext
exts <- getCompState >>* csExternals
exts' <- sequence [do fs' <- transformExternal (findMeta t) extType fs
modifyName (A.Name emptyMeta n) $ \nd -> nd
{A.ndSpecType = A.Proc (findMeta t)
(A.PlainSpec, A.PlainRec) fs' (A.Skip (findMeta t))}
return $ (n, (extType, fs'))
| (n, (extType, fs)) <- exts]
modify $ \cs -> cs { csExternals = exts' }
return t' return t'
) )
where where
@ -358,7 +350,8 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays"
do -- We descend into the scope first, so that all the actuals get do -- We descend into the scope first, so that all the actuals get
-- fixed before the formals: -- fixed before the formals:
s' <- recurse s s' <- recurse s
(args', newargs) <- transformFormals Nothing m args ext <- getCompState >>* csExternals >>* lookup (A.nameName n)
(args', newargs) <- transformFormals ext m args
sequence_ [defineSizesName m' n (A.Declaration m' t) sequence_ [defineSizesName m' n (A.Declaration m' t)
| A.Formal _ t n <- newargs] | A.Formal _ t n <- newargs]
-- We descend into the body after the formals have been -- We descend into the body after the formals have been
@ -372,13 +365,6 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays"
_ -> descend str _ -> descend str
doStructured s = descend s doStructured s = descend s
transformExternal :: Meta -> ExternalType -> [A.Formal] -> PassM [A.Formal]
transformExternal m extType args
= do (args', newargs) <- transformFormals (Just extType) m args
sequence_ [defineSizesName m n (A.Declaration m t)
| A.Formal _ t n <- newargs]
return args'
transformFormals :: Maybe ExternalType -> Meta -> [A.Formal] -> PassM ([A.Formal], [A.Formal]) transformFormals :: Maybe ExternalType -> Meta -> [A.Formal] -> PassM ([A.Formal], [A.Formal])
transformFormals _ _ [] = return ([],[]) transformFormals _ _ [] = return ([],[])
transformFormals ext m ((f@(A.Formal am t n)):fs) transformFormals ext m ((f@(A.Formal am t n)):fs)
@ -413,7 +399,7 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays"
doProcess :: A.Process -> PassM A.Process doProcess :: A.Process -> PassM A.Process
doProcess (A.ProcCall m n params) doProcess (A.ProcCall m n params)
= do ext <- getCompState >>* csExternals >>* lookup (A.nameName n) >>* fmap fst = do ext <- getCompState >>* csExternals >>* lookup (A.nameName n)
A.Proc _ _ fs _ <- specTypeOfName n A.Proc _ _ fs _ <- specTypeOfName n
concatMapM (transformActual ext) (zip fs params) >>* A.ProcCall m n concatMapM (transformActual ext) (zip fs params) >>* A.ProcCall m n
doProcess p = descend p doProcess p = descend p
@ -536,16 +522,16 @@ mobileReturn = cOnlyPass "Add MOBILE returns" [] [] recurse
_ -> return (ps, f : fs') _ -> return (ps, f : fs')
doStructured :: Data a => Transform (A.Structured a) doStructured :: Data a => Transform (A.Structured a)
doStructured s@(A.Spec msp (A.Specification m n (A.Proc m' sm fs pr)) scope) doStructured s@(A.Spec msp (A.Specification m n (A.Proc m' sm fs (Just pr))) scope)
= do pr' <- recurse pr = do pr' <- recurse pr
-- We do the scope first, so that all the callers are updated before -- We do the scope first, so that all the callers are updated before
-- we fix our state: -- we fix our state:
scope' <- recurse scope scope' <- recurse scope
ig <- ignoreProc n ig <- ignoreProc n
if ig if ig
then return $ A.Spec msp (A.Specification m n (A.Proc m' sm fs pr')) scope' then return $ A.Spec msp (A.Specification m n (A.Proc m' sm fs $ Just pr')) scope'
else do (ps, fs') <- addChansForm m fs else do (ps, fs') <- addChansForm m fs
let newSpec = A.Proc m' sm fs' (A.Seq m' $ A.Several m' $ let newSpec = A.Proc m' sm fs' $ Just (A.Seq m' $ A.Several m' $
map (A.Only m') $ pr' : ps) map (A.Only m') $ pr' : ps)
modifyName n (\nd -> nd {A.ndSpecType = newSpec}) modifyName n (\nd -> nd {A.ndSpecType = newSpec})
return $ A.Spec msp (A.Specification m n newSpec) scope' return $ A.Spec msp (A.Specification m n newSpec) scope'

View File

@ -204,7 +204,7 @@ cgenTopLevel headerName s
-- Forward declarations of externals: -- Forward declarations of externals:
sequence_ [tell ["extern void ", mungeExternalName n, "(int*);"] sequence_ [tell ["extern void ", mungeExternalName n, "(int*);"]
| (n, (ExternalOldStyle, _)) <- csExternals cs] | (n, ExternalOldStyle) <- csExternals cs]
call genStructured TopLevel s (\m _ -> tell ["\n#error Invalid top-level item: ", show m]) call genStructured TopLevel s (\m _ -> tell ["\n#error Invalid top-level item: ", show m])
@ -1584,7 +1584,7 @@ realFormals (A.Formal am t n)
-- one of the original top-level procs, other than to add an occam_ prefix (which -- one of the original top-level procs, other than to add an occam_ prefix (which
-- avoids name collisions). -- avoids name collisions).
genProcSpec :: Level -> A.Name -> A.SpecType -> Bool -> CGen () genProcSpec :: Level -> A.Name -> A.SpecType -> Bool -> CGen ()
genProcSpec lvl n (A.Proc _ (sm, rm) fs p) forwardDecl genProcSpec lvl n (A.Proc _ (sm, rm) fs (Just p)) forwardDecl
= do cs <- getCompState = do cs <- getCompState
let (header, params) = if n `Set.member` csParProcs cs let (header, params) = if n `Set.member` csParProcs cs
|| rm == A.Recursive || rm == A.Recursive
@ -1631,6 +1631,8 @@ genProcSpec lvl n (A.Proc _ (sm, rm) fs p) forwardDecl
n n
| (t, n) <- rfs] | (t, n) <- rfs]
tell [")"] tell [")"]
-- For externals, do nothing here:
genProcSpec _ _ (A.Proc _ _ _ Nothing) _ = return ()
-- | Generate a ProcAlloc for a PAR subprocess, returning a nonce for the -- | Generate a ProcAlloc for a PAR subprocess, returning a nonce for the
-- workspace pointer and the name of the function to call. -- workspace pointer and the name of the function to call.
@ -2060,7 +2062,7 @@ cgenProcCall n as
(A.Recursive, _) -> (A.Recursive, _) ->
let m = A.nameMeta n let m = A.nameMeta n
in call genPar A.PlainPar $ A.Only m $ A.ProcCall m n as in call genPar A.PlainPar $ A.Only m $ A.ProcCall m n as
(_, Just (ExternalOldStyle, _)) -> (_, Just ExternalOldStyle) ->
do let (c:cs) = A.nameName n do let (c:cs) = A.nameName n
tell ["{int ext_args[] = {"] tell ["{int ext_args[] = {"]
-- We don't use the formals in csExternals because they won't -- We don't use the formals in csExternals because they won't

View File

@ -574,7 +574,7 @@ cppgenForwardDeclaration _ = return ()
cppintroduceSpec :: Level -> A.Specification -> CGen () cppintroduceSpec :: Level -> A.Specification -> CGen ()
--I generate process wrappers for all functions by default: --I generate process wrappers for all functions by default:
cppintroduceSpec lvl (A.Specification _ n (A.Proc _ (sm, _) fs p)) cppintroduceSpec lvl (A.Specification _ n (A.Proc _ (sm, _) fs (Just p)))
= do --Generate the "process" as a C++ function: = do --Generate the "process" as a C++ function:
genStatic lvl n genStatic lvl n
call genSpecMode sm call genSpecMode sm

View File

@ -29,7 +29,7 @@ module GenericUtils (
, gmapMFor , gmapMFor
, gmapMForRoute , gmapMForRoute
, routeModify, routeGet, routeSet, Route(..), (@->), routeIdentity, routeId, routeList , routeModify, routeGet, routeSet, Route(..), (@->), routeIdentity, routeId, routeList
, route22, route23, route33, route34, route44, route45, route55 , route11, route22, route23, route33, route34, route44, route45, route55
) where ) where
import Control.Monad.Identity import Control.Monad.Identity
@ -286,6 +286,9 @@ gmapMWithRoute f = gmapFuncs [GM {unGM = f' n} | n <- [0..]]
makeRoute :: (Data s, Data t) => Int -> Route s t makeRoute :: (Data s, Data t) => Int -> Route s t
makeRoute target = Route [target] (\f -> gmapFuncs [mkM' (if n == target then f else return) | n <- [0..]]) makeRoute target = Route [target] (\f -> gmapFuncs [mkM' (if n == target then f else return) | n <- [0..]])
decomp11 :: (Monad m, Data a, Typeable a0) => (a0 -> a) -> (a0 -> m a0) -> (a -> m a)
decomp11 con f1 = decomp1 con f1
decomp22 :: (Monad m, Data a, Typeable a0, Typeable a1) => (a0 -> a1 -> a) -> (a1 -> m a1) -> (a -> m a) decomp22 :: (Monad m, Data a, Typeable a0, Typeable a1) => (a0 -> a1 -> a) -> (a1 -> m a1) -> (a -> m a)
decomp22 con f1 = decomp2 con return f1 decomp22 con f1 = decomp2 con return f1
@ -311,6 +314,9 @@ decomp55 :: (Monad m, Data a, Typeable a0, Typeable a1, Typeable a2, Typeable a3
(a0 -> a1 -> a2 -> a3 -> a4 -> a) -> (a4 -> m a4) -> (a -> m a) (a0 -> a1 -> a2 -> a3 -> a4 -> a) -> (a4 -> m a4) -> (a -> m a)
decomp55 con f4 = decomp5 con return return return return f4 decomp55 con f4 = decomp5 con return return return return f4
route11 :: (Data a, Typeable a0) => Route a b -> (a0 -> a) -> Route a0 b
route11 route con = route @-> Route [0] (decomp11 con)
route22 :: (Data a, Typeable a0, Typeable a1) => Route a b -> (a0 -> a1 -> a) -> Route a1 b route22 :: (Data a, Typeable a0, Typeable a1) => Route a b -> (a0 -> a1 -> a) -> Route a1 b
route22 route con = route @-> Route [1] (decomp22 con) route22 route con = route @-> Route [1] (decomp22 con)

View File

@ -250,7 +250,7 @@ oPROC str params body scope = do
s <- scope s <- scope
defineProc str [(A.nameName name, A.Original, t) | (t, A.Variable _ name) <- params] defineProc str [(A.nameName name, A.Original, t) | (t, A.Variable _ name) <- params]
return $ A.Spec emptyMeta (A.Specification emptyMeta (simpleName str) $ return $ A.Spec emptyMeta (A.Specification emptyMeta (simpleName str) $
A.Proc emptyMeta (A.PlainSpec, A.PlainRec) formals p A.Proc emptyMeta (A.PlainSpec, A.PlainRec) formals (Just p)
) (singlify s) ) (singlify s)
where where
formals = [A.Formal A.Original t n | (t, A.Variable _ n) <- params] formals = [A.Formal A.Original t n | (t, A.Variable _ n) <- params]

View File

@ -508,7 +508,7 @@ instance ShowOccam A.RecordAttr where
instance ShowOccam A.Specification where instance ShowOccam A.Specification where
-- TODO add specmode to the output -- TODO add specmode to the output
showOccamM (A.Specification _ n (A.Proc _ sm params body)) showOccamM (A.Specification _ n (A.Proc _ sm params (Just body)))
= do let params' = intersperse (tell [","]) $ map showOccamM params = do let params' = intersperse (tell [","]) $ map showOccamM params
showOccamLine $ do tell ["PROC "] showOccamLine $ do tell ["PROC "]
showName n showName n
@ -535,11 +535,11 @@ instance ShowOccam A.Specification where
occamOutdent occamOutdent
(showOccamLine colon) (showOccamLine colon)
--TODO use the specmode --TODO use the specmode
showOccamM (A.Specification _ n (A.Function _ sm retTypes params (Left el@(A.Only {})))) showOccamM (A.Specification _ n (A.Function _ sm retTypes params (Just (Left el@(A.Only {})))))
= showOccamLine $ = showOccamLine $
showWithCommas retTypes >> (tell [" FUNCTION "]) >> showName n >> tell ["("] >> showWithCommas params >> tell [")"] showWithCommas retTypes >> (tell [" FUNCTION "]) >> showName n >> tell ["("] >> showWithCommas params >> tell [")"]
>> tell [" IS "] >> showOccamM el >> colon >> tell [" IS "] >> showOccamM el >> colon
showOccamM (A.Specification _ n (A.Function _ sm retTypes params (Left body))) showOccamM (A.Specification _ n (A.Function _ sm retTypes params (Just (Left body))))
= (showOccamLine $ showWithCommas retTypes >> (tell [" FUNCTION "]) >> showName n >> tell ["("] >> showWithCommas params >> tell [")"]) = (showOccamLine $ showWithCommas retTypes >> (tell [" FUNCTION "]) >> showName n >> tell ["("] >> showWithCommas params >> tell [")"])
>> occamIndent >> occamIndent
>> showOccamM body >> showOccamM body

View File

@ -111,7 +111,7 @@ testCheck config property =
-- | Wraps a structured process into a complete AST fragment. -- | Wraps a structured process into a complete AST fragment.
wrapProcSeq :: A.Structured A.Process -> A.AST wrapProcSeq :: A.Structured A.Process -> A.AST
wrapProcSeq x = A.Spec emptyMeta (A.Specification emptyMeta (simpleName "foo") wrapProcSeq x = A.Spec emptyMeta (A.Specification emptyMeta (simpleName "foo")
$ A.Proc emptyMeta (A.PlainSpec, A.PlainRec) [] $ A.Seq emptyMeta x) (A.Several emptyMeta []) $ A.Proc emptyMeta (A.PlainSpec, A.PlainRec) [] $ Just $ A.Seq emptyMeta x) (A.Several emptyMeta [])
-- | Helper function to generate an array dimension. -- | Helper function to generate an array dimension.
@ -367,7 +367,7 @@ defineFunction :: String -> [A.Type] -> [(String, A.Type)]
defineFunction s rs as defineFunction s rs as
= defineThing s st A.Original A.NameUser = defineThing s st A.Original A.NameUser
where where
st = A.Function emptyMeta (A.PlainSpec, A.PlainRec) rs fs (Right $ A.Skip emptyMeta) st = A.Function emptyMeta (A.PlainSpec, A.PlainRec) rs fs (Just $ Right $ A.Skip emptyMeta)
fs = [A.Formal A.ValAbbrev t (simpleName s) | (s, t) <- as] fs = [A.Formal A.ValAbbrev t (simpleName s) | (s, t) <- as]
-- | Define a proc. -- | Define a proc.
@ -375,7 +375,7 @@ defineProc :: CSM m => String -> [(String, A.AbbrevMode, A.Type)] -> m ()
defineProc s as defineProc s as
= defineThing s st A.Original A.NameUser = defineThing s st A.Original A.NameUser
where where
st = A.Proc emptyMeta (A.PlainSpec, A.PlainRec) fs $ A.Skip emptyMeta st = A.Proc emptyMeta (A.PlainSpec, A.PlainRec) fs $ Just $ A.Skip emptyMeta
fs = [A.Formal am t (simpleName s) | (s, am, t) <- as] fs = [A.Formal am t (simpleName s) | (s, am, t) <- as]
-- | Define a protocol. -- | Define a protocol.

View File

@ -496,11 +496,11 @@ data SpecType =
-- | Declare a variant protocol. -- | Declare a variant protocol.
-- The list pairs tag names with item types. -- The list pairs tag names with item types.
| ProtocolCase Meta [(Name, [Type])] | ProtocolCase Meta [(Name, [Type])]
-- | Declare a @PROC@. -- | Declare a @PROC@. Body is Nothing if it's external
| Proc Meta (SpecMode, RecMode) [Formal] Process | Proc Meta (SpecMode, RecMode) [Formal] (Maybe Process)
-- | Declare a @FUNCTION@. -- | Declare a @FUNCTION@. Body is Nothing if it's external
| Function Meta (SpecMode, RecMode) [Type] [Formal] | Function Meta (SpecMode, RecMode) [Type] [Formal]
(Either (Structured ExpressionList) Process) (Maybe (Either (Structured ExpressionList) Process))
-- | Declare a retyping abbreviation of a variable. -- | Declare a retyping abbreviation of a variable.
| Retypes Meta AbbrevMode Type Variable | Retypes Meta AbbrevMode Type Variable
-- | Declare a retyping abbreviation of an expression. -- | Declare a retyping abbreviation of an expression.

View File

@ -135,7 +135,7 @@ data CompState = CompState {
-- up (and therefore the things that should be visible to other files during -- up (and therefore the things that should be visible to other files during
-- separate compilation) -- separate compilation)
csOriginalTopLevelProcs :: [String], csOriginalTopLevelProcs :: [String],
csExternals :: [(String, (ExternalType, [A.Formal]))], csExternals :: [(String, ExternalType)],
-- Maps an array variable name to the name of its _sizes array: -- Maps an array variable name to the name of its _sizes array:
csArraySizes :: Map String A.Name, csArraySizes :: Map String A.Name,
-- Stores a map of constant sizes arrays declared for that size: -- Stores a map of constant sizes arrays declared for that size:
@ -396,7 +396,7 @@ defineNonce m s st am
-- | Generate and define a no-arg wrapper PROC around a process. -- | Generate and define a no-arg wrapper PROC around a process.
makeNonceProc :: CSM m => Meta -> A.Process -> m A.Specification makeNonceProc :: CSM m => Meta -> A.Process -> m A.Specification
makeNonceProc m p makeNonceProc m p
= defineNonce m "wrapper_proc" (A.Proc m (A.PlainSpec, A.PlainRec) [] p) A.Abbrev = defineNonce m "wrapper_proc" (A.Proc m (A.PlainSpec, A.PlainRec) [] (Just p)) A.Abbrev
-- | Generate and define a counter for a replicator. -- | Generate and define a counter for a replicator.
makeNonceCounter :: CSM m => String -> Meta -> m A.Name makeNonceCounter :: CSM m => String -> Meta -> m A.Name
@ -440,7 +440,7 @@ findAllProcesses
findAllProcesses' :: (String, A.NameDef) -> Maybe (String, A.Process) findAllProcesses' :: (String, A.NameDef) -> Maybe (String, A.Process)
findAllProcesses' (n, nd) findAllProcesses' (n, nd)
= case A.ndSpecType nd of = case A.ndSpecType nd of
A.Proc _ _ _ p -> Just (n, p) A.Proc _ _ _ (Just p) -> Just (n, p)
_ -> Nothing _ -> Nothing
-- | A new identifer for the unify types in the tree -- | A new identifer for the unify types in the tree

View File

@ -69,16 +69,16 @@ addSpecNodes spec route
-- Descends into process or function specifications, but doesn't join them up. Any other specifications are ignored -- Descends into process or function specifications, but doesn't join them up. Any other specifications are ignored
buildProcessOrFunctionSpec :: (Monad mAlter, Monad mLabel) => A.Specification -> ASTModifier mAlter (A.Specification) structType -> buildProcessOrFunctionSpec :: (Monad mAlter, Monad mLabel) => A.Specification -> ASTModifier mAlter (A.Specification) structType ->
GraphMaker mLabel mAlter label structType () GraphMaker mLabel mAlter label structType ()
buildProcessOrFunctionSpec (A.Specification _ _ (A.Proc m _ args p)) route buildProcessOrFunctionSpec (A.Specification _ _ (A.Proc m _ args (Just p))) route
= let procRoute = (route33 route A.Specification) in = let procRoute = (route33 route A.Specification) in
addNewSubProcFunc m args (Left (p, route44 procRoute A.Proc)) (route34 procRoute A.Proc) addNewSubProcFunc m args (Left (p, route11 (route44 procRoute A.Proc) Just)) (route34 procRoute A.Proc)
buildProcessOrFunctionSpec (A.Specification _ _ (A.Function m _ _ args es)) route buildProcessOrFunctionSpec (A.Specification _ _ (A.Function m _ _ args (Just es))) route
= let funcRoute = (route33 route A.Specification) in = let funcRoute = (route33 route A.Specification) in
case es of case es of
Left sel -> addNewSubProcFunc m args (Right (sel, route55 funcRoute A.Function @-> (Route Left sel -> addNewSubProcFunc m args (Right (sel, route55 funcRoute A.Function @-> (Route
[0] $ \f (Left e) -> f e >>* Left))) (route45 funcRoute A.Function) [0,0] $ \f (Just (Left e)) -> f e >>* (Just . Left)))) (route45 funcRoute A.Function)
Right p -> addNewSubProcFunc m args (Left (p, route55 funcRoute A.Function @-> (Route Right p -> addNewSubProcFunc m args (Left (p, route55 funcRoute A.Function @-> (Route
[0] $ \f (Right p) -> f p >>* Right))) (route45 funcRoute A.Function) [0,0] $ \f (Just (Right p)) -> f p >>* (Just . Right)))) (route45 funcRoute A.Function)
buildProcessOrFunctionSpec _ _ = return () buildProcessOrFunctionSpec _ _ = return ()
-- All the various types of Structured (SEQ, PAR, ALT, IF, CASE, input-CASE, VALOF) deal with their nodes so differently -- All the various types of Structured (SEQ, PAR, ALT, IF, CASE, input-CASE, VALOF) deal with their nodes so differently

View File

@ -386,27 +386,27 @@ testProcFuncSpec = TestLabel "testProcFuncSpec" $ TestList
[ [
-- Single spec of process (with SKIP body) in AST (not connected up): -- Single spec of process (with SKIP body) in AST (not connected up):
testGraph' "testProcFuncSpec 0" [(0, m0), (5,m5)] [5] [(5,0,ESeq Nothing)] testGraph' "testProcFuncSpec 0" [(0, m0), (5,m5)] [5] [(5,0,ESeq Nothing)]
(A.Spec mU (A.Specification m1 undefined $ A.Proc m5 undefined undefined sm0) $ A.Several mU []) (A.Spec mU (A.Specification m1 undefined $ A.Proc m5 undefined undefined $ Just sm0) $ A.Several mU [])
-- Single spec of process (with body with SEQ SKIP SKIP): -- Single spec of process (with body with SEQ SKIP SKIP):
,testGraph' "testProcFuncSpec 1" [(0, m3), (4,m5), (9,m9)] [9] ([(9,0,ESeq Nothing), (0,4,ESeq Nothing)]) ,testGraph' "testProcFuncSpec 1" [(0, m3), (4,m5), (9,m9)] [9] ([(9,0,ESeq Nothing), (0,4,ESeq Nothing)])
(A.Spec mU (A.Specification m6 undefined $ A.Proc m9 undefined undefined $ (A.Spec mU (A.Specification m6 undefined $ A.Proc m9 undefined undefined $
A.Seq m0 $ A.Several m1 [A.Only m2 sm3,A.Only m4 sm5] Just $ A.Seq m0 $ A.Several m1 [A.Only m2 sm3,A.Only m4 sm5]
) $ A.Several mU []) ) $ A.Several mU [])
-- Nested spec of process (with bodies with SEQ SKIP SKIP): -- Nested spec of process (with bodies with SEQ SKIP SKIP):
,testGraph' "testProcFuncSpec 2" [(3,m2),(4,m3),(5,m4),(6,m5), (10,m10), (11, m11)] [10,11] ,testGraph' "testProcFuncSpec 2" [(3,m2),(4,m3),(5,m4),(6,m5), (10,m10), (11, m11)] [10,11]
([(10,3,ESeq Nothing), (3,4,ESeq Nothing)] ++ [(11,5,ESeq Nothing), (5,6,ESeq Nothing)]) ([(10,3,ESeq Nothing), (3,4,ESeq Nothing)] ++ [(11,5,ESeq Nothing), (5,6,ESeq Nothing)])
(A.Spec mU (A.Specification m6 undefined $ A.Proc m10 undefined undefined $ (A.Spec mU (A.Specification m6 undefined $ A.Proc m10 undefined undefined $
A.Seq mU $ A.Several mU [A.Only mU sm2,A.Only mU sm3] Just $ A.Seq mU $ A.Several mU [A.Only mU sm2,A.Only mU sm3]
) $ ) $
A.Spec mU (A.Specification m7 undefined $ A.Proc m11 undefined undefined $ A.Spec mU (A.Specification m7 undefined $ A.Proc m11 undefined undefined $
A.Seq mU $ A.Several mU [A.Only mU sm4,A.Only mU sm5] Just $ A.Seq mU $ A.Several mU [A.Only mU sm4,A.Only mU sm5]
) )
$ A.Several mU []) $ A.Several mU [])
-- Single spec of process (with SKIP body) in a SEQ (connected up): -- Single spec of process (with SKIP body) in a SEQ (connected up):
,testGraph "testProcFuncSpec 10" [(0, m0),(1,m1),(2,sub m1 100), (3, m3), (5,m5)] [1,5] [(5,0,ESeq Nothing), (1,3,ESeq Nothing), (3,2,ESeq Nothing)] ,testGraph "testProcFuncSpec 10" [(0, m0),(1,m1),(2,sub m1 100), (3, m3), (5,m5)] [1,5] [(5,0,ESeq Nothing), (1,3,ESeq Nothing), (3,2,ESeq Nothing)]
(A.Seq mU $ A.Spec mU (A.Specification m1 undefined $ A.Proc m5 undefined undefined sm0) $ A.Several m3 []) (A.Seq mU $ A.Spec mU (A.Specification m1 undefined $ A.Proc m5 undefined undefined $ Just sm0) $ A.Several m3 [])
] ]

View File

@ -69,7 +69,7 @@ writeIncFile = occamOnlyPass "Write .inc file" [] []
)) ))
where where
emitProcsAsExternal :: A.AST -> PassM (Seq.Seq String) emitProcsAsExternal :: A.AST -> PassM (Seq.Seq String)
emitProcsAsExternal (A.Spec _ (A.Specification _ n (A.Proc _ _ fs _)) scope) emitProcsAsExternal (A.Spec _ (A.Specification _ n (A.Proc _ _ fs (Just _))) scope)
= do origN <- lookupName n >>* A.ndOrigName = do origN <- lookupName n >>* A.ndOrigName
thisProc <- sequence ( thisProc <- sequence (
[return $ "#PRAGMA TOCKEXTERNAL \"PROC " ++ origN ++ "(" [return $ "#PRAGMA TOCKEXTERNAL \"PROC " ++ origN ++ "("
@ -79,7 +79,7 @@ writeIncFile = occamOnlyPass "Write .inc file" [] []
modify $ \cs -> cs { csOriginalTopLevelProcs = modify $ \cs -> cs { csOriginalTopLevelProcs =
A.nameName n : csOriginalTopLevelProcs cs } A.nameName n : csOriginalTopLevelProcs cs }
emitProcsAsExternal scope >>* (thisProc Seq.<|) emitProcsAsExternal scope >>* (thisProc Seq.<|)
emitProcsAsExternal (A.Spec _ (A.Specification _ n (A.Function _ _ ts fs _)) scope) emitProcsAsExternal (A.Spec _ (A.Specification _ n (A.Function _ _ ts fs (Just _))) scope)
= do origN <- lookupName n >>* A.ndOrigName = do origN <- lookupName n >>* A.ndOrigName
thisProc <- sequence ( thisProc <- sequence (
[return $ "#PRAGMA TOCKEXTERNAL \"" [return $ "#PRAGMA TOCKEXTERNAL \""

View File

@ -937,12 +937,12 @@ inferTypes = occamOnlyPass "Infer types"
_ -> return (t'', id) _ -> return (t'', id)
_ -> return (t'', id) _ -> return (t'', id)
return $ A.Is m am t''' $ A.ActualChannelArray $ map f vs' return $ A.Is m am t''' $ A.ActualChannelArray $ map f vs'
A.Function m sm ts fs (Left sel) -> lift $ A.Function m sm ts fs (Just (Left sel)) -> lift $
do sm' <- recurse sm do sm' <- recurse sm
ts' <- recurse ts ts' <- recurse ts
fs' <- recurse fs fs' <- recurse fs
sel' <- doFuncDef ts sel sel' <- doFuncDef ts sel
return $ A.Function m sm' ts' fs' (Left sel') return $ A.Function m sm' ts' fs' $ Just (Left sel')
A.RetypesExpr _ _ _ _ -> lift $ noTypeContext $ descend st A.RetypesExpr _ _ _ _ -> lift $ noTypeContext $ descend st
-- For PROCs that take any channels without direction, -- For PROCs that take any channels without direction,
-- we must determine if we can infer a specific direction -- we must determine if we can infer a specific direction
@ -1404,7 +1404,7 @@ checkSpecTypes = checkDepthM doSpecType
doSpecType (A.Proc m _ fs _) doSpecType (A.Proc m _ fs _)
= sequence_ [when (am == A.Original) $ unexpectedAM m = sequence_ [when (am == A.Original) $ unexpectedAM m
| A.Formal am _ n <- fs] | A.Formal am _ n <- fs]
doSpecType (A.Function m _ rs fs body) doSpecType (A.Function m _ rs fs (Just body))
= do when (length rs == 0) $ = do when (length rs == 0) $
dieP m "A function must have at least one return type" dieP m "A function must have at least one return type"
sequence_ [do when (am /= A.ValAbbrev) $ sequence_ [do when (am /= A.ValAbbrev) $
@ -1420,6 +1420,7 @@ checkSpecTypes = checkDepthM doSpecType
doFunctionBody rs (Left s) = checkStructured (checkExpressionList rs) s doFunctionBody rs (Left s) = checkStructured (checkExpressionList rs) s
-- FIXME: Need to know the name of the function to do this -- FIXME: Need to know the name of the function to do this
doFunctionBody rs (Right p) = dieP m "Cannot check function process body" doFunctionBody rs (Right p) = dieP m "Cannot check function process body"
doSpecType (A.Function _ _ _ _ Nothing) = return ()
doSpecType (A.Retypes m am t v) doSpecType (A.Retypes m am t v)
= do fromT <- astTypeOf v = do fromT <- astTypeOf v
checkRetypes m fromT t checkRetypes m fromT t

View File

@ -457,18 +457,18 @@ testOccamTypes = TestList
] ]
-- Proc -- Proc
, testOK 2090 $ A.Proc m (A.PlainSpec, A.PlainRec) [] skip , testOK 2090 $ A.Proc m (A.PlainSpec, A.PlainRec) [] jskip
, testOK 2091 $ A.Proc m (A.InlineSpec, A.PlainRec) [] skip , testOK 2091 $ A.Proc m (A.InlineSpec, A.PlainRec) [] jskip
, testOK 2092 $ A.Proc m (A.PlainSpec, A.PlainRec) , testOK 2092 $ A.Proc m (A.PlainSpec, A.PlainRec)
[ A.Formal A.Abbrev A.Int (simpleName "x") [ A.Formal A.Abbrev A.Int (simpleName "x")
, A.Formal A.ValAbbrev A.Int (simpleName "y") , A.Formal A.ValAbbrev A.Int (simpleName "y")
, A.Formal A.Abbrev chanIntT (simpleName "c") , A.Formal A.Abbrev chanIntT (simpleName "c")
] ]
skip jskip
, testFail 2093 $ A.Proc m (A.PlainSpec, A.PlainRec) , testFail 2093 $ A.Proc m (A.PlainSpec, A.PlainRec)
[ A.Formal A.Original A.Int (simpleName "x") [ A.Formal A.Original A.Int (simpleName "x")
] ]
skip jskip
-- Function -- Function
, testOK 2100 $ A.Function m (A.PlainSpec, A.PlainRec) [A.Int] [] returnOne , testOK 2100 $ A.Function m (A.PlainSpec, A.PlainRec) [A.Int] [] returnOne
@ -600,6 +600,7 @@ testOccamTypes = TestList
--{{{ process fragments --{{{ process fragments
skip = A.Skip m skip = A.Skip m
jskip = Just skip
sskip = A.Only m skip sskip = A.Only m skip
insim iis = A.InputSimple m iis insim iis = A.InputSimple m iis
inputSimple c iis = A.Input m c $ insim iis inputSimple c iis = A.Input m c $ insim iis
@ -620,9 +621,9 @@ testOccamTypes = TestList
--}}} --}}}
--{{{ specification fragments --{{{ specification fragments
returnNone = Left $ A.Only m $ A.ExpressionList m [] returnNone = Just $ Left $ A.Only m $ A.ExpressionList m []
returnOne = Left $ A.Only m $ A.ExpressionList m [intE] returnOne = Just $ Left $ A.Only m $ A.ExpressionList m [intE]
returnTwo = Left $ A.Only m $ A.ExpressionList m [intE, intE] returnTwo = Just $ Left $ A.Only m $ A.ExpressionList m [intE, intE]
retypesV = A.Retypes m A.Abbrev retypesV = A.Retypes m A.Abbrev
retypesE = A.RetypesExpr m A.ValAbbrev retypesE = A.RetypesExpr m A.ValAbbrev

View File

@ -371,8 +371,7 @@ handleSpecs specs inner specMarker
v <- inner v <- inner
mapM scopeOutSpec (reverse ss') mapM scopeOutSpec (reverse ss')
after after
return $ foldl (\e s -> specMarker m s e) v return $ foldl (\e s -> specMarker m s e) v ss'
[s | (s,(_,_,(_,A.NameUser))) <- zip ss' ss]
-- | Run several different parsers with a separator between them. -- | Run several different parsers with a separator between them.
-- If you give it [a, b, c] and s, it'll parse [a, s, b, s, c] then -- If you give it [a, b, c] and s, it'll parse [a, s, b, s, c] then
@ -1179,7 +1178,7 @@ definition
indent indent
n' <- if rm == A.Recursive n' <- if rm == A.Recursive
then scopeIn n ProcName then scopeIn n ProcName
(A.Proc m (sm, rm) (map fst fs) (A.Skip m)) A.Original normalName (A.Proc m (sm, rm) (map fst fs) Nothing) A.Original normalName
else return n else return n
fs' <- scopeInFormals fs fs' <- scopeInFormals fs
p <- process p <- process
@ -1187,7 +1186,7 @@ definition
outdent outdent
sColon sColon
eol eol
return (A.Specification m n' $ A.Proc m (sm, rm) fs' p, ProcName, normalName) return (A.Specification m n' $ A.Proc m (sm, rm) fs' (Just p), ProcName, normalName)
<|> do m <- md <|> do m <- md
(rs, (sm, (rm, _))) <- tryVV (sepBy1 dataType sComma) (specMode $ recMode sFUNCTION) (rs, (sm, (rm, _))) <- tryVV (sepBy1 dataType sComma) (specMode $ recMode sFUNCTION)
n <- newFunctionName n <- newFunctionName
@ -1195,7 +1194,7 @@ definition
let addScope body let addScope body
= do n' <- if rm == A.Recursive = do n' <- if rm == A.Recursive
then scopeIn n FunctionName then scopeIn n FunctionName
(A.Function m (sm, rm) rs (map fst fs) (Left $ A.Several m [])) (A.Function m (sm, rm) rs (map fst fs) Nothing)
A.Original normalName A.Original normalName
else return n else return n
fs' <- scopeInFormals fs fs' <- scopeInFormals fs
@ -1203,9 +1202,11 @@ definition
scopeOutFormals fs' scopeOutFormals fs'
return (x, fs', n') return (x, fs', n')
do { sIS; (el, fs', n') <- addScope expressionList; sColon; eol; do { sIS; (el, fs', n') <- addScope expressionList; sColon; eol;
return (A.Specification m n' $ A.Function m (sm, rm) rs fs' (Left $ A.Only m el), FunctionName, normalName) } return (A.Specification m n' $ A.Function m (sm, rm) rs fs'
(Just $ Left $ A.Only m el), FunctionName, normalName) }
<|> do { eol; indent; (vp, fs', n') <- addScope valueProcess; outdent; sColon; eol; <|> do { eol; indent; (vp, fs', n') <- addScope valueProcess; outdent; sColon; eol;
return (A.Specification m n' $ A.Function m (sm, rm) rs fs' (Left vp), FunctionName, normalName) } return (A.Specification m n' $ A.Function m (sm, rm) rs fs'
(Just $ Left vp), FunctionName, normalName) }
<|> retypesAbbrev <|> retypesAbbrev
<?> "definition" <?> "definition"
where where
@ -1421,23 +1422,23 @@ pragma = do m <- getPosition >>* sourcePosToMeta
fs <- formalList' fs <- formalList'
sEq sEq
integer integer
return (n, ProcName, n, fs, A.Proc m (A.PlainSpec, A.PlainRec) fs (A.Skip m)) return (n, ProcName, n, fs, A.Proc m (A.PlainSpec, A.PlainRec) fs Nothing)
else do sPROC else do sPROC
origN <- anyName ProcName origN <- anyName ProcName
fs <- formalList' fs <- formalList'
sEq sEq
n <- newProcName n <- newProcName
return (n, ProcName, origN, fs, A.Proc m (A.PlainSpec, A.PlainRec) fs (A.Skip m)) return (n, ProcName, origN, fs, A.Proc m (A.PlainSpec, A.PlainRec) fs Nothing)
<|> do ts <- tryVX (sepBy1 dataType sComma) sFUNCTION <|> do ts <- tryVX (sepBy1 dataType sComma) sFUNCTION
origN <- anyName FunctionName origN <- anyName FunctionName
fs <- formalList' fs <- formalList'
sEq sEq
n <- newFunctionName n <- newFunctionName
return (n, FunctionName, origN, fs, A.Function m (A.PlainSpec, A.PlainRec) ts fs return (n, FunctionName, origN, fs, A.Function m (A.PlainSpec, A.PlainRec) ts fs
$ Right (A.Skip m)) Nothing)
let ext = if pragmaType == 2 then ExternalOldStyle else ExternalOccam let ext = if pragmaType == 2 then ExternalOldStyle else ExternalOccam
modify $ \st -> st modify $ \st -> st
{ csExternals = (A.nameName n, (ext, fs)) : csExternals st { csExternals = (A.nameName n, ext) : csExternals st
} }
return $ Just (A.Specification m origN sp, nt, (Just n, A.NameExternal)) return $ Just (A.Specification m origN sp, nt, (Just n, A.NameExternal))
ns <- case (prag, mprod) of ns <- case (prag, mprod) of

View File

@ -495,13 +495,13 @@ terminator = A.Several emptyMeta []
processDecl :: RainParser A.AST processDecl :: RainParser A.AST
processDecl = do {m <- sProcess ; procName <- name ; params <- tupleDef ; body <- block ; processDecl = do {m <- sProcess ; procName <- name ; params <- tupleDef ; body <- block ;
return $ A.Spec m return $ A.Spec m
(A.Specification m procName (A.Proc m (A.PlainSpec, A.Recursive) (formaliseTuple params) body)) (A.Specification m procName (A.Proc m (A.PlainSpec, A.Recursive) (formaliseTuple params) $ Just body))
terminator} terminator}
functionDecl :: RainParser A.AST functionDecl :: RainParser A.AST
functionDecl = do {m <- sFunction ; retType <- dataType ; sColon ; funcName <- name ; params <- tupleDef ; body <- innerBlock False (Just funcName) ; functionDecl = do {m <- sFunction ; retType <- dataType ; sColon ; funcName <- name ; params <- tupleDef ; body <- innerBlock False (Just funcName) ;
return $ A.Spec m return $ A.Spec m
(A.Specification m funcName (A.Function m (A.PlainSpec, A.Recursive) [retType] (formaliseTuple params) (Right $ A.Seq m body))) (A.Specification m funcName (A.Function m (A.PlainSpec, A.Recursive) [retType] (formaliseTuple params) (Just $ Right $ A.Seq m body)))
terminator} terminator}
topLevelDecl :: RainParser A.AST topLevelDecl :: RainParser A.AST

View File

@ -487,21 +487,22 @@ testTopLevelDecl :: [ParseTest A.AST]
testTopLevelDecl = testTopLevelDecl =
[ [
passTop (0, "process noargs() {}", passTop (0, "process noargs() {}",
[A.Spec m (A.Specification m (simpleName "noargs") $ A.Proc m (A.PlainSpec, A.Recursive) [] emptyBlock) emptySeveral]) [A.Spec m (A.Specification m (simpleName "noargs") $ A.Proc m (A.PlainSpec, A.Recursive) [] jemptyBlock) emptySeveral])
,passTop (1, "process onearg(int: x) {x = 0;}", ,passTop (1, "process onearg(int: x) {x = 0;}",
[A.Spec m (A.Specification m (simpleName "onearg") $ A.Proc m (A.PlainSpec, A.Recursive) [A.Spec m (A.Specification m (simpleName "onearg") $ A.Proc m (A.PlainSpec, A.Recursive)
[A.Formal A.ValAbbrev A.Int (simpleName "x")] $ [A.Formal A.ValAbbrev A.Int (simpleName "x")] $ Just $
makeSeq [makeAssign (variable "x") (intLiteral 0)]) makeSeq [makeAssign (variable "x") (intLiteral 0)])
emptySeveral emptySeveral
]) ])
,passTop (2, "process noargs0() {} process noargs1 () {}", ,passTop (2, "process noargs0() {} process noargs1 () {}",
[A.Spec m (A.Specification m (simpleName "noargs0") $ A.Proc m (A.PlainSpec, A.Recursive) [] emptyBlock) emptySeveral [A.Spec m (A.Specification m (simpleName "noargs0") $ A.Proc m (A.PlainSpec, A.Recursive) [] jemptyBlock) emptySeveral
,A.Spec m (A.Specification m (simpleName "noargs1") $ A.Proc m (A.PlainSpec, A.Recursive) [] emptyBlock) emptySeveral]) ,A.Spec m (A.Specification m (simpleName "noargs1") $ A.Proc m (A.PlainSpec, A.Recursive) [] jemptyBlock) emptySeveral])
,passTop (4, "process noargs() par {}", ,passTop (4, "process noargs() par {}",
[A.Spec m (A.Specification m (simpleName "noargs") $ A.Proc m (A.PlainSpec, A.Recursive) [] $ A.Par m A.PlainPar emptySeveral) emptySeveral]) [A.Spec m (A.Specification m (simpleName "noargs") $ A.Proc m (A.PlainSpec, A.Recursive) [] $
Just $ A.Par m A.PlainPar emptySeveral) emptySeveral])
, fail ("process", RP.topLevelDecl) , fail ("process", RP.topLevelDecl)
, fail ("process () {}", RP.topLevelDecl) , fail ("process () {}", RP.topLevelDecl)
@ -513,22 +514,25 @@ testTopLevelDecl =
, fail ("process foo (int x) {}", RP.topLevelDecl) , fail ("process foo (int x) {}", RP.topLevelDecl)
,passTop (100, "function uint8: cons() {}", ,passTop (100, "function uint8: cons() {}",
[A.Spec m (A.Specification m (simpleName "cons") $ A.Function m (A.PlainSpec,A.Recursive) [A.Byte] [] $ Right emptyBlock) emptySeveral]) [A.Spec m (A.Specification m (simpleName "cons") $ A.Function m (A.PlainSpec,A.Recursive) [A.Byte] []
$ Just $ Right emptyBlock) emptySeveral])
,passTop (101, "function uint8: f(uint8: x) {}", ,passTop (101, "function uint8: f(uint8: x) {}",
[A.Spec m (A.Specification m (simpleName "f") $ [A.Spec m (A.Specification m (simpleName "f") $
A.Function m (A.PlainSpec, A.Recursive) [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")] $ Right emptyBlock) A.Function m (A.PlainSpec, A.Recursive) [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")]
$ Just $ Right emptyBlock)
emptySeveral]) emptySeveral])
,passTop (102, "function uint8: id(uint8: x) {return x;}", ,passTop (102, "function uint8: id(uint8: x) {return x;}",
[A.Spec m (A.Specification m (simpleName "id") $ [A.Spec m (A.Specification m (simpleName "id") $
A.Function m (A.PlainSpec, A.Recursive) [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")] $ Right $ A.Function m (A.PlainSpec, A.Recursive) [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")] $ Just $ Right $
A.Seq m $ A.Several m [A.Only m $ A.Assign m [variable "id"] (A.ExpressionList m [exprVariable "x"])]) A.Seq m $ A.Several m [A.Only m $ A.Assign m [variable "id"] (A.ExpressionList m [exprVariable "x"])])
emptySeveral]) emptySeveral])
] ]
where where
passTop :: (Int, String, [A.AST]) -> ParseTest A.AST passTop :: (Int, String, [A.AST]) -> ParseTest A.AST
passTop (ind, input, exp) = pass (input, RP.topLevelDecl, assertPatternMatch ("testTopLevelDecl " ++ show ind) $ pat $ A.Several m exp) passTop (ind, input, exp) = pass (input, RP.topLevelDecl, assertPatternMatch ("testTopLevelDecl " ++ show ind) $ pat $ A.Several m exp)
jemptyBlock = Just emptyBlock
nonShared :: A.ChanAttributes nonShared :: A.ChanAttributes
nonShared = A.ChanAttributes { A.caWritingShared = A.Unshared, A.caReadingShared = A.Unshared} nonShared = A.ChanAttributes { A.caWritingShared = A.Unshared, A.caReadingShared = A.Unshared}

View File

@ -223,7 +223,7 @@ checkFunction :: PassType
checkFunction = return -- applyDepthM checkFunction' checkFunction = return -- applyDepthM checkFunction'
where where
checkFunction' :: A.Specification -> PassM A.Specification checkFunction' :: A.Specification -> PassM A.Specification
checkFunction' spec@(A.Specification _ n (A.Function m _ _ _ (Right body))) checkFunction' spec@(A.Specification _ n (A.Function m _ _ _ (Just (Right body))))
= case body of = case body of
(A.Seq m' seqBody) -> (A.Seq m' seqBody) ->
let A.Several _ statements = skipSpecs seqBody in let A.Several _ statements = skipSpecs seqBody in

View File

@ -175,17 +175,19 @@ testUnique2b = TestCase $ testPassWithItemsStateCheck "testUnique2b" exp uniquif
testUnique3 :: Test testUnique3 :: Test
testUnique3 = TestCase $ testPassWithItemsStateCheck "testUnique3" exp uniquifyAndResolveVars orig (return ()) check testUnique3 = TestCase $ testPassWithItemsStateCheck "testUnique3" exp uniquifyAndResolveVars orig (return ()) check
where where
orig = A.Spec m (A.Specification m (procName "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] $ A.Skip m) (A.Only m $ A.ProcCall m (procName "foo") []) orig = A.Spec m (A.Specification m (procName "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] $ Just
$ A.Skip m) (A.Only m $ A.ProcCall m (procName "foo") [])
exp = orig exp = orig
check (items,state) = assertVarDef "testUnique3: Variable was not recorded" state "foo" check (items,state) = assertVarDef "testUnique3: Variable was not recorded" state "foo"
(tag7 A.NameDef DontCare "foo" "foo" (tag7 A.NameDef DontCare "foo" "foo"
(A.Proc m (A.PlainSpec, A.Recursive) [] $ A.Skip m) A.Original A.NameUser A.Unplaced) (A.Proc m (A.PlainSpec, A.Recursive) [] $ Just $
A.Skip m) A.Original A.NameUser A.Unplaced)
-- | Tests that parameters are uniquified and resolved: -- | Tests that parameters are uniquified and resolved:
testUnique4 :: Test testUnique4 :: Test
testUnique4 = TestCase $ testPassWithItemsStateCheck "testUnique4" exp uniquifyAndResolveVars orig (return ()) check testUnique4 = TestCase $ testPassWithItemsStateCheck "testUnique4" exp uniquifyAndResolveVars orig (return ()) check
where where
orig = A.Spec m (A.Specification m (procName "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [A.Formal A.ValAbbrev A.Byte $ simpleName "c"] $ orig = A.Spec m (A.Specification m (procName "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [A.Formal A.ValAbbrev A.Byte $ simpleName "c"] $ Just $
A.ProcCall m (procName "foo") [A.ActualExpression $ exprVariable "c"]) (skipP) A.ProcCall m (procName "foo") [A.ActualExpression $ exprVariable "c"]) (skipP)
exp = mSpecP exp = mSpecP
(tag3 A.Specification DontCare (procNamePattern "foo") $ tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) (tag3 A.Specification DontCare (procNamePattern "foo") $ tag4 A.Proc DontCare (A.PlainSpec, A.Recursive)
@ -226,7 +228,7 @@ testUnique4 = TestCase $ testPassWithItemsStateCheck "testUnique4" exp uniquifyA
testFindMain0 :: Test testFindMain0 :: Test
testFindMain0 = TestCase $ testPassWithItemsStateCheck "testFindMain0" exp (uniquifyAndResolveVars >>> findMain) orig (return ()) check testFindMain0 = TestCase $ testPassWithItemsStateCheck "testFindMain0" exp (uniquifyAndResolveVars >>> findMain) orig (return ()) check
where where
orig = A.Spec m (A.Specification m (A.Name m "main") $ A.Proc m (A.PlainSpec, A.Recursive) [] (A.Skip m)) $ A.Several m [] :: A.AST orig = A.Spec m (A.Specification m (A.Name m "main") $ A.Proc m (A.PlainSpec, A.Recursive) [] (Just $ A.Skip m)) $ A.Several m [] :: A.AST
exp = mSpecAST (tag3 A.Specification DontCare (tag2 A.Name DontCare ("main"@@DontCare)) $ exp = mSpecAST (tag3 A.Specification DontCare (tag2 A.Name DontCare ("main"@@DontCare)) $
tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) ([] :: [A.Formal]) (tag1 A.Skip DontCare)) $ mSeveralAST ([] :: [A.AST]) tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) ([] :: [A.Formal]) (tag1 A.Skip DontCare)) $ mSeveralAST ([] :: [A.AST])
check (items,state) check (items,state)
@ -239,15 +241,15 @@ testFindMain0 = TestCase $ testPassWithItemsStateCheck "testFindMain0" exp (uniq
testFindMain1 :: Test testFindMain1 :: Test
testFindMain1 = TestCase $ testPassWithStateCheck "testFindMain1" orig (uniquifyAndResolveVars >>> findMain) orig (return ()) check testFindMain1 = TestCase $ testPassWithStateCheck "testFindMain1" orig (uniquifyAndResolveVars >>> findMain) orig (return ()) check
where where
orig = A.Spec m (A.Specification m (A.Name m "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] (A.Skip m)) $ A.Several m ([] :: [A.AST]) orig = A.Spec m (A.Specification m (A.Name m "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] (Just $ A.Skip m)) $ A.Several m ([] :: [A.AST])
check state = assertEqual "testFindMain1" [] (csMainLocals state) check state = assertEqual "testFindMain1" [] (csMainLocals state)
testFindMain2 :: Test testFindMain2 :: Test
testFindMain2 = TestCase $ testPassWithItemsStateCheck "testFindMain2" exp (uniquifyAndResolveVars >>> findMain) orig (return ()) check testFindMain2 = TestCase $ testPassWithItemsStateCheck "testFindMain2" exp (uniquifyAndResolveVars >>> findMain) orig (return ()) check
where where
inner = A.Spec m (A.Specification m (A.Name m "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] (A.Skip m)) $ inner = A.Spec m (A.Specification m (A.Name m "foo") $ A.Proc m (A.PlainSpec, A.Recursive) [] (Just $ A.Skip m)) $
A.Several m ([] :: [A.AST]) A.Several m ([] :: [A.AST])
orig = A.Spec m (A.Specification m (A.Name m "main") $ A.Proc m (A.PlainSpec, A.Recursive) [] (A.Skip m)) inner orig = A.Spec m (A.Specification m (A.Name m "main") $ A.Proc m (A.PlainSpec, A.Recursive) [] (Just $ A.Skip m)) inner
exp = mSpecAST (tag3 A.Specification DontCare (tag2 A.Name DontCare ("main"@@DontCare)) $ exp = mSpecAST (tag3 A.Specification DontCare (tag2 A.Name DontCare ("main"@@DontCare)) $
tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) ([] :: [A.Formal]) (tag1 A.Skip DontCare)) (stopCaringPattern m $ mkPattern inner) tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) ([] :: [A.Formal]) (tag1 A.Skip DontCare)) (stopCaringPattern m $ mkPattern inner)
@ -274,12 +276,12 @@ testParamPass testName formals params transParams
startStateProc = do defineName (simpleName "x") $ simpleDefDecl "x" (A.UInt16) startStateProc = do defineName (simpleName "x") $ simpleDefDecl "x" (A.UInt16)
case formals of case formals of
Nothing -> return () Nothing -> return ()
Just formals' -> defineName (procName "foo") $ simpleDef "foo" $ A.Proc m (A.PlainSpec, A.Recursive) formals' (A.Skip m) Just formals' -> defineName (procName "foo") $ simpleDef "foo" $ A.Proc m (A.PlainSpec, A.Recursive) formals' (Just $ A.Skip m)
startStateFunc :: State CompState () startStateFunc :: State CompState ()
startStateFunc = do defineName (simpleName "x") $ simpleDefDecl "x" (A.UInt16) startStateFunc = do defineName (simpleName "x") $ simpleDefDecl "x" (A.UInt16)
case formals of case formals of
Nothing -> return () Nothing -> return ()
Just formals' -> defineName (funcName "foo") $ simpleDef "foo" $ A.Function m (A.PlainSpec,A.Recursive) [A.Byte] formals' (Left $ A.Only m $ A.ExpressionList m []) Just formals' -> defineName (funcName "foo") $ simpleDef "foo" $ A.Function m (A.PlainSpec,A.Recursive) [A.Byte] formals' (Just $ Left $ A.Only m $ A.ExpressionList m [])
origProc = A.ProcCall m (procName "foo") params origProc = A.ProcCall m (procName "foo") params
expProc ps = A.ProcCall m (procName "foo") ps expProc ps = A.ProcCall m (procName "foo") ps
origFunc = A.FunctionCall m (funcName "foo") (deActualise params) origFunc = A.FunctionCall m (funcName "foo") (deActualise params)

View File

@ -88,11 +88,9 @@ nullStateBodies = Pass
where where
nullProcFuncDefs :: A.NameDef -> A.NameDef nullProcFuncDefs :: A.NameDef -> A.NameDef
nullProcFuncDefs (A.NameDef m n on (A.Proc m' sm fs _) am ns pl) nullProcFuncDefs (A.NameDef m n on (A.Proc m' sm fs _) am ns pl)
= (A.NameDef m n on (A.Proc m' sm fs (A.Skip m')) am ns pl) = (A.NameDef m n on (A.Proc m' sm fs Nothing) am ns pl)
nullProcFuncDefs (A.NameDef m n on (A.Function m' sm ts fs (Left _)) am ns pl) nullProcFuncDefs (A.NameDef m n on (A.Function m' sm ts fs _) am ns pl)
= (A.NameDef m n on (A.Function m' sm ts fs (Left $ A.Several m' [])) am ns pl) = (A.NameDef m n on (A.Function m' sm ts fs Nothing) am ns pl)
nullProcFuncDefs (A.NameDef m n on (A.Function m' sm ts fs (Right _)) am ns pl)
= (A.NameDef m n on (A.Function m' sm ts fs (Right $ A.Skip m')) am ns pl)
nullProcFuncDefs x = x nullProcFuncDefs x = x

View File

@ -61,11 +61,11 @@ assertGetItemCast k kv
-- | Given a body, returns a function spec: -- | Given a body, returns a function spec:
singleParamFunc :: A.Structured A.ExpressionList -> A.Specification singleParamFunc :: A.Structured A.ExpressionList -> A.Specification
singleParamFunc body = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, singleParamFunc body = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec,
A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "param0")] (Left body)) A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "param0")] (Just $ Left body))
singleParamFuncProc :: A.Process -> A.Specification singleParamFuncProc :: A.Process -> A.Specification
singleParamFuncProc body = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, singleParamFuncProc body = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec,
A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "param0")] (Right body)) A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "param0")] (Just $ Right body))
-- | Returns the expected body of the single parameter process (when the function had valof0 as a body) -- | Returns the expected body of the single parameter process (when the function had valof0 as a body)
singleParamBodyExp :: Pattern -- ^ to match: A.Process singleParamBodyExp :: Pattern -- ^ to match: A.Process
@ -100,7 +100,7 @@ testFunctionsToProcs1 :: Test
testFunctionsToProcs1 = TestCase $ testPassWithItemsStateCheck "testFunctionsToProcs1 A" exp functionsToProcs orig (return ()) check testFunctionsToProcs1 = TestCase $ testPassWithItemsStateCheck "testFunctionsToProcs1 A" exp functionsToProcs orig (return ()) check
where where
orig = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, A.Recursive) [A.Int,A.Real32] orig = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, A.Recursive) [A.Int,A.Real32]
[A.Formal A.ValAbbrev A.Byte (simpleName "param0"),A.Formal A.Abbrev A.Real32 (simpleName "param1")] (Left $ valofTwo "param0" "param1")) [A.Formal A.ValAbbrev A.Byte (simpleName "param0"),A.Formal A.Abbrev A.Real32 (simpleName "param1")] (Just $ Left $ valofTwo "param0" "param1"))
exp = tag3 A.Specification DontCare (simpleName "foo") procBody exp = tag3 A.Specification DontCare (simpleName "foo") procBody
procBody = tag4 A.Proc DontCare (A.PlainSpec, A.Recursive) procBody = tag4 A.Proc DontCare (A.PlainSpec, A.Recursive)
[tag3 A.Formal A.ValAbbrev A.Byte (simpleName "param0"), [tag3 A.Formal A.ValAbbrev A.Byte (simpleName "param0"),
@ -134,7 +134,7 @@ testFunctionsToProcs2 :: Test
testFunctionsToProcs2 = TestCase $ testPassWithItemsStateCheck "testFunctionsToProcs2 A" exp functionsToProcs orig (return ()) check testFunctionsToProcs2 = TestCase $ testPassWithItemsStateCheck "testFunctionsToProcs2 A" exp functionsToProcs orig (return ()) check
where where
orig = A.Specification m (simpleName "fooOuter") (A.Function m (A.PlainSpec, orig = A.Specification m (simpleName "fooOuter") (A.Function m (A.PlainSpec,
A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "paramOuter0")] $ Left $ A.PlainRec) [A.Int] [A.Formal A.ValAbbrev A.Byte (simpleName "paramOuter0")] $ Just $ Left $
A.Spec m (singleParamFunc valof0) valof0) A.Spec m (singleParamFunc valof0) valof0)
exp = tag3 A.Specification DontCare (simpleName "fooOuter") procBodyOuter exp = tag3 A.Specification DontCare (simpleName "fooOuter") procBodyOuter
procHeader body = tag4 A.Proc DontCare (A.PlainSpec, A.PlainRec) [tag3 A.Formal A.ValAbbrev A.Byte (simpleName "paramOuter0"), tag3 A.Formal A.Abbrev A.Int (Named "retOuter0" DontCare)] body procHeader body = tag4 A.Proc DontCare (A.PlainSpec, A.PlainRec) [tag3 A.Formal A.ValAbbrev A.Byte (simpleName "paramOuter0"), tag3 A.Formal A.Abbrev A.Int (Named "retOuter0" DontCare)] body
@ -190,7 +190,7 @@ testFunctionsToProcs4 = TestCase $ testPassWithItemsStateCheck "testFunctionsToP
where where
orig = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, A.PlainRec) [A.Int,A.Real32] orig = A.Specification m (simpleName "foo") (A.Function m (A.PlainSpec, A.PlainRec) [A.Int,A.Real32]
[A.Formal A.ValAbbrev A.Byte (simpleName "param0"),A.Formal A.Abbrev A.Real32 (simpleName "param1")] $ [A.Formal A.ValAbbrev A.Byte (simpleName "param0"),A.Formal A.Abbrev A.Real32 (simpleName "param1")] $
Right $ A.Seq m $ A.Only m $ A.Assign m [variable "foo"] $ A.ExpressionList m [exprVariable "param0", exprVariable "param1"]) Just $ Right $ A.Seq m $ A.Only m $ A.Assign m [variable "foo"] $ A.ExpressionList m [exprVariable "param0", exprVariable "param1"])
exp = tag3 A.Specification DontCare (simpleName "foo") procBody exp = tag3 A.Specification DontCare (simpleName "foo") procBody
procBody = tag4 A.Proc DontCare (A.PlainSpec, A.PlainRec) [tag3 A.Formal A.ValAbbrev A.Byte (simpleName "param0"), procBody = tag4 A.Proc DontCare (A.PlainSpec, A.PlainRec) [tag3 A.Formal A.ValAbbrev A.Byte (simpleName "param0"),
tag3 A.Formal A.Abbrev A.Real32 (simpleName "param1"), tag3 A.Formal A.Abbrev A.Real32 (simpleName "param1"),

View File

@ -111,7 +111,7 @@ removeInitial
-- process -- process
-- : -- :
-- inner -- inner
A.Proc m'' sm fs p -> A.Proc m'' sm fs (Just p) ->
do -- Find the INITIAL formals, and note their positions. do -- Find the INITIAL formals, and note their positions.
let (positions, fromFS) let (positions, fromFS)
= unzip [(i, f) = unzip [(i, f)
@ -144,7 +144,7 @@ removeInitial
A.Only m' p)) A.Only m' p))
p (reverse $ zip temps fromFS) p (reverse $ zip temps fromFS)
let spec' = A.Specification m' n (A.Proc m'' sm fs' p') let spec' = A.Specification m' n (A.Proc m'' sm fs' (Just p'))
return $ A.Spec m spec' inner return $ A.Spec m spec' inner
_ -> leave _ -> leave

View File

@ -60,11 +60,11 @@ testRemoveInitial = TestLabel "testRemoveInitial" $ TestList
, ok 30 (spec foo (A.Proc m , ok 30 (spec foo (A.Proc m
(A.PlainSpec, A.PlainRec) (A.PlainSpec, A.PlainRec)
[A.Formal A.InitialAbbrev A.Int bar] [A.Formal A.InitialAbbrev A.Int bar]
skip) $ Just skip)
inner) inner)
(mSpec foo (mProc (A.PlainSpec, A.PlainRec) (mSpec foo (mProc (A.PlainSpec, A.PlainRec)
[mFormal' A.ValAbbrev A.Int mTemp] [mFormal' A.ValAbbrev A.Int mTemp]
(mSeq (Just $ mSeq
(mDeclareAssign bar A.Int mTempE (mDeclareAssign bar A.Int mTempE
(A.Only m skip)))) (A.Only m skip))))
inner) inner)
@ -76,14 +76,14 @@ testRemoveInitial = TestLabel "testRemoveInitial" $ TestList
, A.Formal A.ValAbbrev A.Int baz , A.Formal A.ValAbbrev A.Int baz
, A.Formal A.InitialAbbrev A.Int quux , A.Formal A.InitialAbbrev A.Int quux
] ]
skip) (Just skip))
inner) inner)
(mSpec foo (mProc (A.PlainSpec, A.PlainRec) (mSpec foo (mProc (A.PlainSpec, A.PlainRec)
[ mFormal' A.ValAbbrev A.Int mTemp [ mFormal' A.ValAbbrev A.Int mTemp
, mFormal' A.ValAbbrev A.Int baz , mFormal' A.ValAbbrev A.Int baz
, mFormal' A.ValAbbrev A.Int mTemp2 , mFormal' A.ValAbbrev A.Int mTemp2
] ]
(mSeq (Just $ mSeq
(mDeclareAssign bar A.Int mTempE (mDeclareAssign bar A.Int mTempE
(mOnlyP (mOnlyP
(mSeq (mSeq

View File

@ -51,15 +51,7 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
(Prop.agg_namesDone ++ [Prop.expressionTypesChecked, Prop.parUsageChecked, (Prop.agg_namesDone ++ [Prop.expressionTypesChecked, Prop.parUsageChecked,
Prop.functionTypesChecked]) Prop.functionTypesChecked])
[Prop.functionsRemoved] [Prop.functionsRemoved]
(\t -> do exts <- getCompState >>* csExternals (applyDepthM doSpecification)
exts' <- sequence [do st <- specTypeOfName $ A.Name emptyMeta n
A.Specification _ _ st'@(A.Proc _ _ fs' _) <-
doSpecification $ A.Specification
(findMeta st) (A.Name emptyMeta n) st
return $ (n, (extType, fs'))
| (n, (extType, fs)) <- exts]
modify $ \cs -> cs { csExternals = exts' }
applyDepthM doSpecification t)
where where
doSpecification :: A.Specification -> PassM A.Specification doSpecification :: A.Specification -> PassM A.Specification
doSpecification (A.Specification m n (A.Function mf smrm rts fs evp)) doSpecification (A.Specification m n (A.Function mf smrm rts fs evp))
@ -69,7 +61,7 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
-- Note the return types so we can fix calls later. -- Note the return types so we can fix calls later.
modify $ (\ps -> ps { csFunctionReturns = Map.insert (A.nameName n) rts (csFunctionReturns ps) }) modify $ (\ps -> ps { csFunctionReturns = Map.insert (A.nameName n) rts (csFunctionReturns ps) })
-- Turn the value process into an assignment process. -- Turn the value process into an assignment process.
let p = vpToSeq m n evp [A.Variable mf n | n <- names] let p = fmap (vpToSeq m n [A.Variable mf n | n <- names]) evp
let st = A.Proc mf smrm (fs ++ [A.Formal A.Abbrev t n | (t, n) <- zip rts names]) p let st = A.Proc mf smrm (fs ++ [A.Formal A.Abbrev t n | (t, n) <- zip rts names]) p
-- Build a new specification and redefine the function. -- Build a new specification and redefine the function.
let spec = A.Specification m n st let spec = A.Specification m n st
@ -86,9 +78,9 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
return spec return spec
doSpecification s = return s doSpecification s = return s
vpToSeq :: Meta -> A.Name -> Either (A.Structured A.ExpressionList) A.Process -> [A.Variable] -> A.Process vpToSeq :: Meta -> A.Name -> [A.Variable] -> Either (A.Structured A.ExpressionList) A.Process -> A.Process
vpToSeq m n (Left el) vs = A.Seq m $ vpToSeq' el vs vpToSeq m n vs (Left el) = A.Seq m $ vpToSeq' el vs
vpToSeq _ n (Right p) vs = subst p vpToSeq _ n vs (Right p) = subst p
where where
subst :: Data t => t -> t subst :: Data t => t -> t
subst = doGenericSubst `extT` doAssignSubst subst = doGenericSubst `extT` doAssignSubst

View File

@ -169,7 +169,7 @@ flattenAssign = pass "Flatten assignment"
let code = A.Seq m $ A.Several m $ map (A.Only m) assigns let code = A.Seq m $ A.Several m $ map (A.Only m) assigns
proc = A.Proc m (A.InlineSpec, A.PlainRec) proc = A.Proc m (A.InlineSpec, A.PlainRec)
[A.Formal A.Abbrev t nonceLHS, A.Formal A.ValAbbrev t nonceRHS] [A.Formal A.Abbrev t nonceLHS, A.Formal A.ValAbbrev t nonceRHS]
code (Just code)
defineName n' $ A.NameDef { defineName n' $ A.NameDef {
A.ndMeta = m, A.ndMeta = m,
A.ndName = A.nameName n', A.ndName = A.nameName n',