Changeset 16418

Show
Ignore:
Timestamp:
05/18/07 00:19:55 (18 months ago)
Author:
audreyt
Message:

* Pugs.Monads: Finish up the enterSub/reclose* subsystem;

&?CALLER_CONTINUATION is disabled temporarily because
we're not at all sure if it's lexical or not -- this
perhaps needs a spec discussion.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Monads.hs

    r16380 r16418  
    2424    enterFrame, assertFrame, emptyFrames, 
    2525 
    26     reclosePad, recloseCode, 
     26    reclosePad, recloseCode, recloseVal, 
    2727     
    2828    MaybeT, runMaybeT 
     
    199199enterBlock :: Eval Val -> Eval Val 
    200200enterBlock action = do 
    201     pad <- stm $ newTVar emptyPad 
    202     local (\e -> e{ envLexPads = (pad:envLexPads e) }) action 
     201    local (\e -> e{ envLexPads = (PRuntime emptyPad:envLexPads e) }) action 
    203202 
    204203recloseLexPad :: LexPad -> STM LexPad 
     
    208207recloseLexPad lpad  = return lpad 
    209208 
    210 recloseRef :: VRef -> STM VRef 
    211 recloseRef ref@(MkRef (ICode cv)) 
    212     | Just vcode <- fromTypeable cv 
    213     , Nothing    <- subStarted vcode 
    214     , subType vcode /= SubPrim = do 
     209recloseExp :: Exp -> STM Exp 
     210recloseExp (Val val) = fmap Val (recloseVal val) 
     211recloseExp exp       = return exp 
     212 
     213recloseVal :: Val -> STM Val 
     214recloseVal (VRef ref)   = do 
     215    fmap VRef (recloseRef ref) 
     216recloseVal (VCode code) = do 
     217    fmap VCode (recloseCode code) 
     218recloseVal (VList list) = do 
     219    fmap VList (mapM recloseVal list) 
     220recloseVal val          = return val 
     221 
     222 
     223recloseTraitBlocks :: TraitBlocks -> STM TraitBlocks 
     224recloseTraitBlocks (MkTraitBlocks a b c d e f g h i j k) = do 
     225    [a', b', c', d', e', f', g', h', i', j', k'] <- mapM (mapM recloseCode) [a, b, c, d, e, f, g, h, i, j, k] 
     226    return $ MkTraitBlocks a' b' c' d' e' f' g' h' i' j' k' 
     227 
     228recloseCode :: VCode -> STM VCode 
     229recloseCode vcode 
     230    | Nothing    <- subStarted vcode = do 
     231--  , subType vcode /= SubPrim = do 
    215232        outers'     <- mapM recloseLexPad (subOuterPads vcode) 
    216233        inner'      <- reclosePad (subInnerPad vcode) 
     234        body'       <- transformExp recloseExp (subBody vcode) 
    217235        started'    <- newTVar False 
    218         return . MkRef . ICode $ vcode 
    219             { subOuterPads = outers' 
    220             , subInnerPad  = inner' 
    221             , subStarted   = Just started' 
     236        traits'     <- recloseTraitBlocks (subTraitBlocks vcode) 
     237        return $ vcode 
     238            { subOuterPads   = outers' 
     239            , subInnerPad    = inner' 
     240            , subBody        = body' 
     241            , subStarted     = Just started' 
     242            , subTraitBlocks = traits' 
    222243            } 
    223     | otherwise = return ref 
     244recloseCode vcode = return vcode 
     245 
     246recloseRef :: VRef -> STM VRef 
     247recloseRef (MkRef (ICode cv)) 
     248    | Just vcode <- fromTypeable cv = do 
     249        vcode'   <- recloseCode vcode 
     250        return . MkRef . ICode $ vcode' 
    224251recloseRef ref = return ref 
    225252 
     
    247274    return (name, entry') 
    248275 
    249 enterSub :: VCode -> Eval Val -> Eval Val 
    250 enterSub sub action 
    251     | typ >= SubPrim = runAction -- primitives just happen 
    252     | otherwise     = do 
    253         env <- ask 
    254         pad <- case subStarted sub of 
    255             Just tvar   -> do 
    256                 started <- stm $ readTVar tvar 
    257                 if started then refreshPad (subInnerPad sub) else do 
    258                     -- XXX - Fix up all mpads, recursively, here! 
    259                     stm $ writeTVar tvar True 
    260                     return (subInnerPad sub) 
    261             _           -> return (subInnerPad sub) 
    262         rv  <- case typ of 
    263             _ | typ >= SubBlock -> tryT $ do 
    264                 doFix <- fixEnv return env pad 
    265                 local doFix runAction 
    266  
    267             -- For coroutines, we secretly store a continuation into subCont 
    268             -- whenever "yield" occurs in it.  However, the inner CC must be 
    269             -- delimited on the subroutine boundary, otherwise the resuming 
    270             -- continuation will continue into the rest of the program, 
    271             -- which is now how coroutines are supposed to work. 
    272             -- On the other hand, the normal &?CALLER_CONTINUATION must still 
    273             -- work as an undelimiated continuation, which is why callCC here 
    274             -- occurs before resetT. 
    275             SubCoroutine -> tryT . callCC $ \cc -> resetT $ do 
    276                 doFix <- fixEnv cc env pad 
    277                 local doFix runAction 
    278  
    279             _ -> tryT . callCC $ \cc -> do 
    280                 doFix <- fixEnv cc env pad 
    281                 local doFix runAction 
     276data ApplyKind = AKInline | AKDisplaced deriving (Show) 
     277 
     278enterSub :: ApplyKind -> VCode -> Eval Val -> Eval Val 
     279enterSub appKind sub action = do 
     280    env <- ask 
     281    pad <- case subStarted sub of 
     282        Just tvar   -> do 
     283            started <- stm $ readTVar tvar 
     284            if started 
     285                then refreshPad (subInnerPad sub) 
     286                    -- `finallyM` warn "======= REFRESHED ==========" (subInnerPad sub, sub) 
     287                else (stm $ do 
     288                    writeTVar tvar True 
     289                    reclosePad (subInnerPad sub)) 
     290                    -- `finallyM` warn "======= RECLOSED ==========" (tvar, subInnerPad sub) 
     291        _           -> do 
     292            -- warn "==== NOTHING ====" (subInnerPad sub) 
     293            return (subInnerPad sub) 
     294    rv  <- case typ of 
     295        -- For coroutines, we secretly store a continuation into subCont 
     296        -- whenever "yield" occurs in it.  However, the inner CC must be 
     297        -- delimited on the subroutine boundary, otherwise the resuming 
     298        -- continuation will continue into the rest of the program, 
     299        -- which is now how coroutines are supposed to work. 
     300        -- On the other hand, the normal &?CALLER_CONTINUATION must still 
     301        -- work as an undelimiated continuation, which is why callCC here 
     302        -- occurs before resetT. 
     303        SubCoroutine -> tryT . callCC $ \cc -> resetT $ do 
     304            doFix <- fixEnv cc env pad 
     305            local doFix runAction 
     306 
     307        _ | typ >= SubBlock -> tryT $ do 
     308            doFix <- fixEnv return env pad 
     309            local doFix runAction 
     310 
     311        _ -> tryT . callCC $ \cc -> do 
     312            doFix <- fixEnv cc env pad 
     313            local doFix runAction 
     314 
     315    -- warn "XXX" () 
     316    doFix <- fixEnv return env pad 
     317    local doFix $ do 
    282318        runBlocks (filter (rejectKeepUndo rv . subName) . subLeaveBlocks) 
    283     when (rv == VControl (ControlLoop LoopLast)) $ 
    284         -- We won't have a chance to run the LAST block 
    285         -- once we exit outside the lexical block, so do it now 
    286         runBlocks subLastBlocks 
    287     assertBlocks subPostBlocks "POST" 
     319        when (rv == VControl (ControlLoop LoopLast)) $ 
     320            -- We won't have a chance to run the LAST block 
     321            -- once we exit outside the lexical block, so do it now 
     322            runBlocks subLastBlocks 
     323        assertBlocks subPostBlocks "POST" 
    288324    case rv of 
    289325        VControl l@(ControlLeave ftyp depth val) -> do 
     
    324360    orig sub = sub { subBindings = [], subParams = (map fst (subBindings sub)) } 
    325361 
    326     genRecSym = genSym (if typ >= SubBlock then cast "&?BLOCK" else cast "&?ROUTINE") (codeRef (orig sub)) 
    327  
    328362    fixEnv :: (Val -> Eval Val) -> Env -> Pad -> Eval (Env -> Env) 
    329363    fixEnv cc env pad 
    330         | AKInline <- appKind = do 
    331             -- Entering an inline call. 
    332             subRec    <- genRecSym 
     364        | SubPrim <- typ = do 
    333365            return $ \e -> e 
    334                 { envLexical = subRec (envLexical env `mappend` pad) 
    335                 , envPackage = subPackage sub 
     366                { envLexical = pad `mappend` envLexical env 
    336367                , envLexPads = (PRuntime pad:envLexPads env) 
    337368                } 
    338369        | AKInline <- appKind = do 
    339370            -- Entering an inline call. 
    340             subRec    <- genRecSym 
    341371            return $ \e -> e 
    342                 { envLexical = subRec (pad `mappend` envLexical env) 
     372                { envLexical = pad `mappend` envLexical env 
    343373                , envPackage = subPackage sub 
    344374                , envLexPads = (PRuntime pad:envLexPads env) 
    345375                } 
    346376        | otherwise = do 
    347             subRec    <- genRecSym 
    348             callerRec <- genSym (cast "&?CALLER_CONTINUATION") (codeRef $ ccSub cc env) 
    349             pad'      <- fmap (`mappend` pad) $ mergeLexPads (subOuterPads sub) 
     377            -- callerRec <- genSym (cast "&?CALLER_CONTINUATION") (codeRef $ ccSub cc env) 
     378            pad'      <- fmap (pad `mappend`) $ mergeLexPads (subOuterPads sub) 
    350379            return $ \e -> e 
    351                 { envLexical = combine ([subRec, callerRec]) pad' 
     380                { envLexical = pad' -- combine ([callerRec]) pad' 
    352381                , envPackage = subPackage sub 
    353382                , envLexPads = (PRuntime pad':subOuterPads sub)