Changeset 3740 for src/Pugs/Eval.hs

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.

Files:
1 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