about summary refs log tree commit diff
path: root/boot/tests/transpile/function_as_value.cskt
diff options
context:
space:
mode:
Diffstat (limited to 'boot/tests/transpile/function_as_value.cskt')
-rw-r--r--boot/tests/transpile/function_as_value.cskt43
1 files changed, 43 insertions, 0 deletions
diff --git a/boot/tests/transpile/function_as_value.cskt b/boot/tests/transpile/function_as_value.cskt
new file mode 100644
index 0000000..864eae2
--- /dev/null
+++ b/boot/tests/transpile/function_as_value.cskt
@@ -0,0 +1,43 @@
+any function can be passed around as a normal value.
+this requires us to create a wrapper around the function, which
+converts the thin (normal) calling convention of the function into
+the fat calling convention of a function containing some state.
+this wrapper is called a "thunk".
+
+<<<
+
+add = fun (a int, b int) int { return a + b }
+
+apply = fun (f fun (a int, b int) int, x int, y int) int {
+    return f(x, y)
+}
+
+main = fun () {
+    var r int = apply(add, 5, 7)
+}
+
+>>>
+
+#include "core.c"
+struct __cat_type_0 {
+    void* state;
+    integer (*call)(void* state, integer, integer);
+};
+integer add(integer a, integer b);
+integer __cat_thunk_add(void* state, integer, integer);
+integer apply(struct __cat_type_0 f, integer x, integer y);
+void catskill_main(void);
+integer add(integer a, integer b) {
+    return a + b;
+}
+integer __cat_thunk_add(void* state, integer a, integer b) {
+    (void)state;
+    return add(a, b);
+}
+integer apply(struct __cat_type_0 f, integer x, integer y) {
+    return f.call(f.state, x, y);
+}
+void catskill_main(void) {
+    integer r = apply((struct __cat_type_0){ .state = nil, .call = __cat_thunk_add }, 5, 7);
+}
+#include "runtime.c"