Changed arrays to use vector/tockArrayView
Previously the arrays used the Blitz++ library, but this was not totally satisfactory. I have therefore resorted (after looking at many different libraries) to using std::vector (which could perhaps be boost::array instead) coupled with a roll-my-own "array view" class (tockArrayView) that easily allows all the functionality that we need from arrays (slicing, indexing, copying, unknown dimensions,retyping,reshaping). I have also had to introduce a nasty little wrapper class tockBool, because vector<bool> is a specialisation that totally breaks things. If I do move to boost::array, I will be able to remove tockBool.
This commit is contained in:
parent
f997b823dc
commit
a52d115060
|
@ -200,7 +200,7 @@ genInputSizeAssign :: A.InputItem -> CGen()
|
||||||
genInputSizeAssign (A.InVariable _ arr)
|
genInputSizeAssign (A.InVariable _ arr)
|
||||||
= return ()
|
= return ()
|
||||||
genInputSizeAssign (A.InCounted _ count arr)
|
genInputSizeAssign (A.InCounted _ count arr)
|
||||||
= genVariable count >> tell [" = "] >> genVariable arr >> tell [" .extent(blitz::firstDim);"]
|
= genVariable count >> tell [" = "] >> genVariable arr >> tell [" .extent(0);"]
|
||||||
|
|
||||||
--Generates the long boost::tie expression that will be used to get all the data out of a tuple that we have read
|
--Generates the long boost::tie expression that will be used to get all the data out of a tuple that we have read
|
||||||
genInputTupleAssign :: Bool -> String -> [A.InputItem] -> CGen()
|
genInputTupleAssign :: Bool -> String -> [A.InputItem] -> CGen()
|
||||||
|
@ -338,22 +338,26 @@ genInputItem c (A.InCounted m cv av)
|
||||||
genVariable cv
|
genVariable cv
|
||||||
tell [" = "]
|
tell [" = "]
|
||||||
genVariable av
|
genVariable av
|
||||||
tell [" .extent(blitz::firstDim); "]
|
tell [" .extent(0); "]
|
||||||
genInputItem c (A.InVariable m v)
|
genInputItem c (A.InVariable m v)
|
||||||
= do genVariable c
|
= do genVariable c
|
||||||
tell ["->reader() >> "]
|
tell ["->reader() >> "]
|
||||||
genVariable v
|
genVariable 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 :: A.OutputItem -> CGen()
|
genJustOutputItem :: A.OutputItem -> CGen()
|
||||||
genJustOutputItem (A.OutCounted m ce ae)
|
genJustOutputItem (A.OutCounted m ce ae)
|
||||||
= do genJustOutputItem (A.OutExpression m ae)
|
= do genExpression ae
|
||||||
tell[" (blitz::Range(0,"]
|
tell[" .sliceFor("]
|
||||||
genExpression ce
|
genExpression ce
|
||||||
tell[" - 1)) .copy() "]
|
tell[") .versionToSend() "]
|
||||||
--TODO fill the rest of the dimensions with blitz::Range::all()
|
|
||||||
genJustOutputItem (A.OutExpression m e)
|
genJustOutputItem (A.OutExpression m e)
|
||||||
= genExpression e
|
= do t <- typeOfExpression e
|
||||||
|
genExpression e
|
||||||
|
case t of
|
||||||
|
(A.Array _ _) -> tell [" .versionToSend() "]
|
||||||
|
_ -> return ()
|
||||||
|
|
||||||
genOutputItem :: A.Variable -> A.OutputItem -> CGen ()
|
genOutputItem :: A.Variable -> A.OutputItem -> CGen ()
|
||||||
genOutputItem chan item
|
genOutputItem chan item
|
||||||
|
@ -534,22 +538,47 @@ genProcCall n as
|
||||||
tell [");"]
|
tell [");"]
|
||||||
|
|
||||||
|
|
||||||
--Changed from CIF's untyped channels to C++CSP's typed (templated) channels:
|
--Changed from CIF's untyped channels to C++CSP's typed (templated) channels, and changed the declaration type of an array to be a vector:
|
||||||
declareType :: A.Type -> CGen ()
|
declareType :: A.Type -> CGen ()
|
||||||
|
declareType (A.Array ds t)
|
||||||
|
= do tell [" std::vector< "]
|
||||||
|
genType t
|
||||||
|
tell ["/**/>/**/"]
|
||||||
|
declareType (A.Counted countType valueType)
|
||||||
|
= do tell [" std::vector< "]
|
||||||
|
case valueType of
|
||||||
|
--Don't nest when it's a counted array of arrays:
|
||||||
|
(A.Array _ t) -> genType t
|
||||||
|
_ -> genType valueType
|
||||||
|
tell ["/**/>/**/"]
|
||||||
|
|
||||||
declareType (A.Chan t)
|
declareType (A.Chan t)
|
||||||
= do tell [" csp::One2OneChannel < "]
|
= do tell [" csp::One2OneChannel < "]
|
||||||
genType t
|
genType t
|
||||||
tell [" > "]
|
tell ["/**/>/**/ "]
|
||||||
declareType t = genType t
|
declareType t = genType t
|
||||||
|
|
||||||
--Removed the channel part from GenerateC (not necessary in C++CSP, I think), and also changed the arrays:
|
--Removed the channel part from GenerateC (not necessary in C++CSP, I think), and also changed the arrays:
|
||||||
|
--An array is actually stored as a std::vector, but an array-view object is automatically created with the array
|
||||||
|
--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
|
||||||
genDeclaration :: A.Type -> A.Name -> CGen ()
|
genDeclaration :: A.Type -> A.Name -> CGen ()
|
||||||
genDeclaration arrType@(A.Array ds t) n
|
genDeclaration arrType@(A.Array ds t) n
|
||||||
= do declareType arrType
|
= do declareType arrType
|
||||||
tell [" "]
|
tell [" "]
|
||||||
genName n
|
genName n
|
||||||
genArraySize ds
|
tell ["_actual ("]
|
||||||
tell [";\n"]
|
genFlatArraySize ds
|
||||||
|
tell ["); "]
|
||||||
|
genType arrType
|
||||||
|
tell [" "]
|
||||||
|
genName n;
|
||||||
|
tell ["("]
|
||||||
|
genName n
|
||||||
|
tell ["_actual,tockDims("]
|
||||||
|
genDims ds
|
||||||
|
tell ["));\n"]
|
||||||
genDeclaration t n
|
genDeclaration t n
|
||||||
= do declareType t
|
= do declareType t
|
||||||
tell [" "]
|
tell [" "]
|
||||||
|
@ -564,7 +593,7 @@ declareInit m t@(A.Array ds t') var
|
||||||
return (\sub -> Just $ do genVariable (sub var)
|
return (\sub -> Just $ do genVariable (sub var)
|
||||||
tell [" = new "]
|
tell [" = new "]
|
||||||
declareType t'
|
declareType t'
|
||||||
tell ["();\n"]
|
tell [";\n"]
|
||||||
doMaybe $ declareInit m t' (sub var))
|
doMaybe $ declareInit m t' (sub var))
|
||||||
|
|
||||||
_ -> return (\sub -> declareInit m t' (sub var))
|
_ -> return (\sub -> declareInit m t' (sub var))
|
||||||
|
@ -646,15 +675,6 @@ abbrevExpression am t@(A.Array _ _) e
|
||||||
bad = missing "array expression abbreviation"
|
bad = missing "array expression abbreviation"
|
||||||
abbrevExpression am _ e = genExpression e
|
abbrevExpression am _ e = genExpression e
|
||||||
|
|
||||||
--Uses the Blitz library for giving array dimensions -- hence the round brackets, which actually are part of a constructor call
|
|
||||||
genArraySize :: [A.Dimension] -> CGen ()
|
|
||||||
genArraySize ds
|
|
||||||
= do tell ["( blitz::shape("]
|
|
||||||
sequence $ intersperse (tell [" , "])
|
|
||||||
[case d of A.Dimension n -> tell [show n] | d <- ds]
|
|
||||||
tell [") )"]
|
|
||||||
|
|
||||||
|
|
||||||
--Used to create boost::variant and boost::tuple types. Both these classes can have a maximum of nine items
|
--Used to create boost::variant and boost::tuple types. Both these classes can have a maximum of nine items
|
||||||
--so if there are more than nine items, we must have variants containing variants, or tuples containing tuples
|
--so if there are more than nine items, we must have variants containing variants, or tuples containing tuples
|
||||||
createChainedType :: String -> CGen() -> [CGen()] -> CGen ()
|
createChainedType :: String -> CGen() -> [CGen()] -> CGen ()
|
||||||
|
@ -686,8 +706,18 @@ tupleExpression useBrackets tupleType items
|
||||||
(firstNine,rest) = splitAt 9 items
|
(firstNine,rest) = splitAt 9 items
|
||||||
|
|
||||||
--Takes a list of dimensions and outputs a comma-seperated list of the numerical values
|
--Takes a list of dimensions and outputs a comma-seperated list of the numerical values
|
||||||
|
--Unknown dimensions have value 0 (which is treated specially by the tockArrayView class)
|
||||||
genDims:: [A.Dimension] -> CGen()
|
genDims:: [A.Dimension] -> CGen()
|
||||||
genDims dims = infixComma $ map genDim dims
|
genDims dims = infixComma $ map genDim dims
|
||||||
|
where
|
||||||
|
genDim :: A.Dimension -> CGen()
|
||||||
|
genDim (A.Dimension n) = tell [show n]
|
||||||
|
genDim (A.UnknownDimension) = tell ["0"]
|
||||||
|
|
||||||
|
--Generates an expression that yields the number of total elements in a declared multi-dimensional array
|
||||||
|
--Using it on arrays with unknown dimensions will cause an error (they should only be abbreviations, not declared as actual variables)
|
||||||
|
genFlatArraySize:: [A.Dimension] -> CGen()
|
||||||
|
genFlatArraySize dims = sequence_ $ intersperse (tell ["*"]) $ map genDim dims
|
||||||
where
|
where
|
||||||
genDim :: A.Dimension -> CGen()
|
genDim :: A.Dimension -> CGen()
|
||||||
genDim (A.Dimension n) = tell [show n]
|
genDim (A.Dimension n) = tell [show n]
|
||||||
|
@ -749,15 +779,15 @@ introduceSpec (A.Specification _ n (A.IsExpr _ am t e))
|
||||||
tell [" ",tmp, " [] = "]
|
tell [" ",tmp, " [] = "]
|
||||||
rhs
|
rhs
|
||||||
tell [" ; "]
|
tell [" ; "]
|
||||||
tell ["const tockArray< "]
|
tell ["const tockArrayView< const "]
|
||||||
genType ts
|
genType ts
|
||||||
tell [" , ",show (length dims)," > "]
|
tell [" , ",show (length dims)," /**/>/**/ "]
|
||||||
genName n
|
genName n
|
||||||
tell ["(("]
|
tell ["(("]
|
||||||
genType ts
|
genType ts
|
||||||
tell [" *)",tmp,",blitz::shape("]
|
tell [" *)",tmp,",tockDims("]
|
||||||
genDims dims
|
genDims dims
|
||||||
tell ["),blitz::duplicateData);\n"]
|
tell ["));\n"]
|
||||||
(A.ValAbbrev, A.Record _, A.Literal _ _ _) ->
|
(A.ValAbbrev, A.Record _, A.Literal _ _ _) ->
|
||||||
-- Record literals are even trickier, because there's no way of
|
-- Record literals are even trickier, because there's no way of
|
||||||
-- directly writing a struct literal in C that you can use -> on.
|
-- directly writing a struct literal in C that you can use -> on.
|
||||||
|
@ -774,19 +804,15 @@ introduceSpec (A.Specification _ n (A.IsExpr _ am t e))
|
||||||
tell [" = "]
|
tell [" = "]
|
||||||
rhs
|
rhs
|
||||||
tell [";\n"]
|
tell [";\n"]
|
||||||
--TODO check this clause is ok
|
|
||||||
|
--We must create the channel array then fill it:
|
||||||
introduceSpec (A.Specification _ n (A.IsChannelArray _ t cs))
|
introduceSpec (A.Specification _ n (A.IsChannelArray _ t cs))
|
||||||
= do --tell ["tockArray< csp::One2OneChannel< "]
|
= do genDeclaration t n
|
||||||
genType t
|
|
||||||
--tell [" > * , 1 > "]
|
|
||||||
tell [" "]
|
|
||||||
genName n
|
|
||||||
tell ["(blitz::shape(",show (length cs),"));"]
|
|
||||||
sequence_ $ map genChanArrayElemInit (zip [0 .. ((length cs) - 1)] cs)
|
sequence_ $ map genChanArrayElemInit (zip [0 .. ((length cs) - 1)] cs)
|
||||||
where
|
where
|
||||||
genChanArrayElemInit (index,var)
|
genChanArrayElemInit (index,var)
|
||||||
= do genName n
|
= do genName n
|
||||||
tell ["(",show index,") = "]
|
tell ["[",show index,"].access() = "] --Use the .access() function to cast a 0-dimension array into a T& for access
|
||||||
genVariable var
|
genVariable var
|
||||||
tell [";"]
|
tell [";"]
|
||||||
--This clause is unchanged from GenerateC:
|
--This clause is unchanged from GenerateC:
|
||||||
|
@ -817,15 +843,25 @@ introduceSpec (A.Specification _ n (A.ProtocolCase _ caseList))
|
||||||
typedef_genCaseType n (tag, typeList)
|
typedef_genCaseType n (tag, typeList)
|
||||||
= createChainedType "boost::tuple" (genTupleProtocolTagName n tag) ((genProtocolTagName n tag) : (map genType typeList))
|
= createChainedType "boost::tuple" (genTupleProtocolTagName n tag) ((genProtocolTagName n tag) : (map genType typeList))
|
||||||
|
|
||||||
--TODO check this clause
|
--Clause changed to handle array retyping
|
||||||
introduceSpec (A.Specification _ n (A.Retypes m am t v))
|
introduceSpec (A.Specification _ n (A.Retypes m am t v))
|
||||||
= do origT <- typeOfVariable v
|
= do origT <- typeOfVariable v
|
||||||
let rhs = abbrevVariable A.Abbrev origT v
|
let rhs = abbrevVariable A.Abbrev origT v
|
||||||
genDecl am t n
|
genDecl am t n
|
||||||
tell [" = "]
|
tell [" = "]
|
||||||
|
case t of
|
||||||
|
(A.Array dims _) ->
|
||||||
|
--Arrays need to be handled differently because we need to feed the sizes in, not just perform a straight cast
|
||||||
|
do genDeclType am t
|
||||||
|
tell ["("]
|
||||||
|
rhs
|
||||||
|
tell [",tockDims("]
|
||||||
|
genDims dims
|
||||||
|
tell ["));"]
|
||||||
|
_ ->
|
||||||
-- For scalar types that are VAL abbreviations (e.g. VAL INT64),
|
-- For scalar types that are VAL abbreviations (e.g. VAL INT64),
|
||||||
-- we need to dereference the pointer that abbrevVariable gives us.
|
-- we need to dereference the pointer that abbrevVariable gives us.
|
||||||
let deref = case (am, t) of
|
do let deref = case (am, t) of
|
||||||
(_, A.Array _ _) -> False
|
(_, A.Array _ _) -> False
|
||||||
(_, A.Chan _) -> False
|
(_, A.Chan _) -> False
|
||||||
(A.ValAbbrev, _) -> True
|
(A.ValAbbrev, _) -> True
|
||||||
|
@ -834,11 +870,13 @@ introduceSpec (A.Specification _ n (A.Retypes m am t v))
|
||||||
tell ["("]
|
tell ["("]
|
||||||
genDeclType am t
|
genDeclType am t
|
||||||
when deref $ tell [" *"]
|
when deref $ tell [" *"]
|
||||||
tell [") "]
|
tell [") ("]
|
||||||
rhs
|
rhs
|
||||||
tell [";\n"]
|
case origT of
|
||||||
--TODO work out what this does
|
--We must be retyping from an array, but not to an array (so to a primitive type or something):
|
||||||
-- genRetypeSizes m am t n origT v
|
(A.Array _ _) -> tell [".data()"]
|
||||||
|
_ -> return ()
|
||||||
|
tell [");\n"]
|
||||||
|
|
||||||
--This clause is unchanged from GenerateC:
|
--This clause is unchanged from GenerateC:
|
||||||
introduceSpec n = missing $ "introduceSpec " ++ show n
|
introduceSpec n = missing $ "introduceSpec " ++ show n
|
||||||
|
@ -851,10 +889,10 @@ genExpression (A.MostPos m t) = genTypeSymbol "mostpos" t
|
||||||
genExpression (A.MostNeg m t) = genTypeSymbol "mostneg" t
|
genExpression (A.MostNeg m t) = genTypeSymbol "mostneg" t
|
||||||
genExpression (A.SizeExpr m e)
|
genExpression (A.SizeExpr m e)
|
||||||
= do genExpression e
|
= do genExpression e
|
||||||
tell [" .extent(blitz::firstDim) "]
|
tell [" .extent(0) "]
|
||||||
genExpression (A.SizeVariable m v)
|
genExpression (A.SizeVariable m v)
|
||||||
= do genVariable v
|
= do genVariable v
|
||||||
tell [" .extent(blitz::firstDim)"]
|
tell [" .extent(0)"]
|
||||||
genExpression (A.Conversion m cm t e) = genConversion m cm t e
|
genExpression (A.Conversion m cm t e) = genConversion m cm t e
|
||||||
genExpression (A.ExprVariable m v) = genVariable v
|
genExpression (A.ExprVariable m v) = genVariable v
|
||||||
genExpression (A.Literal _ _ lr) = genLiteral lr
|
genExpression (A.Literal _ _ lr) = genLiteral lr
|
||||||
|
@ -875,8 +913,9 @@ genExpression t = missing $ "genExpression " ++ show t
|
||||||
-- | If a type maps to a simple C type, return Just that; else return Nothing.
|
-- | If a type maps to a simple C type, return Just that; else return Nothing.
|
||||||
|
|
||||||
--Changed from GenerateC to change the A.Timer type to use C++CSP time
|
--Changed from GenerateC to change the A.Timer type to use C++CSP time
|
||||||
|
--Also changed the bool type, because vector<bool> in C++ is odd, so we hide it from the compiler:
|
||||||
scalarType :: A.Type -> Maybe String
|
scalarType :: A.Type -> Maybe String
|
||||||
scalarType A.Bool = Just "bool"
|
scalarType A.Bool = Just "tockBool"
|
||||||
scalarType A.Byte = Just "uint8_t"
|
scalarType A.Byte = Just "uint8_t"
|
||||||
scalarType A.Int = Just "int"
|
scalarType A.Int = Just "int"
|
||||||
scalarType A.Int16 = Just "int16_t"
|
scalarType A.Int16 = Just "int16_t"
|
||||||
|
@ -888,19 +927,20 @@ scalarType A.Timer = Just "csp::Time"
|
||||||
scalarType _ = Nothing
|
scalarType _ = Nothing
|
||||||
|
|
||||||
--Generates an array type, giving the Blitz++ array the correct dimensions
|
--Generates an array type, giving the Blitz++ array the correct dimensions
|
||||||
genArrayType :: A.Type -> Int -> CGen ()
|
genArrayType :: Bool -> A.Type -> Int -> CGen ()
|
||||||
genArrayType (A.Array dims t) rank
|
genArrayType const (A.Array dims t) rank
|
||||||
= genArrayType t (rank + (max 1 (length dims)))
|
= genArrayType const t (rank + (max 1 (length dims)))
|
||||||
genArrayType t rank
|
genArrayType const t rank
|
||||||
= do tell [" tockArray< "]
|
= do tell [" tockArrayView< "]
|
||||||
|
when (const) (tell [" const "])
|
||||||
genType t
|
genType t
|
||||||
tell [" , ",show rank, " > "]
|
tell [" , ",show rank, " > /**/"]
|
||||||
|
|
||||||
--Changed from GenerateC to change the arrays and the channels
|
--Changed from GenerateC to change the arrays and the channels
|
||||||
--Also changed to add counted arrays and user protocols
|
--Also changed to add counted arrays and user protocols
|
||||||
genType :: A.Type -> CGen ()
|
genType :: A.Type -> CGen ()
|
||||||
genType arr@(A.Array _ _)
|
genType arr@(A.Array _ _)
|
||||||
= genArrayType arr 0
|
= genArrayType False arr 0
|
||||||
genType (A.Record n) = genName n
|
genType (A.Record n) = genName n
|
||||||
genType (A.UserProtocol n) = genProtocolName n
|
genType (A.UserProtocol n) = genProtocolName n
|
||||||
genType (A.Chan t)
|
genType (A.Chan t)
|
||||||
|
@ -908,7 +948,7 @@ genType (A.Chan t)
|
||||||
genType t
|
genType t
|
||||||
tell [" > * "]
|
tell [" > * "]
|
||||||
genType (A.Counted countType valueType)
|
genType (A.Counted countType valueType)
|
||||||
= genType (A.Array [] valueType)
|
= genType (A.Array [A.UnknownDimension] valueType)
|
||||||
genType (A.Any)
|
genType (A.Any)
|
||||||
= tell [" tockAny "]
|
= tell [" tockAny "]
|
||||||
-- Any -- not used
|
-- Any -- not used
|
||||||
|
@ -963,13 +1003,11 @@ genSlice _ v ty start count ds
|
||||||
-- We need to disable the index check here because we might be taking
|
-- We need to disable the index check here because we might be taking
|
||||||
-- element 0 of a 0-length array -- which is valid.
|
-- element 0 of a 0-length array -- which is valid.
|
||||||
= do genVariableUnchecked v
|
= do genVariableUnchecked v
|
||||||
tell ["(blitz::Range("]
|
tell [".sliceFromFor("]
|
||||||
genExpression start
|
genExpression start
|
||||||
tell [" , "]
|
tell [" , "]
|
||||||
genExpression start
|
|
||||||
tell [" + "]
|
|
||||||
genExpression count
|
genExpression count
|
||||||
tell [" ))"]
|
tell [")"]
|
||||||
|
|
||||||
|
|
||||||
--Removed the sizing and the & from GenerateC:
|
--Removed the sizing and the & from GenerateC:
|
||||||
|
@ -982,9 +1020,7 @@ genArraySubscript :: Bool -> A.Variable -> [A.Expression] -> CGen ()
|
||||||
genArraySubscript checkValid v es
|
genArraySubscript checkValid v es
|
||||||
= do t <- typeOfVariable v
|
= do t <- typeOfVariable v
|
||||||
let numDims = case t of A.Array ds _ -> length ds
|
let numDims = case t of A.Array ds _ -> length ds
|
||||||
tell ["("]
|
sequence_ $ genPlainSub v es [0..(numDims - 1)]
|
||||||
sequence_ $ intersperse (tell [" , "]) $ genPlainSub v es [0..(numDims - 1)]
|
|
||||||
tell [")"]
|
|
||||||
where
|
where
|
||||||
-- | Generate the individual offsets that need adding together to find the
|
-- | Generate the individual offsets that need adding together to find the
|
||||||
-- right place in the array.
|
-- right place in the array.
|
||||||
|
@ -992,14 +1028,14 @@ genArraySubscript checkValid v es
|
||||||
-- smart C compiler should be able to work it out...
|
-- smart C compiler should be able to work it out...
|
||||||
|
|
||||||
--Subtly changed this function so that empty dimensions have blitz::Range::all() in the C++ version:
|
--Subtly changed this function so that empty dimensions have blitz::Range::all() in the C++ version:
|
||||||
|
--TODO doc
|
||||||
|
|
||||||
genPlainSub :: A.Variable -> [A.Expression] -> [Int] -> [CGen ()]
|
genPlainSub :: A.Variable -> [A.Expression] -> [Int] -> [CGen ()]
|
||||||
genPlainSub _ _ [] = []
|
genPlainSub _ _ [] = []
|
||||||
genPlainSub v [] (sub:subs) = (tell [" blitz::Range::all() "]) : (genPlainSub v [] subs)
|
genPlainSub v [] (sub:subs) = (tell [" "]) : (genPlainSub v [] subs)
|
||||||
genPlainSub v (e:es) (sub:subs)
|
genPlainSub v (e:es) (sub:subs)
|
||||||
= gen : genPlainSub v es subs
|
= (tell ["["] >> genSub >> tell ["]"]) : genPlainSub v es subs
|
||||||
where
|
where
|
||||||
gen = genSub
|
|
||||||
genSub
|
genSub
|
||||||
= if checkValid
|
= if checkValid
|
||||||
then do tell ["occam_check_index ("]
|
then do tell ["occam_check_index ("]
|
||||||
|
@ -1106,6 +1142,21 @@ genIfBody ifExc s = genStructured s doC
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
|
|
||||||
|
--Changed to make array VAL abbreviations have constant data:
|
||||||
|
genDeclType :: A.AbbrevMode -> A.Type -> CGen ()
|
||||||
|
genDeclType am t
|
||||||
|
= do case t of
|
||||||
|
A.Array _ _ -> genArrayType (am == A.ValAbbrev) t 0
|
||||||
|
_ ->
|
||||||
|
do when (am == A.ValAbbrev) $ tell ["const "]
|
||||||
|
genType t
|
||||||
|
case t of
|
||||||
|
A.Chan _ -> return ()
|
||||||
|
A.Record _ -> tell [" *"]
|
||||||
|
_ -> when (am == A.Abbrev) $ tell [" *"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -1380,15 +1431,6 @@ genCheckedConversion m fromT toT exp
|
||||||
|
|
||||||
--{{{ declarations
|
--{{{ declarations
|
||||||
--All taken verbatim from GenerateC
|
--All taken verbatim from GenerateC
|
||||||
genDeclType :: A.AbbrevMode -> A.Type -> CGen ()
|
|
||||||
genDeclType am t
|
|
||||||
= do when (am == A.ValAbbrev) $ tell ["const "]
|
|
||||||
genType t
|
|
||||||
case t of
|
|
||||||
A.Array _ _ -> return ()
|
|
||||||
A.Chan _ -> return ()
|
|
||||||
A.Record _ -> tell [" *"]
|
|
||||||
_ -> when (am == A.Abbrev) $ tell [" *"]
|
|
||||||
|
|
||||||
genDecl :: A.AbbrevMode -> A.Type -> A.Name -> CGen ()
|
genDecl :: A.AbbrevMode -> A.Type -> A.Name -> CGen ()
|
||||||
genDecl am t n
|
genDecl am t n
|
||||||
|
@ -1486,6 +1528,10 @@ genVariable' checkValid v
|
||||||
= do let (es, v) = collectSubs sv
|
= do let (es, v) = collectSubs sv
|
||||||
genVariable v
|
genVariable v
|
||||||
genArraySubscript checkValid v es
|
genArraySubscript checkValid v es
|
||||||
|
t <- typeOfVariable v
|
||||||
|
--To index an actual element of an array we must use the .access() function
|
||||||
|
--Only needed when we have applied enough subscripts to get out an element:
|
||||||
|
case t of A.Array dims _ -> when ((length dims) == (length es)) (tell [" .access() "])
|
||||||
inner (A.SubscriptedVariable _ (A.SubscriptField m n) v)
|
inner (A.SubscriptedVariable _ (A.SubscriptField m n) v)
|
||||||
= do genVariable v
|
= do genVariable v
|
||||||
tell ["->"]
|
tell ["->"]
|
||||||
|
|
|
@ -29,17 +29,11 @@ public:
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
#include <boost/mpl/at.hpp>
|
|
||||||
#include <blitz/array.h>
|
|
||||||
#include <blitz/tinyvec-et.h>
|
|
||||||
#include <boost/any.hpp>
|
#include <boost/any.hpp>
|
||||||
|
#include <vector>
|
||||||
inline blitz::Array<unsigned char, 1> string_to_array(char* c)
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
{
|
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||||
const size_t n = strlen(c) + 1;
|
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||||
return blitz::Array<unsigned char, 1>((unsigned char*)c,blitz::shape(n),blitz::neverDeleteData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class StreamWriter : public csp::CSProcess
|
class StreamWriter : public csp::CSProcess
|
||||||
{
|
{
|
||||||
|
@ -105,93 +99,244 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template < typename T, unsigned dims >
|
class tockBool
|
||||||
class tockArray : public blitz::Array<T,dims>
|
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
bool b;
|
||||||
public:
|
public:
|
||||||
inline tockArray(const tockArray<T,dims>& _array)
|
inline tockBool() {}
|
||||||
: blitz::Array<T,dims>(*(blitz::Array<T,dims>*)&_array) {}
|
inline tockBool(bool _b) : b(_b) {}
|
||||||
|
inline operator bool () const {return b;}
|
||||||
inline tockArray(const tockAny& _any)
|
inline void operator = (const bool& _b) {b = _b;}
|
||||||
: blitz::Array<T,dims>(*(blitz::Array<T,dims>*)& (tockArray)_any) {}
|
};
|
||||||
|
|
||||||
template <typename U>
|
inline std::pair< boost::array<unsigned,1> , unsigned > tockDims(const unsigned d0)
|
||||||
inline tockArray(const tockArray<U,dims>& _diffTypeArray)
|
{
|
||||||
: blitz::Array<T,dims>( (T*) (_diffTypeArray.dataFirst()), (_diffTypeArray.shape() * (int)sizeof(U)) / (int)sizeof(T),blitz::neverDeleteData) {}
|
boost::array<unsigned,1> r;
|
||||||
|
r[0] = d0;
|
||||||
template <unsigned D>
|
return std::pair< boost::array<unsigned,1> , unsigned >(r,1);
|
||||||
inline tockArray(const tockArray<T,D>& _diffDimArray)
|
}
|
||||||
: blitz::Array<T,dims>( (T*) (_diffDimArray.dataFirst()),blitz::shape(_diffDimArray.size()),blitz::neverDeleteData) {}
|
|
||||||
|
/*
|
||||||
template <typename U>
|
Generates functions like this:
|
||||||
inline tockArray(U* u)
|
inline std::pair< boost::array<unsigned,2> , unsigned > tockDims(const unsigned d0,const unsigned d1,const unsigned d2)
|
||||||
: blitz::Array<T,dims>( (T*) u, sizeof(U) / sizeof(T),blitz::neverDeleteData) {}
|
{
|
||||||
|
boost::array<unsigned,2> r;
|
||||||
inline tockArray(T t) : blitz::Array<T,dims>(1) {(*this)(0) = t;}
|
r[0] = d0;
|
||||||
|
r[1] = d1;
|
||||||
|
r[2] = d2;
|
||||||
template <typename U>
|
return std::pair< boost::array<unsigned,2> , unsigned >(r,d1 * d2);
|
||||||
inline tockArray(U u) : blitz::Array<T,dims>(u) {}
|
}
|
||||||
|
*/
|
||||||
template <typename U,typename V>
|
|
||||||
inline tockArray(U u,V v) : blitz::Array<T,dims>(u,v) {}
|
#define TOCKDIMS_ARGS(___z,NUM,___data) ,const unsigned d##NUM
|
||||||
|
#define TOCKDIMS_ASSIGN(___z,NUM,___data) r[ NUM ] = d##NUM ;
|
||||||
template <typename U,typename V,typename W>
|
#define TOCKDIMS_MULT(___z,NUM,___data) * d##NUM
|
||||||
inline tockArray(U u,V v,W w) : blitz::Array<T,dims>(u,v,w) {}
|
|
||||||
|
#define TOCKDIMS(___z,NUM,___data) inline std::pair< boost::array<unsigned, NUM >,unsigned> tockDims(\
|
||||||
template <typename U,typename V,typename W,typename X>
|
const unsigned d0 BOOST_PP_REPEAT_FROM_TO(1,NUM,TOCKDIMS_ARGS,0) ) { \
|
||||||
inline tockArray(U u,V v,W w,X x) : blitz::Array<T,dims>(u,v,w,x) {}
|
boost::array<unsigned, NUM > r; BOOST_PP_REPEAT(NUM,TOCKDIMS_ASSIGN,0) \
|
||||||
|
return std::pair< boost::array<unsigned, NUM > , unsigned >(r,1 BOOST_PP_REPEAT_FROM_TO(1,NUM,TOCKDIMS_MULT,0) ); }
|
||||||
template <typename U,typename V,typename W,typename X,typename Y>
|
|
||||||
inline tockArray(U u,V v,W w,X x,Y y) : blitz::Array<T,dims>(u,v,w,x,y) {}
|
//Up to 12 dimensions:
|
||||||
|
BOOST_PP_REPEAT_FROM_TO(2,12,TOCKDIMS,0)
|
||||||
template <typename U,typename V,typename W,typename X,typename Y,typename Z>
|
|
||||||
inline tockArray(U u,V v,W w,X x,Y y,Z z) : blitz::Array<T,dims>(u,v,w,x,y,z) {}
|
|
||||||
|
template < typename T, unsigned DIMS >
|
||||||
template <typename U,typename V,typename W,typename X,typename Y,typename Z,typename Z0>
|
class tockArrayView
|
||||||
inline tockArray(U u,V v,W w,X x,Y y,Z z,Z0 z0) : blitz::Array<T,dims>(u,v,w,x,y,z,z0) {}
|
{
|
||||||
|
T* realArray;
|
||||||
template <typename U,typename V,typename W,typename X,typename Y,typename Z,typename Z0,typename Z1>
|
boost::array<unsigned,DIMS> dims;
|
||||||
inline tockArray(U u,V v,W w,X x,Y y,Z z,Z0 z0,Z1 z1) : blitz::Array<T,dims>(u,v,w,x,y,z,z0,z1) {}
|
//dims[1] * dims[2] * dims[3] ...
|
||||||
|
//If DIMS is 0 or 1, totalSubDim will be 1
|
||||||
template <typename U,typename V,typename W,typename X,typename Y,typename Z,typename Z0,typename Z1,typename Z2>
|
unsigned totalSubDim;
|
||||||
inline tockArray(U u,V v,W w,X x,Y y,Z z,Z0 z0,Z1 z1,Z2 z2) : blitz::Array<T,dims>(u,v,w,x,y,z,z0,z1,z2) {}
|
|
||||||
|
template <typename U>
|
||||||
template <typename U,typename V,typename W,typename X,typename Y,typename Z,typename Z0,typename Z1,typename Z2,typename Z3>
|
inline void operator=(const U&) {}
|
||||||
inline tockArray(U u,V v,W w,X x,Y y,Z z,Z0 z0,Z1 z1,Z2 z2,Z3 z3) : blitz::Array<T,dims>(u,v,w,x,y,z,z0,z1,z2,z3) {}
|
|
||||||
|
inline tockArrayView(T* _realArray,const boost::array<unsigned,DIMS+1>& _biggerDims,unsigned _totalSubDim)
|
||||||
|
: realArray(_realArray),totalSubDim(_totalSubDim)
|
||||||
inline tockArray() {}
|
{
|
||||||
|
memcpy(dims.c_array(),_biggerDims.data() + 1,sizeof(unsigned) * DIMS);
|
||||||
inline tockArray& operator=(const tockArray<T,dims>& rhs)
|
}
|
||||||
{
|
friend class tockArrayView<T,DIMS + 1>;
|
||||||
resize(rhs.shape());
|
|
||||||
*((blitz::Array<T,dims>*)this) = *((blitz::Array<T,dims>*)&rhs);
|
inline void correctDimsRetype(const unsigned totalSourceBytes)
|
||||||
return *this;
|
{
|
||||||
}
|
if (totalSubDim == 0)
|
||||||
|
{
|
||||||
inline tockArray& operator=(const tockAny& any)
|
//Can only happen if one of the dimensions is zero, i.e. unknown
|
||||||
{
|
//We must find this dimension and calculate it:
|
||||||
return (*this = (tockArray<T,dims>)any);
|
|
||||||
}
|
unsigned zeroDim;
|
||||||
|
unsigned totalDim = 1;
|
||||||
inline tockArray& operator=(const T& t)
|
for (unsigned i = 0;i < DIMS;i++)
|
||||||
{
|
{
|
||||||
this->resize(blitz::shape(1));
|
if (dims[i] == 0)
|
||||||
(*this)(0) = t;
|
zeroDim = i;
|
||||||
return *this;
|
else
|
||||||
}
|
totalDim *= dims[i];
|
||||||
|
}
|
||||||
template <typename U>
|
//Set the size of the unknown dimension:
|
||||||
operator U* ()
|
dims[zeroDim] = (totalSourceBytes / totalDim) / sizeof(T);
|
||||||
{
|
|
||||||
return (U*)(void*)(this->dataFirst());
|
totalSubDim = (totalDim * dims[zeroDim]) / dims[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
}
|
||||||
operator const U* const ()
|
|
||||||
{
|
|
||||||
return (const U*)(const void*)(this->dataFirst());
|
public:
|
||||||
}
|
inline tockArrayView()
|
||||||
|
: realArray(NULL)
|
||||||
|
{
|
||||||
|
dims.assign(0);
|
||||||
|
totalSubDim = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView(const tockArrayView& v)
|
||||||
|
: realArray(v.realArray),
|
||||||
|
dims(v.dims),
|
||||||
|
totalSubDim(v.totalSubDim)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline tockArrayView(T* _realArray,const std::pair< boost::array<unsigned,DIMS> , unsigned >& _dims)
|
||||||
|
: realArray(_realArray),dims(_dims.first),totalSubDim(_dims.second)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView(std::vector<typename boost::remove_const<T>::type>& _vec,const std::pair< boost::array<unsigned,DIMS> , unsigned >& _dims)
|
||||||
|
: realArray(_vec.empty() ? NULL : &(_vec.at(0))),dims(_dims.first),totalSubDim(_dims.second)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Retyping:
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
inline tockArrayView(U* _realArray,const std::pair< boost::array<unsigned,DIMS> , unsigned >& _dims)
|
||||||
|
: realArray(reinterpret_cast<T*>(_realArray)),dims(_dims.first),totalSubDim(_dims.second)
|
||||||
|
{
|
||||||
|
//Assume it's a single U item:
|
||||||
|
correctDimsRetype(sizeof(U));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Retyping, same number of dims:
|
||||||
|
template <typename U,unsigned FROMDIMS>
|
||||||
|
inline tockArrayView(const tockArrayView<U,FROMDIMS>& tav,const std::pair< boost::array<unsigned,DIMS> , unsigned >& _dims)
|
||||||
|
: realArray(reinterpret_cast<T*>(tav.data())),dims(_dims.first),totalSubDim(_dims.second)
|
||||||
|
{
|
||||||
|
correctDimsRetype(tav.size() * sizeof(U));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView<T,DIMS - 1> operator[] (const unsigned index) const
|
||||||
|
{
|
||||||
|
return tockArrayView<T,DIMS - 1>(realArray + (totalSubDim * index),dims,totalSubDim / dims[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView<T,DIMS> sliceFor(const unsigned amount) const
|
||||||
|
{
|
||||||
|
return sliceFromFor(0,amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView<T,DIMS> sliceFrom(const unsigned index) const
|
||||||
|
{
|
||||||
|
return sliceFromFor(index,dims[0] - index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline tockArrayView<T,DIMS> sliceFromFor(const unsigned index,const unsigned amount) const
|
||||||
|
{
|
||||||
|
boost::array<unsigned,DIMS> sliceDims = dims;
|
||||||
|
sliceDims[0] = amount;
|
||||||
|
|
||||||
|
return tockArrayView<T,DIMS>(realArray + (totalSubDim * index),std::make_pair(sliceDims,totalSubDim));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* data() const
|
||||||
|
{
|
||||||
|
return realArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const boost::array<unsigned,DIMS>& getDims() const
|
||||||
|
{
|
||||||
|
return dims;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned getTotalSubDim() const
|
||||||
|
{
|
||||||
|
return totalSubDim;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned size() const
|
||||||
|
{
|
||||||
|
return dims[0] * totalSubDim;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned extent(const unsigned dim) const
|
||||||
|
{
|
||||||
|
return dims[dim];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator tockArrayView<const T,DIMS>() const
|
||||||
|
{
|
||||||
|
return tockArrayView<const T,DIMS>((const T*)realArray,std::make_pair(dims,totalSubDim));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void updateFromVector(std::vector<typename boost::remove_const<T>::type>& v)
|
||||||
|
{
|
||||||
|
realArray = v.empty() ? NULL : &(v.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
class tockArrayView<T,0>
|
||||||
|
{
|
||||||
|
T* realArray;
|
||||||
|
|
||||||
|
inline tockArrayView(T* _realArray,boost::array<unsigned,1>,unsigned)
|
||||||
|
: realArray(_realArray)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class tockArrayView<T,1>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//Should only be used on arrays with zero dimensions:
|
||||||
|
inline T& access() const
|
||||||
|
{
|
||||||
|
return *realArray;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user