summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--foreign_avcall.c3
-rw-r--r--std/io.toc13
-rw-r--r--test.toc67
-rw-r--r--tests/arr.toc16
-rw-r--r--tests/bf.toc13
-rw-r--r--tests/foreign.toc25
-rw-r--r--tests/params.toc12
-rw-r--r--tests/printf.toc4
-rw-r--r--tests/std/arr.toc29
-rw-r--r--tests/std/base.toc23
-rw-r--r--tests/std/io.toc30
-rw-r--r--tests/std/mem.toc6
-rwxr-xr-xtests/test.sh67
13 files changed, 140 insertions, 168 deletions
diff --git a/foreign_avcall.c b/foreign_avcall.c
index 69146bb..1f0ac8d 100644
--- a/foreign_avcall.c
+++ b/foreign_avcall.c
@@ -261,7 +261,8 @@ static Status arg_list_add(av_alist *arg_list, Value val, Type *type, Location w
break;
case BUILTIN_VARARGS:
arr_foreach(val.varargs, VarArg, arg) {
- arg_list_add(arg_list, arg->val, arg->type, where);
+ if (!arg_list_add(arg_list, arg->val, arg->type, where))
+ return false;
}
break;
case BUILTIN_VOID:
diff --git a/std/io.toc b/std/io.toc
index c3d8f71..a56ef55 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -1,13 +1,22 @@
+/* TODO: use write / WriteFile */
+
#include "std/base.toc";
putchar ::= #foreign("putchar", libc) fn(#C int) #C int;
toc_putchar ::= fn(x: char) {
putchar(x as #C int);
}
-fwrite ::= #foreign("fwrite", libc) fn(#C &"const void", #C size_t, #C size_t, #C &"FILE") #C size_t;
+
+/*
+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) {
- fwrite(&x[0], 1, x.len as #C size_t, #builtin("stdout"));
+ for c := x {
+ toc_putchar(c);
+ }
}
puts ::= fn(x: []char) {
diff --git a/test.toc b/test.toc
index a4b7bff..281446d 100644
--- a/test.toc
+++ b/test.toc
@@ -1,34 +1,39 @@
-#include "std/io.toc";
-#include "std/mem.toc";
-main ::= fn() {
- p := #builtin("platform");
- P ::= #builtin("platform");
- puti(p);
- puti(P);
- s := news(char, 12);
- for c, i := "hello, world" {
- s[i] = c;
+// BUGBUGBUG: puti(puti(x))
+
+printf ::= #foreign("printf","libc.so.6") fn(#C &"const char", #C ..) #C int;
+
+
+// NOTE: this doesn't work (e.g. "%%%")
+tprintf_valid ::= fn(fmt :: []char, nargs: int) bool {
+ if fmt[fmt.len-1] != '\0' {
+ return false;
+ }
+ count := 0;
+ for x, i := fmt {
+ if x == '%' {
+ if i == fmt.len-1 {
+ count += 1;
+ } elif fmt[i+1] != '%' {
+ count += 1;
+ } else {
+ count -= 1;
+ }
+ }
+ }
+ count == nargs
+};
+
+
+tprintf ::= fn(fmt :: []char, args: ..) {
+ #if !tprintf_valid(fmt, args.len) {
+ #error "Invalid printf format";
}
- puts(s);
-}
-main();
-/*
-stdc ::= "msvcrt.dll";
-printf ::= #foreign("printf",stdc) fn (#C &"char const", #C ..) #C int;
-puti ::= fn(i: u64) i32 {
- fmt := "number: %llx\n\0";
- printf(&fmt[0], i) as i32
-}
+ f := fmt;
+ printf(&f[0], args);
+};
-// BUG: puti(puti(x))
-sqrt ::= #foreign("sqrt",stdc) fn(f64) f64;
-putf ::= fn(f: f64) i32 {
- fmt := "number: %f\n\0";
- printf(&fmt[0], f) as i32
-}
-foo ::= #foreign("foo", "test.dll") fn(#C unsigned_long_long, #C unsigned_long_long) #C unsigned_long_long;
main ::= fn() {
- puti(foo(0x12345678cafebabe as u64, 0x76543210deadbeef as u64));
-}
-main();
-*/
+ tprintf("%d %d%%\n\0", 3 as #C int, 4 as #C int);
+ tprintf("%d %d %d%%\n\0", 3 as #C int, 4 as #C int, 5 as #C int);
+ tprintf("Hello!\n\0");
+};
diff --git a/tests/arr.toc b/tests/arr.toc
index 3af9edd..afcf340 100644
--- a/tests/arr.toc
+++ b/tests/arr.toc
@@ -1,19 +1,5 @@
#include "std/mem.toc";
-puti ::= fn(x: int) {
-//tcc's giving me "incompatible types for redefinition of 'printf'" for some reason (even though the declarations have the exact same type)
- #C("#ifndef __TINYC__
-extern int printf(const char *fmt, ...);
-#endif
-");
- #C("printf(\"%ld\\n\", (long)x);");
-};
-putf ::= fn(x: float) {
- #C("#ifndef __TINYC__
-extern int printf(const char *fmt, ...);
-#endif
-");
- #C("printf(\"%f\\n\", (double)x);");
-};
+#include "std/io.toc";
// it would be nice if Arr.data.len == Arr.len (: but this will require some C code...
Arr ::= fn (t :: Type) Type {
diff --git a/tests/bf.toc b/tests/bf.toc
index 166601b..83fb291 100644
--- a/tests/bf.toc
+++ b/tests/bf.toc
@@ -1,15 +1,15 @@
#include "std/mem.toc";
-
+#include "std/io.toc";
readfile ::= fn(filename: []char) []char {
#C("extern void *fopen(char *name, char const *mode); extern char *fgets(char *buf, size_t sz, void *f);");
#C("
-extern int printf(const char *fmt, ...);
extern void exit(int);
");
fp : &u8 = #C("(u8 *)fopen(&(((char *)filename.data)[0]), \"r\")");
if !fp {
- #C("printf(\"Couldn't open file\\n\"); exit(-1);");
+ puts("couldn't open file.");
+ #C("exit(-1);");
}
contents := news(char, 1);
contents_sz : int;
@@ -42,13 +42,6 @@ extern void exit(int);
contents
};
-puti ::= fn(x: int) {
- #C("
-extern int printf(const char *fmt, ...);
-");
- #C("printf(\"%ld\\n\", x);");
-};
-
runfile ::= fn(filename: []char) {
#C("extern int putchar(int c);");
code := readfile(filename);
diff --git a/tests/foreign.toc b/tests/foreign.toc
deleted file mode 100644
index 92038d9..0000000
--- a/tests/foreign.toc
+++ /dev/null
@@ -1,25 +0,0 @@
-fwrite ::= #foreign("fwrite", "libc.so.6") fn (#C &"void const", #C size_t, #C size_t, &u8) #C size_t;
-fputc ::= #foreign("fputc", "libc.so.6") fn (#C int, &u8) #C int;
-
-writes ::= fn(x : []char) {
- fwrite(&x[0], 1, x.len as u64, #builtin("stdout"));
-};
-
-puts ::= fn(x : []char) {
- writes(x);
- fputc('\n' as i32, #builtin("stdout"));
-};
-
-hw ::= fn() int {
- writes("Hello,");
- if #builtin("compiling") {
- writes(" compiling");
- }
- puts(" world!");
- 3
-};
-
-main ::= fn() {
- hw();
- x ::= hw();
-};
diff --git a/tests/params.toc b/tests/params.toc
index 4d37cf1..f43d7ba 100644
--- a/tests/params.toc
+++ b/tests/params.toc
@@ -1,3 +1,5 @@
+#include "std/io.toc";
+
addmul ::= fn (x:=0, y:=0) add := x+y, mul := x*y {
};
@@ -6,14 +8,6 @@ do_foo ::= fn (x := 3) y := x {
y += x;
};
-puti ::= fn(x: int) {
- #C("#ifndef __TINYC__
-extern int printf(const char *fmt, ...);
-#endif
-");
- #C("printf(\"%ld\\n\", x);");
-};
-
main ::= fn() {
a, m := addmul();
@@ -37,4 +31,4 @@ main ::= fn() {
puti(z);
z = do_foo(x = -1);
puti(z);
-}; \ No newline at end of file
+};
diff --git a/tests/printf.toc b/tests/printf.toc
index e030af4..ede3012 100644
--- a/tests/printf.toc
+++ b/tests/printf.toc
@@ -31,7 +31,7 @@ tprintf ::= fn(fmt :: []char, args: ..) {
};
main ::= fn() {
- tprintf("%d %d%%\n\0", 3, 4);
- tprintf("%d %d %d%%\n\0", 3, 4, 5);
+ tprintf("%d %d%%\n\0", 3 as #C int, 4 as #C int);
+ tprintf("%d %d %d%%\n\0", 3 as #C int, 4 as #C int, 5 as #C int);
tprintf("Hello!\n\0");
};
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
index 2c82dc9..994cd2a 100644
--- a/tests/std/io.toc
+++ b/tests/std/io.toc
@@ -1,12 +1,22 @@
-putchar ::= #foreign("putchar", "libc.so.6") fn(#C int) #C int;
+/* @TODO: use write / WriteFile */
+
+#include "std/base.toc";
+
+putchar ::= #foreign("putchar", libc) fn(#C int) #C int;
toc_putchar ::= fn(x: char) {
putchar(x as #C int);
}
-printf ::= #foreign("printf", "libc.so.6") fn(#C &"char const", #C ..) #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) {
- printf_strfmt := "%s\0";
- printf(&printf_strfmt[0], &x[0]);
+ for c := x {
+ toc_putchar(c);
+ }
}
puts ::= fn(x: []char) {
@@ -41,3 +51,15 @@ puti ::= fn(x: int) {
toc_putchar('\n');
}
+/* @TODO: write your own version of this */
+printf ::= #foreign("printf", libc) fn(#C &"const char", #C ..) #C int;
+writef ::= fn(x: float) {
+ fmt := "%f\0";
+ printf(&fmt[0], x as f64);
+};
+putf ::= fn(x: float) {
+ writef(x);
+ toc_putchar('\n');
+}
+
+
diff --git a/tests/std/mem.toc b/tests/std/mem.toc
index 6d16895..e283364 100644
--- a/tests/std/mem.toc
+++ b/tests/std/mem.toc
@@ -1,6 +1,8 @@
+#include "std/base.toc";
+
// TODO: check for failed calloc
-calloc ::= #foreign("calloc", "libc.so.6") fn(#C size_t, #C size_t) #C &"void";
-free ::= #foreign("free", "libc.so.6") fn(#C &"void");
+calloc ::= #foreign("calloc", libc) fn(#C size_t, #C size_t) #C &"void";
+free ::= #foreign("free", libc) fn(#C &"void");
new ::= fn(t :: Type) &t {
calloc(1, (sizeof t) as #C size_t)
diff --git a/tests/test.sh b/tests/test.sh
deleted file mode 100755
index 1d01f06..0000000
--- a/tests/test.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-
-tests='bf
-control_flow
-types
-include
-arrs_slices
-ptr_arithmetic
-defer
-sizeof
-new
-arr
-arr2
-arr3
-foreign
-params
-nms
-varargs
-printf
-use
-misc'
-
-STARTPWD=$(pwd)
-cd $(pwd)/$(dirname $0)
-TOC=../toc
-CFLAGS="-g -Wno-parentheses-equality"
-echo $$
-
-compile_c() {
- EXTRA_FLAGS=""
- if [ "$CC" = "gcc -O0 -g" ]; then
- EXTRA_FLAGS="-Wno-builtin-declaration-mismatch"
- elif [ "$CC" = "clang -O3 -s" ]; then
- EXTRA_FLAGS="-Wno-builtin-requires-header -Wno-format-security"
- elif [ "$CC" = "tcc" ]; then
- EXTRA_FLAGS="-w"
- fi
- $CC $CFLAGS $EXTRA_FLAGS -Werror -o a.out out.c || exit 1
-}
-
-failed=false
-
-do_tests() {
- echo "----$1----"
- valgrind -q --exit-on-first-error=yes --error-exitcode=1 $TOC "$1.toc" -o out.c || exit 1
- for CC in "gcc -O0 -g" "tcc" "clang -O3 -s"; do
- if [ "$1" = "sizeof" ]; then
- if [ "$CC" = "tcc" ]; then
- continue # some versions of tcc don't have _Alignof
- fi
- fi
- printf "Running test $1 with C compiler $CC... "
- compile_c "$1"
- ./a.out > got
- if diff "$1"_expected got; then
- printf '\x1b[92mpassed!\x1b[0m\n'
- else
- printf '\x1b[91mfailed!\x1b[0m\n'
- exit 1
- fi
- done
-}
-for x in $tests; do
- do_tests "$x"
-done
-
-rm got a.out out.c