From a8e52c1e13a6cea5cf4197393002c0da206a99d4 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 24 Jan 2020 22:50:50 -0500 Subject: fixed return declarations --- cgen.c | 2 +- eval.c | 4 ++-- location.c | 9 +++------ main.c | 8 ++------ package.c | 2 +- parse.c | 14 +++++++++++++- test.toc | 41 +---------------------------------------- tests/arr/test.sh | 2 +- tests/foreign/expected | 1 + tests/foreign/foreign.toc | 32 ++++++++++++++++++++++++++++++++ tests/foreign/got | 1 + tests/foreign/test.sh | 3 +++ tests/params/expected | 15 +++++++++++++++ tests/params/got | 15 +++++++++++++++ tests/params/params.toc | 37 +++++++++++++++++++++++++++++++++++++ tests/params/test.sh | 3 +++ tests/test.sh | 31 ++++++++++++++++--------------- types.c | 2 +- 18 files changed, 148 insertions(+), 74 deletions(-) create mode 100644 tests/foreign/expected create mode 100644 tests/foreign/foreign.toc create mode 100644 tests/foreign/got create mode 100755 tests/foreign/test.sh create mode 100644 tests/params/expected create mode 100644 tests/params/got create mode 100644 tests/params/params.toc create mode 100755 tests/params/test.sh diff --git a/cgen.c b/cgen.c index 0de47dd..5d97d11 100644 --- a/cgen.c +++ b/cgen.c @@ -1861,7 +1861,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { cgen_write(g, "; "); } if (has_expr) { - assert(g->block && !(d->flags & DECL_IS_CONST)); + assert((g->block || g->fn) && !(d->flags & DECL_IS_CONST)); if (!cgen_expr_pre(g, &d->expr)) return false; if (d->expr.type.kind == TYPE_TUPLE) { if (!cgen_set_tuple(g, NULL, d->idents, NULL, &d->expr)) return false; diff --git a/eval.c b/eval.c index 1c682ff..6ff8d8a 100644 --- a/eval.c +++ b/eval.c @@ -1505,6 +1505,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, &d->expr, &val)) return false; + if (!add_ident_decls(&fn->body, d, 0)) + return false; arr_foreach(d->idents, Identifier, i) { Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type; IdentDecl *id = ident_decl(*i); @@ -1517,8 +1519,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } ++idx; } - if (!add_ident_decls(&fn->body, d, 0)) - return false; } if (!eval_block(ev, &fn->body, &e->type, v)) { fn_exit(fn); diff --git a/location.c b/location.c index 21e686e..e515af7 100644 --- a/location.c +++ b/location.c @@ -6,6 +6,7 @@ static Location const LOCATION_NONE = {0}; +static void err_print_location_text(Location where); /* for debugging */ static void fprint_location(FILE *out, Location location) { if (!location.start) { @@ -16,12 +17,8 @@ static void fprint_location(FILE *out, Location location) { } return; } - /* TODO: show end */ - char *str = location.start->pos.ctx->str + location.start->pos.start; - char *newline = strchr(str, '\n'); - if (newline) *newline = 0; - fprintf(out, "Line %ld: %s\n", (long)location.start->pos.line, str); - if (newline) *newline = '\n'; + fprintf(out, "Line %ld: ", (long)location.start->pos.line); + err_print_location_text(location); } static void print_location(Location location) { diff --git a/main.c b/main.c index 0bc34e1..203ce1b 100644 --- a/main.c +++ b/main.c @@ -18,13 +18,9 @@ /* TODO: -#builtin values - accessed via, e.g. #builtin("sizeof(int)") -- sizeof(int) (size of C int type), sizeof(long), sizeof(size_t) etc. -- compiling - true if @ compile time, false otherwise -- stdout, stderr, stdin - pointers to C FILEs -fully re-test default args & return decls - clean up copy_expr +clean up location printing- general thing for printing location line to a file used by err and print_location + each=>for #C_int, #C_long, etc. diff --git a/package.c b/package.c index 32b3c8e..5808ab2 100644 --- a/package.c +++ b/package.c @@ -672,7 +672,7 @@ static bool export_expr(Exporter *ex, Expression *e) { case EXPR_BUILTIN: if (found_type) { possibly_static_assert(BUILTIN_VAL_COUNT <= 256); - export_u8(ex, e->builtin.which.val); + export_u8(ex, (U8)e->builtin.which.val); } else { if (!export_expr(ex, e->builtin.which.expr)) return false; diff --git a/parse.c b/parse.c index 4fe7008..547ee97 100644 --- a/parse.c +++ b/parse.c @@ -942,7 +942,19 @@ static int op_precedence(Keyword op) { } static bool parse_expr(Parser *p, Expression *e, Token *end) { + Tokenizer *t = p->tokr; + +#if 0 + { + Location where; + where.start = t->token; + where.end = end; + printf("PARSING "); + fprint_location(stdout, where); + } +#endif + e->flags = 0; e->type.flags = 0; if (end == NULL) return false; @@ -1899,7 +1911,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla if (ends_with == DECL_END_RPAREN_COMMA) expr_flags |= EXPR_CAN_END_WITH_COMMA; if (ends_with == DECL_END_LBRACE_COMMA) - expr_flags |= EXPR_CAN_END_WITH_LBRACE; + expr_flags |= EXPR_CAN_END_WITH_LBRACE | EXPR_CAN_END_WITH_COMMA; Token *end = expr_find_end(p, expr_flags); if (!end || !ends_decl(end, ends_with)) { if (end) t->token = end; diff --git a/test.toc b/test.toc index e14881f..e50d6c5 100644 --- a/test.toc +++ b/test.toc @@ -1,41 +1,2 @@ -voidptr ::= &u8; - -getstdout ::= fn() voidptr { - #builtin("stdout") +addmul ::= fn (x:=0, y:=0) add := x+y, mul := x*y { }; - -getstdin ::= fn() voidptr { - #builtin("stdin") -}; - -fwrite :: fn(voidptr, u64, u64, voidptr) u64 = #foreign "fwrite", "libc.so.6"; -fputc :: fn(i32, voidptr) i32 = #foreign "fputc", "libc.so.6"; -fgets :: fn(&char, i32, voidptr) &char = #foreign "fgets", "libc.so.6"; - -writes ::= fn(x : []char) { - fwrite(&x[0] as voidptr, 1, x.len as u64, getstdout()); -}; - -puts ::= fn(x : []char) { - writes(x); - fputc('\n' as i32, getstdout()); -}; - -hw ::= fn() int { - name : [1024]char; - writes("Name? "); - fgets(&name[0], name.len as i32, getstdin()); - - writes("Hello, "); - if #builtin("compiling") { - writes("compiling "); - } - - writes(name[:]); // fgets already has a newline - 2 -}; - -main ::= fn() { - hw(); - x ::= hw(); -}; \ No newline at end of file diff --git a/tests/arr/test.sh b/tests/arr/test.sh index 4977e56..d50fb1a 100755 --- a/tests/arr/test.sh +++ b/tests/arr/test.sh @@ -1,3 +1,3 @@ #!/bin/sh ./arr.bin > got || exit 1 -diff got expected > /dev/null || exit 1 +diff got expected || exit 1 diff --git a/tests/foreign/expected b/tests/foreign/expected new file mode 100644 index 0000000..af5626b --- /dev/null +++ b/tests/foreign/expected @@ -0,0 +1 @@ +Hello, world! diff --git a/tests/foreign/foreign.toc b/tests/foreign/foreign.toc new file mode 100644 index 0000000..beaa822 --- /dev/null +++ b/tests/foreign/foreign.toc @@ -0,0 +1,32 @@ +voidptr ::= &u8; + +getstdout ::= fn() voidptr { + #builtin("stdout") +}; + + +fwrite :: fn(voidptr, u64, u64, voidptr) u64 = #foreign "fwrite", "libc.so.6"; +fputc :: fn(i32, voidptr) i32 = #foreign "fputc", "libc.so.6"; + +writes ::= fn(x : []char) { + fwrite(&x[0] as voidptr, 1, x.len as u64, getstdout()); +}; + +puts ::= fn(x : []char) { + writes(x); + fputc('\n' as i32, getstdout()); +}; + +hw ::= fn() int { + writes("Hello,"); + if #builtin("compiling") { + writes(" compiling"); + } + puts(" world!"); + 3 +}; + +main ::= fn() { + hw(); + x ::= hw(); +}; \ No newline at end of file diff --git a/tests/foreign/got b/tests/foreign/got new file mode 100644 index 0000000..af5626b --- /dev/null +++ b/tests/foreign/got @@ -0,0 +1 @@ +Hello, world! diff --git a/tests/foreign/test.sh b/tests/foreign/test.sh new file mode 100755 index 0000000..1d6eb8f --- /dev/null +++ b/tests/foreign/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh +./foreign.bin > got || exit 1 +diff got expected || exit 1 diff --git a/tests/params/expected b/tests/params/expected new file mode 100644 index 0000000..082b847 --- /dev/null +++ b/tests/params/expected @@ -0,0 +1,15 @@ +0 +0 +10 +21 +5 +0 +17 +0 +0 +0 +10 +21 +39 +-13 +-13 diff --git a/tests/params/got b/tests/params/got new file mode 100644 index 0000000..082b847 --- /dev/null +++ b/tests/params/got @@ -0,0 +1,15 @@ +0 +0 +10 +21 +5 +0 +17 +0 +0 +0 +10 +21 +39 +-13 +-13 diff --git a/tests/params/params.toc b/tests/params/params.toc new file mode 100644 index 0000000..3d8800d --- /dev/null +++ b/tests/params/params.toc @@ -0,0 +1,37 @@ +addmul ::= fn (x:=0, y:=0) add := x+y, mul := x*y { +}; + +do_foo ::= fn (x := 3) y := x { + y *= 12; + y += x; +}; + +puti ::= fn(x: int) { + #C("extern int printf(const char *fmt, ...)"); + #C("printf(\"%ld\\n\", x)"); +}; + + +main ::= fn() { + a, m := addmul(); + puti(a); puti(m); + a, m = addmul(7,3); + puti(a); puti(m); + a, m = addmul(5); + puti(a); puti(m); + a, m = addmul(y = 17); + puti(a); puti(m); + + c, d ::= addmul(); + puti(c); puti(d); + e, f ::= addmul(y = 3, x = 7); + puti(e); puti(f); + + + z := do_foo(); + puti(z); + z = do_foo(-1); + puti(z); + z = do_foo(x = -1); + puti(z); +}; \ No newline at end of file diff --git a/tests/params/test.sh b/tests/params/test.sh new file mode 100755 index 0000000..582bdec --- /dev/null +++ b/tests/params/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh +./params.bin > got || exit 1 +diff got expected || exit 1 diff --git a/tests/test.sh b/tests/test.sh index 0ac4e1a..ceb6cbe 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -2,28 +2,27 @@ DIR=$(dirname $0) TOC=$DIR/../toc CFLAGS="-g -Wno-parentheses-equality" -if [ "$COMPILERS" = "" ]; then - COMPILERS="gcc tcc clang" -fi - echo $$ compile() { - $CC $EXTRA_CFLAGS $CFLAGS -o $DIR/$1/$1.bin $DIR/$1/$1.c || exit 1 + 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" + fi + $CC $CFLAGS $EXTRA_FLAGS -o $DIR/$1/$1.bin $DIR/$1/$1.c || exit 1 } do_tests() { valgrind -q --exit-on-first-error=yes --error-exitcode=1 $TOC "$DIR/$1/$1.toc" -o "$DIR/$1/$1.c" >/dev/null || exit 1 - for CC in $COMPILERS; do - - for EXTRA_CFLAGS in "-O0 -g" "-O3 -s"; do - printf "Running test $1 with C compiler $CC and flags $EXTRA_CFLAGS... " - compile "$1" - cd "$DIR/$1" - ./test.sh || { printf "\x1b[91mfailed!\x1b[0m\n"; exit 1; } - printf '\x1b[92mpassed!\x1b[0m\n' - cd $STARTPWD - done + for CC in "gcc -O0 -g" "tcc" "clang -O3 -s"; do + printf "Running test $1 with C compiler $CC... " + compile "$1" + cd "$DIR/$1" + ./test.sh || { printf "\x1b[91mfailed!\x1b[0m\n"; exit 1; } + printf '\x1b[92mpassed!\x1b[0m\n' + cd $STARTPWD done } @@ -33,3 +32,5 @@ STARTPWD="$(pwd)" do_tests bf do_tests arr do_tests arr2 +do_tests foreign +do_tests params diff --git a/types.c b/types.c index b5cfad9..ee57dc3 100644 --- a/types.c +++ b/types.c @@ -1710,7 +1710,7 @@ static bool types_expr(Typer *tr, Expression *e) { int which = -1; for (BuiltinVal b = 0; b < BUILTIN_VAL_COUNT; b = b + 1) { if (strs_equal(builtin_val_names[b], builtin_name)) { - which = b; + which = (int)b; } } if (which == -1) { -- cgit v1.2.3