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:
parent
63d18373b8
commit
1e06768c20
|
@ -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,9 +634,18 @@ 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
|
||||||
call genType ops t
|
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
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user