diff options
Diffstat (limited to 'examples/std.ek')
| -rw-r--r-- | examples/std.ek | 259 |
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(); -} |
