Added a pass that transforms array constructors into a replicated loop that initialises the array

This commit is contained in:
Neil Brown 2007-08-29 14:18:07 +00:00
parent 1c155490c5
commit e655c1412a
2 changed files with 48 additions and 0 deletions

View File

@ -200,6 +200,27 @@ testIsSafeConversion = TestList $ map runTestRow resultsWithIndexes
,[t, t,t,t,f, t,t,t,t,t] --to Int64
]
skipP :: A.Structured
skipP = A.OnlyP m (A.Skip m)
-- | Tests that a simple constructor (with no expression, nor function call) gets converted into the appropriate initialisation code
testTransformConstr0 :: Test
testTransformConstr0 = testPass "transformConstr0" exp (transformConstr orig) (return ())
where
orig = A.Spec m (A.Specification m (simpleName "arr") $ A.IsExpr m A.ValAbbrev (A.Array [A.Dimension 10] A.Int) $ A.ExprConstr m $
A.RepConstr m (A.For m (simpleName "x") (intLiteral 0) (intLiteral 10)) (exprVariable "x")
) skipP
exp = nameAndStopCaringPattern "indexVar" "i" $ mkPattern exp'
exp' = A.Spec m (A.Specification m (simpleName "arr") (A.Declaration m (A.Array [A.Dimension 10] A.Int))) $
A.ProcThen m
(A.Seq m $ A.Spec m (A.Specification m (simpleName "i") (A.Declaration m A.Int)) $
A.Several m [A.OnlyP m $ A.Assign m [variable "i"] $ A.ExpressionList m [intLiteral 0],
A.Rep m (A.For m (simpleName "x") (intLiteral 0) (intLiteral 10)) $ A.OnlyP m $ A.Seq m $ A.Several m
[A.OnlyP m $ A.Assign m [A.SubscriptedVariable m (A.Subscript m $ exprVariable "i") (variable "arr")] $ A.ExpressionList m [exprVariable "x"],
A.OnlyP m $ A.Assign m [variable "i"] $ A.ExpressionList m [A.Dyadic m A.Plus (exprVariable "i") (intLiteral 1)]]
]
)
skipP
--Returns the list of tests:
@ -210,6 +231,7 @@ tests = TestList
,testFunctionsToProcs1
,testFunctionsToProcs2
,testIsSafeConversion
,testTransformConstr0
]

View File

@ -39,6 +39,7 @@ simplifyExprs = runPasses passes
, ("Convert AFTER to MINUS", removeAfter)
, ("Expand array literals", expandArrayLiterals)
, ("Pull up definitions", pullUp)
, ("Transform array constructors into initialisation code", transformConstr)
]
-- | Convert FUNCTION declarations to PROCs.
@ -119,6 +120,31 @@ expandArrayLiterals = doGeneric `extM` doArrayElem
= liftM A.ArrayElemArray $ sequence [expand ds (A.SubscriptedExpr m (A.Subscript m $ makeConstant m i) e) | i <- [0 .. (n - 1)]]
where m = findMeta e
transformConstr :: Data t => t -> PassM t
transformConstr = doGeneric `extM` doStructured
where
doGeneric :: Data t => t -> PassM t
doGeneric = makeGeneric transformConstr
doStructured :: A.Structured -> PassM A.Structured
doStructured (A.Spec m (A.Specification m' n (A.IsExpr _ _ t (A.ExprConstr m'' (A.RepConstr _ rep exp)))) scope)
= do indexVarSpec@(A.Specification _ indexVar _) <- makeNonceVariable "array_constr_index" m'' A.Int A.VariableName A.Original
scope' <- doGeneric scope
return $ A.Spec m (A.Specification m' n (A.Declaration m' t)) $ A.ProcThen m''
(A.Seq m'' $ A.Spec m'' (indexVarSpec) $ A.Several m'' [
A.OnlyP m'' $ A.Assign m'' [A.Variable m'' indexVar] $ A.ExpressionList m'' [A.Literal m'' A.Int $ A.IntLiteral m'' "0"],
A.Rep m'' rep $ A.OnlyP m'' $ A.Seq m'' $ A.Several m''
[A.OnlyP m'' $ A.Assign m''
[A.SubscriptedVariable m'' (A.Subscript m'' $ A.ExprVariable m'' $ A.Variable m'' indexVar) $ A.Variable m'' n]
$ A.ExpressionList m'' [exp]
,A.OnlyP m'' $ A.Assign m'' [A.Variable m'' indexVar] $ A.ExpressionList m'' [A.Dyadic m'' A.Plus
(A.ExprVariable m'' $ A.Variable m'' indexVar)
(A.Literal m'' A.Int $ A.IntLiteral m'' "1")]
]
])
scope'
doStructured s = doGeneric s
-- | Find things that need to be moved up to their enclosing Structured, and do
-- so.
pullUp :: Data t => t -> PassM t