{- ---------------------------------------------------------------------------
The FSMonad and some helper functions for FixSyntax
-}
module FSLib(module FSLib, TokenId) where
import Syntax hiding (TokenId)
import SysDeps(PackedString,trace)
import IdKind
import Info hiding (TokenId,NewType)
import State
import qualified Data.Map as Map
import Util.Extra(noPos)
import TokenId
import IntState(IntState,lookupIS,addIS,uniqueIS,tidIS,mrpsIS,strIS,defaultMethodsIS)
import NT(NewType(..))
import Id(Id)
import Maybe
type ExpList = (Exp Id,Exp Id,Exp Id,Exp Id) -- expList (nil, cons, TyCon, TyGeneric)
type Inherited = ( ExpList
, Exp Id -- expId
, (TokenId,IdKind) -> Id) --tidFun
type Threaded = (IntState, Map.Map TokenId Id)
type FSMonad a = State Inherited Threaded a Threaded
startfs :: (Decls Id -> FSMonad a)
-> Decls Id
-> IntState
-> ((TokenId,IdKind) -> Id)
-> (a, IntState, Map.Map TokenId Id)
startfs fs x state tidFun =
let down = ( ( ExpCon noPos (tidFun (t_List,Con))
, ExpCon noPos (tidFun (t_Colon,Con))
, ExpVar noPos (tidFun (tTyCon,Var))
, ExpVar noPos (tidFun (tTyGeneric,Var))
)
, ExpVar noPos (tidFun (t_id,Var))
, tidFun
)
up = (state, Map.empty)
in
case fs x down up of
(x,(state,t2i)) -> (x,state,t2i)
fsList :: FSMonad ExpList
fsList down@(expList,expId,tidFun) up = (expList,up)
fsId :: FSMonad (Exp Id)
fsId down@(expList,expId,tidFun) up = (expId,up)
fsState :: FSMonad IntState
fsState down up@(state,t2i) = (state,up)
fsTidFun :: FSMonad ((TokenId,IdKind) -> Id)
fsTidFun down@(expList,expId,tidFun) up =
(tidFun,up)
{-
Returns True iff given data constructor is defined by data definition,
not newtype definition.
-}
fsRealData :: Id -> FSMonad Bool
fsRealData con down up@(state,t2i) =
((isRealData . fromJust . lookupIS state . belongstoI
. fromJust . lookupIS state) con,up)
fsExpAppl :: Pos -> [Exp Id] -> FSMonad (Exp Id)
fsExpAppl pos [x] = unitS x
fsExpAppl pos xs = unitS (ExpApplication pos xs)
fsInstanceFor :: Id -> Id -> Maybe Id -> IntState -> PackedString
fsInstanceFor cls typ sel state =
let clsInfo = fromJust $ lookupIS state cls
typInfo = fromJust $ lookupIS state typ
insts = instancesI clsInfo
defs = defaultMethodsIS state cls
isDef = maybe False (`elem` defs) sel
in if not isDef && isData typInfo then
case Map.lookup typ insts of
Just (rps,free,ctxt) -> rps
Nothing -> error $ "fsInstanceFor: No instance of class " ++ strIS state cls ++
" for type " ++ strIS state typ
else
extractM (tidI clsInfo)
fsClsTypSel :: Pos -> Id -> Id -> Id -> FSMonad (Exp Id)
fsClsTypSel pos cls typ sel down up@(state,t2i) =
let clsInfo = fromJust $ lookupIS state cls
typInfo = fromJust $ lookupIS state typ
mi = fsInstanceFor cls typ (Just sel) state
tid = mkQual3 mi (tidI clsInfo) (tidI typInfo) (tidIS state sel)
in case Map.lookup tid t2i of
Just i -> (ExpVar pos i,up)
Nothing ->
case uniqueIS state of
(u,state) ->
let -- !!! Arity of selector doesn't look right !!!
selAR = (arityIM . fromJust . lookupIS state) sel
clsAR = (length . (\(_,_,x)->x) . fromJust . flip Map.lookup (instancesI clsInfo)) typ
arity = selAR + clsAR
info = InfoName u tid arity tid False --PHtprof
-- info = InfoMethod u tid IEnone (InfixDef,9) NoType (Just arity) cls
in (ExpVar pos u,(addIS u info state,Map.insert tid u t2i))
fsExp2 :: Pos -> Id -> Id
-> State a
(IntState, Map.Map TokenId Id)
(Exp Id)
(IntState, Map.Map TokenId Id)
fsExp2 pos cls i =
unitS (ExpVar pos) =>>> fsExp2i pos cls i
fsExp2i :: Pos -> Id -> Id -> a
-> (IntState, Map.Map TokenId Id)
-> (Id, (IntState, Map.Map TokenId Id))
fsExp2i pos cls i down up@(state,t2i) =
case lookupIS state cls of
Just clsInfo ->
case lookupIS state i of
Just clsdatInfo ->
let mi = fsInstanceFor cls i Nothing state
tid = mkQual2 mi (tidI clsInfo) (tidI clsdatInfo)
in case Map.lookup tid t2i of
Just i -> (i,up)
Nothing ->
case uniqueIS state of
(u,state) ->
if isClass clsdatInfo
then -- Exp2 is either superclass (Ord.Eq) taking one argument ...
(u,(addIS u (InfoMethod u tid IEnone (InfixDef,9) NoType
(Just 1) cls) state
,Map.insert tid u t2i))
else -- ... or instance (Eq.Int) argument depends on type
let arity = (length . (\(_,_,x)->x) . fromJust
. flip Map.lookup (instancesI clsInfo)) i
-- snd instead of fst !!!
in seq arity (u,(addIS u (InfoVar u tid IEall (InfixDef,9)
NoType (Just arity))
state
,Map.insert tid u t2i))
{- End Module FSLib ---------------------------------------------------------}