module UHC.Light.Compiler.Base.TermLike
( AppLike (..)
, appToApp
, BndLike (..)
, RecLike (..)
, rowCanonOrderBy, rowCanonOrder
, appTopApp1
, appRngProdOpt
, appRngParApp
, appConApp, appCon1App
, app1Arr, appArr
, appUnAnn, appUnTop, appUnBind, appUnAnnCanon
, appUnApp
, appUnAppArgs
, appMbApp, appMbConApp
, appMb1MetaArr, appMb1Arr, appMbArr, appUnMetaArrMk, appUnArrMk, appUnMetaArr, appUnArr, appUn1Arr
, appUnArrArgs, appUnArrRes, appUnArrArg
, recUnRecRow
, recRec, recSum, recRecExt, recRecEmp, recSumEmp
, appArrInverse )
where
import UU.Scanner.Position
import UHC.Util.Utils
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Base.HsName
import UHC.Light.Compiler.Base.HsName.Builtin
import Control.Applicative ((<|>))
import Control.Monad
import Data.Maybe
class AppLike a boundmeta
| a -> boundmeta
where
app1App :: a -> a -> a
appTop :: a -> a
appVar :: (Position n,HSNM n) => n -> a
appCon :: (Position n,HSNM n) => n -> a
appPar :: a -> a
app1App = appRngApp1 emptyRange
appTop = appRngTop emptyRange
appVar = appRngVar emptyRange
appCon = appRngCon emptyRange
appPar = appRngPar emptyRange
appRngApp1 :: Range -> a -> a -> a
appRngTop :: Range -> a -> a
appRngVar :: (Position n,HSNM n) => Range -> n -> a
appRngCon :: (Position n,HSNM n) => Range -> n -> a
appRngPar :: Range -> a -> a
appRngApp1 _ = app1App
appRngTop _ = appTop
appRngVar _ = appVar
appRngCon _ = appCon
appRngPar _ = appPar
appMbBind1 :: a -> Maybe (a,a->a)
appMbAnn1 :: a -> Maybe (a,a->a)
appMbTop1 :: a -> Maybe (a,a->a)
appMbCanon1 :: a -> Maybe (a,a->a)
appMbCon :: a -> Maybe (HsName)
appMbApp1 :: a -> Maybe (a,a)
appMbDbg :: a -> Maybe String
appMbBind1 = const Nothing
appMbAnn1 = const Nothing
appMbTop1 = appMbAnn1
appMbCanon1 = const Nothing
appMbCon = const Nothing
appMbApp1 = const Nothing
appMbDbg = const Nothing
appTopApp :: [a] -> a
appProdApp :: [a] -> a
app1MetaArr :: (Maybe HsName,boundmeta) -> a -> a -> a
appTopApp = appRngTopApp emptyRange
appProdApp as = appConApp (hsnProd (length as)) as
app1MetaArr _ a r = appConApp hsnArrow [a,r]
appRngTopApp :: Range -> [a] -> a
appRngProdApp :: Range -> [a] -> a
appRngTopApp r [a] = a
appRngTopApp r as = appRngTop r (foldl1 (appRngApp1 r) as)
appRngProdApp _ as = appProdApp as
appMb1ArrMk :: a -> Maybe (((HsName,boundmeta),a,a),a->a)
appMb1ArrMk x
= do let (x',mktop) = appUnBind $ fst $ appUnAnn x
(arr,[a,r]) <- appMbConApp x'
if hsnIsArrow arr then return (((mkHNm "??TermLike.appMb1ArrMk",appDfltBoundmeta a),a,r),mktop) else Nothing
appDbg :: String -> a
appDbg m = panic $ "TermLike.appDbg: " ++ m
appEvl :: a -> a
appEvl = id
appNonEvl :: a -> a
appNonEvl = id
appDfltBoundmeta :: a -> boundmeta
appDfltBoundmeta _ = panic "TermLike.appDfltBoundmeta not implemented"
appToApp :: (AppLike a aboundmeta, AppLike b bboundmeta) => a -> Maybe b
appToApp x
= c appMbCon appCon x
<|> c appMbDbg appDbg x
where c mbUn mk = fmap mk . mbUn
class BndLike a bndnm where
bndBndIn :: bndnm -> MetaLev -> a -> a -> a
class AppLike a boundmeta => RecLike a boundmeta
where
recRow :: a -> AssocL HsName a -> a
recRowEmp :: a
recRowEmp = appCon hsnRowEmpty
recMbRecRow :: a -> Maybe a
recUnRowExts :: a -> (a,AssocL HsName a)
rowCanonOrderBy :: (o -> o -> Ordering) -> AssocL o a -> AssocL o a
rowCanonOrderBy cmp = sortByOn cmp fst
rowCanonOrder :: AssocL HsName a -> AssocL HsName a
rowCanonOrder = rowCanonOrderBy rowLabCmp
appTopApp1 :: AppLike a boundmeta => a -> a -> a
appTopApp1 a r = appTopApp [a,r]
appRngProdOpt :: AppLike a boundmeta => Range -> [a] -> a
appRngProdOpt r [a] = a
appRngProdOpt r as = appRngProdApp r as
appRngParApp :: AppLike a boundmeta => Range -> [a] -> a
appRngParApp r [a] = a
appRngParApp r as = appRngPar r (appRngTopApp r as)
appConApp :: (AppLike a boundmeta , Position n, HSNM n) => n -> [a] -> a
appConApp c as = appTopApp (appCon c : as)
appCon1App :: (AppLike a boundmeta , Position n, HSNM n) => n -> a -> a
appCon1App c a = appConApp c [a]
app1Arr :: AppLike a boundmeta => a -> a -> a
app1Arr x y = app1MetaArr (Nothing,appDfltBoundmeta x) x y
appArr :: AppLike a boundmeta => [a] -> a -> a
appArr = flip (foldr app1Arr)
appMb2Un :: (a -> Maybe (a,a->a)) -> a -> (a,a->a)
appMb2Un un a
= case un a of
Just (a',mk1) -> (a'', mk1 . mk)
where (a'',mk) = appMb2Un un a'
_ -> (a,id)
appUnBind :: AppLike a boundmeta => a -> (a,a->a)
appUnBind = appMb2Un appMbBind1
appUnAnn :: AppLike a boundmeta => a -> (a,a->a)
appUnAnn = appMb2Un appMbAnn1
appUnAnnCanon :: AppLike a boundmeta => a -> (a,a->a)
appUnAnnCanon = appMb2Un (\a -> appMbAnn1 a <|> appMbCanon1 a)
appUnTop :: AppLike a boundmeta => a -> (a,a->a)
appUnTop = appMb2Un appMbTop1
appUnApp :: AppLike a boundmeta => a -> (a,[a])
appUnApp x
= un [] (fst $ appUnTop x)
where un as x = case appMbApp1 x' of
Just (f,a) -> un (a:as) f
_ -> (x',as)
where x' =
fst $ appUnBind $ fst $ appUnAnn x
appUnAppArgs :: AppLike a boundmeta => a -> [a]
appUnAppArgs = snd . appUnApp
appMbApp :: AppLike a boundmeta => a -> Maybe (a,[a])
appMbApp x
= case appUnApp x of
u@(_,(_:_)) -> Just u
_ -> Nothing
appMbConApp :: AppLike a boundmeta => a -> Maybe (HsName,[a])
appMbConApp x
= do let (f,as) = appUnApp x
c <- appMbCon $ fst $ appUnAnn f
return (c,as)
appMb1MetaArr :: AppLike a boundmeta => a -> Maybe ((HsName,boundmeta),a,a)
appMb1MetaArr = fmap fst . appMb1ArrMk
appMb1Arr :: AppLike a boundmeta => a -> Maybe (a,a)
appMb1Arr = fmap (\(_,x,y) -> (x,y)) . appMb1MetaArr
appMbArr :: AppLike a boundmeta => a -> Maybe ([a],a)
appMbArr x
= case appUnArr x of
a@((_:_),_) -> Just a
_ -> Nothing
appUnMetaArrMk :: AppLike a boundmeta => a -> (([((HsName,boundmeta),a)],a),a->a)
appUnMetaArrMk x
= case appMb1ArrMk x of
Just ((m,a,r),mk) -> (((m,a):as,r'),mk)
where ((as,r'),_) = appUnMetaArrMk r
_ -> (([],x),id)
appUnArrMk :: AppLike a boundmeta => a -> (([a],a),a->a)
appUnArrMk x
= ((map snd as,r),mk)
where ((as,r),mk) = appUnMetaArrMk x
appUnMetaArr :: AppLike a boundmeta => a -> ([((HsName,boundmeta),a)],a)
appUnMetaArr = fst . appUnMetaArrMk
appUnArr :: AppLike a boundmeta => a -> ([a],a)
appUnArr = fst . appUnArrMk
appUn1Arr :: AppLike a boundmeta => a -> (a,a)
appUn1Arr x = maybe (appDbg "appUn1Arr.arg",x) id $ appMb1Arr x
appUnArrArgs :: AppLike a boundmeta => a -> [a]
appUnArrArgs = fst . appUnArr
appUnArrRes :: AppLike a boundmeta => a -> a
appUnArrRes = snd . appUnArr
appUnArrArg :: AppLike a boundmeta => a -> a
appUnArrArg = fst . appUn1Arr
appArrInverse :: AppLike a boundmeta => a -> a
appArrInverse x
= case appUnArrMk x of
(( [a] ,r),mk) -> mk $ [r] `appArr` a
((as@(_:_),r),mk) -> mk $ [r] `appArr` appProdApp as
_ -> x
recUnRecRow :: RecLike a boundmeta => a -> a
recUnRecRow = maybe (panic "recUnRecRow") id . recMbRecRow
recRec :: RecLike a boundmeta => AssocL HsName a -> a
recRec al = hsnRec `appConApp` [recRowEmp `recRow` al]
recSum :: RecLike a boundmeta => AssocL HsName a -> a
recSum al = hsnSum `appConApp` [recRowEmp `recRow` al]
recRecExt :: RecLike a boundmeta => a -> AssocL HsName a -> a
recRecExt recd al
= hsnRec `appConApp` [row `recRow` (exts ++ al)]
where (row,exts) = recUnRowExts (recUnRecRow recd)
recRecEmp :: RecLike a boundmeta => a
recRecEmp = recRec []
recSumEmp :: RecLike a boundmeta => a
recSumEmp = recSum []