Added channel-end support to the C++CSP backend

I have added two helper functions, but since they are used in contexts that are already specific to C++CSP (i.e. the channel-ends have the ">>" and "<<" operators applied to them) I have not added them to the dictionary of functions.
  
This patch allows C++CSP to actually use the direction of channels to pass around channel-ends rather than channel pointers, just as C++CSP was designed for.
This commit is contained in:
Neil Brown 2007-08-22 22:27:04 +00:00
parent 63d18373b8
commit 1e06768c20

View File

@ -166,6 +166,26 @@ cppgenStop _ m s
genMeta m genMeta m
tell [" \"",s,"\" );"] tell [" \"",s,"\" );"]
--{{{ Two helper functions to aggregate some common functionality in this file.
genCPPCSPChannelInput :: GenOps -> A.Variable -> CGen()
genCPPCSPChannelInput ops var
= do t <- typeOfVariable var
case t of
(A.Chan A.DirInput _ _) -> call genVariable ops var
(A.Chan A.DirUnknown _ _) -> do call genVariable ops var
tell [" ->reader() "]
_ -> call genMissing ops $ "genCPPCSPChannelInput used on something which does not support input: " ++ show var
genCPPCSPChannelOutput :: GenOps -> A.Variable -> CGen()
genCPPCSPChannelOutput ops var
= do t <- typeOfVariable var
case t of
(A.Chan A.DirOutput _ _) -> call genVariable ops var
(A.Chan A.DirUnknown _ _) -> do call genVariable ops var
tell [" ->writer() "]
_ -> call genMissing ops $ "genCPPCSPChannelOutput used on something which does not support output: " ++ show var
--}}}
cppgenInput :: GenOps -> A.Variable -> A.InputMode -> CGen () cppgenInput :: GenOps -> A.Variable -> A.InputMode -> CGen ()
cppgenInput ops c im cppgenInput ops c im
= do case im of = do case im of
@ -179,8 +199,8 @@ cppgenInput ops c im
do inputVar <- makeNonce "proto_var" do inputVar <- makeNonce "proto_var"
genProtocolName innerType genProtocolName innerType
tell [" ",inputVar, " ; "] tell [" ",inputVar, " ; "]
call genVariable ops c genCPPCSPChannelInput ops c
tell [" ->reader() >> ",inputVar," ; "] tell [" >> ",inputVar," ; "]
cases <- casesOfProtocol innerType cases <- casesOfProtocol innerType
genInputTupleAssign ops ((length cases) /= 0) inputVar is genInputTupleAssign ops ((length cases) /= 0) inputVar is
_ -> sequence_ $ map (call genInputItem ops c) is _ -> sequence_ $ map (call genInputItem ops c) is
@ -198,8 +218,8 @@ cppgenInputCase ops m c s
genProtocolName proto genProtocolName proto
tell [" ", tag, " ; "] tell [" ", tag, " ; "]
tell ["unsigned ", which, " ; "] tell ["unsigned ", which, " ; "]
call genVariable ops c genCPPCSPChannelInput ops c
tell [" ->reader() >> ", tag, " ; "] tell [" >> ", tag, " ; "]
whichExpr proto which tag 0 (genProtocolName proto) whichExpr proto which tag 0 (genProtocolName proto)
tell [" switch ( ", which, " ) { "] tell [" switch ( ", which, " ) { "]
genInputCaseBody proto tag (return ()) s genInputCaseBody proto tag (return ()) s
@ -379,8 +399,8 @@ cppgenInputItem ops c (A.InCounted m cv av)
call genVariable ops av call genVariable ops av
tell [" .extent(0); "] tell [" .extent(0); "]
cppgenInputItem ops c (A.InVariable m v) cppgenInputItem ops c (A.InVariable m v)
= do call genVariable ops c = do genCPPCSPChannelInput ops c
tell ["->reader() >> "] tell [" >> "]
call genVariable ops v call genVariable ops v
tell [";\n"] tell [";\n"]
@ -400,8 +420,8 @@ genJustOutputItem ops (A.OutExpression m e)
cppgenOutputItem :: GenOps -> A.Variable -> A.OutputItem -> CGen () cppgenOutputItem :: GenOps -> A.Variable -> A.OutputItem -> CGen ()
cppgenOutputItem ops chan item cppgenOutputItem ops chan item
= do call genVariable ops chan = do genCPPCSPChannelOutput ops chan
tell [" ->writer() << "] tell [" << "]
genJustOutputItem ops item genJustOutputItem ops item
tell [" ; "] tell [" ; "]
@ -411,8 +431,8 @@ cppgenOutput ops c ois
case t of case t of
--If it's a protocol, we have to build the appropriate tuple to send down the channel: --If it's a protocol, we have to build the appropriate tuple to send down the channel:
A.Chan _ _ (A.UserProtocol innerType) -> A.Chan _ _ (A.UserProtocol innerType) ->
do call genVariable ops c do genCPPCSPChannelOutput ops c
tell [" ->writer() << "] tell [" << "]
genProtocolName innerType genProtocolName innerType
tell [" ( "] tell [" ( "]
infixComma $ map (genJustOutputItem ops) ois infixComma $ map (genJustOutputItem ops) ois
@ -486,8 +506,8 @@ cppgenOutputCase :: GenOps -> A.Variable -> A.Name -> [A.OutputItem] -> CGen ()
cppgenOutputCase ops c tag ois cppgenOutputCase ops c tag ois
= do t <- typeOfVariable c = do t <- typeOfVariable c
let proto = case t of A.Chan _ _ (A.UserProtocol n) -> n let proto = case t of A.Chan _ _ (A.UserProtocol n) -> n
call genVariable ops c genCPPCSPChannelInput ops c
tell [" ->writer() << "] tell [" << "]
genSubTypes proto tag (middle proto) genSubTypes proto tag (middle proto)
tell [" ; "] tell [" ; "]
where where
@ -553,8 +573,8 @@ cppgenAlt ops _ s
tell [guardList, " . push_back( new csp::TimeoutGuard (",timeVal,"));\n"] tell [guardList, " . push_back( new csp::TimeoutGuard (",timeVal,"));\n"]
_ -> _ ->
do tell [guardList, " . push_back( "] do tell [guardList, " . push_back( "]
call genVariable ops c genCPPCSPChannelInput ops c
tell [" -> reader() . inputGuard());\n"] tell [" . inputGuard());\n"]
-- This is the same as GenerateC for now -- but it's not really reusable -- This is the same as GenerateC for now -- but it's not really reusable
-- because it's so closely tied to how ALT is implemented in the backend. -- because it's so closely tied to how ALT is implemented in the backend.
@ -614,8 +634,17 @@ cppdeclareType ops (A.Counted countType valueType)
_ -> call genType ops valueType _ -> call genType ops valueType
tell ["/**/>/**/"] tell ["/**/>/**/"]
cppdeclareType ops (A.Chan _ _ t) cppdeclareType ops (A.Chan dir attr t)
= do tell [" csp::One2OneChannel < "] = do let chanType = case dir of
A.DirInput -> "csp::Chanin"
A.DirOutput -> "csp::Chanout"
A.DirUnknown ->
case (A.caWritingShared attr,A.caReadingShared attr) of
(False,False) -> "csp::One2OneChannel"
(False,True) -> "csp::One2AnyChannel"
(True,False) -> "csp::Any2OneChannel"
(True,True) -> "csp::Any2AnyChannel"
tell [" ",chanType," < "]
call genType ops t call genType ops t
tell ["/**/>/**/ "] tell ["/**/>/**/ "]
cppdeclareType ops t = call genType ops t cppdeclareType ops t = call genType ops t
@ -938,7 +967,7 @@ cppintroduceSpec ops (A.Specification _ n (A.Retypes m am t v))
-- we need to dereference the pointer that cppabbrevVariable gives us. -- we need to dereference the pointer that cppabbrevVariable gives us.
do let deref = case (am, t) of do let deref = case (am, t) of
(_, A.Array _ _) -> False (_, A.Array _ _) -> False
(_, A.Chan {}) -> False (_, A.Chan A.DirUnknown _ _) -> False
(A.ValAbbrev, _) -> True (A.ValAbbrev, _) -> True
_ -> False _ -> False
when deref $ tell ["*"] when deref $ tell ["*"]
@ -999,10 +1028,17 @@ cppgenType ops arr@(A.Array _ _)
= cppgenArrayType ops False arr 0 = cppgenArrayType ops False arr 0
cppgenType _ (A.Record n) = genName n cppgenType _ (A.Record n) = genName n
cppgenType _ (A.UserProtocol n) = genProtocolName n cppgenType _ (A.UserProtocol n) = genProtocolName n
cppgenType ops (A.Chan _ _ t) cppgenType ops ch@(A.Chan A.DirUnknown _ _)
= do tell ["csp::One2OneChannel < "] = do call declareType ops ch
tell [" * "]
cppgenType ops (A.Chan A.DirInput _ t)
= do tell [" csp::Chanin< "]
call genType ops t call genType ops t
tell [" > * "] tell ["/**/>/**/"]
cppgenType ops (A.Chan A.DirOutput _ t)
= do tell [" csp::Chanout< "]
call genType ops t
tell ["/**/>/**/"]
cppgenType ops (A.Counted countType valueType) cppgenType ops (A.Counted countType valueType)
= call genType ops (A.Array [A.UnknownDimension] valueType) = call genType ops (A.Array [A.UnknownDimension] valueType)
cppgenType _ (A.Any) cppgenType _ (A.Any)