Implemented recursive procs

This works fine in the C++ backend, not tested with the C backend yet
This commit is contained in:
Neil Brown 2009-01-29 00:43:24 +00:00
parent 10e6b4ce02
commit 8a28d765e7
8 changed files with 16 additions and 11 deletions

View File

@ -1420,7 +1420,7 @@ realFormals (A.Formal am t n)
-- This will use ProcGetParam if the Proc is in csParProcs, or the normal C -- This will use ProcGetParam if the Proc is in csParProcs, or the normal C
-- calling convention otherwise. -- calling convention otherwise.
genProcSpec :: A.Name -> A.SpecType -> Bool -> CGen () genProcSpec :: A.Name -> A.SpecType -> Bool -> CGen ()
genProcSpec n (A.Proc _ sm fs p) forwardDecl genProcSpec n (A.Proc _ (sm, _) fs 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
then (genParHeader, genParParams) then (genParHeader, genParParams)

View File

@ -537,7 +537,7 @@ cppgenFormal :: (A.Name -> A.Name) -> A.Formal -> CGen ()
cppgenFormal nameFunc (A.Formal am t n) = call genDecl am t (nameFunc n) cppgenFormal nameFunc (A.Formal am t n) = call genDecl am t (nameFunc n)
cppgenForwardDeclaration :: A.Specification -> CGen() cppgenForwardDeclaration :: A.Specification -> CGen()
cppgenForwardDeclaration (A.Specification _ n (A.Proc _ sm fs _)) cppgenForwardDeclaration (A.Specification _ n (A.Proc _ (sm, _) fs _))
= do --Generate the "process" as a C++ function: = do --Generate the "process" as a C++ function:
call genSpecMode sm call genSpecMode sm
tell ["void "] tell ["void "]
@ -592,7 +592,7 @@ cppgenForwardDeclaration _ = return ()
cppintroduceSpec :: A.Specification -> CGen () cppintroduceSpec :: A.Specification -> CGen ()
--I generate process wrappers for all functions by default: --I generate process wrappers for all functions by default:
cppintroduceSpec (A.Specification _ n (A.Proc _ sm fs p)) cppintroduceSpec (A.Specification _ n (A.Proc _ (sm, _) fs p))
= do --Generate the "process" as a C++ function: = do --Generate the "process" as a C++ function:
call genSpecMode sm call genSpecMode sm
tell ["void "] tell ["void "]

View File

@ -499,7 +499,7 @@ data SpecType =
-- 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@.
| Proc Meta SpecMode [Formal] Process | Proc Meta (SpecMode, RecMode) [Formal] Process
-- | Declare a @FUNCTION@. -- | Declare a @FUNCTION@.
| Function Meta (SpecMode, RecMode) [Type] [Formal] | Function Meta (SpecMode, RecMode) [Type] [Formal]
(Either (Structured ExpressionList) Process) (Either (Structured ExpressionList) Process)

View File

@ -349,7 +349,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 [] p) A.Abbrev = defineNonce m "wrapper_proc" (A.Proc m (A.PlainSpec, A.PlainRec) [] 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

View File

@ -409,6 +409,7 @@ scopeInSpec (spec@(A.Specification m n st), nt)
return $ A.Specification m n' st return $ A.Specification m n' st
where where
isRecursive (A.Function _ (_, A.Recursive) _ _ _) = True isRecursive (A.Function _ (_, A.Recursive) _ _ _) = True
isRecursive (A.Proc _ (_, A.Recursive) _ _) = True
isRecursive _ = False isRecursive _ = False
scopeOutSpec :: A.Specification -> OccParser () scopeOutSpec :: A.Specification -> OccParser ()
@ -1087,18 +1088,22 @@ definition
do { sIS; p <- sequentialProtocol; sColon; eol; return (A.Specification m n $ A.Protocol m p, ProtocolName) } do { sIS; p <- sequentialProtocol; sColon; eol; return (A.Specification m n $ A.Protocol m p, ProtocolName) }
<|> do { eol; indent; sCASE; eol; ps <- maybeIndentedList m "empty CASE protocol" taggedProtocol; outdent; sColon; eol; return (A.Specification m n $ A.ProtocolCase m ps, ProtocolName) } <|> do { eol; indent; sCASE; eol; ps <- maybeIndentedList m "empty CASE protocol" taggedProtocol; outdent; sColon; eol; return (A.Specification m n $ A.ProtocolCase m ps, ProtocolName) }
<|> do m <- md <|> do m <- md
(sm, _) <- specMode sPROC (sm, (rm, _)) <- specMode $ recMode sPROC
n <- newProcName n <- newProcName
fs <- formalList fs <- formalList
eol eol
indent indent
n' <- if rm == A.Recursive
then scopeIn n ProcName
(A.Proc m (sm, rm) (map fst fs) (A.Skip m)) A.Original
else return n
fs' <- scopeInFormals fs fs' <- scopeInFormals fs
p <- process p <- process
scopeOutFormals fs' scopeOutFormals fs'
outdent outdent
sColon sColon
eol eol
return (A.Specification m n $ A.Proc m sm fs' p, ProcName) return (A.Specification m n' $ A.Proc m (sm, rm) fs' p, ProcName)
<|> 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

View File

@ -494,7 +494,7 @@ 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 (formaliseTuple params) body)) (A.Specification m procName (A.Proc m (A.PlainSpec, A.Recursive) (formaliseTuple params) body))
terminator} terminator}
functionDecl :: RainParser A.AST functionDecl :: RainParser A.AST

View File

@ -53,7 +53,7 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
(applyDepthM doSpecification) (applyDepthM doSpecification)
where where
doSpecification :: A.Specification -> PassM A.Specification doSpecification :: A.Specification -> PassM A.Specification
doSpecification (A.Specification m n (A.Function mf (sm, _) rts fs evp)) doSpecification (A.Specification m n (A.Function mf smrm rts fs evp))
= do -- Create new names for the return values. = do -- Create new names for the return values.
specs <- sequence [makeNonceVariable "return_formal" mf t A.Abbrev | t <- rts] specs <- sequence [makeNonceVariable "return_formal" mf t A.Abbrev | t <- rts]
let names = [n | A.Specification mf n _ <- specs] let names = [n | A.Specification mf n _ <- specs]
@ -61,7 +61,7 @@ functionsToProcs = pass "Convert FUNCTIONs to PROCs"
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 = vpToSeq m n evp [A.Variable mf n | n <- names]
let st = A.Proc mf sm (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
let nd = A.NameDef { let nd = A.NameDef {

View File

@ -158,4 +158,4 @@ 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
return (A.Spec m (A.Specification m (n {A.nameName = "copy_" ++ A.nameName n}) return (A.Spec m (A.Specification m (n {A.nameName = "copy_" ++ A.nameName n})
(A.Proc m A.InlineSpec [A.Formal A.Abbrev t nonceLHS, A.Formal A.ValAbbrev t nonceRHS] code))) (A.Proc m (A.InlineSpec, A.PlainRec) [A.Formal A.Abbrev t nonceLHS, A.Formal A.ValAbbrev t nonceRHS] code)))