Changeset 3740

Show
Ignore:
Timestamp:
05/23/05 16:57:32 (4 years ago)
Author:
autrijus
svk:copy_cache_prev:
5329
Message:

* move enterEvalContext to Monads.hs so Prim can use it.
* introduce the maybeM abstraction that lifts fmapM into monads.

Location:
src/Pugs
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Eval.hs

    r3727 r3740  
    145145    return $ concat (concat syms) 
    146146 
    147 enterEvalContext :: Cxt -> Exp -> Eval Val 
    148 enterEvalContext cxt = enterContext cxt . evalExp 
    149  
    150147-- Reduction --------------------------------------------------------------- 
    151148 
     
    191188    case rv of 
    192189        Nothing  -> case name of 
    193             '&':_ -> do 
    194                 sub <- findSub name [] [] 
    195                 case sub of 
    196                     Nothing  -> return Nothing 
    197                     (Just x) -> return $ Just $ codeRef x 
    198             _ -> return Nothing 
     190            ('&':_) -> maybeM (findSub name [] []) $ \sub -> do 
     191                return $ codeRef sub 
     192            _ -> return Nothing 
    199193        Just ref -> fmap Just $ liftSTM (readTVar ref) 
    200194 
     
    586580        evalRef ref 
    587581    sigil:"::()" -> do 
    588         -- These are all parts of the name 
    589         parts   <- mapM fromVal =<< mapM evalExp exps 
    590         -- Now we only have to add the sigil in front of the string and join 
    591         -- the parts with "::". 
    592         let varname = sigil:(concat . (intersperse "::") $ parts) 
    593         -- Finally, eval the varname. 
    594         evalExp . Var $ varname 
     582        -- These are all parts of the name 
     583        parts   <- mapM fromVal =<< mapM evalExp exps 
     584        -- Now we only have to add the sigil in front of the string and join 
     585        -- the parts with "::". 
     586        let varname = sigil:(concat . (intersperse "::") $ parts) 
     587        -- Finally, eval the varname. 
     588        evalExp . Var $ varname 
    595589    "{}" -> do 
    596590        let [listExp, indexExp] = exps 
     
    618612               | otherwise = MkRulePGE str g flag_s 
    619613            g = ('g' `elem` p5flags || flag_g) 
    620             p5re = mkRegexWithPCRE (encodeUTF8 str) $ 
     614            p5re = mkRegexWithPCRE (encodeUTF8 str) $ 
    621615                        [ pcreUtf8 
    622616                        , ('i' `elem` p5flags || flag_i) `implies` pcreCaseless 
     
    658652            { '-' -> "__"; _ | isAlphaNum v -> [v] ; _ -> "_" } 
    659653#endif 
    660         externRequire "Haskell" (file ++ ".o") 
     654        externRequire "Haskell" (file ++ ".o") 
    661655        retEmpty 
    662656    syn | last syn == '=' -> do 
     
    845839            if isJust subs then return subs else findSub' name 
    846840        _ -> do 
    847             sub <- findSub' name 
    848             if isNothing sub then possiblyBuildMetaopVCode name else return sub 
     841            sub <- findSub' name 
     842            if isNothing sub then possiblyBuildMetaopVCode name else return sub 
    849843    where 
    850844    possiblyBuildMetaopVCode op' | "&prefix:[" `isPrefixOf` op', "]" `isSuffixOf` op' = do  
    851         -- Strip the trailing "]" from op 
    852         let op = drop 9 (init op') 
    853         -- We try to find the userdefined sub. 
    854         -- We use the first two elements of invs as invocants, as these are the 
    855         -- types of the op. 
    856         code <- findSub ("&infix:" ++ op) (take 2 (invs ++ [Val undef, Val undef])) [] 
    857         if isNothing code then return Nothing else do 
    858         let body = \[vs] -> do 
    859                 list_of_args <- fromVal vs 
    860                 op2Fold (list_of_args) (VCode $ fromJust code) 
    861         -- Now we construct the sub. Is there a more simple way to do it? 
    862         return . Just $ mkPrim 
     845        -- Strip the trailing "]" from op 
     846        let op = drop 9 (init op') 
     847        -- We try to find the userdefined sub. 
     848        -- We use the first two elements of invs as invocants, as these are the 
     849        -- types of the op. 
     850            rv = findSub ("&infix:" ++ op) (take 2 (invs ++ [Val undef, Val undef])) [] 
     851        maybeM rv $ \code -> return $ mkPrim 
    863852            { subName     = "&prefix:[" ++ op ++ "]" 
    864853            , subType     = SubPrim 
     
    866855            , subParams   = makeParams ["List"] 
    867856            , subReturns  = mkType "Str" 
    868             , subBody     = Prim body 
     857            , subBody     = Prim $ \[vs] -> do 
     858                list_of_args <- fromVal vs 
     859                op2Fold (list_of_args) (VCode code) 
    869860            } 
     861        -- Now we construct the sub. Is there a more simple way to do it? 
    870862    possiblyBuildMetaopVCode op' | "&prefix:" `isPrefixOf` op', "\171" `isSuffixOf` op' = do  
    871         let op = drop 8 (init op') 
    872         possiblyBuildMetaopVCode ("&prefix:" ++ op ++ "<<") 
     863        let op = drop 8 (init op') 
     864        possiblyBuildMetaopVCode ("&prefix:" ++ op ++ "<<") 
    873865    possiblyBuildMetaopVCode op' | "&prefix:" `isPrefixOf` op', "<<" `isSuffixOf` op' = do  
    874         let op = drop 8 (init (init op')) 
    875         code <- findSub ("&prefix:" ++ op) [head $ invs ++ [Val undef]] [] 
    876         if isNothing code then return Nothing else do 
    877         return . Just $ mkPrim 
     866        let op = drop 8 (init (init op')) 
     867            rv = findSub ("&prefix:" ++ op) [head $ invs ++ [Val undef]] [] 
     868        maybeM rv $ \code -> return $ mkPrim 
    878869            { subName     = "&prefix:" ++ op ++ "<<" 
    879870            , subType     = SubPrim 
    880             , subAssoc    = subAssoc (fromJust code) 
    881             , subParams   = subParams (fromJust code) 
     871            , subAssoc    = subAssoc code 
     872            , subParams   = subParams code 
    882873            , subReturns  = mkType "List" 
    883874            , subBody     = Prim 
    884                 (\x -> op1HyperPrefix (fromJust code) (listArg x)) 
     875                (\x -> op1HyperPrefix code (listArg x)) 
    885876            } 
    886877    possiblyBuildMetaopVCode op' | "&postfix:\187" `isPrefixOf` op' = do 
    887         let op = drop 10 op' 
    888         possiblyBuildMetaopVCode ("&postfix:>>" ++ op) 
     878        let op = drop 10 op' 
     879        possiblyBuildMetaopVCode ("&postfix:>>" ++ op) 
    889880    possiblyBuildMetaopVCode op' | "&postfix:>>" `isPrefixOf` op' = do 
    890         let op = drop 11 op' 
    891         code <- findSub ("&postfix:" ++ op) [head $ invs ++ [Val undef]] [] 
    892         if isNothing code then return Nothing else do 
    893         return . Just $ mkPrim 
     881        let op = drop 11 op' 
     882            rv = findSub ("&postfix:" ++ op) [head $ invs ++ [Val undef]] [] 
     883        maybeM rv $ \code -> return $ mkPrim 
    894884            { subName     = "&postfix:>>" ++ op 
    895885            , subType     = SubPrim 
    896             , subAssoc    = subAssoc (fromJust code) 
    897             , subParams   = subParams (fromJust code) 
     886            , subAssoc    = subAssoc code 
     887            , subParams   = subParams code 
    898888            , subReturns  = mkType "List" 
    899889            , subBody     = Prim 
    900                 (\x -> op1HyperPostfix (fromJust code) (listArg x)) 
     890                (\x -> op1HyperPostfix code (listArg x)) 
    901891            } 
    902892    possiblyBuildMetaopVCode op' | "&infix:\187" `isPrefixOf` op', "\171" `isSuffixOf` op' = do  
    903         let op = drop 8 (init op') 
    904         possiblyBuildMetaopVCode ("&infix:>>" ++ op ++ "<<") 
     893        let op = drop 8 (init op') 
     894        possiblyBuildMetaopVCode ("&infix:>>" ++ op ++ "<<") 
    905895    possiblyBuildMetaopVCode op' | "&infix:>>" `isPrefixOf` op', "<<" `isSuffixOf` op' = do  
    906         let op = drop 9 (init (init op')) 
    907         code <- findSub ("&infix:" ++ op) (take 2 (invs ++ [Val undef, Val undef])) [] 
    908         if isNothing code then return Nothing else do 
    909         return . Just $ mkPrim 
     896        let op = drop 9 (init (init op')) 
     897            rv = findSub ("&infix:" ++ op) (take 2 (invs ++ [Val undef, Val undef])) [] 
     898        maybeM rv $ \code -> return $ mkPrim 
    910899            { subName     = "&infix:>>" ++ op ++ "<<" 
    911900            , subType     = SubPrim 
    912             , subAssoc    = subAssoc (fromJust code) 
     901            , subAssoc    = subAssoc code 
    913902            , subParams   = makeParams ["Any", "Any"] 
    914903            , subReturns  = mkType "List" 
    915             , subBody     = Prim (\[x, y] -> op2Hyper (fromJust code) x y) 
     904            , subBody     = Prim (\[x, y] -> op2Hyper code x y) 
    916905            } 
    917         -- Taken from Pugs.Prim. Probably this should be refactored. (?) 
     906        -- Taken from Pugs.Prim. Probably this should be refactored. (?) 
    918907    possiblyBuildMetaopVCode _ = return Nothing 
    919908    listArg [x] = x 
     
    922911    takeWord = takeWhile isWord . dropWhile (not . isWord) 
    923912    isWord   = not . (`elem` "(),:") 
     913    findAttrs pkg = do 
     914        maybeM (findVar (':':pkg)) $ \ref -> do 
     915            obj     <- readRef ref 
     916            fetch   <- doHash obj hash_fetchVal 
     917            fromVal =<< fetch "traits" 
    924918    findWithPkg pkg name = do 
    925         subs <- findSub' (('&':pkg) ++ "::" ++ tail name) 
    926         if isJust subs then return subs else do 
    927         -- get superclasses 
    928         rv <- findVar (':':pkg) 
    929         if isNothing rv then findSub' name else do 
    930         obj     <- readRef (fromJust rv) 
    931         fetch   <- doHash obj hash_fetchVal 
    932         attrs   <- fromVal =<< fetch "traits" 
    933         (`fix` attrs) $ \run pkgs -> do 
    934             if null pkgs then return Nothing else do 
    935             subs <- findWithPkg (head pkgs) name 
     919        subs <- findSub' (('&':pkg) ++ "::" ++ tail name) 
     920        if isJust subs then return subs else do 
     921        -- get superclasses 
     922        attrs <- findAttrs pkg 
     923        if isNothing attrs then findSub' name else do 
     924        (`fix` (fromJust attrs)) $ \run pkgs -> do 
     925            if null pkgs then return Nothing else do 
     926            subs <- findWithPkg (head pkgs) name 
    936927            if isJust subs then return subs else run (tail pkgs) 
    937928    findSub' name = do 
     
    958949        sub@(MkCode{ subType = subT, subReturns = ret, subParams = prms }) <- fromVal val 
    959950        let isGlobal = '*' `elem` n 
    960         let fun = arityMatch sub (length (invs ++ args)) slurpLen 
    961         if isNothing fun then return Nothing else do 
    962         -- if deltaFromCxt ret == 0 then return Nothing else do 
    963         let pairs = map (typeOfCxt . paramContext) prms 
    964                         `zip` (map unwrap $ invs ++ args) 
    965         deltaCxt    <- deltaFromCxt ret 
    966         deltaArgs   <- mapM deltaFromPair pairs 
    967         let bound = either (const False) (const True) $ bindParams sub invs args 
    968         return $ Just 
    969             ( (isGlobal, subT, isMulti sub, bound, sum deltaArgs, deltaCxt) 
    970             , fromJust fun 
    971             ) 
     951        let rv = return $ arityMatch sub (length (invs ++ args)) slurpLen 
     952        maybeM rv $ \fun -> do 
     953            -- if deltaFromCxt ret == 0 then return Nothing else do 
     954            let pairs = map (typeOfCxt . paramContext) prms 
     955                            `zip` (map unwrap $ invs ++ args) 
     956            deltaCxt    <- deltaFromCxt ret 
     957            deltaArgs   <- mapM deltaFromPair pairs 
     958            let bound = either (const False) (const True) $ bindParams sub invs args 
     959            return ((isGlobal, subT, isMulti sub, bound, sum deltaArgs, deltaCxt), fun) 
    972960    deltaFromCxt x  = do 
    973961        cls <- asks envClasses 
  • src/Pugs/Internals.hs

    r3690 r3740  
    2323    module Data.Dynamic, 
    2424    module Data.Unique, 
     25    module Data.FunctorM, 
    2526    module Control.Exception, 
    2627    module System.Environment, 
     
    6667    unsafePerformSTM, 
    6768    possiblyFixOperatorName, 
     69    maybeM, 
    6870) where 
    6971 
     
    98100import Data.Maybe 
    99101import Data.Either 
     102import Data.FunctorM 
    100103import Data.List ( 
    101104    (\\), find, genericLength, insert, sortBy, intersperse, 
     
    184187-- instance MonadIO STM where 
    185188--     liftIO = unsafeIOToSTM 
     189 
     190maybeM :: (FunctorM f, Monad m) => m (f a) -> (a -> m b) -> m (f b) 
     191maybeM f m = fmapM m =<< f 
    186192 
    187193{-| 
  • src/Pugs/Monads.hs

    r3724 r3740  
    4040enterContext :: Cxt -> Eval a -> Eval a 
    4141enterContext cxt = local (\e -> e{ envContext = cxt }) 
     42 
     43{-| 
     44Evaluate the specified wxpression in the specified (Perl6) context ('Cxt'). 
     45 
     46(Subsequent chained 'Eval's do /not/ see this new scope.) 
     47-} 
     48enterEvalContext :: Cxt -> Exp -> Eval Val 
     49enterEvalContext cxt = enterContext cxt . evalExp 
    4250 
    4351{-| 
  • src/Pugs/Prim.hs

    r3739 r3740  
    2727import Pugs.AST 
    2828import Pugs.Types 
     29import Pugs.Monads 
    2930import Pugs.Pretty 
    3031import Text.Printf 
     
    178179        Just subVal -> do 
    179180            sub <- fromVal subVal 
    180             evl <- asks envEval 
    181181            sorted <- (`sortByM` valList) $ \v1 v2 -> do 
    182                 rv  <- local (\e -> e{ envContext = cxtItem "Int" }) $ do 
    183                     evl (App (Val sub) [Val v1, Val v2] []) 
     182                rv  <- enterEvalContext (cxtItem "Int") $ App (Val sub) [Val v1, Val v2] [] 
    184183                int <- fromVal rv 
    185184                return (int <= (0 :: Int)) 
     
    406405    tid     <- liftIO . (if rtsSupportsBoundThreads then forkOS else forkIO) $ do 
    407406        val <- runEvalIO env $ do 
    408             evl <- asks envEval 
    409             local (\e -> e{ envContext = CxtVoid }) $ do 
    410                 evl (App (Val code) [] []) 
     407            enterEvalContext CxtVoid $ App (Val code) [] [] 
    411408        liftSTM $ tryPutTMVar lock val 
    412409        return () 
     
    827824    writeIVar (IHash attrs) named 
    828825    uniq    <- liftIO $ newUnique 
    829     return . VObject $ MkObject{ objType = typ, objAttrs = attrs, objId = uniq } 
     826    let obj = VObject $ MkObject{ objType = typ, objAttrs = attrs, objId = uniq } 
     827    -- Now start calling BUILD for each of parent classes (if defined) 
     828 
     829    return obj 
    830830op3 other = \_ _ _ -> fail ("Unimplemented 3-ary op: " ++ other) 
    831831 
     
    880880        = doHyper =<< readRef x' 
    881881        | otherwise 
    882         = do 
    883             evl <- asks envEval 
    884             local (\e -> e{ envContext = cxtItemAny }) $ do 
    885                 evl (App (Val $ VCode sub) [Val x] []) 
     882        = enterEvalContext cxtItemAny $ App (Val $ VCode sub) [Val x] [] 
    886883    hyperList []     = return [] 
    887884    hyperList (x:xs) = do 
     
    910907    = fail "Hyper OP only works on lists" 
    911908    where 
    912     doHyper x y = do 
    913         evl <- asks envEval 
    914         local (\e -> e{ envContext = cxtItemAny }) $ do 
    915             evl (App (Val $ VCode sub) [Val x, Val y] []) 
     909    doHyper x y = enterEvalContext cxtItemAny $ App (Val $ VCode sub) [Val x, Val y] [] 
    916910    hyperLists [] [] = return [] 
    917911    hyperLists xs [] = return xs