packages feed

haskell-awk-1.2: src/System/Console/Hawk/UserExpr/OriginalExpr.hs

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"