uhc-light-1.1.9.4: src/UHC/Light/Compiler/Foreign.hs
-- UUAGC 0.9.52.1 (build/103/lib-ehc/UHC/Light/Compiler/Foreign.ag)
module UHC.Light.Compiler.Foreign(ForeignEnt (..), CCall (..), PlainCall (..), PrimCall (..), JavaScriptCall (..)
, ForeignExpr (..), ForeignExprs
, ForeignExprAGItf (..), ForeignAGItf (..)
, foreignexprEval
, ForeignDirection (..)) where
import UHC.Light.Compiler.Base.Common
import qualified Data.Map as Map
import qualified Data.Set as Set
import UHC.Util.Utils
import Control.Monad
import UHC.Util.Binary
import UHC.Util.Serialize
-- | evaluation of a ForeignExpr has arguments, known by index [1..], and a foreign entity
data IE e
= IE { ieArgs :: [e]
}
data OE e
= OE { oeEL :: [e]
, oeUsed :: Set.Set Int
}
mkOE :: e -> Set.Set Int -> OE e
mkOE e s = OE [e] s
oeE :: OE e -> e
oeE = head . oeEL
foreignexprEval
:: -- the (partial) algebra for constructing an e
( e -> e -> e -- select
, e -> e -> e -- index
, e -> [e] -> e -- call
, e -> e -- as var/ptr
, [e] -> e -- object
, e -> e -- new object
, String -> e -- name
, String -> e -- string
)
-> ForeignExpr
-> e -- ent
-> [e] -- args
-> e
foreignexprEval
(mkSel,mkInx,mkCall,mkPtr,mkObj,mkNewObj,mkNm,mkStr)
fexpr ent args
= oeE oe
where argl = zip [1..] args
env = Map.fromList argl
oe = ev fexpr (IE [a | (i,a) <- argl, not $ i `Set.member` oeUsed oe])
ev (ForeignExpr_Ent ) ie = let
in mkOE ent
( Set.empty )
ev (ForeignExpr_EntNm n) ie = let
in mkOE ( mkNm n )
( Set.empty )
ev (ForeignExpr_Str s) ie = let
in mkOE ( mkStr s )
( Set.empty )
ev (ForeignExpr_Arg a ) ie = let
in mkOE ( Map.findWithDefault (panic "foreignexprEval.Arg") a env )
( Set.singleton a )
ev (ForeignExpr_AllArg ) ie = let
in OE ( ieArgs ie )
( Set.empty )
ev (ForeignExpr_Sel e s) ie = let eo = ev e ie
so = ev s ie
in mkOE ( mkSel (oeE eo) (oeE so) )
( oeUsed eo `Set.union` oeUsed so )
ev (ForeignExpr_Inx e i) ie = let eo = ev e ie
io = ev i ie
in mkOE ( mkInx (oeE eo) (oeE io) )
( oeUsed eo `Set.union` oeUsed io )
ev (ForeignExpr_Ptr e ) ie = let eo = ev e ie
in eo {oeEL = [mkPtr $ oeE eo]}
ev (ForeignExpr_Call e ) ie = let eo = ev e ie
in eo {oeEL = [mkCall (oeE eo) (ieArgs ie)]}
ev (ForeignExpr_CallArgs f a)
ie = let fo = ev f ie
ao = evs a ie
in mkOE ( mkCall (oeE fo) (concatMap oeEL ao) )
( Set.unions $ oeUsed fo : map oeUsed ao )
ev (ForeignExpr_ObjData) ie = let
in mkOE ( mkObj (ieArgs ie) )
( Set.empty )
ev (ForeignExpr_NewObj e) ie = let eo = ev e ie
in eo { oeEL = [mkNewObj $ oeE eo] }
evs feL ie = map (\e -> ev e ie) feL
data ForeignDirection
= ForeignDirection_Import
| ForeignDirection_Export
deriving (Eq,Ord)
instance Serialize ForeignExpr
instance Serialize ForeignEnt
instance Serialize CCall
instance Serialize PlainCall
instance Serialize PrimCall
instance Serialize JavaScriptCall
-- CCall -------------------------------------------------------
data CCall = CCall_Id {isStatic_CCall_Id :: !(Bool),mbInclude_CCall_Id :: !((Maybe String)),asPointer_CCall_Id :: !(Bool),nm_CCall_Id :: !(String)}
| CCall_Dynamic {}
| CCall_Wrapper {}
deriving ( Eq,Generic,Show,Typeable)
-- ForeignAGItf ------------------------------------------------
data ForeignAGItf = ForeignAGItf_AGItf {ent_ForeignAGItf_AGItf :: !(ForeignEnt)}
-- ForeignEnt --------------------------------------------------
data ForeignEnt = ForeignEnt_CCall {ent_ForeignEnt_CCall :: !(CCall)}
| ForeignEnt_PlainCall {ent_ForeignEnt_PlainCall :: !(PlainCall)}
| ForeignEnt_PrimCall {ent_ForeignEnt_PrimCall :: !(PrimCall)}
| ForeignEnt_JavaScriptCall {ent_ForeignEnt_JavaScriptCall :: !(JavaScriptCall)}
deriving ( Eq,Generic,Show,Typeable)
-- ForeignExpr -------------------------------------------------
data ForeignExpr = ForeignExpr_Call {expr_ForeignExpr_Call :: !(ForeignExpr)}
| ForeignExpr_CallArgs {expr_ForeignExpr_CallArgs :: !(ForeignExpr),args_ForeignExpr_CallArgs :: !(ForeignExprs)}
| ForeignExpr_Ptr {expr_ForeignExpr_Ptr :: !(ForeignExpr)}
| ForeignExpr_Sel {expr_ForeignExpr_Sel :: !(ForeignExpr),sel_ForeignExpr_Sel :: !(ForeignExpr)}
| ForeignExpr_Inx {expr_ForeignExpr_Inx :: !(ForeignExpr),inx_ForeignExpr_Inx :: !(ForeignExpr)}
| ForeignExpr_Ent {}
| ForeignExpr_EntNm {nm_ForeignExpr_EntNm :: !(String)}
| ForeignExpr_Arg {nr_ForeignExpr_Arg :: !(Int)}
| ForeignExpr_AllArg {}
| ForeignExpr_Empty {}
| ForeignExpr_Str {str_ForeignExpr_Str :: !(String)}
| ForeignExpr_ObjData {}
| ForeignExpr_NewObj {expr_ForeignExpr_NewObj :: !(ForeignExpr)}
deriving ( Eq,Generic,Show,Typeable)
-- ForeignExprAGItf --------------------------------------------
data ForeignExprAGItf = ForeignExprAGItf_AGItf {expr_ForeignExprAGItf_AGItf :: !(ForeignExpr)}
-- ForeignExprs ------------------------------------------------
type ForeignExprs = [ForeignExpr]
-- JavaScriptCall ----------------------------------------------
data JavaScriptCall = JavaScriptCall_Id {nm_JavaScriptCall_Id :: !(String),mbInclude_JavaScriptCall_Id :: !((Maybe String)),mbForeignExpr_JavaScriptCall_Id :: !((Maybe ForeignExpr))}
| JavaScriptCall_Dynamic {}
| JavaScriptCall_Wrapper {}
deriving ( Eq,Generic,Show,Typeable)
-- PlainCall ---------------------------------------------------
data PlainCall = PlainCall_Id {nm_PlainCall_Id :: !(String)}
deriving ( Eq,Generic,Show,Typeable)
-- PrimCall ----------------------------------------------------
data PrimCall = PrimCall_Id {nm_PrimCall_Id :: !(String),mbKnownPrim_PrimCall_Id :: !((Maybe KnownPrim))}
deriving ( Eq,Generic,Show,Typeable)