module System.Console.Hawk.UserExpr.OriginalExpr where import qualified Data.ByteString.Lazy.Char8 as B import Text.Printf import Data.HaskellExpr -- | The user expression could have many different types, and we need to track -- how that type changes under our various manipulations. Use `Nothing` to -- indicate that a particular type is not compatible with the modifications -- mandated by the command-line flags. data UserExpr a b c d = UserExpr (Maybe (HaskellExpr a)) (Maybe (HaskellExpr b)) (Maybe (HaskellExpr c)) (Maybe (HaskellExpr d)) -- | To avoid an ambiguous type variable, we instantiate the output type of the -- user expression to unit. The code will still work with any instance of Rows. type OriginalExpr = UserExpr () (B.ByteString -> ()) ([B.ByteString] -> ()) ([[B.ByteString]] -> ()) -- | The user expression is expected to have one of the above four types. -- For now we just pretend like it has all four types, and as the flags -- are processed, some of those cases will be eliminated, until only -- one case remains. -- -- If the actual user expression doesn't have the type we use it at, hint -- will give a type error, and that's fine. originalExpr :: String -> OriginalExpr originalExpr s = UserExpr (wrapExpr s) (wrapExpr s) (wrapExpr s) (wrapExpr s) where wrapExpr :: String -> Maybe (HaskellExpr a) wrapExpr = Just . HaskellExpr . annotateExpr annotateExpr :: String -> String annotateExpr = printf "{-# LINE 1 \"user expression\" #-}\n%s{-# LINE 2 \"wrapper code\" #-}\n"