From d810f37520849e009dfdd21d2d67d40e9f4e36eb Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 18 Mar 2021 20:51:36 +0000 Subject: [PATCH 1/2] remove useless comments in test main.cpp --- src/main.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 766ce0f..440f217 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,15 +59,9 @@ int main() } 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; } From bfc1e0353870c258be3d10cbb1e083cb09c6c8bb Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 18 Mar 2021 23:21:22 +0000 Subject: [PATCH 2/2] added state options --- include/frame.h | 17 ++++++++++++++++- src/gen.cpp | 8 +++++--- src/main.cpp | 7 +++++-- src/state.cpp | 5 +++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/frame.h b/include/frame.h index 59b0226..89514d7 100644 --- a/include/frame.h +++ b/include/frame.h @@ -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 inline T* _sm_init(_sm_user* frame, T init) { diff --git a/src/gen.cpp b/src/gen.cpp index 73eab23..25677dd 100644 --- a/src/gen.cpp +++ b/src/gen.cpp @@ -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) { diff --git a/src/main.cpp b/src/main.cpp index 440f217..1c24472 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -50,14 +50,17 @@ 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); diff --git a/src/state.cpp b/src/state.cpp index 61f3f82..a8797d4 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,6 +1,10 @@ #include #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(); state->current = box<_sm_frame, true>(); + state->opt = _sm_state_opt_default; return state; }