diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-05 22:31:07 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-05 22:31:07 -0500 |
commit | dc9cebe15132c5a15b3d0648285e9c86e40c14f6 (patch) | |
tree | 0973c264ade9e505850fddc0cb207cdf61b3c849 | |
parent | bc96b9a42e3ee59759e6d63cd5f1617bc6a20f1e (diff) |
better package file output
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | cgen.c | 3 | ||||
-rw-r--r-- | err.c | 4 | ||||
-rw-r--r-- | main.c | 16 | ||||
-rw-r--r-- | package.c | 14 | ||||
-rw-r--r-- | parse.c | 3 | ||||
-rw-r--r-- | point.toc | 12 | ||||
-rw-r--r-- | test.toc | 23 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.c | 22 |
10 files changed, 50 insertions, 51 deletions
@@ -1,7 +1,7 @@ toc a.out out.c -out.top +*.top tests/**/*.c tests/**/*.bin vgcore* @@ -1981,7 +1981,8 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { if (!cgen_decls_file(g, f)) return false; cgen_write(g, "/* code */\n"); - cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n"); + if (!f->pkg_name) + cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n"); arr_foreach(f->stmts, Statement, s) { if (!cgen_defs_stmt(g, s)) return false; @@ -126,7 +126,7 @@ static void err_print_footer_(Location where) { static void err_vprint(Location where, const char *fmt, va_list args) { - if (!where.ctx->enabled) return; + if (where.ctx && !where.ctx->enabled) return; err_print_header_(where); err_vfprint(fmt, args); err_print_footer_(where); @@ -139,8 +139,8 @@ static void err_print_( #endif Location where, const char *fmt, ...) { va_list args; - if (where.ctx && !where.ctx->enabled) return; #if ERR_SHOW_SOURCE_LOCATION + if (where.ctx && !where.ctx->enabled) return; if (file) err_fprint("Generated by line %d of %s:\n", line, file); #endif @@ -49,7 +49,6 @@ int main(int argc, char **argv) { in_filename = argv[1]; } const char *out_filename = "out.c"; - for (int i = 2; i < argc-1; ++i) { if (strcmp(argv[i], "-o") == 0) out_filename = argv[i+1]; @@ -122,28 +121,15 @@ int main(int argc, char **argv) { typer_create(&tr, &ev, &main_allocr); tr.exptr = &exptr; -#ifdef TOC_DEBUG - FILE *out_pkg = fopen("out.top", "wb"); - exptr_create(&exptr, out_pkg, contents); - exptr.export_locations = false; -#endif if (!block_enter(NULL, f.stmts, SCOPE_CHECK_REDECL)) /* enter global scope */ return false; - if (!types_file(&tr, &f)) { + if (!types_file(&tr, &f, contents)) { /* TODO(eventually): fix this if the error occured while exporting something */ err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n")); return EXIT_FAILURE; } #ifdef TOC_DEBUG - if (!exptr_finish(&exptr)) { - fclose(out_pkg); - err_fprint(TEXT_IMPORTANT("Errors occured while exporting things.\n")); - return EXIT_FAILURE; - } - fclose(out_pkg); -#endif -#ifdef TOC_DEBUG printf("\n\n"); fprint_parsed_file(stdout, &f); #endif @@ -99,13 +99,15 @@ static inline void export_len(Exporter *ex, size_t len) { /* writes the header */ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len) { - const U8 toc[3] = {116, 111, 99}; /* "toc" in ASCII */ + const U8 toc[3] = {116, 111, 112}; /* "top" in ASCII */ const char *code = ex->code; ex->started = true; export_u8(ex, toc[0]); export_u8(ex, toc[1]); 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_len(ex, pkg_name_len); export_str(ex, pkg_name, pkg_name_len); bool has_code = code != NULL; @@ -555,6 +557,16 @@ static bool export_struct(Exporter *ex, StructDef *s) { /* does NOT close the file */ 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); + fseek(ex->out, 0L, SEEK_END); + + export_len(ex, arr_len(ex->exported_idents)); arr_foreach(ex->exported_idents, Identifier, ident) { Identifier i = *ident; @@ -1818,6 +1818,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla case DECL_END_RPAREN_COMMA: end_str = "')' or ','"; break; case DECL_END_LBRACE_COMMA: end_str = "'{' or ','"; break; } + assert(end_str); if (token_is_kw(t->token, KW_EQ)) { ++t->token; @@ -1842,7 +1843,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla expr_flags |= EXPR_CAN_END_WITH_LBRACE; Token *end = expr_find_end(p, expr_flags); if (!end || !ends_decl(end, ends_with)) { - t->token = end; + if (end) t->token = end; tokr_err(t, "Expected %s at end of declaration.", end_str); goto ret_false; } diff --git a/point.toc b/point.toc new file mode 100644 index 0000000..e37f37a --- /dev/null +++ b/point.toc @@ -0,0 +1,12 @@ +pkg "point"; + +#export Point ::= struct { + x, y: int; +}; + +#export mk_point ::= fn(x, y: int) Point { + p : Point; + p.x = x; + p.y = y; + p +}; diff --git a/test.toc b/test.toc deleted file mode 100644 index 5a69154..0000000 --- a/test.toc +++ /dev/null @@ -1,23 +0,0 @@ -pkg "foo"; - -Foo ::= struct { - x: int; -}; - -foo ::= fn() int { - 3 -}; -#export main ::= fn() { - g ::= fn() int { 3 }; - a := new (int, 3); - b := a[1:3]; - b[0] = 7; - f: Foo; - each i, j := b { - f.x += i + j; - } - each k := 10..100 { - f.x += k; - } - del(a); -};
\ No newline at end of file diff --git a/tokenizer.c b/tokenizer.c index 4c1d31a..901c2ee 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -171,8 +171,8 @@ static void tokr_err_( const char *src_file, int src_line, #endif Tokenizer *t, const char *fmt, ...) { - if (!t->token->where.ctx->enabled) return; #if ERR_SHOW_SOURCE_LOCATION + if (t->token->where.ctx && !t->token->where.ctx->enabled) return; err_fprint("At line %d of %s:\n", src_line, src_file); #endif va_list args; @@ -2045,12 +2045,7 @@ static bool types_decl(Typer *tr, Declaration *d) { err_print(d->where, "Declaration marked for exporting, but no package output was specified."); success = false; } else { -#ifdef TOC_DEBUG /* TODO: remove this */ success = export_decl(tr->exptr, d); -#else - err_print(d->where, "This feature is in progress."); - success = false; -#endif } } } else { @@ -2125,8 +2120,9 @@ static void typer_create(Typer *tr, Evaluator *ev, Allocator *allocr) { *(Block **)arr_adda(&tr->blocks, allocr) = NULL; } -static bool types_file(Typer *tr, ParsedFile *f) { +static bool types_file(Typer *tr, ParsedFile *f, char *code) { bool ret = true; + FILE *pkg_fp = NULL; if (f->pkg_name) { Value pkg_name; if (!types_expr(tr, f->pkg_name)) @@ -2146,6 +2142,16 @@ static bool types_file(Typer *tr, ParsedFile *f) { err_print(f->pkg_name->where, "Package name has a negative length (" I64_FMT ")!", pkg_name_len); return false; } + char *pkg_file_name = err_malloc((size_t)pkg_name_len+5); + sprintf(pkg_file_name, "%s.top", pkg_name_str); + pkg_fp = fopen(pkg_file_name, "wb"); + if (!pkg_fp) { + err_print(f->pkg_name->where, "Could not open package output file: %s.", pkg_file_name); + free(pkg_file_name); + return false; + } + free(pkg_file_name); + exptr_create(tr->exptr, pkg_fp, code); exptr_start(tr->exptr, pkg_name_str, (size_t)pkg_name_len); } arr_foreach(f->stmts, Statement, s) { @@ -2153,6 +2159,10 @@ static bool types_file(Typer *tr, ParsedFile *f) { ret = false; } } + if (pkg_fp) { + exptr_finish(tr->exptr); + fclose(pkg_fp); + } return ret; } |