summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-05 22:31:07 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-05 22:31:07 -0500
commitdc9cebe15132c5a15b3d0648285e9c86e40c14f6 (patch)
tree0973c264ade9e505850fddc0cb207cdf61b3c849
parentbc96b9a42e3ee59759e6d63cd5f1617bc6a20f1e (diff)
better package file output
-rw-r--r--.gitignore2
-rw-r--r--cgen.c3
-rw-r--r--err.c4
-rw-r--r--main.c16
-rw-r--r--package.c14
-rw-r--r--parse.c3
-rw-r--r--point.toc12
-rw-r--r--test.toc23
-rw-r--r--tokenizer.c2
-rw-r--r--types.c22
10 files changed, 50 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore
index 594ef43..fae512f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
toc
a.out
out.c
-out.top
+*.top
tests/**/*.c
tests/**/*.bin
vgcore*
diff --git a/cgen.c b/cgen.c
index 915d7b5..c8daec9 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
diff --git a/err.c b/err.c
index 0a519c1..a98a822 100644
--- a/err.c
+++ b/err.c
@@ -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
diff --git a/main.c b/main.c
index e7b8567..f848130 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/package.c b/package.c
index 7d42928..4763843 100644
--- a/package.c
+++ b/package.c
@@ -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;
diff --git a/parse.c b/parse.c
index ac87acc..3b85e87 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
diff --git a/types.c b/types.c
index fab4c73..50da073 100644
--- a/types.c
+++ b/types.c
@@ -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;
}