diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2026-05-01 22:43:13 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2026-05-01 22:43:13 +0300 |
| commit | db3809488805fbdcd9d726d9ed45ad7335812bd1 (patch) | |
| tree | dcf1ceb68a7d77733a474825a9804fe99d253b48 /examples | |
| parent | f1e9860ab638594e95db0ada848157b860eeb831 (diff) | |
| download | fwd-master.tar.gz fwd-master.zip | |
+ Might come up with proper examples at some point, but for now tests at
least tell us if they're broken
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/callback.fwd | 16 | ||||
| -rw-r--r-- | examples/err.fwd | 17 | ||||
| -rw-r--r-- | examples/fib.fwd | 30 | ||||
| -rw-r--r-- | examples/guard.fwd | 40 | ||||
| -rw-r--r-- | examples/opt_group.fwd | 14 | ||||
| -rw-r--r-- | examples/own.fwd | 33 | ||||
| -rw-r--r-- | examples/ptrs.fwd | 21 | ||||
| -rw-r--r-- | examples/pure_move.fwd | 18 | ||||
| -rw-r--r-- | examples/references.fwd | 24 | ||||
| -rw-r--r-- | examples/sum.fwd | 23 | ||||
| -rw-r--r-- | examples/uniq.fwd | 52 | ||||
| -rw-r--r-- | examples/vec.fwd | 150 |
12 files changed, 0 insertions, 438 deletions
diff --git a/examples/callback.fwd b/examples/callback.fwd deleted file mode 100644 index f750b8b..0000000 --- a/examples/callback.fwd +++ /dev/null @@ -1,16 +0,0 @@ -fwd_println(auto s); - -callee() -{ - fwd_println("Hello from callback!"); -} - -caller(*() callback) -{ - callback(); -} - -main() -{ - caller(callee); -} diff --git a/examples/err.fwd b/examples/err.fwd deleted file mode 100644 index f2833e2..0000000 --- a/examples/err.fwd +++ /dev/null @@ -1,17 +0,0 @@ -do_something((auto, auto) ok); - -/* consume can fail */ -consume(auto a); - -main() -{ - do_something() => auto a, auto b; - consume(a); - /* try commenting out error handler or consume(b); */ - !> e { - consume(b); - error "a failed" - } - - consume(b); -} diff --git a/examples/fib.fwd b/examples/fib.fwd deleted file mode 100644 index 4583a26..0000000 --- a/examples/fib.fwd +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Currently the compilation process requires a bit of manual intervention. - * For this particular example, run something like this from the root dir: - * - * ./fwd examples/fib.fwd > /tmp/fib.c - * gcc -Lmod -Iinclude -Ilib -Wl,-rpath=mod -O2 /tmp/fib.c -lfwdio -o /tmp/fib - * /tmp/fib - * - */ - -/* modules are just libraries that can be loaded at runtime */ -import "../mod/libfwdio.so" - -fib(i64 n, (i64) res) -{ - if n < 2 { - res(1); - } else { - fib(n - 1) => i64 f1; - fib(n - 2) => i64 f2; - res(f1 + f2); - } -} - -main() -{ - fib(42) => i64 n; - fwdprint_i64(n); - fwdprint_nl(); -} diff --git a/examples/guard.fwd b/examples/guard.fwd deleted file mode 100644 index df42ef3..0000000 --- a/examples/guard.fwd +++ /dev/null @@ -1,40 +0,0 @@ -/* 'auto' is a special type that currently is in place of generics, will - * eventually be replaced but this is good enough to play around with */ -fwd_println(auto s); - -/* this is a hack, just creates two copies of whatever is passed to it. - * Primitive types should probably be excluded from the move checking, and more - * complex types would presumably implement some kind of .copy(), but at the - * moment that's still TODO */ -fwd_copy(auto n, (auto, auto) n1); - -guard(bool cond, () err, () ok) -{ - if cond { - err(); - } else { - ok(); - } -} - -try_print_one(int a) -{ - fwd_copy(a) => int a1, int a2; - guard(a1 < 1) => { - fwd_println("smaller than 1"); - } => ; - - fwd_copy(a2) => int a3, int a4; - guard(a3 > 1) => { - fwd_println("larger than 1"); - } => ; - - fwd_println(a4); -} - -main() -{ - try_print_one(0); - try_print_one(1); - try_print_one(2); -} diff --git a/examples/opt_group.fwd b/examples/opt_group.fwd deleted file mode 100644 index e520c70..0000000 --- a/examples/opt_group.fwd +++ /dev/null @@ -1,14 +0,0 @@ -do_something(() a | () b) -{ - a(); - - /* should fail, since either a or b should be called, but not both */ - b(); -} - -main() -{ - do_something() - => {} - => {} -} diff --git a/examples/own.fwd b/examples/own.fwd deleted file mode 100644 index 6634886..0000000 --- a/examples/own.fwd +++ /dev/null @@ -1,33 +0,0 @@ -do_something((auto) a); -consume(auto a); - -main() -{ - do_something() => auto a; - do_something() => auto b; - !> e { - /* if do_something() fails, a is still alive, so we must kill - * it. However, we might enter this error block after the - * callback to do_something() was run, and a might've already - * been moved. own just checks if we still own the resource and - * executes the block. - * - * admittedly, purely syntactically it would look like b is - * already alive at this point, but since it's actually within - * the implicit closure, it is not. Might play around with ordering - * the error block to come before implicit closures... - */ - own a {consume(a);} - error e - } - - consume(a); - !> e { - /* if consume fails, b is still alive, but either this error - * block runs (and throws an error) or the next consume is run, - * so own is not necessary here */ - consume(b); - error e - } - consume(b); -} diff --git a/examples/ptrs.fwd b/examples/ptrs.fwd deleted file mode 100644 index a1efc84..0000000 --- a/examples/ptrs.fwd +++ /dev/null @@ -1,21 +0,0 @@ -extern fwd_copy(auto x, (auto, auto) ok); -extern fwd_println(auto x); -extern fwd_intalloc((*int) ok); - -main() -{ - fwd_intalloc() => *int i; - fwd_copy(i) => *int i1, *int i2; - - /* convert raw pointer to reference, unsure if this should be a - * built-in or a library feature */ - fwd_null(i1) => { - fwd_println("Pointer was null"); - /* error out or something */ - } => &int i; - - fwd_println(i); - - /* Try uncommenting, deref of raw pointer is not allowed! */ - // i* + 20 => int something; -} diff --git a/examples/pure_move.fwd b/examples/pure_move.fwd deleted file mode 100644 index d32b9d5..0000000 --- a/examples/pure_move.fwd +++ /dev/null @@ -1,18 +0,0 @@ -requires_pure(&() p) -{ - p(); - /* ok since closure is pure */ - p(); -} - -main() -{ - 20 => int twenty; - requires_pure() &=> { - /* Try uncommenting! - * Not allowed in pure context (though primitives should maybe - * be excluded just to make people's lives easier?) - */ - // twenty + 10 => int thirty; - } -} diff --git a/examples/references.fwd b/examples/references.fwd deleted file mode 100644 index 5b73aaf..0000000 --- a/examples/references.fwd +++ /dev/null @@ -1,24 +0,0 @@ -references(&int a, &int b, () r) -{ - /* don't have assignment and not quite sure if I want to have to - * dereference references so I guess we can't really do much here at the - * moment, heh */ - r(); -} - -main() -{ - 20 => int twenty; - 30 => int thirty; - references(twenty&, thirty&) => { - 20 + 30 => int fifty; /* ok */ - }; - - /* references are not active anymore so we can reference again */ - references(twenty&, thirty&) => { - /* Try uncommenting! - * Not ok since twenty/thirty is actively borrowed - */ - // twenty + thirty => int fifty; - }; -} diff --git a/examples/sum.fwd b/examples/sum.fwd deleted file mode 100644 index 89a2d11..0000000 --- a/examples/sum.fwd +++ /dev/null @@ -1,23 +0,0 @@ -print_int(i64 a); -print_nl(); - -sum_inner(i64 s, i64 n, (i64) res) -{ - if n <= 0 { - res(s); - } else { - sum_inner(s + n, n - 1, res); - } -} - -sum(i64 n, (i64) res) -{ - sum_inner(0, n, res); -} - -main() -{ - sum(1000000000) => i64 s; - print_int(s); - print_nl(); -} diff --git a/examples/uniq.fwd b/examples/uniq.fwd deleted file mode 100644 index cc6e0af..0000000 --- a/examples/uniq.fwd +++ /dev/null @@ -1,52 +0,0 @@ -/* not entirely sure about the final syntax just yet but something like this */ - -/* 'extern' functions (though some should probably be generic?) */ -fwd_getline( - (optional![string]) next); - -fwd_some(optional![string] o, - (string) something | () nothing); - -fwd_insert(unordered_set![string] set, string line, - (unordered_set![string]) next); - -fwd_destroy(auto a); - -/* at some point I'll probably add in a type system as well, but for now let's - * pretend we're static-dynamic (or dynamic at compiletime? dunno) */ -readlines(unordered_set![string] set, (unordered_set![string]) next) -{ - fwd_getline() => optional![string] line; - !> e { - own set {fwd_destroy(set);} - error e - } - - fwd_some(line) => string line { - /* we had something in our option */ - fwd_insert(set, line) => unordered_set![string] set; - - /* at the moment the only supported looping construct is - * recursion */ - readlines(set, next); - } => { - /* option was illegal, we've read all input there is */ - next(set); - } -} - -fwd_foreach(unordered_set![string] set, - (string) callback); - -fwd_println(string s); - -main() -{ - /* fwdlib.hpp uses namespace std, not good practice but allows us to do - * stuff like this without really caring about implementing "::" */ - unordered_set![string]{} => unordered_set![string] set; - readlines(set) => unordered_set![string] set; - fwd_foreach(set) => string node { - fwd_println(node); - } -} diff --git a/examples/vec.fwd b/examples/vec.fwd deleted file mode 100644 index 75c5b2e..0000000 --- a/examples/vec.fwd +++ /dev/null @@ -1,150 +0,0 @@ -import "../mod/libfwdio.so" -import "../mod/libfwdmem.so" -import "../mod/libfwdutil.so" - -vec { - u64 n; - u64 s; - *i64 buf; -} - -init_vec(u64 n, (vec) ok) -{ - ok([n => n, 0 as u64 => s, * => buf] vec); -} - -next_s_vec(u64 s, (u64) ok) -{ - if s == 0 as u64 { - ok(1 as u64); - } else { - ok(2 as u64 * s); - } -} - -reserve_vec(vec v, u64 c, (vec) ok) -{ - v => [n => n, s => s, buf => buf]; - - /* expand if we run out of space */ - if c > s { - next_s_vec(s) => s; - - /* note that fwdrealloc creates a new closure, meaning that it - * takes ownership of v.buf, so we can't back out and do a - * single ok(v) at the end of the function */ - fwdrealloc(buf, s * sizeof(i64)) => nbuf; - ok([c => n, s => s, nbuf => buf] vec); - } else { - /* if this were a generic vector we'd have to worry about - * destroying the elements, but since we're just dealing with - * integers this is fine */ - ok([c => n, s => s, buf => buf] vec); - } -} - -set_vec(vec v, i64 i, i64 e, (vec) ok) -{ - v => [n => n, s => s, buf => buf]; - /* oh wait, this is dumb, of course nbuf will never be null */ - buf + i => nbuf; - nil nbuf { - nil nbuf; - fwdfree(buf); - fwdpanic("set_vec, should never happen\n"); - } => dst; - - /* perform actual store */ - e => dst*; - - nil nbuf; - ok([n => n, s => s, buf => buf] vec); -} - -n_vec(vec v, (vec, u64) ok) -{ - v => [n => n, s => s, buf => buf]; - ok([n => n, s => s, buf => buf] vec, n); -} - -append_vec(vec v, i64 e, (vec) ok) -{ - n_vec(v) => v, n; - reserve_vec(v, n + 1 as u64) => v; - set_vec(v, n as i64, e) => v; - ok(v); -} - -at_vec(vec v, u64 i, (vec > &i64) ok) -{ - v => [n => n, s => s, buf => buf]; - guard(i < n) => { - fwdfree(buf); - fwdpanic("at_vec, bounds error\n"); - } => ; - - buf + i => *i64 nbuf; - nil nbuf { - nil nbuf; - fwdfree(buf); - fwdpanic("at_vec, should never happen\n"); - } => &i64 bufr; - - nil nbuf; - ok([n => n, s => s, buf => buf] vec, bufr); -} - -destroy_vec(vec v) -{ - v => [n => n, s => s, buf => buf]; - fwdfree(buf); - nil n; - nil s; -} - -populate_vec(i64 i, i64 n, vec v, (vec) ok) -{ - if i < n { - append_vec(v, i) => vec v; - populate_vec(i + 1, n, v, ok); - } else { - ok(v); - } -} - -guard(bool c, () err | () ok) -{ - if c { - ok(); - } else { - err(); - } -} - -check_vec(i64 i, i64 n, vec v, (vec) ok) -{ - if i < n { - at_vec(v, i as u64) => v, elem; - - /* oh, this doesn't really work with the memory analysis, since - * I can destroy `v` but `elem` is still usable. I guess I could - * transform this such that `elem` is only alive within a - * closure? Not sure. */ - guard(elem* == i) => { - destroy_vec(v); - fwdpanic("check_vec, vec built wrong\n"); - } => ; - - check_vec(i + 1, n, v, ok); - } else { - ok(v); - } -} - -main() -{ - init_vec(0 as u64) => vec v; - populate_vec(0, 1000000, v) => vec v; - check_vec(0, 1000000, v) => vec v; - destroy_vec(v); -} |
