diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 0f135eb..59aa23a 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -95,8 +95,9 @@ data GenOps = GenOps { genConversionSymbol :: GenOps -> A.Type -> A.Type -> A.ConversionMode -> CGen (), genDecl :: GenOps -> A.AbbrevMode -> A.Type -> A.Name -> CGen (), genDeclType :: GenOps -> A.AbbrevMode -> A.Type -> CGen (), - -- | Generates a declaration of a variable of the specified type and name - genDeclaration :: GenOps -> A.Type -> A.Name -> CGen (), + -- | Generates a declaration of a variable of the specified type and name. + -- The Bool indicates whether the declaration is inside a record (True) or not (False). + genDeclaration :: GenOps -> A.Type -> A.Name -> Bool -> CGen (), genDirectedVariable :: GenOps -> CGen () -> A.Direction -> CGen (), genDyadic :: GenOps -> Meta -> A.DyadicOp -> A.Expression -> A.Expression -> CGen (), genExpression :: GenOps -> A.Expression -> CGen (), @@ -1176,15 +1177,26 @@ cgenSpec ops spec body call removeSpec ops spec -- | Generate a declaration of a new variable. -cgenDeclaration :: GenOps -> A.Type -> A.Name -> CGen () -cgenDeclaration ops (A.Array ds t) n +cgenDeclaration :: GenOps -> A.Type -> A.Name -> Bool -> CGen () +cgenDeclaration ops (A.Array ds t) n False = do call genType ops t tell [" "] genName n call genFlatArraySize ops ds tell [";"] call declareArraySizes ops ds n -cgenDeclaration ops t n +cgenDeclaration ops (A.Array ds t) n True + = do call genType ops t + tell [" "] + genName n + call genFlatArraySize ops ds + tell [";"] + tell ["int "] + genName n + tell ["_sizes"] + call genArraySizesSize ops ds + tell [";"] +cgenDeclaration ops t n _ = do call genType ops t tell [" "] genName n @@ -1269,7 +1281,7 @@ CHAN OF INT c IS d: Channel *c = d; -} cintroduceSpec :: GenOps -> A.Specification -> CGen () cintroduceSpec ops (A.Specification m n (A.Declaration _ t)) - = do call genDeclaration ops t n + = do call genDeclaration ops t n False case call declareInit ops m t (A.Variable m n) of Just p -> p Nothing -> return () @@ -1334,8 +1346,8 @@ cintroduceSpec ops (A.Specification _ n (A.RecordType _ b fs)) genName n tell ["_sizes"] call genArraySizesSize ops ds - tell [";\n"] - _ -> call genDeclaration ops t n + tell [";"] + _ -> call genDeclaration ops t n True | (n, t) <- fs] tell ["} "] when b $ tell ["occam_struct_packed "] diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs index dbe33bd..5586f0f 100644 --- a/backends/GenerateCPPCSP.hs +++ b/backends/GenerateCPPCSP.hs @@ -648,8 +648,8 @@ cppgenProcCall ops n as --The vector has the suffix _actual, whereas the array-view is what is actually used in place of the array --I think it may be possible to use boost::array instead of std::vector (which would be more efficient), --but I will worry about that later -cppgenDeclaration :: GenOps -> A.Type -> A.Name -> CGen () -cppgenDeclaration ops arrType@(A.Array ds t) n +cppgenDeclaration :: GenOps -> A.Type -> A.Name -> Bool -> CGen () +cppgenDeclaration ops arrType@(A.Array ds t) n False = do call genType ops t tell [" "] genName n @@ -664,7 +664,18 @@ cppgenDeclaration ops arrType@(A.Array ds t) n tell ["_actual,tockDims("] genDims ds tell ["));"] -cppgenDeclaration ops t n +cppgenDeclaration ops arrType@(A.Array ds t) n True + = do call genType ops t + tell [" "] + genName n + tell ["_actual["] + call genFlatArraySize ops ds + tell ["];"] + call genType ops arrType + tell [" "] + genName n; + tell [";"] +cppgenDeclaration ops t n _ = do call genType ops t tell [" "] genName n @@ -914,7 +925,7 @@ cppintroduceSpec ops (A.Specification _ n (A.IsExpr _ am t e)) -- We must create the channel array then fill it: cppintroduceSpec ops (A.Specification _ n (A.IsChannelArray _ t cs)) - = do call genDeclaration ops t n + = do call genDeclaration ops t n False sequence_ $ map genChanArrayElemInit (zip [0 .. ((length cs) - 1)] cs) where genChanArrayElemInit (index,var) @@ -924,8 +935,8 @@ cppintroduceSpec ops (A.Specification _ n (A.IsChannelArray _ t cs)) tell [";"] --This clause was simplified, because we don't need separate array sizes in C++: cppintroduceSpec ops (A.Specification _ n (A.RecordType _ b fs)) - = do tell ["typedef struct {\n"] - sequence_ [call genDeclaration ops t n + = do tell ["typedef struct{"] + sequence_ [call genDeclaration ops t n True | (n, t) <- fs] tell ["} "] when b $ tell ["occam_struct_packed "] diff --git a/backends/GenerateCTest.hs b/backends/GenerateCTest.hs index c72b5a1..78e787e 100644 --- a/backends/GenerateCTest.hs +++ b/backends/GenerateCTest.hs @@ -351,49 +351,57 @@ testDeclaration :: Test testDeclaration = TestList [ --Simple: - testBothSame "genDeclaration 0" "int foo;" (tcall2 genDeclaration A.Int foo) + testBothSame "genDeclaration 0" "int foo;" (tcall3 genDeclaration A.Int foo False) --Channels and channel-ends: - ,testBoth "genDeclaration 1" "Channel foo;" "csp::One2OneChannel foo;" (tcall2 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo) - ,testBoth "genDeclaration 2" "Channel foo;" "csp::Any2OneChannel foo;" (tcall2 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes True False) A.Int) foo) - ,testBoth "genDeclaration 3" "Channel foo;" "csp::One2AnyChannel foo;" (tcall2 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes False True) A.Int) foo) - ,testBoth "genDeclaration 4" "Channel foo;" "csp::Any2AnyChannel foo;" (tcall2 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes True True) A.Int) foo) - ,testBoth "genDeclaration 5" "Channel* foo;" "csp::Chanin foo;" (tcall2 genDeclaration (A.Chan A.DirInput (A.ChanAttributes False False) A.Int) foo) - ,testBoth "genDeclaration 6" "Channel* foo;" "csp::Chanin foo;" (tcall2 genDeclaration (A.Chan A.DirInput (A.ChanAttributes False True) A.Int) foo) - ,testBoth "genDeclaration 7" "Channel* foo;" "csp::Chanout foo;" (tcall2 genDeclaration (A.Chan A.DirOutput (A.ChanAttributes False False) A.Int) foo) - ,testBoth "genDeclaration 8" "Channel* foo;" "csp::Chanout foo;" (tcall2 genDeclaration (A.Chan A.DirOutput (A.ChanAttributes True False) A.Int) foo) + ,testBoth "genDeclaration 1" "Channel foo;" "csp::One2OneChannel foo;" (tcall3 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo False) + ,testBoth "genDeclaration 2" "Channel foo;" "csp::Any2OneChannel foo;" (tcall3 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes True False) A.Int) foo False) + ,testBoth "genDeclaration 3" "Channel foo;" "csp::One2AnyChannel foo;" (tcall3 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes False True) A.Int) foo False) + ,testBoth "genDeclaration 4" "Channel foo;" "csp::Any2AnyChannel foo;" (tcall3 genDeclaration (A.Chan A.DirUnknown (A.ChanAttributes True True) A.Int) foo False) + ,testBoth "genDeclaration 5" "Channel* foo;" "csp::Chanin foo;" (tcall3 genDeclaration (A.Chan A.DirInput (A.ChanAttributes False False) A.Int) foo False) + ,testBoth "genDeclaration 6" "Channel* foo;" "csp::Chanin foo;" (tcall3 genDeclaration (A.Chan A.DirInput (A.ChanAttributes False True) A.Int) foo False) + ,testBoth "genDeclaration 7" "Channel* foo;" "csp::Chanout foo;" (tcall3 genDeclaration (A.Chan A.DirOutput (A.ChanAttributes False False) A.Int) foo False) + ,testBoth "genDeclaration 8" "Channel* foo;" "csp::Chanout foo;" (tcall3 genDeclaration (A.Chan A.DirOutput (A.ChanAttributes True False) A.Int) foo False) --Arrays (of simple): ,testBoth "genDeclaration 100" "int foo[8];const int foo_sizes[]={8};" "int foo_actual[8];tockArrayView foo(foo_actual,tockDims(8));" - (tcall2 genDeclaration (A.Array [A.Dimension 8] A.Int) foo) + (tcall3 genDeclaration (A.Array [A.Dimension 8] A.Int) foo False) ,testBoth "genDeclaration 101" "int foo[8*9];const int foo_sizes[]={8,9};" "int foo_actual[8*9];tockArrayView foo(foo_actual,tockDims(8,9));" - (tcall2 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9] A.Int) foo) + (tcall3 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9] A.Int) foo False) ,testBoth "genDeclaration 102" "int foo[8*9*10];const int foo_sizes[]={8,9,10};" "int foo_actual[8*9*10];tockArrayView foo(foo_actual,tockDims(8,9,10));" - (tcall2 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9,A.Dimension 10] A.Int) foo) + (tcall3 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9,A.Dimension 10] A.Int) foo False) + + --Arrays (of simple) inside records: + ,testBoth "genDeclaration 110" "int foo[8];int foo_sizes[1];" "int foo_actual[8];tockArrayView foo;" + (tcall3 genDeclaration (A.Array [A.Dimension 8] A.Int) foo True) + ,testBoth "genDeclaration 111" "int foo[8*9];int foo_sizes[2];" "int foo_actual[8*9];tockArrayView foo;" + (tcall3 genDeclaration (A.Array [A.Dimension 8,A.Dimension 9] A.Int) foo True) + ,testBoth "genDeclaration 112" "int foo[8*9*10];int foo_sizes[3];" "int foo_actual[8*9*10];tockArrayView foo;" + (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];tockArrayView,1> foo(foo_actual,tockDims(8));" - (tcall2 genDeclaration (A.Array [A.Dimension 8] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo) + (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];tockArrayView,2> foo(foo_actual,tockDims(8,9));" - (tcall2 genDeclaration (A.Array [A.Dimension 8, A.Dimension 9] $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int) foo) + (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};" "csp::Chanin foo_actual[8];tockArrayView,1> foo(foo_actual,tockDims(8));" - (tcall2 genDeclaration (A.Array [A.Dimension 8] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int) foo) + (tcall3 genDeclaration (A.Array [A.Dimension 8] $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int) foo False) ,testBoth "genDeclaration 203" "Channel* foo[8*9];const int foo_sizes[]={8,9};" "csp::Chanout foo_actual[8*9];tockArrayView,2> foo(foo_actual,tockDims(8,9));" - (tcall2 genDeclaration (A.Array [A.Dimension 8, A.Dimension 9] $ A.Chan A.DirOutput (A.ChanAttributes False False) A.Int) foo) + (tcall3 genDeclaration (A.Array [A.Dimension 8, A.Dimension 9] $ A.Chan A.DirOutput (A.ChanAttributes False False) A.Int) foo False) --Records of simple: - ,testBothSameS "genDeclaration 300" "REC foo;" (tcall2 genDeclaration (A.Record $ simpleName "REC") foo) (stateR A.Int) + ,testBothSameS "genDeclaration 300" "REC foo;" (tcall3 genDeclaration (A.Record $ simpleName "REC") foo False) (stateR A.Int) --Records of arrays of int (the sizes are set by declareInit): - ,testBothSameS "genDeclaration 400" "REC foo;" (tcall2 genDeclaration (A.Record $ simpleName "REC") foo) (stateR $ A.Array [A.Dimension 8] A.Int) + ,testBothSameS "genDeclaration 400" "REC foo;" (tcall3 genDeclaration (A.Record $ simpleName "REC") foo False) (stateR $ A.Array [A.Dimension 8] A.Int) ] where stateR t = defRecord "REC" "bar" t @@ -444,7 +452,7 @@ testDeclareInitFree = TestList overArray _ _ v f = case f (\v -> A.SubscriptedVariable emptyMeta (A.Subscript emptyMeta $ intLiteral 0) v) of Just p -> caret >> p >> caret Nothing -> return () - over ops = ops {genDeclaration = override2 at, genOverArray = overArray} + over ops = ops {genDeclaration = override3 at, genOverArray = overArray} testAllSame :: Int -> (String,String) -> A.Type -> Test testAllSame n e t = testAll n e e t @@ -480,7 +488,7 @@ testSpec = TestList ,testBoth ("testSpec " ++ show n) eCR eCPPR ((tcall removeSpec $ A.Specification emptyMeta foo spec) . over) ] testAllSame n e s = testAll n e e s - over ops = ops {genDeclaration = override2 (tell ["#ATION"]), genDecl = override3 (tell ["#DECL"]) + over ops = ops {genDeclaration = override3 (tell ["#ATION"]), genDecl = override3 (tell ["#DECL"]) ,declareInit = (override3 (Just $ tell ["#INIT"])), declareFree = override3 (Just $ tell ["#FREE"]) }