Rain: added a pass to transform functions into the occam form
This commit is contained in:
parent
cd93b481f0
commit
fa405e7e46
|
@ -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
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user