| 1 | {-# OPTIONS_GHC -fglasgow-exts #-} |
|---|
| 2 | |
|---|
| 3 | module Pugs.Meta.Perl5 (Perl5Responder) where |
|---|
| 4 | import Pugs.Val |
|---|
| 5 | import Pugs.Class |
|---|
| 6 | import Pugs.Embed.Perl5 |
|---|
| 7 | import Pugs.Internals |
|---|
| 8 | import Data.Typeable (Typeable) |
|---|
| 9 | import qualified Data.Map as Map |
|---|
| 10 | import qualified StringTable.AtomMap as AtomMap |
|---|
| 11 | import Pugs.AST.Internals (envContext, anyToVal, anyFromVal) |
|---|
| 12 | import Pugs.Types |
|---|
| 13 | |
|---|
| 14 | data Perl5Responder = Perl5Responder deriving Typeable |
|---|
| 15 | |
|---|
| 16 | instance ResponderInterface Eval Perl5Responder where |
|---|
| 17 | dispatch _ = dispatchPerl5 |
|---|
| 18 | fromMethodList _ = return Perl5Responder |
|---|
| 19 | |
|---|
| 20 | instance Boxable PerlSV where |
|---|
| 21 | mkVal sv = MkInvocant sv (MkResponder (return Perl5Responder)) |
|---|
| 22 | coerceVal (MkInvocant x _) |
|---|
| 23 | | Just x' <- fromTypeable x = return x' |
|---|
| 24 | | Just x' <- fromTypeable x = liftIO $ vstrToSV x' |
|---|
| 25 | | Just x' <- fromTypeable x = liftIO . bufToSV $ (cast :: PureStr -> ByteString) x' |
|---|
| 26 | | Just x' <- fromTypeable x = liftIO . vintToSV $ (cast :: PureInt -> Integer) x' |
|---|
| 27 | | Just x' <- fromTypeable x = liftIO . vnumToSV $ (cast :: PureNum -> Double) x' |
|---|
| 28 | | Just x' <- fromTypeable x = anyFromVal x' |
|---|
| 29 | | otherwise = fail $ "Cannot coerce to SV: " ++ show (typeOf x) |
|---|
| 30 | |
|---|
| 31 | __ITEM__, __LIST__ :: MethodName |
|---|
| 32 | __ITEM__ = _cast "ITEM" |
|---|
| 33 | __LIST__ = _cast "LIST" |
|---|
| 34 | |
|---|
| 35 | dispatchPerl5 :: Val -> Call -> Eval Val |
|---|
| 36 | dispatchPerl5 inv call |
|---|
| 37 | | meth == nullID = return inv -- XXX - real HOW support -- |
|---|
| 38 | | meth == __ITEM__ = return inv -- XXX - real rvalue suport -- |
|---|
| 39 | | meth == __LIST__ = return inv -- XXX - real lvalue suport -- |
|---|
| 40 | | otherwise = do |
|---|
| 41 | invSV <- coerceVal inv |
|---|
| 42 | subSV <- liftIO . bufToSV . cast $ meth |
|---|
| 43 | posSVs <- mapM coerceVal (fromP $ f_positionals feed) |
|---|
| 44 | namSVs <- fmap concat . forM (AtomMap.toList (f_nameds feed)) $ \(key, vals) -> do |
|---|
| 45 | keySV <- liftIO (bufToSV $ cast key) |
|---|
| 46 | fmap concat . forM (fromP vals) $ \v -> do |
|---|
| 47 | valSV <- coerceVal v |
|---|
| 48 | return [keySV, valSV] |
|---|
| 49 | env <- ask |
|---|
| 50 | rv <- liftIO $ do |
|---|
| 51 | envSV <- mkEnv env |
|---|
| 52 | invokePerl5 subSV invSV (posSVs ++ namSVs) envSV (enumCxt $ envContext env) |
|---|
| 53 | case rv of |
|---|
| 54 | Perl5ReturnValues [x] -> return $ mkVal x |
|---|
| 55 | Perl5ReturnValues xs -> return $ mkVal xs |
|---|
| 56 | Perl5ErrorString str -> fail str |
|---|
| 57 | Perl5ErrorObject err -> throwError (anyToVal err) |
|---|
| 58 | where |
|---|
| 59 | meth = mi_name call |
|---|
| 60 | feed = concatFeeds (c_feeds (mi_arguments call)) |
|---|