Pugs-6.2.13.1: src/Pugs/Meta/Perl5.hs
{-# OPTIONS_GHC -fglasgow-exts #-}
module Pugs.Meta.Perl5 (Perl5Responder) where
import Pugs.Val
import Pugs.Class
import Pugs.Embed.Perl5
import Pugs.Internals
import Data.Typeable (Typeable)
import qualified Data.Map as Map
import qualified StringTable.AtomMap as AtomMap
import Pugs.AST.Internals (envContext, anyToVal, anyFromVal)
import Pugs.Types
data Perl5Responder = Perl5Responder deriving Typeable
instance ResponderInterface Eval Perl5Responder where
dispatch _ = dispatchPerl5
fromMethodList _ = return Perl5Responder
instance Boxable PerlSV where
mkVal sv = MkInvocant sv (MkResponder (return Perl5Responder))
coerceVal (MkInvocant x _)
| Just x' <- fromTypeable x = return x'
| Just x' <- fromTypeable x = liftIO $ vstrToSV x'
| Just x' <- fromTypeable x = liftIO . bufToSV $ (cast :: PureStr -> ByteString) x'
| Just x' <- fromTypeable x = liftIO . vintToSV $ (cast :: PureInt -> Integer) x'
| Just x' <- fromTypeable x = liftIO . vnumToSV $ (cast :: PureNum -> Double) x'
| Just x' <- fromTypeable x = anyFromVal x'
| otherwise = fail $ "Cannot coerce to SV: " ++ show (typeOf x)
__ITEM__, __LIST__ :: MethodName
__ITEM__ = _cast "ITEM"
__LIST__ = _cast "LIST"
dispatchPerl5 :: Val -> Call -> Eval Val
dispatchPerl5 inv call
| meth == nullID = return inv -- XXX - real HOW support --
| meth == __ITEM__ = return inv -- XXX - real rvalue suport --
| meth == __LIST__ = return inv -- XXX - real lvalue suport --
| otherwise = do
invSV <- coerceVal inv
subSV <- liftIO . bufToSV . cast $ meth
posSVs <- mapM coerceVal (fromP $ f_positionals feed)
namSVs <- fmap concat . forM (AtomMap.toList (f_nameds feed)) $ \(key, vals) -> do
keySV <- liftIO (bufToSV $ cast key)
fmap concat . forM (fromP vals) $ \v -> do
valSV <- coerceVal v
return [keySV, valSV]
env <- ask
rv <- liftIO $ do
envSV <- mkEnv env
invokePerl5 subSV invSV (posSVs ++ namSVs) envSV (enumCxt $ envContext env)
case rv of
Perl5ReturnValues [x] -> return $ mkVal x
Perl5ReturnValues xs -> return $ mkVal xs
Perl5ErrorString str -> fail str
Perl5ErrorObject err -> throwError (anyToVal err)
where
meth = mi_name call
feed = concatFeeds (c_feeds (mi_arguments call))