Re-added the index checking for array slices in the backend
This commit is contained in:
parent
3d1945b517
commit
0265063250
|
@ -692,7 +692,8 @@ cgenVariable' checkValid v
|
||||||
A.Array ds _ <- typeOfVariable v
|
A.Array ds _ <- typeOfVariable v
|
||||||
(cg, n) <- inner ind v (Just t)
|
(cg, n) <- inner ind v (Just t)
|
||||||
let check = if checkValid then subCheck else A.NoCheck
|
let check = if checkValid then subCheck else A.NoCheck
|
||||||
return ((if (length ds /= length es) then tell ["&"] else return ()) >> cg >> call genArraySubscript check v es, n)
|
return ((if (length ds /= length es) then tell ["&"] else return ()) >> cg
|
||||||
|
>> call genArraySubscript check v (map (\e -> (findMeta e, call genExpression e)) es), n)
|
||||||
inner ind sv@(A.SubscriptedVariable _ (A.SubscriptField m n) v) mt
|
inner ind sv@(A.SubscriptedVariable _ (A.SubscriptField m n) v) mt
|
||||||
= do (cg, ind') <- inner ind v mt
|
= do (cg, ind') <- inner ind v mt
|
||||||
t <- typeOfVariable sv
|
t <- typeOfVariable sv
|
||||||
|
@ -700,21 +701,22 @@ cgenVariable' checkValid v
|
||||||
outerInd = if indirectedType t then -1 else 0
|
outerInd = if indirectedType t then -1 else 0
|
||||||
return (addPrefix (addPrefix cg ind' >> tell ["->"] >> genName n) outerInd, 0)
|
return (addPrefix (addPrefix cg ind' >> tell ["->"] >> genName n) outerInd, 0)
|
||||||
|
|
||||||
--TODO check the bounds of slices, at both ends
|
inner ind sv@(A.SubscriptedVariable m (A.SubscriptFromFor m' start count) v) mt
|
||||||
inner ind sv@(A.SubscriptedVariable m (A.SubscriptFromFor m' start _) v) mt
|
|
||||||
= return (
|
= return (
|
||||||
do tell ["(&"]
|
do tell ["(&"]
|
||||||
join $ liftM fst $ inner ind v mt
|
join $ liftM fst $ inner ind v mt
|
||||||
call genArraySubscript A.NoCheck v [start]
|
call genArraySubscript A.NoCheck v [(m',
|
||||||
|
do tell ["occam_check_slice("]
|
||||||
|
call genExpression start
|
||||||
|
genComma
|
||||||
|
call genExpression count
|
||||||
|
genComma
|
||||||
|
call genExpression (A.SizeVariable m' v)
|
||||||
|
genComma
|
||||||
|
genMeta m'
|
||||||
|
tell [")"]
|
||||||
|
)]
|
||||||
tell [")"], 0)
|
tell [")"], 0)
|
||||||
inner ind sv@(A.SubscriptedVariable m (A.SubscriptFrom m' start) v) mt
|
|
||||||
= return (
|
|
||||||
do tell ["(&"]
|
|
||||||
join $ liftM fst $ inner ind v mt
|
|
||||||
call genArraySubscript A.NoCheck v [start]
|
|
||||||
tell [")"], 0)
|
|
||||||
inner ind sv@(A.SubscriptedVariable m (A.SubscriptFor m' _) v) mt
|
|
||||||
= inner ind v mt
|
|
||||||
|
|
||||||
addPrefix :: CGen () -> Int -> CGen ()
|
addPrefix :: CGen () -> Int -> CGen ()
|
||||||
addPrefix cg 0 = cg
|
addPrefix cg 0 = cg
|
||||||
|
@ -743,7 +745,7 @@ indirectedType _ = False
|
||||||
cgenDirectedVariable :: CGen () -> A.Direction -> CGen ()
|
cgenDirectedVariable :: CGen () -> A.Direction -> CGen ()
|
||||||
cgenDirectedVariable var _ = var
|
cgenDirectedVariable var _ = var
|
||||||
|
|
||||||
cgenArraySubscript :: A.SubscriptCheck -> A.Variable -> [A.Expression] -> CGen ()
|
cgenArraySubscript :: A.SubscriptCheck -> A.Variable -> [(Meta, CGen ())] -> CGen ()
|
||||||
cgenArraySubscript check v es
|
cgenArraySubscript check 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
|
||||||
|
@ -758,36 +760,36 @@ cgenArraySubscript check v es
|
||||||
-- right place in the array.
|
-- right place in the array.
|
||||||
-- FIXME This is obviously not the best way to factor this, but I figure a
|
-- FIXME This is obviously not the best way to factor this, but I figure a
|
||||||
-- smart C compiler should be able to work it out...
|
-- smart C compiler should be able to work it out...
|
||||||
genPlainSub :: (Int -> CGen ()) -> [A.Expression] -> [Int] -> [CGen ()]
|
genPlainSub :: (Int -> CGen ()) -> [(Meta, CGen ())] -> [Int] -> [CGen ()]
|
||||||
genPlainSub _ [] _ = []
|
genPlainSub _ [] _ = []
|
||||||
genPlainSub genDim (e:es) (sub:subs)
|
genPlainSub genDim ((m,e):es) (sub:subs)
|
||||||
= gen : genPlainSub genDim es subs
|
= gen : genPlainSub genDim es subs
|
||||||
where
|
where
|
||||||
gen = sequence_ $ intersperse (tell ["*"]) $ genSub : genChunks
|
gen = sequence_ $ intersperse (tell ["*"]) $ genSub : genChunks
|
||||||
genSub
|
genSub
|
||||||
= case check of
|
= case check of
|
||||||
A.NoCheck -> call genExpression e
|
A.NoCheck -> e
|
||||||
A.CheckBoth ->
|
A.CheckBoth ->
|
||||||
do tell ["occam_check_index("]
|
do tell ["occam_check_index("]
|
||||||
call genExpression e
|
e
|
||||||
tell [","]
|
tell [","]
|
||||||
genDim sub
|
genDim sub
|
||||||
tell [","]
|
tell [","]
|
||||||
genMeta (findMeta e)
|
genMeta m
|
||||||
tell [")"]
|
tell [")"]
|
||||||
A.CheckUpper ->
|
A.CheckUpper ->
|
||||||
do tell ["occam_check_index_upper("]
|
do tell ["occam_check_index_upper("]
|
||||||
call genExpression e
|
e
|
||||||
tell [","]
|
tell [","]
|
||||||
genDim sub
|
genDim sub
|
||||||
tell [","]
|
tell [","]
|
||||||
genMeta (findMeta e)
|
genMeta m
|
||||||
tell [")"]
|
tell [")"]
|
||||||
A.CheckLower ->
|
A.CheckLower ->
|
||||||
do tell ["occam_check_index_lower("]
|
do tell ["occam_check_index_lower("]
|
||||||
call genExpression e
|
e
|
||||||
tell [","]
|
tell [","]
|
||||||
genMeta (findMeta e)
|
genMeta m
|
||||||
tell [")"]
|
tell [")"]
|
||||||
genChunks = map genDim subs
|
genChunks = map genDim subs
|
||||||
--}}}
|
--}}}
|
||||||
|
|
|
@ -101,7 +101,7 @@ data GenOps = GenOps {
|
||||||
-- | Writes out the actual data storage array name.
|
-- | Writes out the actual data storage array name.
|
||||||
genArrayStoreName :: A.Name -> CGen(),
|
genArrayStoreName :: A.Name -> CGen(),
|
||||||
-- | Generates an array subscript for the given variable (with error checking according to the first variable), using the given expression list as subscripts
|
-- | Generates an array subscript for the given variable (with error checking according to the first variable), using the given expression list as subscripts
|
||||||
genArraySubscript :: A.SubscriptCheck -> A.Variable -> [A.Expression] -> CGen (),
|
genArraySubscript :: A.SubscriptCheck -> A.Variable -> [(Meta, CGen ())] -> CGen (),
|
||||||
genAssert :: Meta -> A.Expression -> CGen (),
|
genAssert :: Meta -> A.Expression -> CGen (),
|
||||||
-- | Generates an assignment statement with a single destination and single source.
|
-- | Generates an assignment statement with a single destination and single source.
|
||||||
genAssign :: Meta -> [A.Variable] -> A.ExpressionList -> CGen (),
|
genAssign :: Meta -> [A.Variable] -> A.ExpressionList -> CGen (),
|
||||||
|
|
|
@ -66,7 +66,7 @@ static inline int occam_check_slice (int start, int count, int limit, const char
|
||||||
|| count < 0)) {
|
|| count < 0)) {
|
||||||
occam_stop (pos, 4, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit);
|
occam_stop (pos, 4, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit);
|
||||||
}
|
}
|
||||||
return count;
|
return start;
|
||||||
}
|
}
|
||||||
static inline int occam_check_index (int, int, const char *) occam_unused;
|
static inline int occam_check_index (int, int, const char *) occam_unused;
|
||||||
static inline int occam_check_index (int i, int limit, const char *pos) {
|
static inline int occam_check_index (int i, int limit, const char *pos) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user