Changeset 12200 for src/Pugs/Eval

Show
Ignore:
Timestamp:
08/14/06 06:48:18 (2 years ago)
Author:
audreyt
Message:

* Oldland method calls with newVal as invocant is now hooked into a

newland call with new toys such Captures, Feeds, etc. Yay!


pugs> vv('moose').elk(1, 2, antler => 3);
CCall "elk" CaptMeth?

{ c_invocant = VPure (MkStr? "moose")
, c_feeds = [ MkFeed?

{ a_positional = [VPure (IFinite 1),VPure (IFinite 2)]
, a_named = fromList [("antler",[VPure (IFinite 3)])]
} ]

}

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Eval/Var.hs

    r12176 r12200  
    1818import Pugs.Config 
    1919import Pugs.Monads 
     20import qualified Pugs.Val as Val 
     21import Pugs.Val hiding (Val, IValue, VUndef) 
    2022 
    2123findVar :: Var -> Eval (Maybe VRef) 
     
    139141    = NoMatchingMulti 
    140142    | NoSuchSub 
    141     | NoSuchMethod String 
     143    | NoSuchMethod !Type 
    142144 
    143145findSub :: String     -- ^ Name, with leading @\&@. 
     
    146148        -> Eval (Either FindSubFailure VCode) 
    147149findSub name' invs args = do 
    148     let name = possiblyFixOperatorName name' 
    149150    case invs of 
    150151        Just _ | Just (package, name') <- breakOnGlue "::" name 
     
    152153            typ <- asks envPackage 
    153154            findSuperSub (mkType typ) (sig ++ name') 
    154         Just exp | not (':' `elem` drop 2 name) -> do 
    155             typ     <- evalInvType $ unwrap exp 
    156             if typ == mkType "Scalar::Perl5" 
    157                 then do 
    158                     fmap (err $ NoSuchMethod $ show typ) (runPerl5Sub name) 
    159                 else do 
    160                     findTypedSub typ name 
     155        Just exp | not (':' `elem` drop 2 name) -> case unwrap exp of 
     156            Val inv@VV{}     -> withExternalCall callMethodVV inv  
     157            Val inv@PerlSV{} -> withExternalCall callMethodPerl5 inv  
     158            exp' -> do 
     159                typ <- evalInvType exp' 
     160                findTypedSub typ name 
    161161        _ -> findBuiltinSub NoSuchSub name 
     162 
    162163    where 
    163164    err :: b -> Maybe a -> Either b a 
    164165    err _ (Just j) = Right j 
    165166    err x Nothing  = Left x 
     167 
     168    name = possiblyFixOperatorName name' 
    166169 
    167170    findSuperSub :: Type -> String -> Eval (Either FindSubFailure VCode) 
     
    172175        subs'   <- either (flip findBuiltinSub name) (return . Right) subs 
    173176        case subs' of 
    174             Right sub | subName sub == qualified -> return (Left $ NoSuchMethod $ show typ) 
     177            Right sub | subName sub == qualified -> return (Left $ NoSuchMethod typ) 
    175178            _   -> return subs' 
    176179    findTypedSub :: Type -> String -> Eval (Either FindSubFailure VCode) 
     
    183186        maybe (fmap (err failure) $ possiblyBuildMetaopVCode name) (return . Right) sub 
    184187    evalInvType :: Exp -> Eval Type 
    185     evalInvType x@(Var (':':typ)) = do 
    186         typ' <- inferExpType x 
    187         return $ if typ' == mkType "Scalar::Perl5" then typ' else mkType typ 
    188     evalInvType (App (Var "&new") (Just inv) _) = do 
    189         evalInvType $ unwrap inv 
    190     evalInvType x@(App (Var _) (Just inv) _) = do 
    191         typ <- evalInvType $ unwrap inv 
    192         if typ == mkType "Scalar::Perl5" then return typ else inferExpType x 
    193188    evalInvType x = inferExpType $ unwrap x 
    194     runPerl5Sub :: String -> Eval (Maybe VCode) 
    195     runPerl5Sub name = do 
    196         metaSub <- possiblyBuildMetaopVCode name 
    197         if isJust metaSub then return metaSub else do 
     189 
     190    withExternalCall callMeth inv = do 
     191        fmap (err . NoSuchMethod $ valType inv) $ do 
     192            metaSub <- possiblyBuildMetaopVCode name 
     193            if isJust metaSub then return metaSub else callMeth 
     194 
     195    callMethodVV :: Eval (Maybe VCode) 
     196    callMethodVV = do 
     197        let (_, methName) = breakSigil name 
     198        -- Look up the proto for the method in VV land right here 
     199        -- Whether it matched or not, it's the proto's signature 
     200        -- that's available to the inferencer, not any of its children's 
     201        -- (this is because MMD in newland is performed _after_ everything 
     202        -- has been reduced.) 
     203        return . Just $ mkPrim 
     204            { subName     = methName 
     205            , subParams   = makeParams ["Object", "List", "Named"] 
     206            , subReturns  = mkType "Any" 
     207            , subBody     = Prim $ \(inv:named:pos:_) -> do 
     208                invVV   <- fromVal inv      :: Eval Val.Val 
     209                posVVs  <- fromVals pos     :: Eval [Val.Val] 
     210                namVVs  <- do 
     211                    list <- fromVal named 
     212                    fmap Map.fromList $ forM list $ \(k, v) -> do 
     213                        key <- fromVal k 
     214                        val <- fromVal v 
     215                        return (key, [val])   :: Eval (ID, [Val.Val]) 
     216 
     217                -- This is the Capture object we are going to work with 
     218                let capt = CaptMeth invVV [MkFeed posVVs namVVs] 
     219 
     220                return . castV $ "CCall " ++ show methName ++ " " ++ show capt 
     221            } 
     222 
     223    callMethodPerl5 :: Eval (Maybe VCode) 
     224    callMethodPerl5 = do 
    198225        return . Just $ mkPrim 
    199226            { subName     = name 
     
    308335        if isNothing attrs || null (fromJust attrs) then fmap (err NoMatchingMulti) (findSub' name) else do 
    309336        (`fix` (fromJust attrs)) $ \run pkgs -> do 
    310             if null pkgs then return (Left $ NoSuchMethod $ pkg) else do 
     337            if null pkgs then return (Left $ NoSuchMethod $ mkType pkg) else do 
    311338            subs <- findWithPkg (head pkgs) name 
    312339            either (const $ run (tail pkgs)) (return . Right) subs 
     
    377404    sub <- fromVal val 
    378405    return $ subReturns sub 
    379 inferExpType (App (Var "&new") (Just (Val (VType typ))) _) = return typ 
     406inferExpType (App (Var "&new") (Just inv) _) = inferExpType $ unwrap inv 
    380407inferExpType (App (Var name) invs args) = do 
    381408    sub <- findSub name invs args