parent
bc2857fc86
commit
2bab6235db
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
typedef sm_yield (*sm_gen_fun)(sm_state* state); //NOTE: Same as sm_yield
|
||||||
|
|
||||||
|
// A generator method
|
||||||
|
struct sm_generator;
|
||||||
|
|
||||||
|
/// Create a generator method with this function.
|
||||||
|
sm_generator* sm_generate(sm_gen_fun function);
|
||||||
|
/// Free a generator method
|
||||||
|
void sm_free_generator(sm_generator* generator);
|
||||||
|
/// Run this generator until the next yield.
|
||||||
|
/// Returns false if the generator ends.
|
||||||
|
bool sm_next(sm_generator** gen, sm_state* state);
|
@ -0,0 +1,57 @@
|
|||||||
|
#include <gen.h>
|
||||||
|
|
||||||
|
struct sm_generator
|
||||||
|
{
|
||||||
|
sm_generator* prev;
|
||||||
|
sm_gen_fun current;
|
||||||
|
};
|
||||||
|
|
||||||
|
sm_generator* sm_generate(sm_gen_fun function)
|
||||||
|
{
|
||||||
|
auto gen = box<sm_generator>();
|
||||||
|
gen->prev = nullptr;
|
||||||
|
gen->current = function;
|
||||||
|
return gen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_free_generator(sm_generator* gen)
|
||||||
|
{
|
||||||
|
auto g = unbox(gen);
|
||||||
|
if(g.prev)
|
||||||
|
sm_free_generator(g.prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns false if the generator ends.
|
||||||
|
bool sm_next(sm_generator** gen, sm_state* state)
|
||||||
|
{
|
||||||
|
if( !(*gen)->current) return false;
|
||||||
|
|
||||||
|
sm_yield next = (*gen)->current(state);
|
||||||
|
switch((uintptr_t)next)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
// Pop the current
|
||||||
|
(*gen)->current = nullptr;
|
||||||
|
|
||||||
|
if ((*gen)->prev) {
|
||||||
|
|
||||||
|
// Pop back to previous stack
|
||||||
|
_sm_pop_stack(state);
|
||||||
|
|
||||||
|
*gen = unbox(*gen).prev;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
default:
|
||||||
|
if (next == (sm_yield)_sm_noop) return true;
|
||||||
|
|
||||||
|
auto prev = *gen;
|
||||||
|
*gen = sm_generate((sm_gen_fun) next);
|
||||||
|
(*gen)->prev = prev;
|
||||||
|
|
||||||
|
// Set up new stack frame
|
||||||
|
_sm_push_stack(state);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in new issue