diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 979e2d7..e63d759 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -715,33 +715,7 @@ cgenVariableWithAM checkValid v am fct wholeT <- astTypeOf wholeV ct <- call getCType m wholeT A.Original return (call genDirectedVariable m t cg' dir, ct) - inner (A.VariableSizes m (A.Variable _ n)) - = do t <- astTypeOf n - f <- fget getScalarType - let Just intT = f A.Int - case t of - A.Mobile (A.Array {}) - -> return (do call genVariable v A.Original - tell ["->dimensions"] - , Pointer $ Plain intT) - A.Array {} - -> do ss <- getCompState >>* csArraySizes - case Map.lookup (A.nameName n) ss of - Just n_sizes -> return (genName n_sizes - ,Pointer $ Plain intT) - Nothing -> - dieP m $ "No sizes for " ++ A.nameName n - ++ " -- full list: " ++ show (Map.keys ss) - inner (A.VariableSizes m v@(A.SubscriptedVariable {})) - = do (es, innerV, _) <- collectSubs v - case innerV of - plainV@(A.Variable {}) -> - do (gen, ct) <- inner (A.VariableSizes m plainV) - return (do tell ["("] - gen - tell ["+", show (length es),")"] - ,ct) - _ -> diePC m $ formatCode "Cannot handle complex sizes expression %" v + inner (A.VariableSizes m v) = sizes m v inner sv@(A.SubscriptedVariable m sub v) = case sub of A.Subscript _ subCheck _ @@ -797,6 +771,44 @@ cgenVariableWithAM checkValid v am fct )] tell ["))"] , ct) + + sizes :: Meta -> A.Variable -> CGen (CGen (), CType) + sizes m v + = do t <- astTypeOf v + f <- fget getScalarType + let Just intT = f A.Int + case (t, v) of + -- For the size of dereferenced arrays, we use the size of the mobile: + (A.Array {}, A.DerefVariable m' innerV) + -> sizes m innerV + -- For mobile arrays, we just need to use the dimensions member: + (A.Mobile (A.Array {}), _) + -> return (do tell ["("] + cgenVariableWithAM checkValid v A.Original + (const $ Plain "mt_array_t") + tell [").dimensions"] + , Pointer $ Plain intT) + (A.Array {}, A.Variable _ n) + -> do ss <- getCompState >>* csArraySizes + case Map.lookup (A.nameName n) ss of + Just n_sizes -> return (genName n_sizes + ,Pointer $ Plain intT) + Nothing -> + dieP m $ "No sizes for " ++ A.nameName n + ++ " -- full list: " ++ show (Map.keys ss) + (A.Array {}, A.SubscriptedVariable {}) + -> do (es, innerV, _) <- collectSubs v + case innerV of + plainV@(A.Variable {}) -> + do (gen, ct) <- inner (A.VariableSizes m plainV) + return (do tell ["("] + gen + tell ["+", show (length es),")"] + ,ct) + _ -> diePC m $ formatCode "Cannot handle complex sizes expression %" v + _ -> diePC m $ formatCode "Cannot handle complex sizes expression %" v + + -- | Collect all the plain subscripts on a variable, so we can combine them. collectSubs :: A.Variable -> CGen ([A.Expression], A.Variable, A.Type) collectSubs (A.SubscriptedVariable m (A.Subscript _ _ e) v)