runStatement b (Statement ws rs as) = checkE b `fmap`
    do ws' <- expandWords ws
       case ws' of
         [] -> return $ BuiltinProcess $ withRedirs rs $ setVars as
         ("unset":xs) -> return $ BuiltinProcess $ do forM_ xs unsetEnv
                                                      return ExitSuccess
         ("local":xs) -> return $ BuiltinProcess $ setLocals xs
         ["export"] -> return $ BuiltinProcess $ withEnv rs as $ setExports []
         ("export":xs) -> return $ BuiltinProcess $
                          setExports xs -- NOTE: can't be in a withEnv
         (name:args) -> do func <- getFunction name
                           case func of   -- order of redirs matches dash
                             Just (f,rs') -> return $ BuiltinProcess $
                                               withEnv (rs++rs') as $
                                               withPositionals args $
                                               runCompound b f
                             Nothing      -> do job <- runBuiltinOrExe
                                                       name args
                                                return $
                                                  withShellProcess `flip` job $
                                                    \j -> withEnv rs as j
runStatement b (Statement ws rs as) = checkE b `fmap`
    do ws' <- expandWords ws
       case ws' of
         [] -> return $ BuiltinProcess $ withRedirs rs $ setVars as
         ("unset":xs) -> return $ BuiltinProcess $ do forM_ xs unsetEnv
                                                      return ExitSuccess
         ("local":xs) -> return $ BuiltinProcess $ setLocals xs
         ["export"] -> return $ BuiltinProcess $ withEnv rs as $ setExports []
         ("export":xs) -> return $ BuiltinProcess $
                          setExports xs -- NOTE: can't be in a withEnv
         (name:args) -> do func <- getFunction name
                           case func of   -- order of redirs matches dash
                             Just (f,rs') -> return $ BuiltinProcess $
                                               withEnv (rs++rs') as $
                                               withPositionals args $
                                               runCompound b f
                             Nothing      -> do job <- runBuiltinOrExe
                                                       name args
                                                return $
                                                  withShellProcess `flip` job $
                                                    \j -> withEnv rs as j
runStatement b (Statement ws rs as) = checkE b `fmap`
    do ws' <- expandWords ws
       case ws' of
         [] -> return $ BuiltinProcess $ withRedirs rs $ setVars as
         ("unset":xs) -> return $ BuiltinProcess $ do forM_ xs unsetEnv
                                                      return ExitSuccess
         ("local":xs) -> return $ BuiltinProcess $ setLocals xs
         ["export"] -> return $ BuiltinProcess $ withEnv rs as $ setExports []
         ("export":xs) -> return $ BuiltinProcess $
                          setExports xs -- NOTE: can't be in a withEnv
         (name:args) -> do func <- getFunction name
                           case func of   -- order of redirs matches dash
                             Just (f,rs') -> return $ BuiltinProcess $
                                               withEnv (rs++rs') as $
                                               withPositionals args $
                                               runCompound b f
                             Nothing      -> do job <- runBuiltinOrExe
                                                       name args
                                                return $
                                                  withShellProcess `flip` job $
                                                    \j -> withEnv rs as j