|
| 1 | +// Generator objects |
| 2 | + |
| 3 | +package py |
| 4 | + |
| 5 | +// A python Generator object |
| 6 | +typeGeneratorstruct{ |
| 7 | +// Note: gi_frame can be NULL if the generator is "finished" |
| 8 | +Frame*Frame |
| 9 | + |
| 10 | +// True if generator is being executed. |
| 11 | +Runningbool |
| 12 | + |
| 13 | +// The code object backing the generator |
| 14 | +Code*Code |
| 15 | + |
| 16 | +// List of weak reference. |
| 17 | +WeakreflistObject |
| 18 | +} |
| 19 | + |
| 20 | +varGeneratorType=NewType("generator", "generator object") |
| 21 | + |
| 22 | +// Type of this object |
| 23 | +func (o*Generator) Type() *Type{ |
| 24 | +returnGeneratorType |
| 25 | +} |
| 26 | + |
| 27 | +// Define a new generator |
| 28 | +funcNewGenerator(frame*Frame) *Generator{ |
| 29 | +g:=&Generator{ |
| 30 | +Frame: frame, |
| 31 | +Running: false, |
| 32 | +Code: frame.Code, |
| 33 | + } |
| 34 | +returng |
| 35 | +} |
| 36 | + |
| 37 | +func (it*Generator) M__iter__() Object{ |
| 38 | +returnit |
| 39 | +} |
| 40 | + |
| 41 | +// generator.__next__() |
| 42 | +// |
| 43 | +// Starts the execution of a generator function or resumes it at the |
| 44 | +// last executed yield expression. When a generator function is |
| 45 | +// resumed with a __next__() method, the current yield expression |
| 46 | +// always evaluates to None. The execution then continues to the next |
| 47 | +// yield expression, where the generator is suspended again, and the |
| 48 | +// value of the expression_list is returned to next()‘s caller. If the |
| 49 | +// generator exits without yielding another value, a StopIteration |
| 50 | +// exception is raised. |
| 51 | +// |
| 52 | +// This method is normally called implicitly, e.g. by a for loop, or by the built-in next() function. |
| 53 | +func (it*Generator) M__next__() Object{ |
| 54 | +it.Running=true |
| 55 | +res, err:=RunFrame(it.Frame) |
| 56 | +it.Running=false |
| 57 | +// Push a None on the stack for next time |
| 58 | +// FIXME this value is the one sent by Send |
| 59 | +it.Frame.Stack=append(it.Frame.Stack, None) |
| 60 | +// FIXME not correct |
| 61 | +iferr!=nil{ |
| 62 | +panic(err) |
| 63 | + } |
| 64 | +ifit.Frame.Yielded{ |
| 65 | +returnres |
| 66 | + } |
| 67 | +panic(StopIteration) |
| 68 | +} |
| 69 | + |
| 70 | +// generator.send(value) |
| 71 | +// |
| 72 | +// Resumes the execution and “sends” a value into the generator |
| 73 | +// function. The value argument becomes the result of the current |
| 74 | +// yield expression. The send() method returns the next value yielded |
| 75 | +// by the generator, or raises StopIteration if the generator exits |
| 76 | +// without yielding another value. When send() is called to start the |
| 77 | +// generator, it must be called with None as the argument, because |
| 78 | +// there is no yield expression that could receive the value. |
| 79 | +func (it*Generator) Send(valueObject){ |
| 80 | +panic("generator send not implemented") |
| 81 | +} |
| 82 | + |
| 83 | +// generator.throw(type[, value[, traceback]]) |
| 84 | +// |
| 85 | +// Raises an exception of type type at the point where generator was |
| 86 | +// paused, and returns the next value yielded by the generator |
| 87 | +// function. If the generator exits without yielding another value, a |
| 88 | +// StopIteration exception is raised. If the generator function does |
| 89 | +// not catch the passed-in exception, or raises a different exception, |
| 90 | +// then that exception propagates to the caller. |
| 91 | +func (it*Generator) Throw(argsTuple, kwargsStringDict){ |
| 92 | +panic("generator throw not implemented") |
| 93 | +} |
| 94 | + |
| 95 | +// generator.close() |
| 96 | +// |
| 97 | +// Raises a GeneratorExit at the point where the generator function |
| 98 | +// was paused. If the generator function then raises StopIteration (by |
| 99 | +// exiting normally, or due to already being closed) or GeneratorExit |
| 100 | +// (by not catching the exception), close returns to its caller. If |
| 101 | +// the generator yields a value, a RuntimeError is raised. If the |
| 102 | +// generator raises any other exception, it is propagated to the |
| 103 | +// caller. close() does nothing if the generator has already exited |
| 104 | +// due to an exception or normal exit. |
| 105 | +func (it*Generator) Close(){ |
| 106 | +panic("generator close not implemented") |
| 107 | +} |
| 108 | + |
| 109 | +// Check interface is satisfied |
| 110 | +var_I_iterator= (*Generator)(nil) |
0 commit comments