| | 358 | |
| | 359 | reducePad SLet lex exp = do |
| | 360 | tmps <- mapM (\(sym, _) -> evalExp $ App (_Var "&TEMP") (Just $ Var sym) []) $ padToList lex |
| | 361 | -- default to nonlocal exit |
| | 362 | isNonLocal <- liftSTM $ newTVar True |
| | 363 | val <- tryT $ do |
| | 364 | -- if the liftSTM is reached, exp evaluated without error; no need to shift out |
| | 365 | evalExp exp `finallyM` liftSTM (writeTVar isNonLocal False) |
| | 366 | isn <- liftSTM $ readTVar isNonLocal |
| | 367 | if isn |
| | 368 | then do |
| | 369 | when (isFailure val) $ do |
| | 370 | mapM_ (\tmp -> evalExp $ App (Val tmp) Nothing []) tmps |
| | 371 | retShift val |
| | 372 | else return val |
| | 373 | where |
| | 374 | isFailure (VControl (ControlLeave{ leaveValue = v })) |
| | 375 | | VUndef <- v = True |
| | 376 | | VRef r <- v = refType r == mkType "Failure" |
| | 377 | | otherwise = False |
| | 378 | isFailure VControl{} = True |
| | 379 | isFailure _ = False |
| | 380 | |
| | 381 | |