Changeset 12200 for src/Pugs/Eval
- Timestamp:
- 08/14/06 06:48:18 (2 years ago)
- Files:
-
- 1 modified
-
src/Pugs/Eval/Var.hs (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Eval/Var.hs
r12176 r12200 18 18 import Pugs.Config 19 19 import Pugs.Monads 20 import qualified Pugs.Val as Val 21 import Pugs.Val hiding (Val, IValue, VUndef) 20 22 21 23 findVar :: Var -> Eval (Maybe VRef) … … 139 141 = NoMatchingMulti 140 142 | NoSuchSub 141 | NoSuchMethod String143 | NoSuchMethod !Type 142 144 143 145 findSub :: String -- ^ Name, with leading @\&@. … … 146 148 -> Eval (Either FindSubFailure VCode) 147 149 findSub name' invs args = do 148 let name = possiblyFixOperatorName name'149 150 case invs of 150 151 Just _ | Just (package, name') <- breakOnGlue "::" name … … 152 153 typ <- asks envPackage 153 154 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 161 161 _ -> findBuiltinSub NoSuchSub name 162 162 163 where 163 164 err :: b -> Maybe a -> Either b a 164 165 err _ (Just j) = Right j 165 166 err x Nothing = Left x 167 168 name = possiblyFixOperatorName name' 166 169 167 170 findSuperSub :: Type -> String -> Eval (Either FindSubFailure VCode) … … 172 175 subs' <- either (flip findBuiltinSub name) (return . Right) subs 173 176 case subs' of 174 Right sub | subName sub == qualified -> return (Left $ NoSuchMethod $ showtyp)177 Right sub | subName sub == qualified -> return (Left $ NoSuchMethod typ) 175 178 _ -> return subs' 176 179 findTypedSub :: Type -> String -> Eval (Either FindSubFailure VCode) … … 183 186 maybe (fmap (err failure) $ possiblyBuildMetaopVCode name) (return . Right) sub 184 187 evalInvType :: Exp -> Eval Type 185 evalInvType x@(Var (':':typ)) = do186 typ' <- inferExpType x187 return $ if typ' == mkType "Scalar::Perl5" then typ' else mkType typ188 evalInvType (App (Var "&new") (Just inv) _) = do189 evalInvType $ unwrap inv190 evalInvType x@(App (Var _) (Just inv) _) = do191 typ <- evalInvType $ unwrap inv192 if typ == mkType "Scalar::Perl5" then return typ else inferExpType x193 188 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 198 225 return . Just $ mkPrim 199 226 { subName = name … … 308 335 if isNothing attrs || null (fromJust attrs) then fmap (err NoMatchingMulti) (findSub' name) else do 309 336 (`fix` (fromJust attrs)) $ \run pkgs -> do 310 if null pkgs then return (Left $ NoSuchMethod $ pkg) else do337 if null pkgs then return (Left $ NoSuchMethod $ mkType pkg) else do 311 338 subs <- findWithPkg (head pkgs) name 312 339 either (const $ run (tail pkgs)) (return . Right) subs … … 377 404 sub <- fromVal val 378 405 return $ subReturns sub 379 inferExpType (App (Var "&new") (Just (Val (VType typ))) _) = return typ406 inferExpType (App (Var "&new") (Just inv) _) = inferExpType $ unwrap inv 380 407 inferExpType (App (Var name) invs args) = do 381 408 sub <- findSub name invs args
