Added the input-case to case pass to the pass-list, and therefore removed all code dealing with input-case statements in the C and C++ backends (and corresponding tests)
This commit is contained in:
parent
d98cb21415
commit
e9dbfbab3c
|
@ -114,7 +114,6 @@ data GenOps = GenOps {
|
||||||
-- | Generates an IF statement (which can have replicators, specifications and such things inside it).
|
-- | Generates an IF statement (which can have replicators, specifications and such things inside it).
|
||||||
genIf :: GenOps -> Meta -> A.Structured -> CGen (),
|
genIf :: GenOps -> Meta -> A.Structured -> CGen (),
|
||||||
genInput :: GenOps -> A.Variable -> A.InputMode -> CGen (),
|
genInput :: GenOps -> A.Variable -> A.InputMode -> CGen (),
|
||||||
genInputCase :: GenOps -> Meta -> A.Variable -> A.Structured -> CGen (),
|
|
||||||
genInputItem :: GenOps -> A.Variable -> A.InputItem -> CGen (),
|
genInputItem :: GenOps -> A.Variable -> A.InputItem -> CGen (),
|
||||||
genIntrinsicFunction :: GenOps -> Meta -> String -> [A.Expression] -> CGen (),
|
genIntrinsicFunction :: GenOps -> Meta -> String -> [A.Expression] -> CGen (),
|
||||||
genIntrinsicProc :: GenOps -> Meta -> String -> [A.Actual] -> CGen (),
|
genIntrinsicProc :: GenOps -> Meta -> String -> [A.Actual] -> CGen (),
|
||||||
|
@ -212,7 +211,6 @@ cgenOps = GenOps {
|
||||||
genGetTime = cgenGetTime,
|
genGetTime = cgenGetTime,
|
||||||
genIf = cgenIf,
|
genIf = cgenIf,
|
||||||
genInput = cgenInput,
|
genInput = cgenInput,
|
||||||
genInputCase = cgenInputCase,
|
|
||||||
genInputItem = cgenInputItem,
|
genInputItem = cgenInputItem,
|
||||||
genIntrinsicFunction = cgenIntrinsicFunction,
|
genIntrinsicFunction = cgenIntrinsicFunction,
|
||||||
genIntrinsicProc = cgenIntrinsicProc,
|
genIntrinsicProc = cgenIntrinsicProc,
|
||||||
|
@ -1530,44 +1528,8 @@ cgenInput ops c im
|
||||||
A.InputTimerRead m (A.InVariable m' v) -> call genTimerRead ops c v
|
A.InputTimerRead m (A.InVariable m' v) -> call genTimerRead ops c v
|
||||||
A.InputTimerAfter m e -> call genTimerWait ops e
|
A.InputTimerAfter m e -> call genTimerWait ops e
|
||||||
A.InputSimple m is -> sequence_ $ map (call genInputItem ops c) is
|
A.InputSimple m is -> sequence_ $ map (call genInputItem ops c) is
|
||||||
A.InputCase m s -> call genInputCase ops m c s
|
|
||||||
_ -> call genMissing ops $ "genInput " ++ show im
|
_ -> call genMissing ops $ "genInput " ++ show im
|
||||||
|
|
||||||
cgenInputCase :: GenOps -> Meta -> A.Variable -> A.Structured -> CGen ()
|
|
||||||
cgenInputCase ops m c s
|
|
||||||
= do t <- typeOfVariable c
|
|
||||||
let proto = case t of A.Chan _ _ (A.UserProtocol n) -> n
|
|
||||||
tag <- makeNonce "case_tag"
|
|
||||||
genName proto
|
|
||||||
tell [" ", tag, ";\n"]
|
|
||||||
tell ["ChanInInt ("]
|
|
||||||
call genVariable ops c
|
|
||||||
tell [", &", tag, ");\n"]
|
|
||||||
tell ["switch (", tag, ") {\n"]
|
|
||||||
genInputCaseBody proto c (return ()) s
|
|
||||||
tell ["default:\n"]
|
|
||||||
call genStop ops m "unhandled variant in CASE input"
|
|
||||||
tell ["}\n"]
|
|
||||||
where
|
|
||||||
-- This handles specs in a slightly odd way, because we can't insert specs into
|
|
||||||
-- the body of a switch.
|
|
||||||
genInputCaseBody :: A.Name -> A.Variable -> CGen () -> A.Structured -> CGen ()
|
|
||||||
genInputCaseBody proto c coll (A.Spec _ spec s)
|
|
||||||
= genInputCaseBody proto c (call genSpec ops spec coll) s
|
|
||||||
genInputCaseBody proto c coll (A.OnlyV _ (A.Variant _ n iis p))
|
|
||||||
= do tell ["case "]
|
|
||||||
genName n
|
|
||||||
tell ["_"]
|
|
||||||
genName proto
|
|
||||||
tell [": {\n"]
|
|
||||||
coll
|
|
||||||
sequence_ $ map (call genInputItem ops c) iis
|
|
||||||
call genProcess ops p
|
|
||||||
tell ["break;\n"]
|
|
||||||
tell ["}\n"]
|
|
||||||
genInputCaseBody proto c coll (A.Several _ ss)
|
|
||||||
= sequence_ $ map (genInputCaseBody proto c coll) ss
|
|
||||||
|
|
||||||
cgenTimerRead :: GenOps -> A.Variable -> A.Variable -> CGen ()
|
cgenTimerRead :: GenOps -> A.Variable -> A.Variable -> CGen ()
|
||||||
cgenTimerRead ops c v
|
cgenTimerRead ops c v
|
||||||
= do tell ["ProcTime (&"]
|
= do tell ["ProcTime (&"]
|
||||||
|
@ -1660,7 +1622,6 @@ cgenCase ops m e s
|
||||||
call genStop ops m "no option matched in CASE process"
|
call genStop ops m "no option matched in CASE process"
|
||||||
tell ["}"]
|
tell ["}"]
|
||||||
where
|
where
|
||||||
-- FIXME -- can this be made common with genInputCaseBody above?
|
|
||||||
genCaseBody :: CGen () -> A.Structured -> CGen Bool
|
genCaseBody :: CGen () -> A.Structured -> CGen Bool
|
||||||
genCaseBody coll (A.Spec _ spec s)
|
genCaseBody coll (A.Spec _ spec s)
|
||||||
= genCaseBody (call genSpec ops spec coll) s
|
= genCaseBody (call genSpec ops spec coll) s
|
||||||
|
|
|
@ -107,7 +107,6 @@ cppgenOps = cgenOps {
|
||||||
genForwardDeclaration = cppgenForwardDeclaration,
|
genForwardDeclaration = cppgenForwardDeclaration,
|
||||||
genGetTime = cppgenGetTime,
|
genGetTime = cppgenGetTime,
|
||||||
genIf = cppgenIf,
|
genIf = cppgenIf,
|
||||||
genInputCase = cppgenInputCase,
|
|
||||||
genInputItem = cppgenInputItem,
|
genInputItem = cppgenInputItem,
|
||||||
genOutputCase = cppgenOutputCase,
|
genOutputCase = cppgenOutputCase,
|
||||||
genOutputItem = cppgenOutputItem,
|
genOutputItem = cppgenOutputItem,
|
||||||
|
@ -199,65 +198,9 @@ cppgenInput ops c im
|
||||||
= do case im of
|
= do case im of
|
||||||
A.InputTimerRead m (A.InVariable m' v) -> call genTimerRead ops c v
|
A.InputTimerRead m (A.InVariable m' v) -> call genTimerRead ops c v
|
||||||
A.InputTimerAfter m e -> call genTimerWait ops e
|
A.InputTimerAfter m e -> call genTimerWait ops e
|
||||||
A.InputSimple m is ->
|
A.InputSimple m is -> mapM_ (call genInputItem ops c) is
|
||||||
do t <- typeOfVariable c
|
|
||||||
case t of
|
|
||||||
A.Chan _ _ (A.UserProtocol innerType) ->
|
|
||||||
--We read from the channel into a temporary var, then deal with the var afterwards
|
|
||||||
do inputVar <- makeNonce "proto_var"
|
|
||||||
genProtocolName innerType
|
|
||||||
tell [" ",inputVar, " ; "]
|
|
||||||
genCPPCSPChannelInput ops c
|
|
||||||
tell [" >> ",inputVar," ; "]
|
|
||||||
cases <- casesOfProtocol innerType
|
|
||||||
genInputTupleAssign ops ((length cases) /= 0) inputVar is
|
|
||||||
_ -> sequence_ $ map (call genInputItem ops c) is
|
|
||||||
A.InputCase m s -> call genInputCase ops m c s
|
|
||||||
_ -> call genMissing ops $ "genInput " ++ show im
|
_ -> call genMissing ops $ "genInput " ++ show im
|
||||||
|
|
||||||
cppgenInputCase :: GenOps -> Meta -> A.Variable -> A.Structured -> CGen ()
|
|
||||||
cppgenInputCase ops m c s
|
|
||||||
= do t <- typeOfVariable c
|
|
||||||
--We have to do complex things with the which() function of the variant (which may be a chained variant)
|
|
||||||
--to actually get the real index of the item we have received.
|
|
||||||
let proto = case t of A.Chan _ _ (A.UserProtocol n) -> n
|
|
||||||
tag <- makeNonce "case_tag"
|
|
||||||
which <- makeNonce "which_val"
|
|
||||||
genProtocolName proto
|
|
||||||
tell [" ", tag, " ; "]
|
|
||||||
tell ["unsigned ", which, " ; "]
|
|
||||||
genCPPCSPChannelInput ops c
|
|
||||||
tell [" >> ", tag, " ; "]
|
|
||||||
whichExpr proto which tag 0 (genProtocolName proto)
|
|
||||||
tell [" switch ( ", which, " ) { "]
|
|
||||||
genInputCaseBody proto tag (return ()) s
|
|
||||||
tell ["default:"]
|
|
||||||
call genStop ops m "unhandled variant in CASE input"
|
|
||||||
tell [" } "]
|
|
||||||
where
|
|
||||||
-- This handles specs in a slightly odd way, because we can't insert specs into
|
|
||||||
-- the body of a switch.
|
|
||||||
genInputCaseBody :: A.Name -> String -> CGen () -> A.Structured -> CGen ()
|
|
||||||
genInputCaseBody proto var coll (A.Spec _ spec s)
|
|
||||||
= genInputCaseBody proto var (call genSpec ops spec coll) s
|
|
||||||
genInputCaseBody proto var coll (A.OnlyV _ (A.Variant _ n iis p))
|
|
||||||
= do protoType <- specTypeOfName proto
|
|
||||||
tell ["case ",show (index protoType)," : {"]
|
|
||||||
coll
|
|
||||||
case iis of
|
|
||||||
[] -> return()
|
|
||||||
_ ->
|
|
||||||
do caseVar <- genVariantGet proto n var (genProtocolName proto)
|
|
||||||
genInputTupleAssign ops True caseVar iis
|
|
||||||
call genProcess ops p
|
|
||||||
tell ["break;\n"]
|
|
||||||
tell ["}\n"]
|
|
||||||
where
|
|
||||||
typeList protoType = case protoType of A.ProtocolCase _ types -> types
|
|
||||||
index protoType = indexOfTag (typeList protoType) n
|
|
||||||
genInputCaseBody proto var coll (A.Several _ ss)
|
|
||||||
= sequence_ $ map (genInputCaseBody proto var coll) ss
|
|
||||||
|
|
||||||
-- | This function processes (potentially chained) variants to get the real index of the data item inside the variant
|
-- | This function processes (potentially chained) variants to get the real index of the data item inside the variant
|
||||||
whichExpr :: A.Name -> String -> String -> Int -> CGen() -> CGen()
|
whichExpr :: A.Name -> String -> String -> Int -> CGen() -> CGen()
|
||||||
whichExpr proto which variant offset protoGen
|
whichExpr proto which variant offset protoGen
|
||||||
|
|
|
@ -835,7 +835,6 @@ testInput = TestList
|
||||||
testBothSame "testInput 0" "" ((tcall2 genInput undefined $ A.InputSimple undefined []) . overInputItemCase)
|
testBothSame "testInput 0" "" ((tcall2 genInput undefined $ A.InputSimple undefined []) . overInputItemCase)
|
||||||
,testBothSame "testInput 1" "^" ((tcall2 genInput undefined $ A.InputSimple undefined [undefined]) . overInputItemCase)
|
,testBothSame "testInput 1" "^" ((tcall2 genInput undefined $ A.InputSimple undefined [undefined]) . overInputItemCase)
|
||||||
,testBothSame "testInput 2" "^^^" ((tcall2 genInput undefined $ A.InputSimple undefined [undefined, undefined, undefined]) . overInputItemCase)
|
,testBothSame "testInput 2" "^^^" ((tcall2 genInput undefined $ A.InputSimple undefined [undefined, undefined, undefined]) . overInputItemCase)
|
||||||
,testBothSame "testInput 3" "$" ((tcall2 genInput undefined $ A.InputCase undefined undefined) . overInputItemCase)
|
|
||||||
|
|
||||||
-- Reading an integer (special case in the C backend):
|
-- Reading an integer (special case in the C backend):
|
||||||
,testInputItem 100 "ChanInInt(#,&x);" "#>>x;" (A.InVariable emptyMeta $ variable "x") A.Int
|
,testInputItem 100 "ChanInInt(#,&x);" "#>>x;" (A.InVariable emptyMeta $ variable "x") A.Int
|
||||||
|
@ -877,10 +876,6 @@ testInput = TestList
|
||||||
"tockRecvArrayOfBytes(#,tockSendableArrayOfBytes(^,&x));tockRecvArrayOfBytes(#,tockSendableArrayOfBytes(x*^,xs));"
|
"tockRecvArrayOfBytes(#,tockSendableArrayOfBytes(^,&x));tockRecvArrayOfBytes(#,tockSendableArrayOfBytes(x*^,xs));"
|
||||||
(A.InCounted emptyMeta (variable "x") (variable "xs")) (A.Counted A.Int8 A.Int8)
|
(A.InCounted emptyMeta (variable "x") (variable "xs")) (A.Counted A.Int8 A.Int8)
|
||||||
|
|
||||||
|
|
||||||
-- TODO write tests for genInputCase
|
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
sub0 = A.SubscriptedVariable emptyMeta (A.Subscript emptyMeta (intLiteral 0))
|
sub0 = A.SubscriptedVariable emptyMeta (A.Subscript emptyMeta (intLiteral 0))
|
||||||
|
@ -914,7 +909,7 @@ testInput = TestList
|
||||||
-- state = do defineName chan $ simpleDefDecl "c" (A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.UserProtocol foo)
|
-- state = do defineName chan $ simpleDefDecl "c" (A.Chan A.DirUnknown (A.ChanAttributes False False) $ A.UserProtocol foo)
|
||||||
-- defineName chanOut $ simpleDefDecl "cIn" (A.Chan A.DirInput (A.ChanAttributes False False) $ A.UserProtocol foo)
|
-- defineName chanOut $ simpleDefDecl "cIn" (A.Chan A.DirInput (A.ChanAttributes False False) $ A.UserProtocol foo)
|
||||||
|
|
||||||
overInputItemCase ops = ops {genInputItem = override2 caret, genInputCase = override3 dollar}
|
overInputItemCase ops = ops {genInputItem = override2 caret}
|
||||||
over ops = ops {genBytesIn = override2 caret, genArraySubscript = override3 dollar}
|
over ops = ops {genBytesIn = override2 caret, genArraySubscript = override3 dollar}
|
||||||
|
|
||||||
testOutput :: Test
|
testOutput :: Test
|
||||||
|
|
|
@ -34,6 +34,7 @@ simplifyComms = runPasses passes
|
||||||
where
|
where
|
||||||
passes =
|
passes =
|
||||||
[ ("Define temporary variables for outputting expressions", outExprs)
|
[ ("Define temporary variables for outputting expressions", outExprs)
|
||||||
|
,("Transform ? CASE statements/guards into plain CASE", transformInputCase)
|
||||||
]
|
]
|
||||||
|
|
||||||
outExprs :: Data t => t -> PassM t
|
outExprs :: Data t => t -> PassM t
|
||||||
|
|
Loading…
Reference in New Issue
Block a user