Fixed the channel arrays (and abbreviations thereof) to have the correct types (correcting an earlier mistake), and added helper functions to the support headers for easy initialisation of the arrays

This commit is contained in:
Neil Brown 2007-10-07 23:03:15 +00:00
parent 4e6938e0ae
commit 5b10466e68
5 changed files with 79 additions and 14 deletions

View File

@ -386,6 +386,9 @@ cgetScalarType _ _ = Nothing
cgenType :: GenOps -> A.Type -> CGen ()
cgenType ops (A.Array _ t)
= do call genType ops t
case t of
A.Chan A.DirUnknown _ _ -> tell ["*"]
_ -> return ()
tell ["*"]
cgenType _ (A.Record n) = genName n
-- UserProtocol -- not used
@ -694,9 +697,9 @@ MYREC r: MYREC r; MYREC *r; MYREC *r;
CHAN OF INT c: Channel c; Channel *c;
c &c c
[10]CHAN OF INT cs: Channel cs[10]; Channel *cs[10];
[10]CHAN OF INT cs: Channel* cs[10]; Channel **cs;
cs cs cs
cs[i] &cs[i] cs[i]
cs[i] cs[i] cs[i]
I suspect there's probably a nicer way of doing this, but as a translation of
the above table this isn't too horrible...
@ -743,7 +746,8 @@ cgenVariable' ops checkValid v
= do am <- accessAbbrevMode v
t <- typeOfVariable v
return $ case (sub, t) of
(A.Subscript _ _, A.Array _ (A.Chan A.DirUnknown _ _)) -> am
--Channel arrays are of pointers to channels; i.e. channels in arrays are always abbreviated:
(A.Subscript _ _, A.Array _ (A.Chan A.DirUnknown _ _)) -> A.Abbrev
(A.Subscript _ _, _) -> A.Original
(A.SubscriptField _ _, _) -> A.Original
_ -> am
@ -1192,6 +1196,15 @@ cgenDeclaration :: GenOps -> A.Type -> A.Name -> Bool -> CGen ()
cgenDeclaration ops at@(A.Array ds t) n False
= do call genType ops t
tell [" "]
case t of
A.Chan A.DirUnknown _ _ ->
do genName n
tell ["_storage"]
call genFlatArraySize ops ds
tell [";"]
call genType ops t
tell ["* "]
_ -> return ()
call genArrayStoreName ops n
call genFlatArraySize ops ds
tell [";"]
@ -1244,7 +1257,17 @@ cdeclareInit ops _ (A.Chan A.DirUnknown _ _) var
call genVariableUnchecked ops var
tell [");"]
cdeclareInit ops m t@(A.Array ds t') var
= Just $ do init <- return (\sub -> call declareInit ops m t' (sub var))
= Just $ do case t' of
A.Chan A.DirUnknown _ _ ->
do tell ["tock_init_chan_array("]
call genVariableUnchecked ops var
tell ["_storage,"]
call genVariableUnchecked ops var
tell [","]
sequence_ $ intersperse (tell ["*"]) [case dim of A.Dimension d -> tell [show d] | dim <- ds]
tell [");"]
_ -> return ()
init <- return (\sub -> call declareInit ops m t' (sub var))
call genOverArray ops m var init
cdeclareInit ops m rt@(A.Record _) var
= Just $ do fs <- recordFields m rt

View File

@ -665,6 +665,15 @@ cppgenDeclaration :: GenOps -> A.Type -> A.Name -> Bool -> CGen ()
cppgenDeclaration ops arrType@(A.Array ds t) n False
= do call genType ops t
tell [" "]
case t of
A.Chan A.DirUnknown _ _ ->
do genName n
tell ["_storage"]
call genFlatArraySize ops ds
tell [";"]
call genType ops t
tell ["* "]
_ -> return ()
call genArrayStoreName ops n
call genFlatArraySize ops ds
tell [";"]
@ -710,11 +719,21 @@ cppgenArraySizesLiteral ops n t@(A.Array ds _) =
_ -> die "unknown dimension in array type"
| d <- ds]
-- | Changed because we don't need any initialisation in C++
-- | Changed because we initialise channels and arrays differently in C++
cppdeclareInit :: GenOps -> Meta -> A.Type -> A.Variable -> Maybe (CGen ())
cppdeclareInit ops m t@(A.Array ds t') var
= Just $ do init <- return (\sub -> call declareInit ops m t' (sub var))
call genOverArray ops m var init
case t' of
A.Chan A.DirUnknown _ _ ->
do tell ["tockInitChanArray("]
call genVariableUnchecked ops var
tell ["_storage,"]
call genVariableUnchecked ops var
tell [","]
sequence_ $ intersperse (tell ["*"]) [case dim of A.Dimension d -> tell [show d] | dim <- ds]
tell [");"]
_ -> return ()
cppdeclareInit ops m rt@(A.Record _) var
= Just $ do fs <- recordFields m rt
sequence_ [initField t (A.SubscriptedVariable m (A.SubscriptField m n) var)
@ -1026,6 +1045,9 @@ cppgenArrayType ops const t rank
= do tell ["tockArrayView<"]
when (const) (tell ["const "])
call genType ops t
case t of
A.Chan A.DirUnknown _ _ -> tell ["*"]
_ -> return ()
tell [",",show rank, ">/**/"]
-- | Changed from GenerateC to change the arrays and the channels

View File

@ -233,7 +233,7 @@ testGenType = TestList
,testBothFail "GenType 600" (tcall genType $ A.UserProtocol (simpleName "foo"))
,testBothFail "GenType 650" (tcall genType $ A.Counted A.Int A.Int)
,testBoth "GenType 700" "Channel*" "tockArrayView<csp::One2OneChannel<int>,1>" (tcall genType $ A.Array [A.Dimension 5] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int)
,testBoth "GenType 700" "Channel**" "tockArrayView<csp::One2OneChannel<int>*,1>" (tcall genType $ A.Array [A.Dimension 5] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int)
,testBoth "GenType 701" "Channel**" "tockArrayView<csp::Chanin<int>,1>" (tcall genType $ A.Array [A.Dimension 5] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int)
--Test types that can only occur inside channels:
@ -386,12 +386,12 @@ testDeclaration = TestList
(tcall3 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9,A.Dimension 10] A.Int) foo True)
--Arrays of channels and channel-ends:
,testBoth "genDeclaration 200" "Channel foo[8];const int foo_sizes[]={8};"
"csp::One2OneChannel<int> foo_actual[8];const tockArrayView<csp::One2OneChannel<int>,1> foo=tockArrayView<csp::One2OneChannel<int>,1>(foo_actual,tockDims(8));"
,testBoth "genDeclaration 200" "Channel foo_storage[8];Channel* foo[8];const int foo_sizes[]={8};"
"csp::One2OneChannel<int> foo_storage[8];csp::One2OneChannel<int>* foo_actual[8];const tockArrayView<csp::One2OneChannel<int>*,1> foo=tockArrayView<csp::One2OneChannel<int>*,1>(foo_actual,tockDims(8));"
(tcall3 genDeclaration (A.Array [A.Dimension 8] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo False)
,testBoth "genDeclaration 201" "Channel foo[8*9];const int foo_sizes[]={8,9};"
"csp::One2OneChannel<int> foo_actual[8*9];const tockArrayView<csp::One2OneChannel<int>,2> foo=tockArrayView<csp::One2OneChannel<int>,2>(foo_actual,tockDims(8,9));"
,testBoth "genDeclaration 201" "Channel foo_storage[8*9];Channel* foo[8*9];const int foo_sizes[]={8,9};"
"csp::One2OneChannel<int> foo_storage[8*9];csp::One2OneChannel<int>* foo_actual[8*9];const tockArrayView<csp::One2OneChannel<int>*,2> foo=tockArrayView<csp::One2OneChannel<int>*,2>(foo_actual,tockDims(8,9));"
(tcall3 genDeclaration (A.Array [A.Dimension 8, A.Dimension 9] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo False)
,testBoth "genDeclaration 202" "Channel* foo[8];const int foo_sizes[]={8};"
@ -426,8 +426,11 @@ testDeclareInitFree = TestList
,testAllSame 3 ("","") $ A.Array [A.Dimension 4] A.Int
-- Channel arrays:
,testAll 4 ("^ChanInit((&foo[0]));^","") ("","") $ A.Array [A.Dimension 4] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int
,testAllSame 5 ("","") $ A.Array [A.Dimension 4] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int
,testAll 4 ("tock_init_chan_array(foo_storage,foo,4);^ChanInit(foo[0]);^","") ("tockInitChanArray(foo_storage,foo,4);","") $ A.Array [A.Dimension 4] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int
-- The subscripting on this test is incomplete; it should probably be fixed at some point:
,testAll 5 ("tock_init_chan_array(foo_storage,foo,4*5*6);^ChanInit(foo[0*foo_sizes[1]*foo_sizes[2]]);^","") ("tockInitChanArray(foo_storage,foo,4*5*6);","") $
A.Array [A.Dimension 4,A.Dimension 5,A.Dimension 6] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int
,testAllSame 6 ("","") $ A.Array [A.Dimension 4] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int
-- Plain records:
,testAllR 100 ("","") ("","") A.Int
@ -564,8 +567,8 @@ testGenVariable = TestList
,testAC 300 ("foo@C4","foo@U4") (sub 4) (A.Array [A.Dimension 8] A.Int)
,testAC 305 ("foo@C4,5,6","foo@U4,5,6") ((sub 6) . (sub 5) . (sub 4)) (A.Array [A.Dimension 8,A.Dimension 9,A.Dimension 10] A.Int)
,testAC 310 ("(&foo@C4)","(&foo@U4)") (sub 4) (A.Array [A.Dimension 8] $ A.Record bar)
-- Original channel arrays are Channel[], but abbreviated channel arrays are Channel*[]:
,testAC2 320 ("(&foo@C4)","(&foo@U4)") ("foo@C4","foo@U4") (sub 4) (A.Array [A.Dimension 8] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int)
-- Original channel arrays are Channel*[], abbreviated channel arrays are Channel*[]:
,testAC2 320 ("foo@C4","foo@U4") ("foo@C4","foo@U4") (sub 4) (A.Array [A.Dimension 8] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int)
,testAC 330 ("foo@C4","foo@U4") (sub 4) (A.Array [A.Dimension 8] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int)
-- Fully subscripted array, and record field reference:

View File

@ -66,6 +66,16 @@
#endif
//}}}
//{{{ helper functions to simplify the code generation
static inline void tock_init_chan_array(Channel*, Channel**, int) occam_unused;
static inline void tock_init_chan_array(Channel* pointTo, Channel** pointFrom, int count) {
for (int i = 0; i < count; i++) {
pointFrom[i] = &(pointTo[i]);
}
}
//}}}
//{{{ runtime check functions
//C++CSP may have defined this function already:

View File

@ -402,3 +402,10 @@ void tockRecvArray(const csp::Chanin< tockSendableArray<T,N> >& in,const tockArr
tockSendableArray<T,N> tsa(arr);
in >> tsa;
}
template <typename T>
inline void tockInitChanArray(T* pointTo,T** pointFrom,int count)
{
for (int i = 0;i < count;i++)
pointFrom[count] = &(pointTo[i]);
}