aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/fib.fwd31
-rw-r--r--examples/ptrs.fwd7
-rw-r--r--examples/sum.fwd23
-rw-r--r--examples/vec.fwd143
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);
+}