More yielding from

Add more elaborate tests of generators, make generators pass return values correctly, and refactor some unnecessary code.
@nedbat this is the critical line - the lack of `value` on `StopIteration` was causing the "return" value to get lost.

To kinda push the point further: the following code is identical:

```python
def x():
    if False:
        yield
    return 1
```

```python
def x():
    if False:
        yield
    raise StopIteration(1)
```