Changeset 3888

Show
Ignore:
Timestamp:
05/26/05 02:20:34 (4 years ago)
Author:
autrijus
svk:copy_cache_prev:
5477
Message:

* fix double-evaluation bug for Perl 5 method invocation;

reported by Gruber.

Location:
src/Pugs
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Eval.hs

    r3884 r3888  
    837837        [exp] | not (':' `elem` drop 2 name) -> do 
    838838            typ     <- evalExpType exp 
    839             if typ == mkType "Scalar::Perl5" then findPerl5Sub name else do 
     839            if typ == mkType "Scalar::Perl5" then runPerl5Sub name else do 
    840840            subs    <- findWithPkg (showType typ) name 
    841841            if isJust subs then return subs else findSub' name 
     
    844844            if isNothing sub then possiblyBuildMetaopVCode name else return sub 
    845845    where 
    846     findPerl5Sub name = do 
    847         sv      <- fromVal =<< fromVal =<< evalExp (head invs) 
    848         -- liftIO $ print ("Starting to handle", name, sv) 
    849         found   <- liftIO $ canPerl5 sv (tail name) 
    850         -- liftIO $ print ("Stage 1", found) 
    851         if found then runPerl5Sub name else do 
    852         sub     <- findSub' name 
    853         -- liftIO $ print ("Stage 2", sub) 
    854         if isJust sub then return sub else do 
    855         found   <- liftIO $ canPerl5 sv "AUTOLOAD" 
    856         -- liftIO $ print ("Stage 3", found) 
    857         if found then runPerl5Sub name else do 
    858         possiblyBuildMetaopVCode name 
    859846    runPerl5Sub name = do 
    860         subs    <- findWithPkg "Scalar::Perl5" "&AUTOLOAD" 
    861         writeVar "$*AUTOLOAD" (VStr $ tail name) 
    862         return subs 
     847        metaSub <- possiblyBuildMetaopVCode name 
     848        if isJust metaSub then return metaSub else do 
     849        return . Just $ mkPrim 
     850            { subName     = name 
     851            , subType     = SubPrim 
     852            , subAssoc    = "pre" 
     853            , subParams   = makeParams ["Object", "List"] 
     854            , subReturns  = mkType "Scalar::Perl5" 
     855            , subBody     = Prim $ \(inv:args:_) -> do 
     856                sv      <- fromVal inv 
     857                svs     <- fromVals args 
     858                found   <- liftIO $ canPerl5 sv (tail name) `mplus` canPerl5 sv "AUTOLOAD" 
     859                if not found then evalExp (App (Var name) [] (map (Val . PerlSV) (sv:svs))) else do 
     860                cxt     <- asks envContext 
     861                rv      <- liftIO $ callPerl5 (tail name) (sv:svs) (enumCxt cxt) 
     862                return $ PerlSV rv 
     863            } 
    863864    possiblyBuildMetaopVCode op' | "&prefix:[" `isPrefixOf` op', "]" `isSuffixOf` op' = do  
    864865        -- Strip the trailing "]" from op 
  • src/Pugs/Prim.hs

    r3880 r3888  
    243243op1 "eval_perl5" = \v -> do 
    244244    str <- fromVal v 
     245    cxt <- asks envContext 
    245246    tryIO undef $ do 
    246         sv <- evalPerl5 str 
     247        sv <- evalPerl5 str $ enumCxt cxt 
    247248        return $ PerlSV sv 
    248249op1 "eval_haskell" = op1EvalHaskell 
     
    807808op2 "say" = \x (VList ys) -> op1Print hPutStrLn (VList (x:ys)) 
    808809op2 "print" = \x (VList ys) -> op1Print hPutStr (VList (x:ys)) 
    809 op2 "Scalar::Perl5::AUTOLOAD" = \inv args -> do 
    810     meth <- readVar "$*AUTOLOAD" 
    811     str  <- fromVal meth 
    812     sv   <- fromVal inv 
    813     svs  <- fromVals args 
    814     rv   <- liftIO $ callPerl5 str (sv:svs) 
    815     return $ PerlSV rv 
    816810op2 other = \_ _ -> fail ("Unimplemented binaryOp: " ++ other) 
    817811 
     
    14041398\\n   Int       pre     arity   (Code)\ 
    14051399\\n   Bool      pre     Thread::yield   (Thread)\ 
    1406 \\n   Scalar::Perl5    pre     Scalar::Perl5::AUTOLOAD (Object: List)\ 
    14071400\\n   List      pre     Pugs::Internals::runInteractiveCommand    (?Str=$_)\ 
    14081401\\n   List      pre     Pugs::Internals::openFile    (?Str,?Str=$_)\