Fixed all the tests for sending items in C++, and made the tests pass
This commit is contained in:
parent
6d29bbd260
commit
9af1ec78bb
|
@ -423,26 +423,56 @@ cppgenInputItem ops c (A.InVariable m v)
|
||||||
call genVariable ops v
|
call genVariable ops v
|
||||||
tell [";\n"]
|
tell [";\n"]
|
||||||
|
|
||||||
-- | If we are sending an array, we use the versionToSend function to coerce away any annoying const tags on the array data:
|
|
||||||
genJustOutputItem :: GenOps -> A.OutputItem -> CGen()
|
|
||||||
genJustOutputItem ops (A.OutCounted m ce ae)
|
|
||||||
= do call genExpression ops ae
|
|
||||||
tell[" .sliceFor("]
|
|
||||||
call genExpression ops ce
|
|
||||||
tell[") .versionToSend() "]
|
|
||||||
genJustOutputItem ops (A.OutExpression m e)
|
|
||||||
= do t <- typeOfExpression e
|
|
||||||
call genExpression ops e
|
|
||||||
case t of
|
|
||||||
(A.Array _ _) -> tell [" .versionToSend() "]
|
|
||||||
_ -> return ()
|
|
||||||
|
|
||||||
cppgenOutputItem :: GenOps -> A.Variable -> A.OutputItem -> CGen ()
|
cppgenOutputItem :: GenOps -> A.Variable -> A.OutputItem -> CGen ()
|
||||||
cppgenOutputItem ops chan item
|
cppgenOutputItem ops chan item
|
||||||
= do genCPPCSPChannelOutput ops chan
|
= case item of
|
||||||
|
(A.OutCounted m (A.ExprVariable _ cv) (A.ExprVariable _ av)) ->
|
||||||
|
do chan'
|
||||||
|
tell ["<<tockSendableArrayOfBytes("]
|
||||||
|
genPoint cv
|
||||||
|
tell [");"]
|
||||||
|
chan'
|
||||||
|
tell ["<<tockSendableArrayOfBytes("]
|
||||||
|
genPoint av
|
||||||
|
tell [");"]
|
||||||
|
(A.OutExpression _ (A.ExprVariable _ sv)) ->
|
||||||
|
do t <- typeOfVariable chan
|
||||||
|
tsv <- typeOfVariable sv
|
||||||
|
case (byteArrayChan t,tsv) of
|
||||||
|
(True,_) -> do chan'
|
||||||
|
tell ["<<tockSendableArrayOfBytes("]
|
||||||
|
genPoint sv
|
||||||
|
tell [");"]
|
||||||
|
(False,A.Array {}) -> do tell ["tockSendArray("]
|
||||||
|
chan'
|
||||||
|
tell [","]
|
||||||
|
call genVariable ops sv
|
||||||
|
tell [");"]
|
||||||
|
(False,_) -> do chan'
|
||||||
tell ["<<"]
|
tell ["<<"]
|
||||||
genJustOutputItem ops item
|
genNonPoint sv
|
||||||
tell [";"]
|
tell [";"]
|
||||||
|
where
|
||||||
|
chan' = genCPPCSPChannelOutput ops chan
|
||||||
|
|
||||||
|
byteArrayChan :: A.Type -> Bool
|
||||||
|
byteArrayChan (A.Chan _ _ (A.UserProtocol _)) = True
|
||||||
|
byteArrayChan (A.Chan _ _ A.Any) = True
|
||||||
|
byteArrayChan (A.Chan _ _ (A.Counted _ _)) = True
|
||||||
|
byteArrayChan _ = False
|
||||||
|
|
||||||
|
genPoint :: A.Variable -> CGen()
|
||||||
|
genPoint v = do t <- typeOfVariable v
|
||||||
|
when (not $ isPoint t) $ tell ["&"]
|
||||||
|
call genVariable ops v
|
||||||
|
genNonPoint :: A.Variable -> CGen()
|
||||||
|
genNonPoint v = do t <- typeOfVariable v
|
||||||
|
when (isPoint t) $ tell ["*"]
|
||||||
|
call genVariable ops v
|
||||||
|
isPoint :: A.Type -> Bool
|
||||||
|
isPoint (A.Record _) = True
|
||||||
|
isPoint (A.Array _ _) = True
|
||||||
|
isPoint _ = False
|
||||||
|
|
||||||
-- FIXME Should be a generic helper somewhere (along with the others from GenerateC)
|
-- FIXME Should be a generic helper somewhere (along with the others from GenerateC)
|
||||||
-- | Helper function to place a comma between items, but not before or after
|
-- | Helper function to place a comma between items, but not before or after
|
||||||
|
@ -1028,6 +1058,12 @@ cppgenType ops (A.Chan dir attr t)
|
||||||
cppTypeInsideChannel ops A.Any = tell ["tockSendableArrayOfBytes"]
|
cppTypeInsideChannel ops A.Any = tell ["tockSendableArrayOfBytes"]
|
||||||
cppTypeInsideChannel ops (A.Counted _ _) = tell ["tockSendableArrayOfBytes"]
|
cppTypeInsideChannel ops (A.Counted _ _) = tell ["tockSendableArrayOfBytes"]
|
||||||
cppTypeInsideChannel ops (A.UserProtocol _) = tell ["tockSendableArrayOfBytes"]
|
cppTypeInsideChannel ops (A.UserProtocol _) = tell ["tockSendableArrayOfBytes"]
|
||||||
|
cppTypeInsideChannel ops (A.Array ds t)
|
||||||
|
= do tell ["tockSendableArray<"]
|
||||||
|
call genType ops t
|
||||||
|
tell [","]
|
||||||
|
tell $ intersperse "*" [case d of A.Dimension n -> show n | d <- ds]
|
||||||
|
tell [">/**/"]
|
||||||
cppTypeInsideChannel ops t = call genType ops t
|
cppTypeInsideChannel ops t = call genType ops t
|
||||||
cppgenType ops t
|
cppgenType ops t
|
||||||
= case call getScalarType ops t of
|
= case call getScalarType ops t of
|
||||||
|
|
|
@ -244,6 +244,13 @@ testGenType = TestList
|
||||||
--Counted:
|
--Counted:
|
||||||
,testBoth "GenType 1000" "Channel" "csp::One2OneChannel<tockSendableArrayOfBytes>" (tcall genType $ A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.Counted A.Int A.Int)
|
,testBoth "GenType 1000" "Channel" "csp::One2OneChannel<tockSendableArrayOfBytes>" (tcall genType $ A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.Counted A.Int A.Int)
|
||||||
|
|
||||||
|
--Channels of arrays are special in C++:
|
||||||
|
,testBoth "GenType 1100" "Channel" "csp::One2OneChannel<tockSendableArray<int,6>>"
|
||||||
|
(tcall genType $ A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.Array [A.Dimension 6] A.Int)
|
||||||
|
,testBoth "GenType 1101" "Channel" "csp::One2OneChannel<tockSendableArray<int,6*7*8>>"
|
||||||
|
(tcall genType $ A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.Array [A.Dimension 6,A.Dimension 7,A.Dimension 8] A.Int)
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
testStop :: Test
|
testStop :: Test
|
||||||
|
@ -692,39 +699,54 @@ testOutput = TestList
|
||||||
,testBothSame "testOutput 1" "^" ((tcall2 genOutput undefined [undefined]) . overOutputItem)
|
,testBothSame "testOutput 1" "^" ((tcall2 genOutput undefined [undefined]) . overOutputItem)
|
||||||
,testBothSame "testOutput 2" "^^^" ((tcall2 genOutput undefined [undefined,undefined,undefined]) . overOutputItem)
|
,testBothSame "testOutput 2" "^^^" ((tcall2 genOutput undefined [undefined,undefined,undefined]) . overOutputItem)
|
||||||
|
|
||||||
,testBothS "testOutput 100" "ChanOutInt(@,bar_foo);^" "tockSendInt(@->writer(),bar_foo);^" ((tcall3 genOutputCase (A.Variable emptyMeta chan) bar []) . overOutput) state
|
,testBothS "testOutput 100" "ChanOutInt((&c),bar_foo);^" "tockSendInt((&c)->writer(),bar_foo);^" ((tcall3 genOutputCase (A.Variable emptyMeta chan) bar []) . overOutput) state
|
||||||
,testBothS "testOutput 101" "ChanOutInt(@,bar_foo);^" "tockSendInt(@,bar_foo);^" ((tcall3 genOutputCase (A.Variable emptyMeta chanOut) bar []) . overOutput) state
|
,testBothS "testOutput 101" "ChanOutInt(cOut,bar_foo);^" "tockSendInt(cOut,bar_foo);^" ((tcall3 genOutputCase (A.Variable emptyMeta chanOut) bar []) . overOutput) state
|
||||||
|
|
||||||
--Integers are a special case in the C backend:
|
--Integers are a special case in the C backend:
|
||||||
,testOutputItem 200 "ChanOutInt(@,$);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ intLiteral 0) A.Int
|
,testOutputItem 201 "ChanOutInt(#,x);" "#<<x;" (A.OutExpression emptyMeta $ exprVariable "x") A.Int
|
||||||
,testOutputItem 201 "ChanOutInt(@,$);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ exprVariable "x") A.Int
|
|
||||||
--A plain type on the channel of the right type:
|
--A plain type on the channel of the right type:
|
||||||
,testOutputItem 202 "ChanOut(@,&@,^);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ exprVariable "x") A.Int64
|
,testOutputItem 202 "ChanOut(#,&x,^);" "#<<x;" (A.OutExpression emptyMeta $ exprVariable "x") A.Int64
|
||||||
--A record type on the channel of the right type (because records are pointed to, so they shouldn't need the address-of operator):
|
--A record type on the channel of the right type (because records are always referenced by pointer):
|
||||||
,testOutputItem 202 "ChanOut(@,@,^);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ exprVariable "x") (A.Record foo)
|
,testOutputItem 203 "ChanOut(#,(&x),^);" "#<<*(&x);" (A.OutExpression emptyMeta $ exprVariable "x") (A.Record foo)
|
||||||
--A fixed size array on the channel of the right type:
|
--A fixed size array on the channel of the right type:
|
||||||
,testOutputItem 203 "ChanOut(@,@,^);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6] A.Int)
|
,testOutputItem 204 "ChanOut(#,x,^);" "tockSendArray(#,x);" (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6] A.Int)
|
||||||
,testOutputItem 204 "ChanOut(@,@,^);" ("@->writer()<<$;", "@<<$;") (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6, A.Dimension 7, A.Dimension 8] A.Int)
|
,testOutputItem 205 "ChanOut(#,x,^);" "tockSendArray(#,x);" (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6, A.Dimension 7, A.Dimension 8] A.Int)
|
||||||
|
|
||||||
--A counted array:
|
--A counted array:
|
||||||
,testOutputItem 205 "ChanOutInt(@,$);ChanOut(@,@,$*^);" ("tockSendInt(@->writer(),$);@->writer()<<$;", "tockSendInt(@,$);@<<$;")
|
,testOutputItem 206 "ChanOutInt(#,x);ChanOut(#,xs,x*^);" "#<<tockSendableArrayOfBytes(&x);#<<tockSendableArrayOfBytes(xs);"
|
||||||
(A.OutCounted emptyMeta (exprVariable "x") (exprVariable "xs")) (A.Counted A.Int A.Int)
|
(A.OutCounted emptyMeta (exprVariable "x") (exprVariable "xs")) (A.Counted A.Int A.Int)
|
||||||
,testOutputItem 206 "ChanOutInt(@,$);ChanOut(@,@,$*^);" ("tockSendInt(@->writer(),$);@->writer()<<$;", "tockSendInt(@,$);@<<$;")
|
,testOutputItem 206 "ChanOutInt(@,$);ChanOut(@,@,$*^);" ("tockSendInt(@->writer(),$);@->writer()<<$;", "tockSendInt(@,$);@<<$;")
|
||||||
(A.OutCounted emptyMeta (exprVariable "x") (exprVariable "xs")) (A.Counted A.Int (A.Array [A.Dimension 8] A.Int))
|
(A.OutCounted emptyMeta (exprVariable "x") (exprVariable "xs")) (A.Counted A.Int (A.Array [A.Dimension 8] A.Int))
|
||||||
|
|
||||||
--TODO add a pass that makes sure all outputs are either of type Int or are variables. Including count for counted items
|
--TODO add a pass that makes sure all outputs are variables. Including count for counted items
|
||||||
|
|
||||||
|
--Test sending things that are part of protocols (this will require different code in the C++ backend)
|
||||||
|
,testOutputItemProt 301 "ChanOutInt(#,x);" "#<<tockSendableArrayOfBytes(&x);" (A.OutExpression emptyMeta $ exprVariable "x") A.Int
|
||||||
|
,testOutputItemProt 302 "ChanOut(#,&x,^);" "#<<tockSendableArrayOfBytes(&x);" (A.OutExpression emptyMeta $ exprVariable "x") A.Int64
|
||||||
|
,testOutputItemProt 303 "ChanOut(#,(&x),^);" "#<<tockSendableArrayOfBytes((&x));" (A.OutExpression emptyMeta $ exprVariable "x") (A.Record foo)
|
||||||
|
,testOutputItemProt 304 "ChanOut(#,x,^);" "#<<tockSendableArrayOfBytes(x);" (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6] A.Int)
|
||||||
|
,testOutputItemProt 305 "ChanOut(#,x,^);" "#<<tockSendableArrayOfBytes(x);" (A.OutExpression emptyMeta $ exprVariable "x") (A.Array [A.Dimension 6, A.Dimension 7, A.Dimension 8] A.Int)
|
||||||
|
,testOutputItemProt 306 "ChanOutInt(#,x);ChanOut(#,xs,x*^);" "#<<tockSendableArrayOfBytes(&x);#<<tockSendableArrayOfBytes(xs);"
|
||||||
|
(A.OutCounted emptyMeta (exprVariable "x") (exprVariable "xs")) (A.Counted A.Int A.Int)
|
||||||
|
|
||||||
--TODO test sending things that are part of protocols (this will require different code in the C++ backend)
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
testOutputItem :: Int -> String -> (String,String) -> A.OutputItem -> A.Type -> Test
|
testOutputItem :: Int -> String -> String -> A.OutputItem -> A.Type -> Test
|
||||||
testOutputItem n eC (eCPP,eCPP_Out) oi t = TestList
|
testOutputItem n eC eCPP oi t = testOutputItem' n eC eCPP oi t t
|
||||||
|
-- Tests sending things over channels of protocol or ANY
|
||||||
|
testOutputItemProt :: Int -> String -> String -> A.OutputItem -> A.Type -> Test
|
||||||
|
testOutputItemProt n eC eCPP oi t = TestList [testOutputItem' n eC eCPP oi t (A.UserProtocol foo),testOutputItem' n eC eCPP oi t A.Any]
|
||||||
|
|
||||||
|
testOutputItem' :: Int -> String -> String -> A.OutputItem -> A.Type -> A.Type -> Test
|
||||||
|
testOutputItem' n eC eCPP oi t ct = TestList
|
||||||
[
|
[
|
||||||
testBothS ("testOutput " ++ show n) eC eCPP ((tcall2 genOutputItem (A.Variable emptyMeta $ simpleName "c") oi) . over) (state A.DirUnknown)
|
testBothS ("testOutput " ++ show n) (hashIs "(&c)" eC) (hashIs "(&c)->writer()" eCPP) ((tcall2 genOutputItem (A.Variable emptyMeta $ simpleName "c") oi) . over) (state A.DirUnknown)
|
||||||
,testBothS ("testOutput [out] " ++ show n) eC eCPP_Out ((tcall2 genOutputItem (A.Variable emptyMeta $ simpleName "c") oi) . over) (state A.DirOutput)
|
,testBothS ("testOutput [out] " ++ show n) (hashIs "c" eC) (hashIs "c" eCPP) ((tcall2 genOutputItem (A.Variable emptyMeta $ simpleName "c") oi) . over) (state A.DirOutput)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
state dir = do defineName (simpleName "c") $ simpleDefDecl "c" (A.Chan dir (A.ChanAttributes False False) t)
|
hashIs x y = subRegex (mkRegex "#") y x
|
||||||
|
|
||||||
|
state dir = do defineName (simpleName "c") $ simpleDefDecl "c" (A.Chan dir (A.ChanAttributes False False) ct)
|
||||||
case t of
|
case t of
|
||||||
A.Counted t t' -> do defineName (simpleName "x") $ simpleDefDecl "x" t
|
A.Counted t t' -> do defineName (simpleName "x") $ simpleDefDecl "x" t
|
||||||
defineName (simpleName "xs") $ simpleDefDecl "xs" (A.Array [A.Dimension 6] t')
|
defineName (simpleName "xs") $ simpleDefDecl "xs" (A.Array [A.Dimension 6] t')
|
||||||
|
@ -734,9 +756,9 @@ testOutput = TestList
|
||||||
chanOut = simpleName "cOut"
|
chanOut = simpleName "cOut"
|
||||||
state = do defineName chan $ simpleDefDecl "c" (A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.UserProtocol foo)
|
state = do defineName chan $ simpleDefDecl "c" (A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.UserProtocol foo)
|
||||||
defineName chanOut $ simpleDefDecl "cOut" (A.Chan A.DirOutput (A.ChanAttributes False False) $ A.UserProtocol foo)
|
defineName chanOut $ simpleDefDecl "cOut" (A.Chan A.DirOutput (A.ChanAttributes False False) $ A.UserProtocol foo)
|
||||||
overOutput ops = ops {genVariable = override1 at, genOutput = override2 caret}
|
overOutput ops = ops {genOutput = override2 caret}
|
||||||
overOutputItem ops = ops {genOutputItem = override2 caret}
|
overOutputItem ops = ops {genOutputItem = override2 caret}
|
||||||
over ops = ops {genVariable = override1 at, genExpression = override1 dollar, genBytesIn = override2 caret}
|
over ops = ops {genBytesIn = override2 caret}
|
||||||
|
|
||||||
---Returns the list of tests:
|
---Returns the list of tests:
|
||||||
tests :: Test
|
tests :: Test
|
||||||
|
|
|
@ -313,35 +313,6 @@ public:
|
||||||
return tockArrayView<const T,DIMS>((const T*)realArray,std::make_pair(dims,totalSubDim));
|
return tockArrayView<const T,DIMS>((const T*)realArray,std::make_pair(dims,totalSubDim));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline tockArrayView<typename boost::remove_const<T>::type,DIMS> versionToSend()
|
|
||||||
{
|
|
||||||
return tockArrayView<typename boost::remove_const<T>::type,DIMS>(const_cast<typename boost::remove_const<T>::type*>(realArray),std::make_pair(dims,totalSubDim));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const tockArrayView<typename boost::remove_const<T>::type,DIMS> versionToSend() const
|
|
||||||
{
|
|
||||||
return tockArrayView<typename boost::remove_const<T>::type,DIMS>(const_cast<typename boost::remove_const<T>::type*>(realArray),std::make_pair(dims,totalSubDim));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline tockArrayView& operator=(const tockArrayView& tav)
|
|
||||||
{
|
|
||||||
//TODO investigate speeding up when T is primitive (maybe there's a boost class for that?)
|
|
||||||
|
|
||||||
unsigned n = tav.size();
|
|
||||||
for (unsigned i = 0;i < n;i++)
|
|
||||||
{
|
|
||||||
realArray[i] = tav.realArray[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
dims = tav.dims;
|
|
||||||
totalSubDim = tav.totalSubDim;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline tockArrayView& operator=(const tockAny&)
|
|
||||||
{
|
|
||||||
//TODO later on
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -405,3 +376,29 @@ void tockRecvInt(const csp::Chanin<tockSendableArrayOfBytes>& c, unsigned int* p
|
||||||
tockSendableArrayOfBytes d(sizeof(unsigned int),p);
|
tockSendableArrayOfBytes d(sizeof(unsigned int),p);
|
||||||
c >> d;
|
c >> d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, unsigned N>
|
||||||
|
class tockSendableArray
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
tockSendableArrayOfBytes aob;
|
||||||
|
public:
|
||||||
|
template <unsigned D>
|
||||||
|
inline explicit tockSendableArray(const tockArrayView<T,D>& arr)
|
||||||
|
: aob(N*sizeof(T),arr.data())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, unsigned N, unsigned D>
|
||||||
|
void tockSendArray(const csp::Chanout< tockSendableArray<T,N> >& out,const tockArrayView<T,D>& arr)
|
||||||
|
{
|
||||||
|
out << tockSendableArray<T,N>(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, unsigned N, unsigned D>
|
||||||
|
void tockRecvArray(const csp::Chanin< tockSendableArray<T,N> >& in,const tockArrayView<T,D>& arr)
|
||||||
|
{
|
||||||
|
tockSendableArray<T,N> tsa(arr);
|
||||||
|
in >> tsa;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user