Re-added the index checking for array slices in the backend

This commit is contained in:
Neil Brown 2008-03-09 16:19:01 +00:00
parent 3d1945b517
commit 0265063250
3 changed files with 26 additions and 24 deletions

View File

@ -692,7 +692,8 @@ cgenVariable' checkValid v
A.Array ds _ <- typeOfVariable v
(cg, n) <- inner ind v (Just t)
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
= do (cg, ind') <- inner ind v mt
t <- typeOfVariable sv
@ -700,21 +701,22 @@ cgenVariable' checkValid v
outerInd = if indirectedType t then -1 else 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 _) v) mt
inner ind sv@(A.SubscriptedVariable m (A.SubscriptFromFor m' start count) v) mt
= return (
do tell ["(&"]
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)
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 cg 0 = cg
@ -743,7 +745,7 @@ indirectedType _ = False
cgenDirectedVariable :: CGen () -> A.Direction -> CGen ()
cgenDirectedVariable var _ = var
cgenArraySubscript :: A.SubscriptCheck -> A.Variable -> [A.Expression] -> CGen ()
cgenArraySubscript :: A.SubscriptCheck -> A.Variable -> [(Meta, CGen ())] -> CGen ()
cgenArraySubscript check v es
= do t <- typeOfVariable v
let numDims = case t of A.Array ds _ -> length ds
@ -758,36 +760,36 @@ cgenArraySubscript check v es
-- right place in the array.
-- 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...
genPlainSub :: (Int -> CGen ()) -> [A.Expression] -> [Int] -> [CGen ()]
genPlainSub :: (Int -> CGen ()) -> [(Meta, CGen ())] -> [Int] -> [CGen ()]
genPlainSub _ [] _ = []
genPlainSub genDim (e:es) (sub:subs)
genPlainSub genDim ((m,e):es) (sub:subs)
= gen : genPlainSub genDim es subs
where
gen = sequence_ $ intersperse (tell ["*"]) $ genSub : genChunks
genSub
= case check of
A.NoCheck -> call genExpression e
A.NoCheck -> e
A.CheckBoth ->
do tell ["occam_check_index("]
call genExpression e
e
tell [","]
genDim sub
tell [","]
genMeta (findMeta e)
genMeta m
tell [")"]
A.CheckUpper ->
do tell ["occam_check_index_upper("]
call genExpression e
e
tell [","]
genDim sub
tell [","]
genMeta (findMeta e)
genMeta m
tell [")"]
A.CheckLower ->
do tell ["occam_check_index_lower("]
call genExpression e
e
tell [","]
genMeta (findMeta e)
genMeta m
tell [")"]
genChunks = map genDim subs
--}}}

View File

@ -101,7 +101,7 @@ data GenOps = GenOps {
-- | Writes out the actual data storage array name.
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
genArraySubscript :: A.SubscriptCheck -> A.Variable -> [A.Expression] -> CGen (),
genArraySubscript :: A.SubscriptCheck -> A.Variable -> [(Meta, CGen ())] -> CGen (),
genAssert :: Meta -> A.Expression -> CGen (),
-- | Generates an assignment statement with a single destination and single source.
genAssign :: Meta -> [A.Variable] -> A.ExpressionList -> CGen (),

View File

@ -66,7 +66,7 @@ static inline int occam_check_slice (int start, int count, int limit, const char
|| count < 0)) {
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 i, int limit, const char *pos) {