Merge branch 'master' into lib

lib
Avril 3 years ago
commit 7ab10e4235
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -41,12 +41,27 @@ struct _sm_frame {
_sm_frame* prev;
};
/// Options for `state`.
struct _sm_state_opt
{
/// Set the return value within a generator at every yield point, instead of just at the end of the function.
/// (default: true)
bool _opt_INTERMEDIATE_RETURNS;
};
extern const _sm_state_opt _sm_state_opt_default;
struct sm_state {
_sm_state_opt opt;
_sm_frame* current;
};
#define sm_state_setopt(state, name, value) ((state)->opt._opt_ ## name = (value))
#define sm_state_getopt(state, name) ((state)->opt._opt_ ## name)
template<typename T>
inline T* _sm_init(_sm_user* frame, T init)
{

@ -28,9 +28,11 @@ bool sm_next(sm_generator** gen, sm_state* state, _sm_user* output)
sm_yield next = (*gen)->current(state);
// Set the return value to `output`.
if(output && state->current->rval) *output = *state->current->rval;
else if(output) output->set = false;
if(sm_state_getopt(state, INTERMEDIATE_RETURNS) || next == nullptr) {
// Set the return value to `output`.
if(output && state->current->rval) *output = *state->current->rval;
else if(output) output->set = false;
}
switch((uintptr_t)next)
{

@ -1,6 +1,10 @@
#include <state.h>
#include "dev.h"
const _sm_state_opt _sm_state_opt_default = {
._opt_INTERMEDIATE_RETURNS = true,
};
/// A generator that just returns `nullptr` (end). Used for yielding without calling in to another generator.
///
/// NOTE: To avoid uselessly creating a stack frame for calls to this generator, its address is (TODO) directly compared to when switching into a deeper generator, and then skipped entirely.
@ -13,6 +17,7 @@ sm_state* sm_new_state()
{
auto state = box<sm_state>();
state->current = box<_sm_frame, true>();
state->opt = _sm_state_opt_default;
return state;
}

@ -50,24 +50,21 @@ int main()
auto state = sm_new_state();
auto gen = sm_generate(&sm_test);
sm_state_setopt(state, INTERMEDIATE_RETURNS, false);
sm_output output;
int out_int;
while(sm_next(&gen, state, &output)) {
int out_int;
if(!sm_output_value(output, &out_int))
continue;
printf("OUT \t\ta = %d\n", out_int);
printf("OUT \t\ta = %d\n", out_int); // prints the last one, is this a good or bad thing?
}
printf("\n\nFinal output: %d\n", out_int);
sm_free_output(&output);
sm_free_generator(gen);
sm_free_state(state);
/*
//TODO: `sm_state` creation/initialisation & freeing functions
//TODO: Test `sm_test`
_test hi = { 0, 0 };
auto _a = _sm_init(nullptr, hi);
*/
return 0;
}

Loading…
Cancel
Save