packages feed

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)