Changeset 16341
- Timestamp:
- 05/17/07 23:17:45 (18 months ago)
- Files:
-
- 12 modified
-
docs/notes/pad-refactoring.pod (modified) (1 diff)
-
src/DrIFT/YAML.hs (modified) (3 diffs)
-
src/Pugs/AST/Internals.hs (modified) (2 diffs)
-
src/Pugs/Eval.hs (modified) (8 diffs)
-
src/Pugs/Meta/Str.hs (modified) (1 diff)
-
src/Pugs/Monads.hs (modified) (1 diff)
-
src/Pugs/Parser.hs (modified) (8 diffs)
-
src/Pugs/Parser/Program.hs (modified) (2 diffs)
-
src/Pugs/Parser/Types.hs (modified) (2 diffs)
-
src/Pugs/Parser/Util.hs (modified) (1 diff)
-
src/Pugs/Prim/Code.hs (modified) (1 diff)
-
src/Pugs/Types.hs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
docs/notes/pad-refactoring.pod
r16330 r16341 14 14 -- otoh, it's rare enough that we don't actually care. 15 15 -- 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. 16 20 17 21 -- envLexPads :: LexPads -
src/DrIFT/YAML.hs
r16336 r16341 16 16 import Data.List ( foldl' ) 17 17 import Data.Int ( Int32, Int64 ) 18 import Pugs.Internals (encodeUTF8, decodeUTF8 )18 import Pugs.Internals (encodeUTF8, decodeUTF8, addressOf) 19 19 import Data.HashTable (HashTable) 20 20 import qualified UTF8 as Buf 21 21 import qualified Data.ByteString as Bytes 22 import qualified Data.Int Map as IntMap22 import qualified Data.IntSet as IntSet 23 23 import qualified Data.HashTable as Hash 24 24 … … 28 28 type YAMLKey = String 29 29 type YAMLVal = YamlNode 30 type SeenCache = IORef (IntMap.IntMap (Ptr ()))30 type SeenCache = IORef IntSet.IntSet 31 31 32 32 toYamlNode :: YAML a => a -> IO YamlNode 33 33 toYamlNode x = do 34 cache <- newIORef Int Map.empty34 cache <- newIORef IntSet.empty 35 35 runReaderT (asYAML x) cache 36 36 … … 235 235 236 236 asYAMLanchor :: a -> EmitAs YamlNode -> EmitAs YamlNode 237 asYAMLanchor _ m = m 238 {-do 237 asYAMLanchor x m = do 239 238 cache <- ask 240 239 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 244 242 then return nilNode{ n_anchor = AReference ptr } 245 243 else do 246 liftIO $ modifyIORef cache (Int Map.insert ptr ref)244 liftIO $ modifyIORef cache (IntSet.insert ptr) 247 245 rv <- m 248 246 return rv{ n_anchor = AAnchor ptr } 249 -}250 247 251 248 asYAMLwith :: (YAML a, YAML b) => (a -> EmitAs b) -> a -> EmitAs YamlNode -
src/Pugs/AST/Internals.hs
r16340 r16341 1312 1312 defaultArrayParam = buildParam "" "*" "@_" (Val VUndef) 1313 1313 defaultHashParam = buildParam "" "*" "%_" (Val VUndef) 1314 defaultScalarParam = buildParam "" "?" "$_" (Var $ cast "$ _")1314 defaultScalarParam = buildParam "" "?" "$_" (Var $ cast "$OUTER::_") 1315 1315 1316 1316 type DebugInfo = Maybe (TVar (Map ID String)) … … 1558 1558 1559 1559 writeVar :: 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 1560 writeVar 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 1568 1572 1569 1573 readVar :: Var -> Eval Val -
src/Pugs/Eval.hs
r16340 r16341 445 445 unless (isEmptyParams (subParams sub)) $ 446 446 fail "Blocks with implicit params cannot occur at statement level" 447 env <- ask448 447 enterSub sub . reduce $ case unwrap (subBody sub) of 449 448 Syn "block" [exp] -> case unwrap exp of … … 475 474 -- newBody <- transformExp cloneBodyStates $ subBody sub 476 475 -- 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) 479 479 return $ VCode sub 480 480 { subCont = cont 481 , subOuterPads = envLexPads env 482 , subLexical = pad 481 , subOuterPads = lpads 482 , subInnerPad = inner 483 , subLexical = outer `mappend` inner 483 484 , subStarted = started 484 485 } 485 486 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) 486 498 -- cloneBodyStates (Pad scope pad exp) | scope <= SMy = do 487 499 -- pad' <- clonePad pad 488 500 -- return $ Pad scope pad' exp 489 501 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) 490 509 clonePad pad = stm $ do 491 510 fmap listToPad $ forM (padToList pad) $ \(var, entry) -> do … … 503 522 clonePadEntry x@PELexical{} f = do 504 523 tvar' <- newTVar =<< f x 505 fresh' <- newTVar False506 524 return x{ pe_store = tvar' } 507 525 … … 1350 1368 applyThunk styp bound@(arg:_) thunk = do 1351 1369 -- introduce self and $_ as the first invocant. 1370 {- 1352 1371 inv <- case styp of 1353 1372 SubPointy -> aliased [cast "$_"] 1354 _ | styp <= SubMethod -> aliased [cast "&self"] -- , "$_"]1373 _ | styp <= SubMethod -> aliased [cast "&self"] 1355 1374 _ -> 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 1385 bindVar :: Var -> Val -> Eval () 1386 bindVar 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 1368 1398 1369 1399 {-| … … 1411 1441 ++ show ((genericLength (take 1000 extra)) + n) ++ " actual, " 1412 1442 ++ show n ++ " expected" 1413 (syms, bound) <- doBind [](subBindings sub)1443 bound <- mapM doBind (subBindings sub) 1414 1444 -- trace (show bound) $ return () 1415 val <- local fixEnv $ enterLex syms $do1445 val <- local fixEnv $ do 1416 1446 (`juncApply` bound) $ \realBound -> do 1417 1447 enterSub sub $ case cont of … … 1441 1471 fixEnv | typ >= SubBlock = id 1442 1472 | 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 1446 1475 -- trace ("<== " ++ (show (prm, exp))) $ return () 1447 1476 let var = paramName prm … … 1449 1478 (val, coll) <- enterContext cxt $ case exp of 1450 1479 Syn "param-default" [exp, Val (VCode sub)] -> do 1451 local (fixSub sub . fixEnv) $ e nterLex syms $ expToVal prm exp1480 local (fixSub sub . fixEnv) $ expToVal prm exp 1452 1481 _ -> expToVal prm exp 1453 1482 -- 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 1458 1486 expToVal :: Param -> Exp -> Eval (Val, Bool) 1459 1487 expToVal MkOldParam{ isLazy = thunk, isLValue = lv, paramContext = cxt, paramName = var, isWritable = rw } exp = do … … 1562 1590 Syn "block" [Val VCode{}] -> fromClosure x 1563 1591 Syn "block" [_] -> do 1564 env <- ask1565 1592 return $ mkCode 1566 1593 { -- subEnv = Just env - XXX -
src/Pugs/Meta/Str.hs
r15829 r16341 1 1 {-# OPTIONS_GHC -fglasgow-exts #-} 2 2 3 module Pugs.Meta.Str where3 module Pugs.Meta.Str (_StrClass) where 4 4 import Data.Maybe 5 5 import Pugs.Val -
src/Pugs/Monads.hs
r16340 r16341 276 276 -- Entering a block. 277 277 blockRec <- genSym (cast "&?BLOCK") (codeRef (orig sub)) 278 pad <- fmap (`mappend` pad) $ mergeLexPads (subOuterPads sub)279 278 return $ \e -> e 280 { envLexical = combine [blockRec] pad279 { envLexical = combine [blockRec] (envLexical env `mappend` pad) 281 280 , envPackage = subPackage sub 282 , envLexPads = (PRuntime pad: subOuterPads sub)281 , envLexPads = (PRuntime pad:envLexPads env) 283 282 } 284 283 | otherwise = do 285 284 subRec <- genSym (cast "&?ROUTINE") (codeRef (orig sub)) 286 285 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) 288 287 return $ \e -> e 289 { envLexical = combine ([subRec, callerRec]) pad 288 { envLexical = combine ([subRec, callerRec]) pad' 290 289 , envPackage = subPackage sub 291 , envLexPads = (PRuntime pad :subOuterPads sub)290 , envLexPads = (PRuntime pad':subOuterPads sub) 292 291 } 293 292 ccSub :: (Val -> Eval Val) -> Env -> VCode -
src/Pugs/Parser.hs
r16340 r16341 26 26 ruleInvocationParens, verbatimVarNameString, ruleVerbatimBlock, retVerbatimBlock, 27 27 ruleBlockLiteral, ruleDoBlock, regularVarName, regularVarNameForSigil, ruleNamedMethodCall, 28 29 genParamEntries 28 30 ) where 29 31 import Pugs.Internals … … 388 390 -- XXX - Generate init pad for each of our params... 389 391 390 paramsPad <- genParamEntries s ignature392 paramsPad <- genParamEntries styp signature 391 393 modify $ \s -> s{ s_protoPad = paramsPad } 392 394 block <- ruleBlock … … 410 412 411 413 -- Don't add the sub if it's unsafe and we're in safemode. 412 if "unsafe" `elem` traits && safeMode then return emptyExpelse do414 if "unsafe" `elem` traits && safeMode then return (Var var) else do 413 415 (`finallyM` clearDynParsers) $ if not (isLexicalVar var) 414 then do unsafeEvalExp $ mkSym sub nameQualified Noop416 then do unsafeEvalExp $ mkSym sub nameQualified (Var var) 415 417 else do 416 let doExportCode rv = if not isExported then return emptyExpelse do418 let doExportCode = if not isExported then return (Var var) else do 417 419 -- we mustn't perform the export immediately upon parse, because 418 420 -- then only the first consumer of a module will see it. Instead, … … 433 435 , subParams = multiSig 434 436 } 435 return . seq rv$ Syn "|="437 unsafeEvalExp $ Syn "|=" 436 438 [ Syn "{}" [_Var ("%" ++ pkg ++ "::EXPORTS"), Val $ VStr exportedName] 437 439 , Val exportedSub 438 440 ] 441 return (Var var) 439 442 case lookupPad var newPad of 440 443 Just entry -> do 441 Val val@(VCode code) <- unsafeEvalExp (Syn "sub" [Val sub])444 Val (VCode code) <- unsafeEvalExp (Syn "sub" [Val sub]) 442 445 let entry' = entry{ pe_proto = cv' } 443 446 cv' = MkRef (ICode code) 444 447 addBlockPad (adjustPad (const entry') var newPad) 445 result <- doExportCode val448 result <- doExportCode 446 449 case entry' of 447 PEConstant{} -> return result450 PEConstant{} -> return result 448 451 _ -> return $! unsafePerformSTM $! do 449 452 rv <- writePadEntry entry' cv' … … 1248 1251 ruleBlockVariants variants = do 1249 1252 (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 1250 1257 block <- ruleBlock 1251 1258 retBlock styp formal lvalue block … … 1329 1336 | otherwise = t 1330 1337 1331 genParamEntries params = genNameTypeEntries SMy (paramsToNameTypes params "") 1338 genParamEntries 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) 1332 1348 1333 1349 ruleVarDecl :: RuleParser Exp … … 1371 1387 makeAccessor prm = do 1372 1388 -- Generate accessor for class attributes. 1373 pkg <- asks envPackage 1389 pkg <- asks envPackage 1390 paramsPad <- genParamEntries SubPrim [selfParam $ cast pkg] 1374 1391 let sub = mkPrim 1375 1392 { isMulti = False … … 1380 1397 , subLValue = isWritable prm 1381 1398 , subType = SubMethod 1399 , subInnerPad = paramsPad 1382 1400 } 1383 1401 fun = Var var{ v_twigil = TNil } -
src/Pugs/Parser/Program.hs
r16340 r16341 165 165 ruleProgram = rule "program" $ do 166 166 env <- getRuleEnv 167 168 topPad <- genParamEntries SubRoutine [defaultArrayParam] 169 modify $ \s -> s{ s_protoPad = topPad } 170 167 171 block <- ruleBlockBody 168 main <- retVerbatimBlock Sub RoutineNothing False $172 main <- retVerbatimBlock SubPointy Nothing False $ 169 173 block{ bi_body = mergeStmts emptyExp $ bi_body block } 174 170 175 -- error $ show statements 171 176 eof … … 185 190 env' <- getRuleEnv 186 191 return $ env' 187 { envBody = App main Nothing [ _Var "@*ARGS"]192 { envBody = App main Nothing [] -- _Var "@*ARGS"] 188 193 , envPackage = envPackage env 189 194 } -
src/Pugs/Parser/Types.hs
r16340 r16341 252 252 -- First we check that our pad does not contain shadows OUTER symbols. 253 253 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) 256 258 257 259 unless (Set.null dupVars) $ do … … 261 263 262 264 -- 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) 265 266 266 267 let myKnownVars = Map.fromDistinctAscList [ (var, compPad) | var <- Set.toAscList myVars ] -
src/Pugs/Parser/Util.hs
r16340 r16341 118 118 119 119 defaultParamFor :: SubType -> [Param] 120 defaultParamFor SubBlock = [ defaultScalarParam]120 defaultParamFor SubBlock = [] -- defaultScalarParam] 121 121 defaultParamFor SubPointy = [] 122 122 defaultParamFor _ = [defaultArrayParam] -
src/Pugs/Prim/Code.hs
r16328 r16341 37 37 38 38 op1CodePos :: Val -> Eval Val 39 op1CodePos v = die "XXX - code.pos not implemented" v 39 op1CodePos v = do -- die "XXX - code.pos not implemented" v 40 return $ castV (show v) 40 41 {- 41 42 do -
src/Pugs/Types.hs
r16339 r16341 464 464 (twi, (pkg, (cat, afterCat))) 465 465 | len == 0 = (TNil, (emptyPkg, (CNil, afterSig))) 466 -- | len <= 1 = (TNil, (emptyPkg, (CNil, afterSig))) 466 467 | len == 1 = case Buf.head afterSig of 467 468 '!' -> (TGlobal, (emptyPkg, (CNil, afterSig))) -- XXX $! always global - WRONG
