summaryrefslogtreecommitdiffhomepage
path: root/misc/examples
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-02-22 14:35:56 +0100
committerTyge Løvset <[email protected]>2023-02-22 15:05:27 +0100
commitb63df794ee2bda2c33856a646ca6e1386f5ab782 (patch)
tree93ae40aca24ed5a71adfec252e2b4255db6f617b /misc/examples
parenta8fc8ac4e8c1481300e0d46bbd376f32ebeb4635 (diff)
downloadSTC-modified-b63df794ee2bda2c33856a646ca6e1386f5ab782.tar.gz
STC-modified-b63df794ee2bda2c33856a646ca6e1386f5ab782.zip
Added coroutines, based upon Simon Tatham's famous implementation. This version is much improved, but uses the same basic mechanisms.
Diffstat (limited to 'misc/examples')
-rw-r--r--misc/examples/cofib.c40
-rw-r--r--misc/examples/coread.c41
2 files changed, 81 insertions, 0 deletions
diff --git a/misc/examples/cofib.c b/misc/examples/cofib.c
new file mode 100644
index 00000000..d0e4ac2a
--- /dev/null
+++ b/misc/examples/cofib.c
@@ -0,0 +1,40 @@
+#include <stc/algo/cco.h>
+#include <stdio.h>
+#include <stdint.h>
+
+// Use coroutine to create a fibonacci sequence generator:
+
+typedef long long llong;
+
+llong fibonacci_sequence(ccontext* ctx, unsigned n) {
+ assert (n < 95);
+
+ cco_context(ctx,
+ llong a, b, idx;
+ );
+
+ cco_routine(u,
+ u->a = 0;
+ u->b = 1;
+ for (u->idx = 2; u->idx < n; u->idx++) {
+ llong sum = u->a + u->b;
+ cco_yield(sum);
+ u->a = u->b;
+ u->b = sum;
+ }
+ cco_finish:
+ );
+ return 0;
+}
+
+
+int main(void) {
+ ccontext z = 0;
+ printf("Fibonacci numbers:\n");
+ for (;;) {
+ llong x = fibonacci_sequence(&z, 30);
+ if (!z) break;
+ printf(" %lld", x);
+ }
+ puts("");
+}
diff --git a/misc/examples/coread.c b/misc/examples/coread.c
new file mode 100644
index 00000000..9181401d
--- /dev/null
+++ b/misc/examples/coread.c
@@ -0,0 +1,41 @@
+#include <stc/cstr.h>
+#include <stc/algo/cco.h>
+#include <errno.h>
+
+// Read file line by line using coroutines:
+
+cstr file_nextline(ccontext* ccx, const char* name)
+{
+ cco_context(ccx,
+ FILE* fp;
+ cstr line;
+ );
+
+ cco_routine(U,
+ U->fp = fopen(name, "r");
+ U->line = cstr_NULL;
+
+ while (cstr_getline(&U->line, U->fp))
+ cco_yield (cstr_clone(U->line));
+
+ cco_finish: // cco_finish is needed to support cco_stop.
+ printf("finish\n");
+ cstr_drop(&U->line);
+ fclose(U->fp);
+ );
+ return cstr_NULL;
+}
+
+
+int main(void) {
+ ccontext z = 0;
+ int n = 0;
+ do {
+ c_with (cstr line = file_nextline(&z, __FILE__), z, cstr_drop(&line)) {
+ printf("%3d %s\n", ++n, cstr_str(&line));
+
+ // stop after 10 lines:
+ if (n == 10) file_nextline(cco_stop(&z), __FILE__);
+ }
+ } while (z);
+}