diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/fib.fwd | 31 | ||||
| -rw-r--r-- | examples/ptrs.fwd | 7 | ||||
| -rw-r--r-- | examples/sum.fwd | 23 | ||||
| -rw-r--r-- | examples/vec.fwd | 143 |
4 files changed, 187 insertions, 17 deletions
diff --git a/examples/fib.fwd b/examples/fib.fwd index 7084b9d..4583a26 100644 --- a/examples/fib.fwd +++ b/examples/fib.fwd @@ -1,25 +1,30 @@ -/* heh, this technically speaking works, but I guess the compiler can't collapse - * frames so the bifurcating nature of fibonacci just gets mapped to a linear - * sequence of calls, taking up way more stack space than a typical, returning, - * function */ +/* + * 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 + * + */ -fib(int n, (int) res) +/* 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) => int f1; - fib(n - 2) => int f2; + fib(n - 1) => i64 f1; + fib(n - 2) => i64 f2; res(f1 + f2); } } -/* 'extern' println */ -fwd_println(auto n); -fwd_copy(auto n, (auto, auto) n1); - main() { - fib(6) => int n; - fwd_println(n); + fib(42) => i64 n; + fwdprint_i64(n); + fwdprint_nl(); } diff --git a/examples/ptrs.fwd b/examples/ptrs.fwd index a0f8aac..a1efc84 100644 --- a/examples/ptrs.fwd +++ b/examples/ptrs.fwd @@ -1,7 +1,6 @@ -fwd_null(auto x, () null, (&auto) ok); -fwd_copy(auto x, (auto, auto) ok); -fwd_println(auto x); -fwd_intalloc((*int) ok); +extern fwd_copy(auto x, (auto, auto) ok); +extern fwd_println(auto x); +extern fwd_intalloc((*int) ok); main() { diff --git a/examples/sum.fwd b/examples/sum.fwd new file mode 100644 index 0000000..89a2d11 --- /dev/null +++ b/examples/sum.fwd @@ -0,0 +1,23 @@ +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/vec.fwd b/examples/vec.fwd new file mode 100644 index 0000000..22049e0 --- /dev/null +++ b/examples/vec.fwd @@ -0,0 +1,143 @@ +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]; + n + c => nn; + + /* expand if we run out of space */ + if nn > 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([nn => n, s => s, nbuf => buf] vec); + } else { + ok([nn => n, s => s, buf => buf] vec); + } +} + +set_vec(vec v, i64 i, i64 e, (vec) ok) +{ + v => [n => n, s => s, buf => buf]; + buf + (n - 1 as u64) => nbuf; + nil nbuf { + nil nbuf; + fwdfree(buf); + fwdpanic("should never happen"); + } => 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 - 1, 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("bounds error"); + } => ; + + buf + i => *i64 nbuf; + nil nbuf { + nil nbuf; + fwdfree(buf); + fwdpanic("should never happen"); + } => &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 { + err(); + } else { + ok(); + } +} + +check_vec(i64 i, i64 n, vec v, (vec) ok) +{ + if i < n { + at_vec(v, i as u64) => v, elem; + + guard(elem* != i) => { + destroy_vec(v); + fwdpanic("vec built wrong"); + } => ; + + 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); +} |
