diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-15 17:50:43 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-15 17:50:43 -0400 |
| commit | 8b512adbbcf62f49b3e92410e643c86f2e70908a (patch) | |
| tree | b3f5e08c6589bc7c00e2a089fbe5304cb60d742a /examples/coroutine/coroutine.tm | |
| parent | 3d1a102a8d8425b8f4a08b78c77ee4b38f6de55b (diff) | |
Move each example to its own folder
Diffstat (limited to 'examples/coroutine/coroutine.tm')
| -rw-r--r-- | examples/coroutine/coroutine.tm | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/examples/coroutine/coroutine.tm b/examples/coroutine/coroutine.tm new file mode 100644 index 00000000..35eb5fda --- /dev/null +++ b/examples/coroutine/coroutine.tm @@ -0,0 +1,64 @@ +# This is a coroutine library that uses libaco. If you don't have it installed, +# you can get it from the website: https://libaco.org +# +# Lua programmers will recognize this as similar to Lua's stackful coroutines. +# +# Async/Await programmers will weep at its beauty and gnash their teeth and +# rend their garments in despair at what they could have had. + +use libaco.so +use <aco.h> + +func main(): + !! Example usage: + co := new(func(): + say("I'm in the coroutine!") + yield() + say("I'm back in the coroutine!") + ) + >> co + say("I'm in the main func") + >> co:resume() + say("I'm back in the main func") + >> co:resume() + say("I'm back in the main func again") + >> co:resume() + +_main_co := !@Memory +_shared_stack := !@Memory + +struct Coroutine(co:@Memory): + func is_finished(co:Coroutine; inline)->Bool: + return inline C:Bool {((aco_t*)$co.$co)->is_finished} + + func resume(co:Coroutine)->Bool: + if co:is_finished(): + return no + inline C { aco_resume($co.$co); } + return yes + +func _init(): + inline C { + aco_set_allocator(GC_malloc, NULL); + aco_thread_init(aco_exit_fn); + } + _main_co = inline C:@Memory { aco_create(NULL, NULL, 0, NULL, NULL) } + + _shared_stack = inline C:@Memory { aco_shared_stack_new(0) } + +func new(co:func())->Coroutine: + if not _main_co: + _init() + + main_co := _main_co + shared_stack := _shared_stack + aco_ptr := inline C:@Memory { + aco_create($main_co, $shared_stack, 0, (void*)$co.fn, $co.userdata) + } + return Coroutine(aco_ptr) + +func yield(; inline): + inline C { + aco_yield(); + } + |
