Rain: added a pass to transform functions into the occam form

This commit is contained in:
Neil Brown 2007-09-02 16:50:12 +00:00
parent cd93b481f0
commit fa405e7e46
2 changed files with 43 additions and 0 deletions

View File

@ -472,6 +472,27 @@ testRangeRepPass1 = testPass "testRangeRepPass1" exp (transformRangeRep orig) (r
orig = A.ExprConstr m $ A.RangeConstr m (intLiteral 1) (intLiteral 0) 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 [] exp = A.Literal m (A.Array [A.Dimension 0] A.Int) $ A.ArrayLiteral m []
--TODO consider/test pulling up the definitions of variables involved in return statements in functions
-- | Test a fairly standard function:
testTransformFunction0 :: Test
testTransformFunction0 = testPass "testTransformFunction0" exp (transformFunction orig) (return ())
where
orig = A.Specification m (procName "id") $
A.Function m A.PlainSpec [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")] $
(A.OnlyP m $ A.Seq m $ A.Several m [A.OnlyEL m $ A.ExpressionList m [exprVariable "x"]])
exp = tag3 A.Specification DontCare (procNamePattern "id") $
tag5 A.Function DontCare A.PlainSpec [A.Byte] [tag3 A.Formal A.ValAbbrev A.Byte (simpleNamePattern "x")] $
tag3 A.ProcThen DontCare (tag2 A.Seq DontCare $ tag2 A.Several DontCare ([] :: [A.Structured])) $
tag2 A.OnlyEL DontCare $ tag2 A.ExpressionList DontCare [exprVariablePattern "x"]
-- | Test a function without a return as the final statement:
testTransformFunction1 :: Test
testTransformFunction1 = testPassShouldFail "testTransformFunction1" (transformFunction orig) (return ())
where
orig = A.Specification m (procName "brokenid") $
A.Function m A.PlainSpec [A.Byte] [A.Formal A.ValAbbrev A.Byte (simpleName "x")] $
(A.OnlyP m $ A.Seq m $ A.Several m [])
---Returns the list of tests: ---Returns the list of tests:
tests :: Test tests :: Test
@ -507,6 +528,8 @@ tests = TestList
,testParamPass8 ,testParamPass8
,testRangeRepPass0 ,testRangeRepPass0
,testRangeRepPass1 ,testRangeRepPass1
,testTransformFunction0
,testTransformFunction1
] ]

View File

@ -47,6 +47,8 @@ rainPasses =
--depends on uniquifyAndResolveVars and recordInfNameTypes, and should be done after transformEachRange --depends on uniquifyAndResolveVars and recordInfNameTypes, and should be done after transformEachRange
,("Convert simple Rain range constructors into more general array constructors",transformRangeRep) ,("Convert simple Rain range constructors into more general array constructors",transformRangeRep)
--must be done after transformEachRange --must be done after transformEachRange
,("Transform Rain functions into the occam form",transformFunction)
--must be done after transformEach, depends on uniquifyAndResolveVars and recordInfNameTypes
] ]
-- | A pass that transforms all instances of 'A.Int' into 'A.Int64' -- | A pass that transforms all instances of 'A.Int' into 'A.Int64'
@ -301,3 +303,21 @@ transformRangeRep = everywhereM (mkM transformRangeRep')
(A.Literal m A.Int (A.IntLiteral m $ show count)) (A.Literal m A.Int (A.IntLiteral m $ show count))
) (A.ExprVariable m $ A.Variable m rep) ) (A.ExprVariable m $ A.Variable m rep)
transformRangeRep' s = return s transformRangeRep' s = return s
transformFunction :: Data t => t -> PassM t
transformFunction = everywhereM (mkM transformFunction')
where
transformFunction' :: A.SpecType -> PassM A.SpecType
transformFunction' (A.Function m specMode types params body)
= case body of
(A.OnlyP _ (A.Seq m' (A.Several m'' statements))) ->
if (null statements)
then dieP m "Functions must not have empty bodies"
else case (last statements) of
ret@(A.OnlyEL {}) -> return $
(A.Function m specMode types params
(A.ProcThen m' (A.Seq m' (A.Several m'' (init statements))) ret)
)
_ -> dieP m "Functions must have a return statement as their last statement"
_ -> dieP m "Functions must have seq[uential] bodies"
transformFunction' s = return s