summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--foreign64.c19
-rw-r--r--main.c3
-rw-r--r--misc.c4
-rw-r--r--std/io.toc14
-rw-r--r--test.toc9
-rw-r--r--tests/.gitignore2
-rw-r--r--tests/std/io.toc9
-rw-r--r--tests/test.bat4
-rwxr-xr-xtests/test.sh2
-rw-r--r--tests/tests.c (renamed from tests/test.c)2
-rw-r--r--types.c40
11 files changed, 69 insertions, 39 deletions
diff --git a/foreign64.c b/foreign64.c
index d00d5d2..0a0fc40 100644
--- a/foreign64.c
+++ b/foreign64.c
@@ -7,10 +7,17 @@
#error "What's going on? The 64-bit #foreign file was included, but size_t isn't 64 bits!"
#endif
+#ifdef __cplusplus
+#define external extern "C"
+#else
+#define external extern
+#endif
+
#ifdef _WIN64
-extern U64 win64_call(FnPtr fn, U64 *args, I64 nargs);
-extern float win64_callf(FnPtr fn, U64 *args, I64 nargs);
-extern double win64_calld(FnPtr fn, U64 *args, I64 nargs);
+
+external U64 win64_call(FnPtr fn, U64 *args, I64 nargs);
+external float win64_callf(FnPtr fn, U64 *args, I64 nargs);
+external double win64_calld(FnPtr fn, U64 *args, I64 nargs);
static inline U64 foreign_calli(FnPtr fn, U64 *args, I64 nargs, bool *is_float) {
(void)is_float;
@@ -27,9 +34,9 @@ static inline double foreign_calld(FnPtr fn, U64 *args, I64 nargs, bool *is_floa
return win64_calld(fn, args, nargs);
}
#else
-extern U64 systemv64_call(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
-extern float systemv64_callf(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
-extern double systemv64_calld(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
+external U64 systemv64_call(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
+external float systemv64_callf(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
+external double systemv64_calld(FnPtr fn, U64 *args, I64 nargs, bool *is_float);
static inline U64 foreign_calli(FnPtr fn, U64 *args, I64 nargs, bool *is_float) {
return systemv64_call(fn, args, nargs, is_float);
}
diff --git a/main.c b/main.c
index 74aada4..a584916 100644
--- a/main.c
+++ b/main.c
@@ -8,10 +8,11 @@
/*
@TODO:
-do #include "std/base.toc", base; in std/io.toc and std/mem.toc
does our use before declare thing work with #include?
+allow using constant before declaring it, and do DECL_FINDING_TYPE, for circular dependencies
#no_warn
start making a standard library... (printf; stringbuilder would be nice to have)
+if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
improve type_to_str:
Foo ::= struct(t::Type) {}
type_to_str(Foo(int))
diff --git a/misc.c b/misc.c
index 056c84d..0a8ee86 100644
--- a/misc.c
+++ b/misc.c
@@ -62,6 +62,10 @@ static char *cstr(const char *str, size_t len) {
return ret;
}
+static inline char *str_to_cstr(String s) {
+ return cstr(s.str, s.len);
+}
+
static bool str_eq_cstr(String s, const char *str) {
return strncmp(s.str, str, s.len) == 0;
}
diff --git a/std/io.toc b/std/io.toc
index 9fa7e08..4f05be5 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -6,13 +6,14 @@ putchar ::= #foreign("putchar", base.libc) fn(#C int) #C int;
toc_putchar ::= fn(x: char) {
putchar(x as #C int);
}
+printf ::= #foreign("printf", base.libc) fn (#C &"const char", #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) {
for c := x {
toc_putchar(c);
@@ -50,4 +51,15 @@ puti ::= fn(x: int) {
writei(x);
toc_putchar('\n');
}
+*/
+/*
+writef ::= fn(x: float) {
+ fmt := "%f\0";
+ printf(&fmt[0], x);
+}
+putf ::= fn(x: float) {
+ writef(x);
+ toc_putchar('\n');
+}
+*/
diff --git a/test.toc b/test.toc
index 57063b1..4a91877 100644
--- a/test.toc
+++ b/test.toc
@@ -1,10 +1 @@
#include "std/io.toc", io;
-#include "std/io.toc", io;
-
-foo ::= #foreign("abort", "libc.so.6") fn();
-
-main ::= fn() {
- io.puts("hi");
- foo();
-}
-main();
diff --git a/tests/.gitignore b/tests/.gitignore
index 33ccc5b..9c57a91 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -2,5 +2,5 @@ got
out.c
a.out
*.exe
-test
+tests
*.core
diff --git a/tests/std/io.toc b/tests/std/io.toc
index 9fa7e08..2b9e999 100644
--- a/tests/std/io.toc
+++ b/tests/std/io.toc
@@ -51,3 +51,12 @@ puti ::= fn(x: int) {
toc_putchar('\n');
}
+printf ::= #foreign("printf", base.libc) fn (#C &"const char", #C ..) #C int;
+writef ::= fn(x: float) {
+ fmt := "%f\0";
+ printf(&fmt[0], x);
+}
+putf ::= fn(x: float) {
+ writef(x);
+ toc_putchar('\n');
+}
diff --git a/tests/test.bat b/tests/test.bat
index b8156ad..1acfe32 100644
--- a/tests/test.bat
+++ b/tests/test.bat
@@ -1,5 +1,5 @@
@echo off
pushd "%~dp0"
-cl /nologo test.c
-test
+cl /nologo tests.c
+tests.exe
popd
diff --git a/tests/test.sh b/tests/test.sh
index ce7b294..779fafe 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -1,4 +1,4 @@
#!/bin/sh
cd $(dirname $0)
-cc test.c -o test -Wall -Wconversion -Wshadow -Werror && ./test
+cc tests.c -o tests -Wall -Wconversion -Wshadow -Werror && ./tests || exit 1
cd - >/dev/null
diff --git a/tests/test.c b/tests/tests.c
index 0593c9d..57f611e 100644
--- a/tests/test.c
+++ b/tests/tests.c
@@ -96,6 +96,8 @@ int main(int argc, char **argv) {
}
for (c = 0; c < ncompilers; ++c) {
const char *compiler = str_dup(compilers[c]);
+ if (strcmp(test, "sizeof") == 0 && strncmp(compiler, "tcc", 3) == 0)
+ continue; /* i think some versions of tcc have _Alignof but some don't */
char *p = strchr(compiler, ' ');
if (p) *p = 0;
printf("on %s... ", compiler);
diff --git a/types.c b/types.c
index 7e4b56c..e657799 100644
--- a/types.c
+++ b/types.c
@@ -3728,8 +3728,8 @@ static Status types_stmt(Typer *tr, Statement *s) {
char *filename = eval_expr_as_cstr(tr, &inc->filename, "import filename");
if (!filename)
return false;
+ Namespace *prev_nms = tr->nms;
IncludedFile *inc_f = NULL;
-
Namespace *inc_nms = NULL; /* non-NULL if this is an include to nms */
if (inc->nms) {
inc_nms = typer_calloc(tr, 1, sizeof *inc_nms);
@@ -3738,6 +3738,9 @@ static Status types_stmt(Typer *tr, Statement *s) {
body->where = s->where;
idents_create(&body->idents, tr->allocr, body);
body->parent = tr->block;
+ /* go inside namespace and block (it'll help to be there later on) */
+ tr->nms = inc_nms;
+ typer_block_enter(tr, &inc_nms->body);
}
s->kind = STMT_INLINE_BLOCK;
@@ -3750,7 +3753,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
s->inline_block = NULL; /* nothing needed here */
/* just set ident declarations */
if (!include_stmts_link_to_nms(tr, inc_f->main_nms, inc_f->stmts))
- return false;
+ goto inc_fail;
goto nms_transform;
}
inc_f = str_hash_table_insert(&tr->included_files, filename, filename_len);
@@ -3760,7 +3763,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
char *contents = read_file_contents(tr->allocr, filename, s->where);
if (!contents) {
tr->had_include_err = true;
- return false;
+ goto inc_fail;
}
Tokenizer tokr;
@@ -3771,38 +3774,34 @@ static Status types_stmt(Typer *tr, Statement *s) {
file->ctx = tr->err_ctx;
if (!tokenize_file(&tokr, file))
- return false;
+ goto inc_fail;
Parser parser;
parser_create(&parser, tr->globals, &tokr, tr->allocr);
- parser.block = inc_nms ? &inc_nms->body : tr->block;
+ parser.block = tr->block;
ParsedFile parsed_file;
if (!parse_file(&parser, &parsed_file)) {
- return false;
+ goto inc_fail;
}
Statement *stmts_inc = parsed_file.stmts;
if (inc_f) {
inc_f->stmts = stmts_inc;
}
s->inline_block = stmts_inc;
- Namespace *prev_nms = tr->nms;
- Block *prev_block = tr->block;
- if (inc_nms) {
- tr->nms = inc_nms;
- tr->block = &inc_nms->body;
- }
arr_foreach(stmts_inc, Statement, s_incd) {
if (!types_stmt(tr, s_incd)) {
- return false;
+ goto inc_fail;
}
}
if (inc_nms) {
- tr->nms = prev_nms;
- tr->block = prev_block;
inc_nms->body.stmts = stmts_inc;
}
}
- nms_transform:
+ nms_transform:
if (inc_nms) {
+ /* go back to parent namespace/block because that's where the declaration is gonna be */
+ tr->nms = prev_nms;
+ typer_block_exit(tr);
+
inc_nms->inc_file = inc_f;
/* turn #include "foo", bar into bar ::= nms { ... } */
s->kind = STMT_DECL;
@@ -3826,7 +3825,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
err_print(s->where, "Redeclaration of identifier %s.", istr);
info_print(ident_decl_location(i), "Previous declaration was here.");
free(istr);
- return false;
+ goto inc_fail;
}
}
i->decl = d;
@@ -3838,7 +3837,12 @@ static Status types_stmt(Typer *tr, Statement *s) {
d->val.nms = inc_nms;
d->where = d->expr.where = s->where;
}
- } break;
+ break;
+ inc_fail:
+ tr->nms = prev_nms;
+ typer_block_exit(tr);
+ return false;
+ }
case STMT_MESSAGE: {
Message *m = s->message;
char *text = eval_expr_as_cstr(tr, &m->text, "message");