aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-12-29 00:07:16 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2025-12-29 00:07:16 +0200
commit90b0d817fedfa5715b195e16da67fa6bdd67638e (patch)
treede5c01884a434ffcc940be2e96474f188c95362c /examples
parent0e0c41af58a0f4ec5a39ce77822de71e5523fcba (diff)
downloadfwd-90b0d817fedfa5715b195e16da67fa6bdd67638e.tar.gz
fwd-90b0d817fedfa5715b195e16da67fa6bdd67638e.zip
work towards a simple integer vector implementationgnc
+ Hopefully shows that useful programs can be implemented with the rules present + Still missing at least external functions with non-void returns
Diffstat (limited to 'examples')
-rw-r--r--examples/ptrs.fwd7
-rw-r--r--examples/vec.fwd150
2 files changed, 115 insertions, 42 deletions
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/vec.fwd b/examples/vec.fwd
index 1cc10b3..6c854d5 100644
--- a/examples/vec.fwd
+++ b/examples/vec.fwd
@@ -1,51 +1,125 @@
+import "../mod/libfwdio.so"
import "../mod/libfwdmem.so"
import "../mod/libfwdutil.so"
-/* trait */
-any = {}
+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);
+ }
+}
-/* template */
-vec[any type]() {
- <> {
- i64 s;
- i64 n;
- *[]type buf;
+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 {fwdpanic("should never happen");} => dst;
+ e => dst*;
+ ok([n => n, s => s, nbuf => 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];
+ if i >= n {fwdpanic("bounds error");}
+ fwdptradd(buf, (i * sizeof(i64)) as i64) => *i64 buf;
+ nil buf {fwdpanic("should never happen");} => &i64 bufr;
+ 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;
+}
- <>create((<>) next)
- {
- next((0 => s, 0 => n, * => buf)<>);
+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);
}
+}
- <>append(<> v, type n, (<>) next)
- {
- v.n = v.n + 1;
- if v.s == 0 {
- v.s = 1;
- }
-
- if v.n > v.s {
- if v.s == 0 {
- v.s = 1;
- }
-
- v.s = v.s * 2;
- fwdrealloc(v.buf, v.s as u64 * sizeof(type)) => ptr;
- v.buf = ptr;
- }
-
- /* in a real implementation this would be moved to after
- * fwdrealloc I guess, but this is fine for now */
- nil v.buf {fwdpanic("no buf for vector");} => buf;
- buf*[v.n - 1] = n;
- next(v);
+guard(bool c, () err | () ok)
+{
+ if c {
+ err();
+ } else {
+ ok();
}
+}
- <>destroy(<> v)
- {
- fwdfree(v.buf);
- nil v;
+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);
}
}
-u8vec = vec[u8]()
+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);
+}