Changeset 16341

Show
Ignore:
Timestamp:
05/17/07 23:17:45 (18 months ago)
Author:
audreyt
Message:

* Tonights work

Files:
12 modified

Legend:

Unmodified
Added
Removed
  • docs/notes/pad-refactoring.pod

    r16330 r16341  
    1414    -- otoh, it's rare enough that we don't actually care. 
    1515        -- but our Var is current symbolic. 
     16 
     17-- A subroutine when it's fully formed will always have its own pad as static. 
     18   (copied from envCompPad.) 
     19-- A subroutine when it's cloned wil use env's outer as outer. 
    1620 
    1721-- envLexPads :: LexPads 
  • src/DrIFT/YAML.hs

    r16336 r16341  
    1616import Data.List        ( foldl' ) 
    1717import Data.Int         ( Int32, Int64 ) 
    18 import Pugs.Internals (encodeUTF8, decodeUTF8) 
     18import Pugs.Internals (encodeUTF8, decodeUTF8, addressOf) 
    1919import Data.HashTable (HashTable) 
    2020import qualified UTF8 as Buf 
    2121import qualified Data.ByteString as Bytes 
    22 import qualified Data.IntMap as IntMap 
     22import qualified Data.IntSet as IntSet 
    2323import qualified Data.HashTable as Hash 
    2424 
     
    2828type YAMLKey = String 
    2929type YAMLVal = YamlNode 
    30 type SeenCache = IORef (IntMap.IntMap (Ptr ())) 
     30type SeenCache = IORef IntSet.IntSet 
    3131 
    3232toYamlNode :: YAML a => a -> IO YamlNode 
    3333toYamlNode x = do 
    34     cache   <- newIORef IntMap.empty  
     34    cache   <- newIORef IntSet.empty  
    3535    runReaderT (asYAML x) cache 
    3636 
     
    235235 
    236236asYAMLanchor :: a -> EmitAs YamlNode -> EmitAs YamlNode 
    237 asYAMLanchor _ m = m 
    238 {-do 
     237asYAMLanchor x m = do 
    239238    cache   <- ask 
    240239    seen    <- liftIO $ readIORef cache 
    241     ref     <- liftIO $ fmap castStablePtrToPtr (newStablePtr x) 
    242     let ptr = ref `minusPtr` nullPtr 
    243     if IntMap.member ptr seen 
     240    let ptr = -(fromEnum (addressOf x)) 
     241    if IntSet.member ptr seen 
    244242        then return nilNode{ n_anchor = AReference ptr }  
    245243        else do 
    246             liftIO $ modifyIORef cache (IntMap.insert ptr ref) 
     244            liftIO $ modifyIORef cache (IntSet.insert ptr) 
    247245            rv  <- m 
    248246            return rv{ n_anchor = AAnchor ptr } 
    249 -} 
    250247 
    251248asYAMLwith :: (YAML a, YAML b) => (a -> EmitAs b) -> a -> EmitAs YamlNode 
  • src/Pugs/AST/Internals.hs

    r16340 r16341  
    13121312defaultArrayParam   = buildParam "" "*" "@_" (Val VUndef) 
    13131313defaultHashParam    = buildParam "" "*" "%_" (Val VUndef) 
    1314 defaultScalarParam  = buildParam "" "?" "$_" (Var $ cast "$_") 
     1314defaultScalarParam  = buildParam "" "?" "$_" (Var $ cast "$OUTER::_") 
    13151315 
    13161316type DebugInfo = Maybe (TVar (Map ID String)) 
     
    15581558 
    15591559writeVar :: Var -> Val -> Eval () 
    1560 writeVar name val = do 
    1561     glob <- askGlobal 
    1562     case lookupPad name glob of 
    1563         Just PEConstant{} -> fail $ "Cannot rebind constant: " ++ show name 
    1564         Just c -> do 
    1565             ref <- stm $ readTVar (pe_store c) 
    1566             writeRef ref val 
    1567         _  -> fail $ "Cannot bind to non-existing variable: " ++ show name 
     1560writeVar var val 
     1561    | isLexicalVar var  = doWriteVar (asks envLexical) 
     1562    | otherwise         = doWriteVar askGlobal 
     1563    where 
     1564    doWriteVar askPad = do 
     1565        pad <- askPad 
     1566        case lookupPad var pad of 
     1567            Just PEConstant{} -> fail $ "Cannot rebind constant: " ++ show var 
     1568            Just c -> do 
     1569                ref <- stm $ readTVar (pe_store c) 
     1570                writeRef ref val 
     1571            _  -> fail $ "Cannot bind to non-existing variable: " ++ show var 
    15681572 
    15691573readVar :: Var -> Eval Val 
  • src/Pugs/Eval.hs

    r16340 r16341  
    445445        unless (isEmptyParams (subParams sub)) $ 
    446446            fail "Blocks with implicit params cannot occur at statement level" 
    447         env <- ask 
    448447        enterSub sub . reduce $ case unwrap (subBody sub) of 
    449448            Syn "block" [exp] -> case unwrap exp of 
     
    475474    -- newBody <- transformExp cloneBodyStates $ subBody sub 
    476475    -- add &?BLOCK &?ROUTINE etc here 
    477     started <- if isCompileTime env then return Nothing else fmap Just (stm $ newTVar False) 
    478     pad     <- fmap (`mappend` subInnerPad sub) $ mergeLexPads (envLexPads env) 
     476    started         <- if isCompileTime env then return Nothing else fmap Just (stm $ newTVar False) 
     477    inner           <- clonePad (subInnerPad sub)  
     478    (lpads, outer)  <- cloneLexPads (envLexPads env) 
    479479    return $ VCode sub 
    480480        { subCont       = cont 
    481         , subOuterPads  = envLexPads env 
    482         , subLexical    = pad 
     481        , subOuterPads  = lpads 
     482        , subInnerPad   = inner 
     483        , subLexical    = outer `mappend` inner  
    483484        , subStarted    = started 
    484485        } 
    485486    where 
     487    cloneLexPads chain = do 
     488        pads <- forM chain $ \lpad -> case lpad of 
     489            PRuntime p      -> do 
     490                p'  <- snapPad p 
     491                return (PRuntime p', p') 
     492            PCompiling p    -> do 
     493                p'  <- stm $ readTVar p 
     494                return (lpad, p') 
     495        let merged  = MkPad $ Map.unionsWith mergePadEntry (map (padEntries . snd) pads) 
     496            lexpads = map fst pads 
     497        return (lexpads, merged) 
    486498--    cloneBodyStates (Pad scope pad exp) | scope <= SMy = do 
    487499--        pad' <- clonePad pad 
    488500--        return $ Pad scope pad' exp 
    489501    cloneBodyStates x = return x -- XXX! 
     502    snapPad pad = stm $ do 
     503        fmap listToPad $ forM (padToList pad) $ \(var, entry) -> do 
     504            case entry of 
     505                PELexical{} -> do 
     506                    store <- newTVar =<< readTVar (pe_store entry) 
     507                    return (var, entry{ pe_store = store }) 
     508                _   -> return (var, entry) 
    490509    clonePad pad = stm $ do 
    491510        fmap listToPad $ forM (padToList pad) $ \(var, entry) -> do 
     
    503522    clonePadEntry x@PELexical{} f = do 
    504523        tvar'   <- newTVar =<< f x 
    505         fresh'  <- newTVar False 
    506524        return x{ pe_store = tvar' } 
    507525 
     
    13501368applyThunk styp bound@(arg:_) thunk = do 
    13511369    -- introduce self and $_ as the first invocant. 
     1370    {- 
    13521371    inv     <- case styp of 
    13531372        SubPointy               -> aliased [cast "$_"] 
    1354         _ | styp <= SubMethod   -> aliased [cast "&self"] -- , "$_"] 
     1373        _ | styp <= SubMethod   -> aliased [cast "&self"] 
    13551374        _                       -> return [] 
    1356     pad <- formal 
    1357     enterLex (inv ++ pad) $ thunk_force thunk 
    1358     where 
    1359     -- Don't generate pad entries for siglets such as "$" and "@". 
    1360     formal = sequence 
    1361         [ genSym var =<< fromVal val 
    1362         | ApplyArg var val _ <- bound 
    1363         , v_name var /= nullID 
    1364         ] 
    1365     aliased names = do 
    1366         argRef  <- fromVal (argValue arg) 
    1367         mapM (`genSym` argRef) names 
     1375    -} 
     1376    let withInv | styp <= SubMethod = (ApplyArg (cast "&self") (argValue arg) False:) 
     1377                | otherwise         = id 
     1378    sequence_ [ bindVar var val 
     1379              | ApplyArg var val _ <- withInv bound 
     1380              -- Don't generate pad entries for siglets such as "$" and "@". 
     1381              , v_name var /= nullID 
     1382              ] 
     1383    thunk_force thunk 
     1384 
     1385bindVar :: Var -> Val -> Eval () 
     1386bindVar var val 
     1387    | isLexicalVar var  = doBindVar (asks envLexical) 
     1388    | otherwise         = doBindVar askGlobal 
     1389    where 
     1390    doBindVar askPad = do 
     1391        pad <- askPad 
     1392        case lookupPad var pad of 
     1393            Just PEConstant{} -> fail $ "Cannot rebind constant: " ++ show var 
     1394            Just c -> do 
     1395                ref <- fromVal val 
     1396                stm $ writeTVar (pe_store c) ref 
     1397            _  -> fail $ "Cannot bind to non-existing variable: " ++ show var 
    13681398 
    13691399{-| 
     
    14111441                        ++ show ((genericLength (take 1000 extra)) + n) ++ " actual, " 
    14121442                        ++ show n ++ " expected" 
    1413             (syms, bound) <- doBind [] (subBindings sub) 
     1443            bound <- mapM doBind (subBindings sub) 
    14141444            -- trace (show bound) $ return () 
    1415             val <- local fixEnv $ enterLex syms $ do 
     1445            val <- local fixEnv $ do 
    14161446                (`juncApply` bound) $ \realBound -> do 
    14171447                    enterSub sub $ case cont of 
     
    14411471    fixEnv | typ >= SubBlock = id 
    14421472           | otherwise       = envEnterCaller 
    1443     doBind :: [PadMutator] -> [(Param, Exp)] -> Eval ([PadMutator], [ApplyArg]) 
    1444     doBind syms [] = return (syms, []) 
    1445     doBind syms ((prm, exp):rest) = do 
     1473    doBind :: (Param, Exp) -> Eval ApplyArg -- ([PadMutator], [ApplyArg]) 
     1474    doBind (prm, exp) = do 
    14461475        -- trace ("<== " ++ (show (prm, exp))) $ return () 
    14471476        let var = paramName prm 
     
    14491478        (val, coll) <- enterContext cxt $ case exp of 
    14501479            Syn "param-default" [exp, Val (VCode sub)] -> do 
    1451                 local (fixSub sub . fixEnv) $ enterLex syms $ expToVal prm exp 
     1480                local (fixSub sub . fixEnv) $ expToVal prm exp 
    14521481            _  -> expToVal prm exp 
    14531482        -- trace ("==> " ++ (show val)) $ return () 
    1454         boundRef <- fromVal val 
    1455         newSym   <- genSym var boundRef 
    1456         (syms', restArgs) <- doBind (newSym:syms) rest 
    1457         return (syms', ApplyArg var val coll:restArgs) 
     1483        -- boundRef <- fromVal val 
     1484        -- newSym   <- genSym var boundRef 
     1485        return $ ApplyArg var val coll 
    14581486    expToVal :: Param -> Exp -> Eval (Val, Bool) 
    14591487    expToVal MkOldParam{ isLazy = thunk, isLValue = lv, paramContext = cxt, paramName = var, isWritable = rw } exp = do 
     
    15621590    Syn "block" [Val VCode{}]   -> fromClosure x 
    15631591    Syn "block" [_]             -> do 
    1564         env <- ask 
    15651592        return $ mkCode 
    15661593            { -- subEnv        = Just env - XXX 
  • src/Pugs/Meta/Str.hs

    r15829 r16341  
    11{-# OPTIONS_GHC -fglasgow-exts #-} 
    22 
    3 module Pugs.Meta.Str where 
     3module Pugs.Meta.Str (_StrClass) where 
    44import Data.Maybe 
    55import Pugs.Val 
  • src/Pugs/Monads.hs

    r16340 r16341  
    276276            -- Entering a block. 
    277277            blockRec  <- genSym (cast "&?BLOCK") (codeRef (orig sub)) 
    278             pad       <- fmap (`mappend` pad) $ mergeLexPads (subOuterPads sub) 
    279278            return $ \e -> e 
    280                 { envLexical = combine [blockRec] pad 
     279                { envLexical = combine [blockRec] (envLexical env `mappend` pad) 
    281280                , envPackage = subPackage sub 
    282                 , envLexPads = (PRuntime pad:subOuterPads sub) 
     281                , envLexPads = (PRuntime pad:envLexPads env) 
    283282                } 
    284283        | otherwise = do 
    285284            subRec    <- genSym (cast "&?ROUTINE") (codeRef (orig sub)) 
    286285            callerRec <- genSym (cast "&?CALLER_CONTINUATION") (codeRef $ ccSub cc env) 
    287             pad       <- fmap (`mappend` pad) $ mergeLexPads (subOuterPads sub) 
     286            pad'      <- fmap (`mappend` pad) $ mergeLexPads (subOuterPads sub) 
    288287            return $ \e -> e 
    289                 { envLexical = combine ([subRec, callerRec]) pad 
     288                { envLexical = combine ([subRec, callerRec]) pad' 
    290289                , envPackage = subPackage sub 
    291                 , envLexPads = (PRuntime pad:subOuterPads sub) 
     290                , envLexPads = (PRuntime pad':subOuterPads sub) 
    292291                } 
    293292    ccSub :: (Val -> Eval Val) -> Env -> VCode 
  • src/Pugs/Parser.hs

    r16340 r16341  
    2626    ruleInvocationParens, verbatimVarNameString, ruleVerbatimBlock, retVerbatimBlock, 
    2727    ruleBlockLiteral, ruleDoBlock, regularVarName, regularVarNameForSigil, ruleNamedMethodCall, 
     28 
     29    genParamEntries 
    2830) where 
    2931import Pugs.Internals 
     
    388390    -- XXX - Generate init pad for each of our params... 
    389391 
    390     paramsPad   <- genParamEntries signature 
     392    paramsPad   <- genParamEntries styp signature 
    391393    modify $ \s -> s{ s_protoPad = paramsPad } 
    392394    block       <- ruleBlock 
     
    410412     
    411413    -- Don't add the sub if it's unsafe and we're in safemode. 
    412     if "unsafe" `elem` traits && safeMode then return emptyExp else do 
     414    if "unsafe" `elem` traits && safeMode then return (Var var) else do 
    413415    (`finallyM` clearDynParsers) $ if not (isLexicalVar var) 
    414         then do unsafeEvalExp $ mkSym sub nameQualified Noop 
     416        then do unsafeEvalExp $ mkSym sub nameQualified (Var var) 
    415417        else do 
    416             let doExportCode rv = if not isExported then return emptyExp else do 
     418            let doExportCode = if not isExported then return (Var var) else do 
    417419                    -- we mustn't perform the export immediately upon parse, because 
    418420                    -- then only the first consumer of a module will see it. Instead, 
     
    433435                                , subParams = multiSig 
    434436                                } 
    435                     return . seq rv $ Syn "|=" 
     437                    unsafeEvalExp $ Syn "|=" 
    436438                        [ Syn "{}" [_Var ("%" ++ pkg ++ "::EXPORTS"), Val $ VStr exportedName] 
    437439                        , Val exportedSub 
    438440                        ] 
     441                    return (Var var) 
    439442            case lookupPad var newPad of 
    440443                Just entry  -> do 
    441                     Val val@(VCode code) <- unsafeEvalExp (Syn "sub" [Val sub]) 
     444                    Val (VCode code) <- unsafeEvalExp (Syn "sub" [Val sub]) 
    442445                    let entry'  = entry{ pe_proto = cv' } 
    443446                        cv'     = MkRef (ICode code) 
    444447                    addBlockPad (adjustPad (const entry') var newPad) 
    445                     result <- doExportCode val 
     448                    result <- doExportCode 
    446449                    case entry' of 
    447                         PEConstant{} -> return result 
     450                        PEConstant{}    -> return result 
    448451                        _               -> return $! unsafePerformSTM $! do 
    449452                            rv  <- writePadEntry entry' cv' 
     
    12481251ruleBlockVariants variants = do 
    12491252    (styp, formal, lvalue) <- option (SubBlock, Nothing, False) $ choice variants 
     1253 
     1254    paramsPad  <- genParamEntries styp (maybe (defaultParamFor styp) id formal) 
     1255    modify $ \s -> s{ s_protoPad = paramsPad } 
     1256 
    12501257    block <- ruleBlock 
    12511258    retBlock styp formal lvalue block 
     
    13291336        | otherwise                     = t 
    13301337 
    1331 genParamEntries params = genNameTypeEntries SMy (paramsToNameTypes params "") 
     1338genParamEntries styp params 
     1339    | styp >= SubBlock  = genNameTypeEntries SMy nameTypes 
     1340    | otherwise         = genNameTypeEntries SMy (foldl' withImplicit nameTypes implicitNames) 
     1341    where 
     1342    nameTypes       = paramsToNameTypes params "" 
     1343    names           = Set.fromList $ map (\(n, _, _, _) -> n) nameTypes 
     1344    implicitNames   = ["$_"] -- , "$/", "$!"] 
     1345    withImplicit ntys name 
     1346        | Set.member (cast name) names  = ntys 
     1347        | otherwise                     = (((cast name), anyType, MkEntryFlags True, Noop):ntys) 
    13321348 
    13331349ruleVarDecl :: RuleParser Exp 
     
    13711387    makeAccessor prm = do 
    13721388        -- Generate accessor for class attributes. 
    1373         pkg <- asks envPackage 
     1389        pkg         <- asks envPackage 
     1390        paramsPad   <- genParamEntries SubPrim [selfParam $ cast pkg] 
    13741391        let sub = mkPrim 
    13751392                { isMulti       = False 
     
    13801397                , subLValue     = isWritable prm 
    13811398                , subType       = SubMethod 
     1399                , subInnerPad   = paramsPad 
    13821400                } 
    13831401            fun = Var var{ v_twigil = TNil } 
  • src/Pugs/Parser/Program.hs

    r16340 r16341  
    165165ruleProgram = rule "program" $ do 
    166166    env     <- getRuleEnv 
     167 
     168    topPad  <- genParamEntries SubRoutine [defaultArrayParam] 
     169    modify $ \s -> s{ s_protoPad = topPad } 
     170 
    167171    block   <- ruleBlockBody 
    168     main    <- retVerbatimBlock SubRoutine Nothing False $ 
     172    main    <- retVerbatimBlock SubPointy Nothing False $ 
    169173        block{ bi_body = mergeStmts emptyExp $ bi_body block } 
     174 
    170175    -- error $ show statements 
    171176    eof 
     
    185190    env' <- getRuleEnv 
    186191    return $ env' 
    187         { envBody       = App main Nothing [_Var "@*ARGS"] 
     192        { envBody       = App main Nothing [] -- _Var "@*ARGS"] 
    188193        , envPackage    = envPackage env 
    189194        } 
  • src/Pugs/Parser/Types.hs

    r16340 r16341  
    252252    -- First we check that our pad does not contain shadows OUTER symbols. 
    253253    state <- get 
    254     let myVars  = padKeys pad 
    255         dupVars = myVars `Set.intersection` Map.keysSet (s_knownVars state) 
     254    let myVars          = padKeys pad 
     255        dupVars         = myVars `Set.intersection` Map.keysSet outerKnownVars 
     256        outerKnownVars  = Map.filter (/= compPad) (s_knownVars state) 
     257        Just compPad    = envCompPad (s_env state) 
    256258 
    257259    unless (Set.null dupVars) $ do 
     
    261263 
    262264    -- Then we merge the Pad into COMPILING, and add those vars into s_knownVars. 
    263     Just compPad <- asks envCompPad 
    264     ()           <- stm $ modifyTVar compPad (`unionPads` pad) 
     265    ()  <- stm $ modifyTVar compPad (`unionPads` pad) 
    265266 
    266267    let myKnownVars = Map.fromDistinctAscList [ (var, compPad) | var <- Set.toAscList myVars ] 
  • src/Pugs/Parser/Util.hs

    r16340 r16341  
    118118     
    119119defaultParamFor :: SubType -> [Param] 
    120 defaultParamFor SubBlock    = [defaultScalarParam] 
     120defaultParamFor SubBlock    = [] -- defaultScalarParam] 
    121121defaultParamFor SubPointy   = [] 
    122122defaultParamFor _           = [defaultArrayParam] 
  • src/Pugs/Prim/Code.hs

    r16328 r16341  
    3737 
    3838op1CodePos :: Val -> Eval Val 
    39 op1CodePos v = die "XXX - code.pos not implemented" v 
     39op1CodePos v = do -- die "XXX - code.pos not implemented" v 
     40    return $ castV (show v) 
    4041{- 
    4142do 
  • src/Pugs/Types.hs

    r16339 r16341  
    464464    (twi, (pkg, (cat, afterCat))) 
    465465        | len == 0 = (TNil, (emptyPkg, (CNil, afterSig))) 
     466--      | len <= 1 = (TNil, (emptyPkg, (CNil, afterSig))) 
    466467        | len == 1 = case Buf.head afterSig of 
    467468            '!' -> (TGlobal, (emptyPkg, (CNil, afterSig)))  -- XXX $! always global - WRONG