diff --git a/backends/BackendPasses.hs b/backends/BackendPasses.hs index a2056ae..263f103 100644 --- a/backends/BackendPasses.hs +++ b/backends/BackendPasses.hs @@ -236,13 +236,13 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays" -- to the abbreviation source (for everything but record fields) -- or the globally declared record field _sizes constant varSrcSizes <- case innerV of - A.Variable _ srcN -> return (A.Variable m $ append_sizes srcN) + A.Variable _ srcN -> return (A.ExprVariable m $ A.Variable m $ append_sizes srcN) A.SubscriptedVariable _ (A.SubscriptField _ fieldName) recordV -> do A.Record recordName <- astTypeOf recordV - return (A.Variable m $ A.Name m $ A.nameName recordName ++ A.nameName fieldName ++ "_sizes") - A.DirectedVariable _ _ (A.Variable _ srcN) -> return (A.Variable m - $ append_sizes srcN) - _ -> diePC m $ formatCode "Cannot handle variable % in abbrevVarSizes" innerV + return (A.ExprVariable m $ A.Variable m $ A.Name m $ A.nameName recordName ++ A.nameName fieldName ++ "_sizes") + A.DirectedVariable _ _ (A.Variable _ srcN) -> return (A.ExprVariable + m $ A.Variable m $ append_sizes srcN) + _ -> return $ A.AllSizesVariable m innerV -- Get the dimensions of the source variable: innerVT <- astTypeOf innerV srcDs <- case innerVT of @@ -251,13 +251,13 @@ declareSizesArray = occamOnlyPass "Declare array-size arrays" ++ " (%) in declareSizesArray: %") innerV innerVT -- Calculate the correct subscript into the source _sizes variable to get to the dimensions for the destination: let sizeDiff = length srcDs - length ds - subSrcSizeVar = A.SubscriptedVariable m (A.SubscriptFromFor m A.NoCheck (makeConstant m sizeDiff) (makeConstant m $ length ds)) varSrcSizes + subSrcSizeVar = A.SubscriptedExpr m (A.SubscriptFromFor m A.NoCheck (makeConstant m sizeDiff) (makeConstant m $ length ds)) varSrcSizes sizeType = A.Array [makeDimension m $ length ds] A.Int sizeExpr = case sliceSize of - Just exp -> let subDims = [A.SubscriptedVariable m (A.Subscript m A.NoCheck $ makeConstant m n) varSrcSizes | n <- [1 .. (length srcDs - 1)]] in + Just exp -> let subDims = [A.SubscriptedExpr m (A.Subscript m A.NoCheck $ makeConstant m n) varSrcSizes | n <- [1 .. (length srcDs - 1)]] in A.Literal m sizeType $ A.ArrayListLiteral m $ A.Several m $ - A.Only m exp : map (A.Only m . A.ExprVariable m) subDims - Nothing -> A.ExprVariable m subSrcSizeVar + A.Only m exp : map (A.Only m) subDims + Nothing -> subSrcSizeVar sizeSpecType = A.IsExpr m A.ValAbbrev sizeType sizeExpr defineSizesName m n_sizes sizeSpecType return $ A.Specification m n_sizes sizeSpecType diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 651daf7..27e9826 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -269,7 +269,8 @@ cgenOverArray m var func case d of A.UnknownDimension -> do call genVariable var A.Original - call genSizeSuffix (show v) + t <- astTypeOf var + call genSizeSuffix m t (show v) A.Dimension n -> call genExpression n tell [";"] call genVariable i A.Original @@ -384,7 +385,8 @@ cgenBytesIn m t v = case v of Right rv -> do call genVariable rv A.Original - call genSizeSuffix (show i) + t <- astTypeOf rv + call genSizeSuffix (findMeta rv) t (show i) tell ["*"] _ -> return () @@ -797,7 +799,9 @@ cgenArraySubscript check v es genName n genName fn tell ["[", show i, "]"] - _ -> call genVariable v A.Original >> call genSizeSuffix (show i) + _ -> do call genVariable v A.Original + t <- astTypeOf v + call genSizeSuffix (findMeta v) t (show i) -- | Generate the individual offsets that need adding together to find the -- right place in the array. @@ -854,7 +858,8 @@ cgenExpression (A.MostNeg m t) = call genTypeSymbol "mostneg" t --cgenExpression (A.SizeType m t) cgenExpression (A.SizeExpr m e) = do call genExpression e - call genSizeSuffix "0" + t <- astTypeOf e + call genSizeSuffix m t "0" cgenExpression (A.SizeVariable m v) = do t <- astTypeOf v case t of @@ -864,7 +869,8 @@ cgenExpression (A.SizeVariable m v) A.UnknownDimension -> let (n, v') = countSubscripts v in do call genVariable v' A.Original - call genSizeSuffix (show n) + v't <- astTypeOf v' + call genSizeSuffix m v't (show n) A.List _ -> call genListSize v cgenExpression e@(A.AllSizesVariable m v) @@ -895,10 +901,22 @@ cgenExpression (A.BytesInType m t) = call genBytesIn m t (Left False) --cgenExpression (A.ExprConstr {}) cgenExpression (A.AllocMobile m t me) = call genAllocMobile m t me cgenExpression (A.CloneMobile m e) = call genCloneMobile m e +cgenExpression (A.SubscriptedExpr m sub (A.ExprVariable _ v)) + = call genVariable (A.SubscriptedVariable m sub v) A.Original +cgenExpression (A.SubscriptedExpr m (A.SubscriptFromFor _ _ start _) e@(A.AllSizesVariable {})) + = do tell ["(&("] + call genExpression e + tell ["["] + call genExpression start + tell ["]))"] cgenExpression t = call genMissing $ "genExpression " ++ show t -cgenSizeSuffix :: String -> CGen () -cgenSizeSuffix dim = tell ["_sizes[", dim, "]"] +cgenSizeSuffix :: Meta -> A.Type -> String -> CGen () +cgenSizeSuffix m t dim + = case t of + A.Array {} -> tell ["_sizes[", dim, "]"] + A.Mobile (A.Array {}) -> tell ["->dimensions[", dim, "]"] + _ -> diePC emptyMeta $ formatCode "Cannot produce dimensions for type: %" t cgenTypeSymbol :: String -> A.Type -> CGen () cgenTypeSymbol s t @@ -1159,7 +1177,9 @@ abbrevExpression am t@(A.Array _ _) e = case e of A.ExprVariable _ v -> call genVariable v am A.Literal _ t@(A.Array _ _) r -> call genExpression e - _ -> call genMissing "array expression abbreviation" + A.AllSizesVariable {} -> call genExpression e + A.SubscriptedExpr {} -> call genExpression e + _ -> call genMissingC $ formatCode "array expression abbreviation %" e abbrevExpression am t@(A.Record _) (A.ExprVariable _ v) = call genVariable v am abbrevExpression am _ e = call genExpression e @@ -1564,17 +1584,18 @@ cgenProcess p = case p of cgenAssign :: Meta -> [A.Variable] -> A.ExpressionList -> CGen () cgenAssign m [v] (A.ExpressionList _ [e]) = do t <- astTypeOf v + trhs <- astTypeOf e f <- fget getScalarType isMobile <- isMobileType t case f t of Just _ -> doAssign v e - Nothing -> case (t, isMobile) of + Nothing -> case (t, isMobile, trhs) of -- Assignment of channel-ends, but not channels, is possible (at least in Rain): - (A.ChanEnd A.DirInput _ _, _) -> doAssign v e - (A.ChanEnd A.DirOutput _ _, _) -> doAssign v e - (A.List _, _) -> call genListAssign v e - (A.Mobile (A.List _), _) -> call genListAssign v e - (_, True) + (A.ChanEnd A.DirInput _ _, _, _) -> doAssign v e + (A.ChanEnd A.DirOutput _ _, _, _) -> doAssign v e + (A.List _, _, _) -> call genListAssign v e + (A.Mobile (A.List _), _, _) -> call genListAssign v e + (_, True, _) -> do call genClearMobile m v case e of A.AllocMobile _ _ Nothing -> doAssign v e @@ -1588,7 +1609,7 @@ cgenAssign m [v] (A.ExpressionList _ [e]) call genVariable vrhs A.Original tell ["=NULL;"] _ -> call genMissing $ "Mobile assignment from " ++ show e - (A.Array ds innerT, _) | isPOD innerT && A.UnknownDimension `notElem` ds + (A.Array ds innerT, _, _) | isPOD innerT && A.UnknownDimension `notElem` ds -> do tell ["memcpy("] call genVariable v A.Abbrev tell [","] @@ -1596,6 +1617,14 @@ cgenAssign m [v] (A.ExpressionList _ [e]) tell [","] call genBytesIn m t (Left False) tell [");"] + (_, _, A.Array ds innerT) | isPOD innerT && A.UnknownDimension `notElem` ds + -> do tell ["memcpy("] + call genVariable v A.Abbrev + tell [","] + call genExpression e + tell [","] + call genBytesIn m trhs (Left False) + tell [");"] _ -> call genMissingC $ formatCode "assignment of type %" t where doAssign :: A.Variable -> A.Expression -> CGen () @@ -1966,6 +1995,7 @@ mobileElemType _ (A.Record n) genName n tell ["_mttype"] mobileElemType b A.Int = mobileElemType b cIntReplacement +mobileElemType b A.Bool = mobileElemType b A.Byte -- CCSP only supports NUM with MTAlloc inside arrays: mobileElemType True t = tell ["MT_MAKE_NUM(MT_NUM_", showOccam t,")"] mobileElemType False t = tell ["MT_SIMPLE|MT_MAKE_TYPE(MT_DATA)"] diff --git a/backends/GenerateCBased.hs b/backends/GenerateCBased.hs index dd6bbea..534ea6a 100644 --- a/backends/GenerateCBased.hs +++ b/backends/GenerateCBased.hs @@ -166,7 +166,7 @@ data GenOps = GenOps { genSeq :: A.Structured A.Process -> CGen (), genSimpleDyadic :: String -> A.Expression -> A.Expression -> CGen (), genSimpleMonadic :: String -> A.Expression -> CGen (), - genSizeSuffix :: String -> CGen (), + genSizeSuffix :: Meta -> A.Type -> String -> CGen (), genSpec :: forall b. A.Specification -> CGen b -> CGen b, genSpecMode :: A.SpecMode -> CGen (), -- | Generates a STOP process that uses the given Meta tag and message as its printed message. diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs index ccd09dc..b8810db 100644 --- a/backends/GenerateCPPCSP.hs +++ b/backends/GenerateCPPCSP.hs @@ -617,7 +617,7 @@ cppintroduceSpec (A.Specification _ n (A.Is _ am t@(A.Array ds c@(A.ChanEnd {})) genName n tell [","] genName n - call genSizeSuffix "0" + call genSizeSuffix m t' "0" tell [");"] --For all other cases, use the C implementation: cppintroduceSpec n = cintroduceSpec n