From 5b10466e684cfd8f925b0f7b5b0347da2fb99db7 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sun, 7 Oct 2007 23:03:15 +0000 Subject: [PATCH] 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 --- backends/GenerateC.hs | 31 +++++++++++++++++++++++++++---- backends/GenerateCPPCSP.hs | 24 +++++++++++++++++++++++- backends/GenerateCTest.hs | 21 ++++++++++++--------- tock_support.h | 10 ++++++++++ tock_support_cppcsp.h | 7 +++++++ 5 files changed, 79 insertions(+), 14 deletions(-) diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 9f3bf9f..9ccf7e6 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -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 diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs index b32afc7..68bca7e 100644 --- a/backends/GenerateCPPCSP.hs +++ b/backends/GenerateCPPCSP.hs @@ -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 diff --git a/backends/GenerateCTest.hs b/backends/GenerateCTest.hs index 3e39901..6dcf020 100644 --- a/backends/GenerateCTest.hs +++ b/backends/GenerateCTest.hs @@ -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,1>" (tcall genType $ A.Array [A.Dimension 5] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) + ,testBoth "GenType 700" "Channel**" "tockArrayView*,1>" (tcall genType $ A.Array [A.Dimension 5] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) ,testBoth "GenType 701" "Channel**" "tockArrayView,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 foo_actual[8];const tockArrayView,1> foo=tockArrayView,1>(foo_actual,tockDims(8));" + ,testBoth "genDeclaration 200" "Channel foo_storage[8];Channel* foo[8];const int foo_sizes[]={8};" + "csp::One2OneChannel foo_storage[8];csp::One2OneChannel* foo_actual[8];const tockArrayView*,1> foo=tockArrayView*,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 foo_actual[8*9];const tockArrayView,2> foo=tockArrayView,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 foo_storage[8*9];csp::One2OneChannel* foo_actual[8*9];const tockArrayView*,2> foo=tockArrayView*,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: diff --git a/tock_support.h b/tock_support.h index 90c2ad1..4d1307e 100644 --- a/tock_support.h +++ b/tock_support.h @@ -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: diff --git a/tock_support_cppcsp.h b/tock_support_cppcsp.h index 0d7e48e..4a3e460 100644 --- a/tock_support_cppcsp.h +++ b/tock_support_cppcsp.h @@ -402,3 +402,10 @@ void tockRecvArray(const csp::Chanin< tockSendableArray >& in,const tockArr tockSendableArray tsa(arr); in >> tsa; } + +template +inline void tockInitChanArray(T* pointTo,T** pointFrom,int count) +{ + for (int i = 0;i < count;i++) + pointFrom[count] = &(pointTo[i]); +}