diff options
Diffstat (limited to 'tests/std')
l--------- | tests/std | 1 | ||||
-rw-r--r-- | tests/std/arr.toc | 29 | ||||
-rw-r--r-- | tests/std/base.toc | 23 | ||||
-rw-r--r-- | tests/std/io.toc | 53 | ||||
-rw-r--r-- | tests/std/mem.toc | 25 |
5 files changed, 130 insertions, 1 deletions
diff --git a/tests/std b/tests/std deleted file mode 120000 index 6ef7545..0000000 --- a/tests/std +++ /dev/null @@ -1 +0,0 @@ -../std
\ No newline at end of file diff --git a/tests/std/arr.toc b/tests/std/arr.toc new file mode 100644 index 0000000..a2d202b --- /dev/null +++ b/tests/std/arr.toc @@ -0,0 +1,29 @@ +// this could be made quite a bit faster with realloc + +Arr ::= struct (t :: Type) { + data : []t; + cap : int; +}; + +resv ::= fn(t ::=, a : &Arr(t), n: int) { + if a.cap >= n { + return; + } + a.cap = n; + new_data := new(t, a.cap); + new_data.len = a.data.len; + for x, i := &new_data { + *x = a.data[i]; + } + a.data = new_data; +}; + +add ::= fn(t ::=, a : &Arr(t), x : t) { + if a.data.len >= a.cap { + resv(a, a.cap * 2 + 2); + } + a.data.len += 1; + a.data[a.data.len-1] = x; +}; + +len ::= fn(t ::=, a : Arr(t)) int { a.data.len }; diff --git a/tests/std/base.toc b/tests/std/base.toc new file mode 100644 index 0000000..bdb91e0 --- /dev/null +++ b/tests/std/base.toc @@ -0,0 +1,23 @@ +PLATFORM_OTHER ::= 0; +PLATFORM_LINUX ::= 1; +PLATFORM_WINDOWS ::= 2; +PLATFORM_OSX ::= 3; +PLATFORM_FREEBSD ::= 4; +PLATFORM_OPENBSD ::= 5; +PLATFORM_MISC_UNIX ::= 6; + +PLATFORM ::= #builtin("platform"); +#if PLATFORM == PLATFORM_LINUX { + libc ::= "libc.so.6"; +} elif PLATFORM == PLATFORM_WINDOWS { + libc ::= "msvcrt.dll"; +} elif PLATFORM == PLATFORM_OSX { + libc ::= "libc.dylib"; +} elif PLATFORM == PLATFORM_FREEBSD || PLATFORM == PLATFORM_OPENBSD { + libc ::= "libc.so"; +} else { + /* maybe it's non-linux gnu? */ + libc ::= "libc.so.6"; +} + + diff --git a/tests/std/io.toc b/tests/std/io.toc new file mode 100644 index 0000000..9fa7e08 --- /dev/null +++ b/tests/std/io.toc @@ -0,0 +1,53 @@ +/* @TODO: use write / WriteFile */ + +#include "std/base.toc", base; + +putchar ::= #foreign("putchar", base.libc) fn(#C int) #C int; +toc_putchar ::= fn(x: char) { + putchar(x as #C int); +} + +/* +unfortunately, we can't use fwrite because MSVC doesn't like it when you +use a file handle that's not from the DLL. (i.e. you can't pass your stdout +to the imported version of fwrite) +*/ + +writes ::= fn(x: []char) { + for c := x { + toc_putchar(c); + } +} + +puts ::= fn(x: []char) { + writes(x); + toc_putchar('\n'); +} + +writei ::= fn(x: int) { + if x < 0 { + toc_putchar('-'); + // NOTE: don't do x = -x; here to make sure I64_MIN works + } + if x == 0 { + toc_putchar('0'); + } else { + abs ::= fn(x: int) int { if x < 0 { -x } else { x } }; + scan_digit := 1000000000000000000; + started := false; + while scan_digit > 0 { + digit := abs((x / scan_digit) % 10); + if digit > 0 { started = true; } + if started { + toc_putchar((('0' as int) + digit) as char); + } + scan_digit /= 10; + } + } +} + +puti ::= fn(x: int) { + writei(x); + toc_putchar('\n'); +} + diff --git a/tests/std/mem.toc b/tests/std/mem.toc new file mode 100644 index 0000000..ef4e638 --- /dev/null +++ b/tests/std/mem.toc @@ -0,0 +1,25 @@ +#include "std/base.toc", base; + +// TODO: check for failed calloc +calloc ::= #foreign("calloc", base.libc) fn(#C size_t, #C size_t) #C &"void"; +free ::= #foreign("free", base.libc) fn(#C &"void"); + +new ::= fn(t :: Type) &t { + calloc(1, (sizeof t) as #C size_t) +} + +news ::= fn(t :: Type, n : int) []t { + s: []t; + s.data = calloc(n as #C size_t, (sizeof t) as #C size_t); + s.len = n; + s +} + +// TODO(eventually): use type information to make this just one function +del ::= fn(t::=, x: &t) { + free(x); +} + +dels ::= fn(t::=, x: []t) { + free(x.data); +} |