From def83bb2ae78f12c5c9588bd6cdc639b8aaaf27e Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 6 Jan 2020 11:31:25 -0500 Subject: cleaning up; fixed a few bugs --- cgen.c | 25 ++++++++++++++----------- decls_cgen.c | 28 +++++++++++++++++++++++++--- package.c | 8 ++------ parse.c | 5 ++++- point.toc | 4 +--- test.toc | 11 +++++++++++ tests/test.sh | 2 +- 7 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 test.toc diff --git a/cgen.c b/cgen.c index c8daec9..82857b0 100644 --- a/cgen.c +++ b/cgen.c @@ -1566,6 +1566,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu if (!cgen_decl(g, d)) return false; } + if (!cgen_block_enter(g, &f->body)) return false; if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOENTER | CGEN_BLOCK_NOBRACES)) return false; @@ -1728,13 +1729,14 @@ static bool cgen_val(CGenerator *g, Value v, Type *t, Location where) { static bool cgen_decl(CGenerator *g, Declaration *d) { int has_expr = d->flags & DECL_HAS_EXPR; - bool is_tuple = d->type.kind == TYPE_TUPLE; - if ((d->flags & DECL_IS_CONST) || (g->block == NULL && g->fn == NULL)) { + if (cgen_fn_is_direct(g, d)) + return true; /* dealt with in cgen_defs_ */ + if (d->flags & DECL_FOUND_VAL) { /* declarations where we use a value */ - for (size_t idx = 0; idx < arr_len(d->idents); ++idx) { + for (int idx = 0, nidents = (int)arr_len(d->idents); idx < nidents; ++idx) { Identifier i = d->idents[idx]; - Type *type = is_tuple ? &d->type.tuple[idx] : &d->type; - Value *val = is_tuple ? &d->val.tuple[idx] : &d->val; + Type *type = decl_type_at_index(d, idx); + Value *val = decl_val_at_index(d, idx); if (type->kind == TYPE_TYPE) { /* confusingly, @@ -1743,10 +1745,9 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { we don't need to do anything here. */ continue; - } else if (type->kind == TYPE_FN && (d->flags & DECL_IS_CONST)) { - /* don't generate function pointer declaration for constant fns */ - continue; } + if (g->block == NULL && g->fn == NULL && !i->export_name) + cgen_write(g, "static "); if (has_expr) { if (!cgen_val_pre(g, *val, type, d->where)) return false; @@ -1768,10 +1769,12 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { } } else { /* declarations where we use an expression */ - size_t nidents = arr_len(d->idents); - for (size_t idx = 0; idx < nidents; ++idx) { + assert(g->block && !(d->flags & DECL_IS_CONST)); + int nidents = (int)arr_len(d->idents); + for (int idx = 0; idx < nidents; ++idx) { Identifier i = d->idents[idx]; - Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type; + Type *type = decl_type_at_index(d, idx); + if (g->block == NULL && g->fn == NULL && !i->export_name) cgen_write(g, "static "); if (!cgen_type_pre(g, type, d->where)) return false; cgen_write(g, " "); cgen_ident(g, i); diff --git a/decls_cgen.c b/decls_cgen.c index 0809262..61840a6 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -118,9 +118,31 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) { } } cgen_recurse_subexprs(g, (&d->expr), cgen_decls_expr, cgen_decls_block, cgen_decls_decl); - } else if (d->flags & DECL_HAS_EXPR) { - if (!cgen_decls_expr(g, &d->expr)) - return false; + } else { + if (d->flags & DECL_HAS_EXPR) { + if (!cgen_decls_expr(g, &d->expr)) + return false; + } + if (g->block == NULL && g->fn == NULL) { + for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) { + Identifier ident = d->idents[i]; + Type *type = decl_type_at_index(d, i); + if (type->kind != TYPE_TYPE) { + if (ident->export_name) + cgen_write(g, "extern "); + else + cgen_write(g, "static "); + if (!cgen_type_pre(g, type, d->where)) + return false; + cgen_write(g, " "); + cgen_ident(g, ident); + if (!cgen_type_post(g, type, d->where)) + return false; + cgen_write(g, ";"); + cgen_nl(g); + } + } + } } return true; } diff --git a/package.c b/package.c index 4763843..bef9a76 100644 --- a/package.c +++ b/package.c @@ -107,7 +107,7 @@ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len) export_u8(ex, toc[2]); export_u32(ex, TOP_FMT_VERSION); assert(ftell(ex->out) == 7L); - export_u32(ex, 0); /* placeholder for identifier offset in file */ + export_u64(ex, 0); /* placeholder for identifier offset in file */ export_len(ex, pkg_name_len); export_str(ex, pkg_name, pkg_name_len); bool has_code = code != NULL; @@ -559,11 +559,7 @@ static bool export_struct(Exporter *ex, StructDef *s) { static bool exptr_finish(Exporter *ex) { long ident_offset = ftell(ex->out); fseek(ex->out, 7L, SEEK_SET); - if (ident_offset > U32_MAX) { - err_print(LOCATION_NONE, "Package file is too large."); - return false; - } - export_u32(ex, (U32)ident_offset); + export_u64(ex, (U64)ident_offset); fseek(ex->out, 0L, SEEK_END); diff --git a/parse.c b/parse.c index 3b85e87..b410e66 100644 --- a/parse.c +++ b/parse.c @@ -1952,6 +1952,7 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } if (p->file->pkg_name) { tokr_err(t, "You've already set the package name."); + info_print(p->file->pkg_name->where, "The package name was previously set here."); t->token = end + 1; return false; } @@ -2320,7 +2321,9 @@ static inline Value *decl_val_at_index(Declaration *d, int i) { } static inline Type *decl_type_at_index(Declaration *d, int i) { - return d->type.kind == TYPE_TUPLE ? &d->type.tuple[i] : &d->type; + Type *ret = d->type.kind == TYPE_TUPLE ? &d->type.tuple[i] : &d->type; + assert(ret->kind != TYPE_TUPLE); + return ret; } diff --git a/point.toc b/point.toc index e37f37a..ede3c7c 100644 --- a/point.toc +++ b/point.toc @@ -4,9 +4,7 @@ pkg "point"; x, y: int; }; -#export mk_point ::= fn(x, y: int) Point { - p : Point; +#export mk_point ::= fn(x, y: int) p : Point { p.x = x; p.y = y; - p }; diff --git a/test.toc b/test.toc new file mode 100644 index 0000000..f6bac2f --- /dev/null +++ b/test.toc @@ -0,0 +1,11 @@ +f ::= g(); + +x ::= 3; + +g ::= fn() int { x }; + +main ::= fn() { + #C("printf(\"%ld\\n\", (long)x)"); + a := g(); + #C("printf(\"%ld\\n\", (long)a)"); +}; \ No newline at end of file diff --git a/tests/test.sh b/tests/test.sh index d0fc3cb..0ac4e1a 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -13,7 +13,7 @@ compile() { } 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 + 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 -- cgit v1.2.3