+ let fname = Name.getOccString f in
+ if fname == "fst" || fname == "snd" then do
+ (args', Tuple [a, b]) <- flattenExpr binds (last args)
+ return (args', if fname == "fst" then a else b)
+ else if fname == "patError" then do
+ -- This is essentially don't care, since the program will error out
+ -- here. We'll just define undriven signals here.
+ let (argtys, resty) = Type.splitFunTys $ CoreUtils.exprType app
+ args <- mapM genSignals argtys
+ res <- genSignals resty
+ mapM (Traversable.mapM (addNameHint "NC")) args
+ Traversable.mapM (addNameHint "NC") res
+ return (args, res)
+ else if fname == "==" then do
+ -- Flatten the last two arguments (this skips the type arguments)
+ ([], a) <- flattenExpr binds (last $ init args)
+ ([], b) <- flattenExpr binds (last args)
+ res <- mkEqComparisons a b
+ return ([], res)
+ else if fname == "fromInteger" then do
+ let [to_ty, to_dict, val] = args
+ -- We assume this is an application of the GHC.Integer.smallInteger
+ -- function to a literal
+ let App smallint (Lit lit) = val
+ let (Literal.MachInt int) = lit
+ let ty = CoreUtils.exprType app
+ sig_id <- genSignalId SigInternal ty
+ -- TODO: fromInteger is defined for more types than just SizedWord
+ let len = sized_word_len ty
+ -- Use a to_unsigned to translate the number (a natural) to an unsiged
+ -- (array of bits)
+ let lit_str = "to_unsigned(" ++ (show int) ++ ", " ++ (show len) ++ ")"
+ -- Set the signal to our literal unconditionally, but add the type so
+ -- the literal will be typecast to the proper type.
+ addDef $ UncondDef (Right $ Literal lit_str (Just ty)) sig_id
+ return ([], Single sig_id)
+ else
+ flattenApplicationExpr binds (CoreUtils.exprType app) f args