From 4fadab442d6642bd321ba59ec12ec5aec5be6e30 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sat, 1 Sep 2007 14:40:50 +0000 Subject: [PATCH] Rain: added a pass to turn range constructors into the more general array constructor form --- RainPassTest.hs | 18 ++++++++++++++++++ RainPasses.hs | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/RainPassTest.hs b/RainPassTest.hs index 12a37cc..07b82ad 100644 --- a/RainPassTest.hs +++ b/RainPassTest.hs @@ -440,6 +440,22 @@ testParamPass8 = testPassShouldFail "testParamPass6" (matchParamPass orig) (star --TODO test passing in channel ends +-- | Transform an example list +testRangeRepPass0 :: Test +testRangeRepPass0 = testPass "testRangeRepPass0" exp (transformRangeRep orig) (return()) + where + orig = A.ExprConstr m $ A.RangeConstr m (intLiteral 0) (intLiteral 1) + exp = tag2 A.ExprConstr DontCare $ tag3 A.RepConstr DontCare (tag4 A.For DontCare (Named "repIndex" DontCare) (intLiteral 0) (intLiteral 2)) + (tag2 A.ExprVariable DontCare $ tag2 A.Variable DontCare $ Named "repIndex" DontCare) + +-- | Lists with negative counts should be turned into an empty literal list +testRangeRepPass1 :: Test +testRangeRepPass1 = testPass "testRangeRepPass1" exp (transformRangeRep orig) (return()) + where + orig = A.ExprConstr m $ A.RangeConstr m (intLiteral 1) (intLiteral 0) + exp = A.Literal m (A.Array [A.Dimension 0] A.Int) $ A.ArrayLiteral m [] + + ---Returns the list of tests: tests :: Test tests = TestList @@ -472,6 +488,8 @@ tests = TestList ,testParamPass6 ,testParamPass7 ,testParamPass8 + ,testRangeRepPass0 + ,testRangeRepPass1 ] diff --git a/RainPasses.hs b/RainPasses.hs index 4b03664..11d41ec 100644 --- a/RainPasses.hs +++ b/RainPasses.hs @@ -45,6 +45,8 @@ rainPasses = --depends on uniquifyAndResolveVars and recordInfNameTypes ,("Convert seqeach/pareach loops into classic replicated SEQ/PAR",transformEach) --depends on uniquifyAndResolveVars and recordInfNameTypes, and should be done after transformEachRange + ,("Convert simple Rain range constructors into more general array constructors",transformRangeRep) + --must be done after transformEachRange ] -- | A pass that transforms all instances of 'A.Int' into 'A.Int64' @@ -255,3 +257,26 @@ transformEach = everywhereM (mkM transformEach') s return (spec (A.Rep m newRep s')) transformEach' s = return s + +-- | A pass that changes all the Rain range constructor expressions into the more general array constructor expressions +transformRangeRep :: Data t => t -> PassM t +transformRangeRep = everywhereM (mkM transformRangeRep') + where + transformRangeRep' :: A.Expression -> PassM A.Expression + transformRangeRep' (A.ExprConstr _ (A.RangeConstr m (A.Literal _ _ beginLit) (A.Literal _ _ endLit))) + = if (isJust $ checkIntegral beginLit) && (isJust $ checkIntegral endLit) + then transformRangeRep'' m (fromJust $ checkIntegral beginLit) (fromJust $ checkIntegral endLit) + else dieP m "Items in range constructor (x..y) are not integer literals" + where + transformRangeRep'' :: Meta -> Integer -> Integer -> PassM A.Expression + transformRangeRep'' m begin end + = if (end < begin) + then return $ A.Literal m (A.Array [A.Dimension 0] A.Int) $ A.ArrayLiteral m [] + else do A.Specification _ rep _ <- makeNonceVariable "rep_constr" m A.Int A.VariableName A.ValAbbrev + let count = end - begin + 1 + return $ A.ExprConstr m $ A.RepConstr m + (A.For m rep + (A.Literal m A.Int (A.IntLiteral m $ show begin)) + (A.Literal m A.Int (A.IntLiteral m $ show count)) + ) (A.ExprVariable m $ A.Variable m rep) + transformRangeRep' s = return s