Changeset 8681 for src/Pugs/CodeGen
- Timestamp:
- 01/15/06 16:49:47 (3 years ago)
- Files:
-
- 1 modified
-
src/Pugs/CodeGen/PIR.hs (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/CodeGen/PIR.hs
r7853 r8681 14 14 -} 15 15 16 module Pugs.CodeGen.PIR (genPIR ) where16 module Pugs.CodeGen.PIR (genPIR, genPIR_YAML) where 17 17 import Pugs.Internals 18 18 import Pugs.AST … … 27 27 import Pugs.Compile 28 28 import Pugs.Run (getLibs) 29 import DrIFT.YAML 29 30 30 31 type CodeGen a = WriterT [Stmt] (ReaderT TEnv IO) a … … 78 79 trans (PExp exp) = fmap ExpLV $ trans exp 79 80 trans (PLit (PVal VUndef)) = do 80 pmc <- gen LV"undef"81 pmc <- genScalar "undef" 81 82 return $ ExpLV pmc 82 83 trans (PLit lit) = do 83 84 -- generate fresh supply and things... 84 85 litC <- trans lit 85 pmc <- gen LV"lit"86 tellIns $ pmc <== ExpLitlitC86 pmc <- genScalar "lit" 87 tellIns $ pmc <== litC 87 88 return $ ExpLV pmc 88 89 trans (PThunk exp) = do 89 [begL, sndL, retL, endL] <- genLabel ["thunkBegin", "thunkAgain", "thunkReturn", "thunkEnd"] 90 this <- genPMC "block" 91 tellIns $ InsNew (reg this) Continuation 92 tellIns $ "set_addr" .- [reg this, bare begL] 93 tellIns $ "goto" .- [bare endL] 94 tellLabel begL 95 cc <- genPMC "cc" 96 fetchCC cc (reg this) 97 expC <- trans exp 98 tellIns $ "set_addr" .- [reg this, bare sndL] 99 tellIns $ "goto" .- [bare retL] 100 tellLabel sndL 101 fetchCC cc (reg this) 102 tellLabel retL 103 tellIns $ if parrotBrokenXXX 104 then "store_global" .- [tempSTR, expC] 105 else "set_args" .- [lit "(0b10)", expC] 106 tellIns $ "invokecc" .- [reg cc] 107 tellLabel endL 90 [begL, initL] <- genLabel ["thunk", "thunkInit"] 91 this <- genPMC "thunk" 92 let begP = begL ++ "_C" 93 tellIns $ InsConst (VAR begP) Sub (lit begL) 94 tellIns $ reg this <-- "newclosure" $ [bare begP] 95 -- inner subroutine begins 96 censor ((:[]) . StmtSub begL) $ do 97 -- tellIns $ "push_eh" .- [bare initL] 98 expC <- trans exp 99 tellIns $ "set_returns" .- retSigList [expC] 100 tellIns $ "returncc" .- [] 108 101 return (ExpLV this) 109 102 trans (PCode styp params _ _ body) = do 110 [begL , endL] <- genLabel ["blockBegin", "blockEnd"]103 [begL] <- genLabel ["block"] 111 104 this <- genPMC "block" 112 105 let begP = begL ++ "_C" 113 106 tellIns $ InsConst (VAR begP) Sub (lit begL) 114 107 tellIns $ reg this <-- "newclosure" $ [bare begP] 115 tellIns $ "goto" .- [bare endL] 116 tellLabel begL 117 let prms = map tpParam params 118 mapM_ (tellIns . InsLocal RegPMC . prmToIdent) prms 119 tellIns $ "get_params" .- sigList (map prmToSig prms) 120 tellIns $ "new_pad" .- [lit curPad] 121 wrapSub styp $ do 122 mapM storeLex params 123 trans body -- XXX - consistency check 124 bodyC <- lastPMC 125 tellIns $ "set_returns" .- retSigList [bodyC] 126 tellIns $ "returncc" .- [] 127 tellLabel endL 108 -- inner subroutine begins 109 censor ((:[]) . StmtSub begL) $ do 110 let prms = map tpParam params 111 tell [StmtPad (map prmToPad prms) []] 112 tellIns $ "get_params" .- sigList (map prmToSig prms) 113 wrapSub styp $ do 114 mapM storeLex params 115 bodyC <- case body of 116 PNil -> return nullPMC 117 _ -> trans body >> lastPMC 118 tellIns $ "set_returns" .- retSigList [bodyC] 119 tellIns $ "returncc" .- [] 128 120 return (ExpLV this) 121 122 prmToPad :: Param -> (VarName, Expression) 123 prmToPad prm = (paramName prm, ExpLV (VAR $ prmToIdent prm)) 129 124 130 125 instance Translate PIL_Decl Decl where … … 135 130 (_, stmts) <- listen $ do 136 131 let prms = map tpParam params 137 mapM_ (tellIns . InsLocal RegPMC . prmToIdent) prms132 tell [StmtPad (map prmToPad prms) []] 138 133 tellIns $ "get_params" .- sigList (map prmToSig prms) 139 tellIns $ "new_pad" .- [lit curPad]134 -- tellIns $ "new_pad" .- [lit curPad] 140 135 wrapSub styp $ do 141 136 mapM storeLex params 142 trans body 143 bodyC <- lastPMC 137 bodyC <- case body of 138 PNil -> return nullPMC 139 _ -> trans body >> lastPMC 144 140 tellIns $ "set_returns" .- retSigList [bodyC] 145 141 tellIns $ "returncc" .- [] 146 return (DeclSub name [] stmts) 147 148 instance Translate PIL_Literal Literal where 149 trans (PVal (VBool bool)) = return $ LitInt (toInteger $ fromEnum bool) 150 trans (PVal (VStr str)) = return $ LitStr str 151 trans (PVal (VInt int)) = return $ LitInt int 152 trans (PVal (VNum num)) = return $ LitNum num 153 trans (PVal (VRat rat)) = return $ LitNum (ratToNum rat) 154 trans (PVal (VList [])) = return $ LitInt 0 -- XXX Wrong 142 return (DeclSub name [SubOUTER "main"] stmts) 143 144 instance Translate PIL_Literal Expression where 145 trans (PVal (VBool bool)) = return $ ExpLit (LitInt (toInteger $ fromEnum bool)) 146 trans (PVal (VStr str)) = return $ ExpLit (LitStr str) 147 trans (PVal (VInt int)) = return $ ExpLit (LitInt int) 148 trans (PVal (VNum num)) = return $ ExpLit (LitNum num) 149 trans (PVal (VRat rat)) = return $ ExpLit (LitNum (ratToNum rat)) 150 -- trans (PVal (VList [])) = return $ LitInt 0 -- XXX Wrong 151 trans (PVal (VList vs)) = do 152 pmc <- genArray "vlist" 153 forM vs $ \val -> do 154 valC <- trans (PVal val) 155 tellIns $ "push" .- [pmc, valC] 156 return pmc 155 157 trans val@(PVal _) = transError val 156 158 157 159 instance Translate PIL_LValue LValue where 158 160 trans (PVar name) | Just (pkg, name') <- isQualified name = do 159 -- XXX - this is terribly ugly. Fix at parrot side perhaps? 160 pmc <- genLV "glob" 161 let initL = "init_" ++ pmcStr 162 doneL = "done_" ++ pmcStr 163 pmcStr = render (emit pmc) 164 tellIns $ "push_eh" .- [bare initL] 165 tellIns $ pmc <-- "find_global" $ [lit pkg, lit name'] 166 tellIns $ "goto" .- [bare doneL] 167 tellLabel initL 161 [globL] <- genLabel ["glob"] 162 pmc <- genScalar "glob" 163 tell [StmtRaw (text "errorsoff .PARROT_ERRORS_GLOBALS_FLAG")] 164 tellIns $ pmc <-- "find_global" $ [lit pkg, lit name'] 165 tellIns $ tempINT <-- "defined" $ [reg pmc] 166 tellIns $ "if" .- [tempINT, bare globL] 167 tellIns $ InsNew pmc PerlScalar 168 168 tellIns $ "store_global" .- [lit pkg, lit name', reg pmc] 169 tellLabel doneL170 tell Ins $ "clear_eh" .- []169 tellLabel globL 170 tell [StmtRaw (text "errorson .PARROT_ERRORS_GLOBALS_FLAG")] 171 171 return pmc 172 172 trans (PVar name) = do 173 pmc <- gen LV"lex"173 pmc <- genScalar "lex" 174 174 tellIns $ pmc <-- "find_name" $ [lit $ possiblyFixOperatorName name] 175 175 return pmc … … 179 179 tellIns $ lhsC <== rhsC 180 180 return lhsC 181 trans (PBind [PVar name] rhs) 182 | Just (pkg, name') <- isQualified (qualify name) = do 181 trans (PBind [PVar name] rhs) = do 183 182 rhsC <- trans rhs 184 tellIns $ "store_ global" .- [lit pkg, lit name', rhsC]183 tellIns $ "store_lex" .- [lit name, rhsC] 185 184 trans (PVar name) 186 185 trans (PBind [lhs] rhs) = do … … 189 188 tellIns $ lhsC <:= rhsC 190 189 return lhsC 191 trans (PApp _ exp@ (PCode _ _ _ _ _)Nothing []) = do190 trans (PApp _ exp@PCode{} Nothing []) = do 192 191 blockC <- trans exp 193 192 tellIns $ [reg tempPMC] <-& blockC $ [] … … 200 199 trans (PApp ctx fun Nothing (inv:args)) -- XXX wrong 201 200 trans (PApp _ fun Nothing args) = do 202 funC <- trans fun {- case fun of201 funC <- trans fun {- case fun of 203 202 PExp (PVar name) -> return $ lit name 204 203 _ -> trans fun … … 206 205 argsC <- mapM trans args 207 206 -- XXX WORKAROUND PARROT BUG (see below) 208 pmc <- gen LV"app"207 pmc <- genScalar "app" 209 208 -- XXX - probe if funC is slurpy, then modify ExpLV pmc accordingly 210 209 tellIns $ [reg pmc] <-& funC $ argsC … … 216 215 return nullPMC 217 216 _ -> do 218 pmc <- gen LV"app"217 pmc <- genScalar "app" 219 218 -- XXX - probe if funC is slurpy, then modify ExpLV pmc accordingly 220 219 tellIns $ [reg pmc] <-& funC $ argsC … … 222 221 -} 223 222 trans x = transError x 224 225 fetchCC :: LValue -> Expression -> CodeGen ()226 fetchCC cc begL | parrotBrokenXXX = do227 tellIns $ tempINT <-- "get_addr" $ [begL]228 tellIns $ tempSTR <:= tempINT229 tellIns $ "find_global" .- [reg cc, tempSTR]230 fetchCC cc _ = do231 tellIns $ "get_params" .- sigList [reg cc]232 223 233 224 -- XXX - slow way of implementing "return" … … 240 231 body 241 232 tellLabel retL 242 tellIns $ tempPMC <:= ExpLV (errPMC `KEYED` lit False)233 tellIns $ ("get_results" .- sigList [tempPMC, tempSTR]) 243 234 tellIns $ "clear_eh" .- [] 244 tellIns $ tempSTR <-- "typeof" $ [ errPMC]235 tellIns $ tempSTR <-- "typeof" $ [tempPMC] 245 236 tellIns $ "eq" .- [tempSTR, lit "Exception", bare errL] 246 237 tellIns $ "set_returns" .- sigList [tempPMC] 247 238 tellIns $ "returncc" .- [] 248 239 tellLabel errL 249 tellIns $ "throw" .- [ errPMC]240 tellIns $ "throw" .- [tempPMC] 250 241 251 242 prmToSig :: Param -> Sig … … 275 266 tellIns $ VAR name <:= expC 276 267 tellLabel defC 277 tellIns $ "store_lex" .- [lit curPad, litvar, bare name]268 tellIns $ "store_lex" .- [lit var, bare name] 278 269 where 279 270 var = paramName prm … … 291 282 lastPMC = do 292 283 tvar <- asks tReg 293 name' <-liftIO $ liftSTM $ do284 liftIO $ liftSTM $ do 294 285 (cur, name) <- readTVar tvar 295 return $ ('P':show cur) ++ (if null name then name else ('_':name)) 296 return $ reg (VAR name') 286 return $ case cur of 287 0 -> nullPMC 288 _ -> reg (VAR (('p':show cur) ++ (if null name then name else ('_':name)))) 297 289 298 290 genPMC :: (RegClass a) => String -> CodeGen a … … 302 294 (cur, _) <- readTVar tvar 303 295 writeTVar tvar (cur + 1, name) 304 return $ (' P':show (cur + 1)) ++ ('_':name)296 return $ ('p':show (cur + 1)) ++ ('_':name) 305 297 tellIns $ InsLocal RegPMC name' 306 298 return $ reg (VAR name') 307 299 308 gen LV :: (RegClass a) => String -> CodeGen a309 gen LVname = do300 genWith :: (RegClass a) => (LValue -> Ins) -> String -> CodeGen a 301 genWith f name = do 310 302 pmc <- genPMC name 311 tellIns $ InsNew pmc PerlScalar303 tellIns $ f pmc 312 304 return $ reg pmc 305 306 genScalar :: (RegClass a) => String -> CodeGen a 307 genScalar = genWith (`InsNew` PerlScalar) 308 309 genArray :: (RegClass a) => String -> CodeGen a 310 genArray = genWith (`InsNew` PerlArray) 311 312 genHash :: (RegClass a) => String -> CodeGen a 313 genHash = genWith (`InsNew` PerlHash) 313 314 314 315 genLabel :: [String] -> CodeGen [LabelName] … … 335 336 varInit x = internalError $ "Invalid name: " ++ x 336 337 338 genPIR_YAML :: Eval Val 339 genPIR_YAML = genPIRWith $ \globPIR mainPIR _ -> do 340 yaml <- liftIO (showYaml (mainPIR, globPIR)) 341 return (VStr yaml) 342 337 343 {-| Compiles the current environment to PIR code. -} 338 344 genPIR :: Eval Val 339 genPIR = do 340 tenv <- initTEnv 341 -- Load the PIR Prelude. 342 local (\env -> env{ envDebug = Nothing }) $ do 343 opEval style "<prelude-pir>" preludeStr 344 penv <- compile () 345 globPIR <- runCodeGenGlob tenv (pilGlob penv) 346 mainPIR <- runCodeGenMain tenv (pilMain penv) 345 genPIR = genPIRWith $ \globPIR mainPIR penv -> do 347 346 libs <- liftIO $ getLibs 348 347 return . VStr . unlines $ … … 350 349 , renderStyle (Style PageMode 0 0) $ preludePIR $+$ vcat 351 350 -- Namespaces have bugs in both pugs and parrot. 352 [ emit globPIR 353 , emit $ DeclNS "main" 351 [ emit $ DeclNS "main" 354 352 [ DeclSub "init" [SubMAIN, SubANON] $ map StmtIns ( 355 353 -- Eventually, we'll have to write our own find_name wrapper (or 356 354 -- fix Parrot's find_name appropriately). See Pugs.Eval.Var. 357 355 -- For now, we simply store $P0 twice. 358 [ "new_pad" .- [lit0] 359 , InsNew tempPMC PerlEnv 356 [ InsNew tempPMC PerlEnv 360 357 , "store_global" .- [lit "%*ENV", tempPMC] 361 358 , "store_global" .- [lit "%ENV", tempPMC] … … 392 389 , StmtIns $ "invokecc" .- [tempPMC] 393 390 ] 394 , DeclSub "main" [SubANON] [ StmtRaw $ emit mainPIR ] 395 ] ] ] 391 , DeclSub "main" [SubANON] (concatMap vivifySub globPIR ++ mainPIR) ] 392 , emit globPIR ] ] 393 394 vivifySub :: Decl -> [Stmt] 395 vivifySub (DeclNS "main" decls) = concatMap vivifySub decls 396 vivifySub (DeclSub name@('&':c:_') [SubOUTER "main"] _) 397 | c /= '*' 398 = map StmtIns 399 [ tempPMC <-- "find_name" $ [lit name] 400 , tempPMC <-- "newclosure" $ [tempPMC] 401 , "store_global" .- [lit "main", lit name, tempPMC] 402 ] 403 vivifySub _ = [] 404 405 genPIRWith f = do 406 tenv <- initTEnv 407 -- Load the PIR Prelude. 408 local (\env -> env{ envDebug = Nothing }) $ do 409 opEval style "<prelude-pir>" preludeStr 410 penv <- compile () 411 globPIR <- runCodeGenGlob tenv (pilGlob penv) 412 mainPIR <- runCodeGenMain tenv (pilMain penv) 413 f globPIR mainPIR penv 396 414 where 397 415 style = MkEvalStyle
