aboutsummaryrefslogtreecommitdiff
path: root/examples/std.ek
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 20:44:26 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-14 20:44:26 +0300
commit2023a7b2d9656f80b00de81453348c0a66f200f7 (patch)
tree06e4ea293318955cc4cf620428d04f1708c17364 /examples/std.ek
parent1a56a881bc2c37614cfd074e7b986211c6d04809 (diff)
downloadek-2023a7b2d9656f80b00de81453348c0a66f200f7.tar.gz
ek-2023a7b2d9656f80b00de81453348c0a66f200f7.zip
test cleanup
+ Somewhat poor Git hygiene but I also fixed some bugs while I was at it.
Diffstat (limited to 'examples/std.ek')
-rw-r--r--examples/std.ek259
1 files changed, 0 insertions, 259 deletions
diff --git a/examples/std.ek b/examples/std.ek
deleted file mode 100644
index fda6d23..0000000
--- a/examples/std.ek
+++ /dev/null
@@ -1,259 +0,0 @@
-/* comparison traits */
-pub define cmp[] {
- eq(*cmp a, *cmp b => bool);
- lt(*cmp a, *cmp b => bool);
- bt(*cmp a, *cmp b => bool);
-
- ne(*cmp a, *cmp b => bool) {return !a.eq(b)}
-
- le(*cmp a, *cmp b => bool) {return !a.bt(b)}
- ge(*cmp a, *cmp b => bool) {return !a.lt(b)}
-}
-
-/* hash traits */
-pub define hash[] {
- hash(*hash h => i27);
-}
-
-/* builtin type 'implementations' */
-/* as a special case, builtin types are allowed to be typedef'd to implement
- * interfaces */
-pub typedef i27 {}
-pub typedef i9 {
- fmt![];
- fmt(*i9 i, string args => result![string]) {
- /* hmm, this static string would have to be deinitialized
- * somewhere else with possibly bad results. Should free() or
- * whatever I choose to use check if the pointer is in static
- * memory or something? Or should it be the user's
- * responsibility to ensure static strings are cloned? */
- return ok!(string!("123"));
- }
-
- cmp![];
- eq(*i9 i, *i9 o => bool) {
- return i* == o*;
- }
-
- cmp(*i9 i, *i9 o => bool) {
- return i* - o*;
- }
-
- hash![];
- hash(*i9 i => i27) {
- return i;
- }
-}
-
-pub typedef bool {
-}
-
-/* special case of special case, 'str' means *i9 but pointers aren't allowed in
- * the parser stage. Is this an ugly solution? Feels kind of ugly. */
-pub typedef str {
- fmt![];
- fmt(*i9 s, string args => result![string]) {
- /* here we should probably copy s in case it is statically
- * defined */
- return ok!(string!("cp"));
- }
-
- cmp![];
- eq(*i9 s, *i9 o => bool) {
- if s == o {return true;}
- /* iterate over stuff I guess */
- }
-
- lt(*i9 s, *i9 o => bool) {
- if s == o {return false;}
- /* iterate over stuff */
- }
-
- hash![];
- hash(*i9 s => i27) {
- /* iterate over all characters and hash them I guess */
- }
-}
-
-/* 'continue typedef' to implement more traits and stuff, can be postponed a bit
- * as I don't think it's an essential feature yet. Might be in the future,
- * though, just requires some extra finangling to figure out how each thing
- * should work.
- * Particularly template continuations might be a bit interesting, should we
- * force the user to replicate the type arguments or should it be done
- * automatically?
-
-pub continue str {
- /* implement some other traits */
-};
-*/
-
-/* any import */
-pub typedef any {}
-
-/* string import */
-pub typedef string {
- usize len;
- *i9 buf;
-}
-
-pub define string(s) {
- string!{.len = sizeof(s), .buf = s}
-}
-
-/* result import */
-pub typedef result[any T] {
- *i9 err;
- T val;
-
- err(*result r => bool) {
- return r*.err != null;
- }
-}
-
-pub define ok(v) {
- result!{.err = null, .val = v};
-}
-
-pub define err(e) {
- /* for this to work properly, I'll probably need some pretty decent type
- * decuction...*/
- result!{.err = e};
-}
-
-pub define errv(e, v) {
- result!{.err = e, .val = v};
-}
-
-/* fmt import */
-pub define fmt[] {
- fmt(*fmt p, string args => result![string]);
- str(*fmt p => string) {
- /* is this a loop? allowed? */
- const r = p*.fmt(string!(""));
- if r*.err() {
- abort("error converting to string");
- }
-
- return r*.v;
- }
-}
-
-/* file import */
-pub typedef file {
- /* file could also just be a memory region, kind of like memstream? */
-}
-
-/* here would be useful if macros could take type arguments as well, for example
- * f must be a file and fmt must be a string, but I guess this is a quirk I can
- * live with... */
-pub define fprint(f, fmt, ...args) {
- /* possible name clash, hmmm */
- i27 __ek_reserved_pos = 0;
- const for __ek_reserved_a : args {
- __ek_reserved_pos += f.output_fmt_string(fmt, pos);
- if __ek_reserved_pos < 0 {
- abort("too many print arguments");
- }
-
- /* pos should be at a {}, with an unknown string of arguments
- * within */
- /* find matching '}' */
- i27 __ek_reserved_prev_pos = __ek_reserved_pos;
- do {
- if fmt.at(__ek_reserved_pos) == '}' {break;}
- __ek_reserved_pos += 1;
- } while 1;
-
- /* skip leading '{' */
- __ek_reserved_prev_pos += 1;
-
- /* copy arguments to a separate string (probably pretty slow, a
- * string_view or something could be beneficial here)*/
- const p = fmt.dup(__ek_reserved_prev_pos, __ek_reserved_pos);
- const string r = a.fmt(p);
-
- /* better abort messages could be useful, provide some
- * "stringify" operator? #a or something? I guess we have
- * src_loc that could lift the appropriate code, maybe? not
- * high priority for now anyway */
- if r.err() {abort("failed to format argument");}
- f.output_raw_string(r.v);
-
- /* skip over trailing '}' */
- __ek_reserved_pos += 1;
- }
-
- /* if output_fmt_string() still wants to continue, we have extra
- * brackets that can't be handled as we ran out of args */
- if f.output_fmt_string(fmt, pos) > 0 {
- abort("too few print arguments");
- }
-}
-
-/* vec import */
-pub typedef vec[any T] {
- // we want our vector to be formattable, used by print etc.
- fmt![];
- fmt(*vec v, string args => result![string]) {
- return ok!(string!("test"));
- }
-
- usize len;
- *T buf;
- ^(usize) alloc;
-
- init(*vec v, ^(usize) alloc) {
- v*.len = 0;
- v*.buf = null;
- v*.alloc = alloc;
- }
-
- init(*vec v) {
- v*.init(alloc);
- }
-
- length(*vec v => usize) { return v.len; }
- index(*vec v, usize i => T)
- {
- assert(i < v*.len, "index %zu out of bounds\n", i);
- return &v*.buf[i];
- }
-
- index(*vec v, isize i => T)
- {
- if i < 0 {
- assert(-i < v*.len, "reverse index %zi out of bounds\n", i);
- return &v*.buf[v*.len + i];
- }
-
- /* v.whatever() is effectively syntactic sugar for
- * whatever::typeof(v)(&v), but since I don't allow typeof()
- * it's built-in. */
- return v*.index(i as usize);
- }
-
- prepend(*vec v, T e) { v*.insert(e, 0); }
- append(*vec v, T e) { v*.insert(e, v*.len); }
-
- preplace(*vec v, T e) { v*.place(e, 0); }
- applace(*vec v, T e) { v*.place(e, v*.len); }
-
- place(*vec v, T e) {}
- insert(*vec v, T e) {}
-
- deinit(*vec v)
- {
- for i27 i = 0; i < v.len; i += 1 {
- deinit(v[i]);
- v[i] = null;
- }
-
- dealloc(v.buf);
- }
-}
-
-main() {
- vec![i9] what;
- what.length();
-}