Added a test for genAssign in the C and C++ backends, and tweaked its implementation to pass the tests
This commit is contained in:
parent
d3fa9fb8c8
commit
38fb0baa4e
|
@ -64,7 +64,9 @@ instance Die CGen where
|
||||||
data GenOps = GenOps {
|
data GenOps = GenOps {
|
||||||
-- | Declares the C array of sizes for an occam array.
|
-- | Declares the C array of sizes for an occam array.
|
||||||
declareArraySizes :: GenOps -> [A.Dimension] -> A.Name -> CGen (),
|
declareArraySizes :: GenOps -> [A.Dimension] -> A.Name -> CGen (),
|
||||||
|
-- | Generates code when a variable goes out of scope (e.g. deallocating memory).
|
||||||
declareFree :: GenOps -> Meta -> A.Type -> A.Variable -> Maybe (CGen ()),
|
declareFree :: GenOps -> Meta -> A.Type -> A.Variable -> Maybe (CGen ()),
|
||||||
|
-- | Generates code when a variable comes into scope (e.g. allocating memory, initialising variables).
|
||||||
declareInit :: GenOps -> Meta -> A.Type -> A.Variable -> Maybe (CGen ()),
|
declareInit :: GenOps -> Meta -> A.Type -> A.Variable -> Maybe (CGen ()),
|
||||||
declareType :: GenOps -> A.Type -> CGen (),
|
declareType :: GenOps -> A.Type -> CGen (),
|
||||||
-- | Generates an individual parameter to a function\/proc.
|
-- | Generates an individual parameter to a function\/proc.
|
||||||
|
@ -83,6 +85,7 @@ data GenOps = GenOps {
|
||||||
-- | Generates an array subscript for the given variable (with error checking if the Bool is True), using the given expression list as subscripts
|
-- | Generates an array subscript for the given variable (with error checking if the Bool is True), using the given expression list as subscripts
|
||||||
genArraySubscript :: GenOps -> Bool -> A.Variable -> [A.Expression] -> CGen (),
|
genArraySubscript :: GenOps -> Bool -> A.Variable -> [A.Expression] -> CGen (),
|
||||||
genAssert :: GenOps -> Meta -> A.Expression -> CGen (),
|
genAssert :: GenOps -> Meta -> A.Expression -> CGen (),
|
||||||
|
-- | Generates an assignment statement with a single destination and single source.
|
||||||
genAssign :: GenOps -> Meta -> [A.Variable] -> A.ExpressionList -> CGen (),
|
genAssign :: GenOps -> Meta -> [A.Variable] -> A.ExpressionList -> CGen (),
|
||||||
genBytesIn :: GenOps -> A.Type -> Maybe A.Variable -> CGen (),
|
genBytesIn :: GenOps -> A.Type -> Maybe A.Variable -> CGen (),
|
||||||
genBytesIn' :: GenOps -> A.Type -> Maybe A.Variable -> CGen (Maybe Int),
|
genBytesIn' :: GenOps -> A.Type -> Maybe A.Variable -> CGen (Maybe Int),
|
||||||
|
@ -1480,22 +1483,24 @@ cgenProcess ops p = case p of
|
||||||
|
|
||||||
--{{{ assignment
|
--{{{ assignment
|
||||||
cgenAssign :: GenOps -> Meta -> [A.Variable] -> A.ExpressionList -> CGen ()
|
cgenAssign :: GenOps -> Meta -> [A.Variable] -> A.ExpressionList -> CGen ()
|
||||||
cgenAssign ops m [v] el
|
cgenAssign ops m [v] (A.ExpressionList _ [e])
|
||||||
= case el of
|
= do t <- typeOfVariable v
|
||||||
A.FunctionCallList _ _ _ -> call genMissing ops "function call"
|
case call getScalarType ops t of
|
||||||
A.ExpressionList _ [e] ->
|
Just _ -> doAssign v e
|
||||||
do t <- typeOfVariable v
|
Nothing -> case t of
|
||||||
doAssign t v e
|
-- Assignment of channel-ends, but not channels, is possible (at least in Rain):
|
||||||
|
A.Chan A.DirInput _ _ -> doAssign v e
|
||||||
|
A.Chan A.DirOutput _ _ -> doAssign v e
|
||||||
|
_ -> call genMissingC ops $ formatCode "assignment of type %" t
|
||||||
where
|
where
|
||||||
doAssign :: A.Type -> A.Variable -> A.Expression -> CGen ()
|
doAssign :: A.Variable -> A.Expression -> CGen ()
|
||||||
doAssign t v e
|
doAssign v e
|
||||||
= case call getScalarType ops t of
|
= do call genVariable ops v
|
||||||
Just _ ->
|
tell ["="]
|
||||||
do call genVariable ops v
|
call genExpression ops e
|
||||||
tell [" = "]
|
tell [";"]
|
||||||
call genExpression ops e
|
cgenAssign ops m _ _ = call genMissing ops "Cannot perform assignment with multiple destinations or multiple sources"
|
||||||
tell [";\n"]
|
|
||||||
Nothing -> call genMissingC ops $ formatCode "assignment of type %" t
|
|
||||||
--}}}
|
--}}}
|
||||||
--{{{ input
|
--{{{ input
|
||||||
cgenInput :: GenOps -> A.Variable -> A.InputMode -> CGen ()
|
cgenInput :: GenOps -> A.Variable -> A.InputMode -> CGen ()
|
||||||
|
|
|
@ -498,6 +498,31 @@ testGenVariable = TestList
|
||||||
testSameA2 :: Int -> (String,String) -> (A.Variable -> A.Variable) -> A.Type -> Test
|
testSameA2 :: Int -> (String,String) -> (A.Variable -> A.Variable) -> A.Type -> Test
|
||||||
testSameA2 n (eO,eA) sub t = TestList [testSame n eO sub A.Original t,testSame (n+1) eA sub A.Abbrev t]
|
testSameA2 n (eO,eA) sub t = TestList [testSame n eO sub A.Original t,testSame (n+1) eA sub A.Abbrev t]
|
||||||
|
|
||||||
|
testAssign :: Test
|
||||||
|
testAssign = TestList
|
||||||
|
[
|
||||||
|
testBothSameS "testAssign 0" "@=$;" ((tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e])) . over) (state A.Int)
|
||||||
|
,testBothSameS "testAssign 1" "@=$;" ((tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e])) . over) (state A.Time)
|
||||||
|
,testBothSameS "testAssign 2" "@=$;" ((tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e])) . over)
|
||||||
|
(state $ A.Chan A.DirInput (A.ChanAttributes False False) A.Int)
|
||||||
|
|
||||||
|
-- Fail because genAssign only handles one destination and one source:
|
||||||
|
,testBothFail "testAssign 100" (tcall3 genAssign emptyMeta [A.Variable emptyMeta foo,A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e]))
|
||||||
|
,testBothFail "testAssign 101" (tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e,e]))
|
||||||
|
,testBothFail "testAssign 102" (tcall3 genAssign emptyMeta [A.Variable emptyMeta foo,A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e, e]))
|
||||||
|
|
||||||
|
-- Fail because assignment can't be done with these types (should have already been transformed away):
|
||||||
|
,testBothFailS "testAssign 200" ((tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e])) . over)
|
||||||
|
(state $ A.Chan A.DirUnknown (A.ChanAttributes False False) A.Int)
|
||||||
|
,testBothFailS "testAssign 201" ((tcall3 genAssign emptyMeta [A.Variable emptyMeta foo] (A.ExpressionList emptyMeta [e])) . over)
|
||||||
|
(state $ A.Record bar)
|
||||||
|
]
|
||||||
|
where
|
||||||
|
--The expression won't be examined so we can use what we like:
|
||||||
|
e = A.True emptyMeta
|
||||||
|
state t = defineName (simpleName "foo") $ simpleDefDecl "foo" t
|
||||||
|
over ops = ops {genVariable = override1 at, genExpression = override1 dollar}
|
||||||
|
|
||||||
---Returns the list of tests:
|
---Returns the list of tests:
|
||||||
tests :: Test
|
tests :: Test
|
||||||
tests = TestList
|
tests = TestList
|
||||||
|
@ -505,6 +530,7 @@ tests = TestList
|
||||||
testActuals
|
testActuals
|
||||||
,testArraySizes
|
,testArraySizes
|
||||||
,testArraySubscript
|
,testArraySubscript
|
||||||
|
,testAssign
|
||||||
,testDeclaration
|
,testDeclaration
|
||||||
,testDeclareInitFree
|
,testDeclareInitFree
|
||||||
,testGenType
|
,testGenType
|
||||||
|
|
Loading…
Reference in New Issue
Block a user