Added a pass that transforms array constructors into a replicated loop that initialises the array
This commit is contained in:
parent
1c155490c5
commit
e655c1412a
22
PassTest.hs
22
PassTest.hs
|
@ -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
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user