diff --git a/PassTest.hs b/PassTest.hs index 42ecf3a..64e2aad 100644 --- a/PassTest.hs +++ b/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 ] diff --git a/SimplifyExprs.hs b/SimplifyExprs.hs index 896c1c4..9508afa 100644 --- a/SimplifyExprs.hs +++ b/SimplifyExprs.hs @@ -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