aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-03-07 02:18:26 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-03-07 02:18:26 +0200
commitae5fee63f160643a397d18e9e0658275606bc4d4 (patch)
treef68af302374f9ae3c9dbb28dab5547036252d559 /examples
downloadek-ae5fee63f160643a397d18e9e0658275606bc4d4.tar.gz
ek-ae5fee63f160643a397d18e9e0658275606bc4d4.zip
initial commit
Diffstat (limited to 'examples')
-rw-r--r--examples/alloc.ct18
-rw-r--r--examples/arc.ct53
-rw-r--r--examples/example.ct97
-rw-r--r--examples/numeral.ct35
-rw-r--r--examples/option.ct6
-rw-r--r--examples/std.ct35
-rw-r--r--examples/v.ct12
-rw-r--r--examples/vec.ct62
8 files changed, 318 insertions, 0 deletions
diff --git a/examples/alloc.ct b/examples/alloc.ct
new file mode 100644
index 0000000..5f11bb7
--- /dev/null
+++ b/examples/alloc.ct
@@ -0,0 +1,18 @@
+/* from c bindings */
+
+pub alloc(s usize) *void
+{
+ p *u8 = malloc(s);
+ assert(p, "memory allocation failed\n");
+ return p;
+}
+
+pub dealloc(p *void)
+{
+ free(p);
+}
+
+pub realloc(p *, s usize) *void
+{
+ realloc(p, s);
+}
diff --git a/examples/arc.ct b/examples/arc.ct
new file mode 100644
index 0000000..8869b42
--- /dev/null
+++ b/examples/arc.ct
@@ -0,0 +1,53 @@
+/* could be non-null instead of raw pointer? */
+typedef atomic_rc [t any] {
+ count *usize;
+ data *t;
+}
+
+/* macros must be 'called' with () */
+pub define arc(t) { struct (atomic_rc[t]) };
+
+pub dereference(a *arc) *#a.data
+{
+ return a.t;
+}
+
+pub init(mut a *arc, e #a.data)
+{
+ new(a.count, 0);
+ a.data = e;
+}
+
+pub init(mut a *arc, b *arc<#a.data>)
+{
+ copy(a, b);
+}
+
+pub deinit(mut a *arc)
+{
+ if atomic_fetch_add(a.count, -1) == 1 {
+ dealloc(a.data);
+ dealloc(a.count);
+ }
+
+ a.count = null;
+ a.data = null;
+}
+
+pub copy(mut a *arc, b *arc<#a.data>)
+{
+ deinit(a);
+ a.count = b.count;
+ a.data = b.data;
+ atomic_fetch_add(b.count, 1);
+}
+
+pub move(mut a *arc, mut b *arc<#a.data>)
+{
+ deinit(a);
+ a.count = b.count;
+ a.data = b.data;
+ /* reference count stays the same */
+ b.count = null;
+ a.count = null;
+}
diff --git a/examples/example.ct b/examples/example.ct
new file mode 100644
index 0000000..ce3e4e7
--- /dev/null
+++ b/examples/example.ct
@@ -0,0 +1,97 @@
+/* String example */
+
+pub struct string {
+ len usize;
+ buf *u8;
+}
+
+pub init(mut s *string)
+{
+ s.len = 0;
+ s.buf = null;
+}
+
+pub deinit(mut s *string)
+{
+ dealloc(s.buf);
+}
+
+pub init(mut s *string, u *u8)
+{
+ len usize = 0;
+ r any = u;
+ while r++ {len++;}
+
+ s.len = len;
+ s.buf = alloc(s.len);
+ memcpy(s.buf, u);
+}
+
+pub copy(mut r *string, s *string) *string
+{
+ dealloc(r.buf);
+ r.len = s.len;
+ r.buf = alloc(r.len);
+ memcpy(r.buf, s.buf);
+}
+
+pub move(mut r *string, mut s *string) *string
+{
+ dealloc(r.buf);
+ r.len = s.len;
+ r.buf = s.buf;
+ s.buf = null;
+ s.len = 0;
+}
+
+pub length(s *string) usize
+{
+ return s.len;
+}
+
+pub index(s *string, i usize) u8
+{
+ assert(i < len, "index %zu out of bounds\n", i);
+ return s.buf[i];
+}
+
+pub add(r *string, a *string, b *string)
+{
+ len any = length(a) + length(b);
+ buf any = alloc(l);
+
+ if r.buf == a.buf {
+ dealloc(a.buf);
+ } else if r.buf == b.buf {
+ dealloc(b.buf);
+ }
+
+ r.buf = buf;
+ r.len = len;
+}
+
+pub define new(x ...args)
+{
+ x = alloc(sizeof(x));
+ init(@ ...args);
+}
+
+pub define ctx(x ...args)
+{
+ init(&x ...args);
+ defer(deinit(@));
+}
+
+main(argc i32, argv [argc] * u8)
+{
+ something = argv[10]; // run type bounds checking for ranged array?
+ // will not be automatically freed
+ new(a *string);
+ new(b *string, "hello");
+ c string; // undefined state
+ // will be automatically 'freed'
+ ctx(c string);
+ ctx(v vec<string>);
+ append(v, a);
+ append(v, c);
+}
diff --git a/examples/numeral.ct b/examples/numeral.ct
new file mode 100644
index 0000000..38936e9
--- /dev/null
+++ b/examples/numeral.ct
@@ -0,0 +1,35 @@
+/* good optimisation target: make these built in */
+type numeral {
+ u8;
+ u16;
+ u32;
+ u64;
+ i8;
+ i16;
+ i32;
+ i64;
+ isize;
+ usize;
+ float;
+ double;
+}
+
+pub init(mut a *numeral)
+{
+ *a = 0;
+}
+
+pub deinit(mut a *numeral)
+{
+ *a = 0;
+}
+
+pub copy(mut a *numeral, b *numeral)
+{
+ *a = *b;
+}
+
+pub move(mut a *numeral, mut b *numeral)
+{
+ *a = *b;
+}
diff --git a/examples/option.ct b/examples/option.ct
new file mode 100644
index 0000000..483a9ee
--- /dev/null
+++ b/examples/option.ct
@@ -0,0 +1,6 @@
+type t {any};
+
+struct option <t> {
+ u8 res;
+ t val;
+};
diff --git a/examples/std.ct b/examples/std.ct
new file mode 100644
index 0000000..339459f
--- /dev/null
+++ b/examples/std.ct
@@ -0,0 +1,35 @@
+type std {
+ init(mut * any);
+ deinit(mut * any);
+ copy(mut * any, * any);
+ move(mut * any, mut * any);
+}
+
+/* these as well could be way optimized for builtin types */
+type comparable {
+ equal(* any, * any) bool;
+ less_than(* any, * any) bool;
+}
+
+/* I'm imagining that if someone provides a specific function for these, it will
+ * be used rather than these ones, but that the minimum to implement comparable
+ * is as small as possible this should be fine */
+pub not_equal(a * comparable, b * comparable) bool
+{
+ return !equal(a, b);
+}
+
+pub greater_than(a * comparable. b * comparable) bool
+{
+ return !equal(a, b) && !less_than(a, b);
+}
+
+pub less_or_equal(a * comparable, b * comparable) bool
+{
+ return !greater_than(a, b);
+}
+
+pub greater_or_equal(a * comparable, b * comparable) bool
+{
+ return !less_than(a, b);
+}
diff --git a/examples/v.ct b/examples/v.ct
new file mode 100644
index 0000000..2026d55
--- /dev/null
+++ b/examples/v.ct
@@ -0,0 +1,12 @@
+main(argc u32, argv[argc] *u8) i32
+{
+ ctx(vec(u32) a);
+ // equivalent to
+ ctx(struct (vec[u32]) a);
+
+ // All entities defined with struct [vector<u32>] are seen as the same
+ // structure, i.e. mangled the same. Something like vector_u32
+ // If someone adds a name, i.e. structure lol [vector(u32)] the mangling
+ // is lol_vector_u32 and considered a different type. All identical
+ // definitions of structs are considered the same struct, in short.
+}
diff --git a/examples/vec.ct b/examples/vec.ct
new file mode 100644
index 0000000..f44fec0
--- /dev/null
+++ b/examples/vec.ct
@@ -0,0 +1,62 @@
+typedef vectorable {
+ std;
+ /* this would be needed for comparisons like find() or something */
+ comparable;
+}
+
+typedef vec (t vectorable) {
+ void std_vector;
+ len usize;
+ buf *t;
+}
+
+pub define vec(t) { struct (vector[t]) }
+
+pub init(mut v *vector)
+{
+ v.len = 0;
+ v.buf = null;
+}
+
+pub length(v *vec) usize { return v.len; }
+
+pub index(v *vec, i usize) *#(v.buf)
+{
+ assert(i < v.len, "index %zu out of bounds\n", i);
+ return &v.buf[i];
+}
+
+pub index(v *vec, i isize) *#v.buf
+{
+ if i < 0 {
+ assert(-i < v.len, "reverse index %zi out of bounds\n", i);
+ return &v.buf[v.len + i];
+ }
+
+ assert(i < v.len, "index %zi out of bounds\n", i);
+ return &v.buf[i];
+}
+
+pub prepend(mut *vec, e *#v.buf) { insert(v, e, 0uz); }
+pub append(mut v *vec, e *#v.buf) { insert(v, e, v.len) }
+
+pub preplace(mut v *vec, e *#v.buf) { place(v, e, 0uz); }
+pub applace(mut v *vec, e *#v.buf) { place(v, e, v.len - 1); }
+
+pub place(mut v *vec, e *#v.buf, i usize)
+{
+}
+
+pub insert(mut v *vec, e *#v.buf, i usize)
+{
+}
+
+pub deinit(mut v *vec)
+{
+ for i usize : v {
+ deinit(v[i]);
+ v[i] = null;
+ }
+
+ dealloc(v.buf);
+}