+ mkConditional :: SignalId -> (SignalId, SignalId) -> FlattenState SignalId
+ mkConditional boolsigid (true, false) = do
+ -- Create a new signal (true and false should be identically typed,
+ -- so it doesn't matter which one we copy).
+ res <- copySignal true
+ addDef (CondDef boolsigid true false res)
+ return res
+
+ flattenMultipleAltCaseExpr binds scrut b (a:alts) =
+ flattenSingleAltCaseExpr binds scrut b a
+
+flattenExpr _ expr = do
+ error $ "Unsupported expression: " ++ (showSDoc $ ppr expr)
+
+-- | Flatten a normal application expression
+flattenApplicationExpr binds ty f args = do
+ -- Find the function to call
+ let func = appToHsFunction ty f args
+ -- Flatten each of our args
+ flat_args <- (mapM (flattenExpr binds) args)
+ -- Check and split each of the arguments
+ let (_, arg_ress) = unzip (zipWith checkArg args flat_args)
+ -- Generate signals for our result
+ res <- genSignals ty
+ -- Add name hints to the generated signals
+ let resname = Name.getOccString f ++ "_res"
+ Traversable.mapM (addNameHint resname) res
+ -- Create the function application
+ let app = FApp {
+ appFunc = func,
+ appArgs = arg_ress,
+ appRes = res
+ }
+ addDef app
+ return ([], res)
+-- | Check a flattened expression to see if it is valid to use as a
+-- function argument. The first argument is the original expression for
+-- use in the error message.
+checkArg arg flat =
+ let (args, res) = flat in
+ if not (null args)
+ then error $ "Passing lambda expression or function as a function argument not supported: " ++ (showSDoc $ ppr arg)
+ else flat
+
+-- | Translates a dataconstructor without arguments to the corresponding
+-- literal.
+dataConToLiteral :: DataCon.DataCon -> FlattenState String
+dataConToLiteral datacon = do
+ let tycon = DataCon.dataConTyCon datacon
+ let tyname = TyCon.tyConName tycon
+ case Name.getOccString tyname of
+ -- TODO: Do something more robust than string matching
+ "Bit" -> do
+ let dcname = DataCon.dataConName datacon
+ let lit = case Name.getOccString dcname of "High" -> "'1'"; "Low" -> "'0'"
+ return lit
+ "Bool" -> do
+ let dcname = DataCon.dataConName datacon
+ let lit = case Name.getOccString dcname of "True" -> "true"; "False" -> "false"
+ return lit
+ otherwise ->
+ error $ "Literals of type " ++ (Name.getOccString tyname) ++ " not supported."