summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--err.c142
-rw-r--r--location.c79
-rw-r--r--main.c10
-rw-r--r--package.c22
-rw-r--r--parse.c27
-rw-r--r--test.toc8
-rw-r--r--tokenizer.c35
-rw-r--r--types.c9
-rw-r--r--types.h20
9 files changed, 187 insertions, 165 deletions
diff --git a/err.c b/err.c
index 1307a15..a6ad230 100644
--- a/err.c
+++ b/err.c
@@ -16,8 +16,6 @@
#define TEXT_ERR_START "\x1b[91m"
#define TEXT_ERR_END "\x1b[0m"
-#define TEXT_INDICATOR_START "\x1b[96m"
-#define TEXT_INDICATOR_END "\x1b[0m"
#define TEXT_INFO_START "\x1b[94m"
#define TEXT_INFO_END "\x1b[0m"
#define TEXT_WARN_START "\x1b[93m"
@@ -38,142 +36,90 @@ static inline const char *ordinals(size_t x) {
}
}
-/* Write directly to the error file */
-static void err_fwrite(const void *data, size_t size, size_t n) {
- fwrite(data, size, n, stderr);
+static FILE *err_ctx_file(ErrCtx *ctx) {
+ (void)ctx;
+ return stderr;
}
-static void err_fprint(const char *fmt, ...) {
+static void err_fprint(ErrCtx *ctx, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
- vfprintf(stderr, fmt, args);
+ vfprintf(err_ctx_file(ctx), fmt, args);
va_end(args);
}
static void err_text_err(ErrCtx *ctx, const char *s) {
if (ctx->color_enabled)
- err_fprint(TEXT_ERR_START "%s" TEXT_ERR_END, s);
+ err_fprint(ctx, TEXT_ERR_START "%s" TEXT_ERR_END, s);
else
- err_fprint("%s", s);
+ err_fprint(ctx, "%s", s);
}
static void err_text_warn(ErrCtx *ctx, const char *s) {
if (ctx->color_enabled)
- err_fprint(TEXT_WARN_START "%s" TEXT_WARN_END, s);
+ err_fprint(ctx, TEXT_WARN_START "%s" TEXT_WARN_END, s);
else
- err_fprint("%s", s);
+ err_fprint(ctx, "%s", s);
}
static void err_text_info(ErrCtx *ctx, const char *s) {
if (ctx->color_enabled)
- err_fprint(TEXT_INFO_START "%s" TEXT_INFO_END, s);
+ err_fprint(ctx, TEXT_INFO_START "%s" TEXT_INFO_END, s);
else
- err_fprint("%s", s);
+ err_fprint(ctx, "%s", s);
}
static void err_text_important(ErrCtx *ctx, const char *s) {
if (ctx->color_enabled)
- err_fprint(TEXT_IMPORTANT_START "%s" TEXT_IMPORTANT_END, s);
+ err_fprint(ctx, TEXT_IMPORTANT_START "%s" TEXT_IMPORTANT_END, s);
else
- err_fprint("%s", s);
+ err_fprint(ctx, "%s", s);
}
-static void err_vfprint(const char *fmt, va_list args) {
- vfprintf(stderr, fmt, args);
+static void err_vfprint(ErrCtx *ctx, const char *fmt, va_list args) {
+ vfprintf(err_ctx_file(ctx), fmt, args);
}
static void err_print_line_file(Location where) {
+ ErrCtx *ctx = where.file->ctx;
if (where.start) {
- err_fprint(" at line %lu of %s:\n", (unsigned long)where.start->pos.line, where.start->pos.ctx->filename);
- } else if (where.simple_location) {
- err_fprint(" at line %lu of %s:\n", (unsigned long)where.simple_location->line, where.simple_location->ctx->filename);
+ err_fprint(ctx, " at line %lu of %s:\n", (unsigned long)where.start->pos.line, where.file->filename);
} else {
- err_fprint(":\n");
-
+ U32 line = where.simple_location.line;
+ if (line)
+ err_fprint(ctx, " at line %lu of %s:\n", (unsigned long)line, where.file->filename);
+ else
+ err_fprint(ctx, ":\n");
}
}
static void err_print_header_(Location where) {
- SourcePos start_pos = where.start->pos;
- ErrCtx *ctx = start_pos.ctx;
+ ErrCtx *ctx = where.file->ctx;
err_text_err(ctx, "error");
err_print_line_file(where);
}
static void info_print_header_(Location where) {
- SourcePos start_pos = where.start->pos;
- ErrCtx *ctx = start_pos.ctx;
+ ErrCtx *ctx = where.file->ctx;
err_text_info(ctx, "info");
err_print_line_file(where);
}
static void warn_print_header_(Location where) {
- SourcePos start_pos = where.start->pos;
- ErrCtx *ctx = start_pos.ctx;
+ ErrCtx *ctx = where.file->ctx;
err_text_warn(ctx, "warning");
err_print_line_file(where);
}
-static void err_print_pos_text(ErrCtx *ctx, U32 start_pos, U32 end_pos) {
- char *str = ctx->str;
- if (!str) {
- return;
- }
-
- char *start = str + start_pos;
- char *line_start = start;
- char *end = str + end_pos;
-
- /* go back to last newline / 0 byte */
- while (*line_start != '\0' && *line_start != '\n') --line_start;
- if (line_start < start) ++line_start;
-
- char *line_end = strchr(start, '\n');
- int has_newline = line_end != NULL;
- if (!has_newline)
- line_end = strchr(start, '\0');
- assert(line_end);
- err_fprint("\t");
- if (!line_start[0])
- err_fprint("<end of file>");
- else {
- /* write up to start of error */
- err_fwrite(line_start, 1, (size_t)(start - line_start));
- if (ctx->color_enabled)
- err_fprint(TEXT_INDICATOR_START);
- if (line_end < end) {
- /* write error part (only go to end of line) */
- err_fwrite(start, 1, (size_t)(line_end - start));
- if (ctx->color_enabled)
- err_fprint(TEXT_INDICATOR_END);
- } else {
- /* write error part */
- err_fwrite(start, 1, (size_t)(end - start));
- if (ctx->color_enabled)
- err_fprint(TEXT_INDICATOR_END);
- /* write rest of line */
- err_fwrite(end, 1, (size_t)(line_end - end));
- }
- }
- err_fprint("\n");
-}
-
-static void err_print_location_text(Location where) {
- if (where.start) {
- ErrCtx *ctx = where.start->pos.ctx;
- err_print_pos_text(ctx, where.start->pos.start, where.end[-1].pos.end);
- }
-
-}
static void err_print_footer_(Location where) {
- ErrCtx *ctx = where.start->pos.ctx;
- err_fprint("\n");
- err_print_location_text(where);
+ ErrCtx *ctx = where.file->ctx;
+ err_fprint(ctx, "\n");
+ print_location_highlight(err_ctx_file(ctx), where);
if (ctx) {
arr_foreach(ctx->instance_stack, Location, inst) {
- err_fprint("While generating the instance of a function\n");
- err_print_location_text(*inst);
+ err_fprint(ctx, "While generating the instance of a function\n");
+ print_location_highlight(err_ctx_file(ctx), *inst);
}
}
}
@@ -181,14 +127,11 @@ static void err_print_footer_(Location where) {
/* Write nicely-formatted errors to the error file */
static void err_vprint(Location where, const char *fmt, va_list args) {
- if (location_is_ctx_disabled(where)) return;
- if (where.start) {
- where.start->pos.ctx->have_errored = true;
- } else if (where.simple_location) {
- where.simple_location->ctx->have_errored = true;
- }
+ ErrCtx *ctx = where.file->ctx;
+ if (!ctx->enabled) return;
+ ctx->have_errored = true;
err_print_header_(where);
- err_vfprint(fmt, args);
+ err_vfprint(ctx, fmt, args);
err_print_footer_(where);
}
@@ -200,9 +143,10 @@ static void err_print_(
Location where, const char *fmt, ...) {
va_list args;
#if ERR_SHOW_SOURCE_LOCATION
- if (location_is_ctx_disabled(where)) return;
+ ErrCtx *ctx = where.file->ctx;
+ if (!ctx->enabled) return;
if (file)
- err_fprint("Generated by line %d of %s:\n", line, file);
+ err_fprint(ctx, "Generated by line %d of %s:\n", line, file);
#endif
va_start(args, fmt);
err_vprint(where, fmt, args);
@@ -217,10 +161,11 @@ static void err_print_(
static void info_print(Location where, const char *fmt, ...) {
va_list args;
- if (location_is_ctx_disabled(where)) return;
+ ErrCtx *ctx = where.file->ctx;
+ if (!ctx->enabled) return;
va_start(args, fmt);
info_print_header_(where);
- err_vfprint(fmt, args);
+ err_vfprint(ctx, fmt, args);
err_print_footer_(where);
va_end(args);
}
@@ -231,14 +176,15 @@ static void warn_print_(
#endif
Location where, const char *fmt, ...) {
va_list args;
- if (location_is_ctx_disabled(where)) return;
+ ErrCtx *ctx = where.file->ctx;
+ if (!ctx->enabled) return;
#if ERR_SHOW_SOURCE_LOCATION
if (file)
- err_fprint("Generated by line %d of %s:\n", line, file);
+ err_fprint(ctx, "Generated by line %d of %s:\n", line, file);
#endif
va_start(args, fmt);
warn_print_header_(where);
- err_vfprint(fmt, args);
+ err_vfprint(ctx, fmt, args);
err_print_footer_(where);
va_end(args);
}
diff --git a/location.c b/location.c
index e515af7..36e95bb 100644
--- a/location.c
+++ b/location.c
@@ -4,29 +4,76 @@
You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>.
*/
-static Location const LOCATION_NONE = {0};
+#define TEXT_INDICATOR_START "\x1b[96m"
+#define TEXT_INDICATOR_END "\x1b[0m"
-static void err_print_location_text(Location where);
-/* for debugging */
-static void fprint_location(FILE *out, Location location) {
- if (!location.start) {
- if (location.simple_location) {
- fprintf(out, "Line %lu of %s", (unsigned long)location.simple_location->line, location.simple_location->ctx->filename);
+static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_pos, U32 end_pos) {
+ char *str = file->contents;
+ if (!str) {
+ return;
+ }
+
+ char *start = str + start_pos;
+ char *line_start = start;
+ char *end = str + end_pos;
+
+ /* go back to last newline / 0 byte */
+ while (*line_start != '\0' && *line_start != '\n') --line_start;
+ if (line_start < start) ++line_start;
+
+ char *line_end = strchr(start, '\n');
+ int has_newline = line_end != NULL;
+ if (!has_newline)
+ line_end = strchr(start, '\0');
+ assert(line_end);
+ fprintf(out, "\t");
+ if (!line_start[0])
+ fprintf(out, "<end of file>");
+ else {
+ /* write up to start of error */
+ fwrite(line_start, 1, (size_t)(start - line_start), out);
+ if (ctx->color_enabled)
+ fprintf(out, TEXT_INDICATOR_START);
+ if (line_end < end) {
+ /* write error part (only go to end of line) */
+ fwrite(start, 1, (size_t)(line_end - start), out);
+ if (ctx->color_enabled)
+ fprintf(out, TEXT_INDICATOR_END);
} else {
- fprintf(out, "No location available.");
+ /* write error part */
+ fwrite(start, 1, (size_t)(end - start), out);
+ if (ctx->color_enabled)
+ fprintf(out, TEXT_INDICATOR_END);
+ /* write rest of line */
+ fwrite(end, 1, (size_t)(line_end - end), out);
}
- return;
}
- fprintf(out, "Line %ld: ", (long)location.start->pos.line);
- err_print_location_text(location);
+ fprintf(out, "\n");
}
-static void print_location(Location location) {
- fprint_location(stdout, location);
+static void print_location_highlight(FILE *out, Location where) {
+ if (where.start) {
+ ErrCtx *ctx = where.file->ctx;
+ print_pos_highlight(out, ctx, where.file, where.start->pos.start, where.end[-1].pos.end);
+ }
+
}
+/* for debugging */
+static void fprint_location(FILE *out, Location location) {
+ if (location.start) {
+ fprintf(out, "Line %ld of %s: ", (long)location.start->pos.line, location.file->filename);
+ } else {
+ U32 line = location.simple_location.line;
+ if (line)
+ fprintf(out, "Line %lu of %s: ", (unsigned long)line, location.file->filename);
+ else
+ fprintf(out, "In file %s: ", location.file->filename);
+ return;
+ }
+ print_location_highlight(out, location);
+}
-static bool location_is_ctx_disabled(Location location) {
- if (!location.start) return true;
- return !location.start->pos.ctx->enabled;
+static void print_location(Location location) {
+ fprint_location(stdout, location);
}
diff --git a/main.c b/main.c
index 5f8180e..0d6bf11 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,6 @@
/*
TODO:
-clean up location printing- general thing for printing location line to a file used by err and print_location
passing structs to foreign functions
each=>for
@@ -96,11 +95,14 @@ int main(int argc, char **argv) {
Allocator main_allocr;
allocr_create(&main_allocr);
ErrCtx err_ctx = {0};
- err_ctx.filename = in_filename;
err_ctx.enabled = true;
err_ctx.color_enabled = true;
+ File file = {0};
+ file.filename = in_filename;
+ file.contents = contents;
+ file.ctx = &err_ctx;
tokr_create(&t, &idents, &err_ctx, &main_allocr);
- if (!tokenize_string(&t, contents)) {
+ if (!tokenize_file(&t, &file)) {
err_text_important(&err_ctx, "Errors occured during preprocessing.\n");
return EXIT_FAILURE;
}
@@ -147,7 +149,7 @@ int main(int argc, char **argv) {
FILE *out = fopen(out_filename, "w");
if (!out) {
err_text_important(&err_ctx, "Could not open output file: ");
- err_fprint("%s\n", out_filename);
+ err_fprint(&err_ctx, "%s\n", out_filename);
return EXIT_FAILURE;
}
CGenerator g;
diff --git a/package.c b/package.c
index 5808ab2..bc1f5b3 100644
--- a/package.c
+++ b/package.c
@@ -16,9 +16,11 @@ static void import_block(Importer *im, Block *b);
static inline Expression *import_expr_(Importer *im);
-static void exptr_create(Exporter *ex, FILE *out) {
+static void exptr_create(Exporter *ex, FILE *out, const char *filename, ErrCtx *err_ctx) {
/* construct full filename */
ex->out = out;
+ ex->exporting_to.ctx = err_ctx;
+ ex->exporting_to.filename = filename;
ex->ident_id = 0;
ex->exported_fns = NULL;
ex->exported_structs = NULL;
@@ -167,10 +169,9 @@ static void export_location(Exporter *ex, Location where) {
}
static Location import_location(Importer *im) {
Location l;
+ l.file = &im->importing_from;
l.start = NULL;
- l.simple_location = imptr_malloc(im, sizeof *l.simple_location);
- l.simple_location->ctx = im->err_ctx;
- l.simple_location->line = (U32)import_vlq(im);
+ l.simple_location.line = (U32)import_vlq(im);
return l;
}
@@ -219,16 +220,13 @@ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len)
/* where = where was this imported. don't free fname while imported stuff is in use. */
static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname, ErrCtx *parent_ctx, Location where) {
Importer i = {0};
- ErrCtx *err_ctx = i.err_ctx = allocr_malloc(allocr, sizeof *i.err_ctx);
+ i.importing_from.filename = fname;
+ i.importing_from.ctx = parent_ctx;
idents_create(&p->idents);
i.pkg = p;
i.in = f;
i.import_location = where;
i.allocr = allocr;
- *err_ctx = *parent_ctx;
- err_ctx->filename = fname;
- err_ctx->instance_stack = NULL;
- err_ctx->str = NULL;
/* read header */
U8 toc[3];
toc[0] = import_u8(&i);
@@ -257,7 +255,7 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname
if (has_code) {
size_t code_len = import_len(&i);
char *code = import_str(&i, code_len);
- err_ctx->str = code;
+ i.importing_from.contents = code;
}
long decls_offset = ftell(f);
fseek(f, (long)footer_offset, SEEK_SET);
@@ -1229,7 +1227,9 @@ static bool exptr_finish(Exporter *ex) {
export_u64(ex, (U64)struct_info_offset);
if (ferror(ex->out)) {
- warn_print(LOCATION_NONE, "An error occured while writing the package output. It may be incorrect.");
+ Location none = {0};
+ none.file = &ex->exporting_to;
+ warn_print(none, "An error occured while writing the package output. It may be incorrect.");
}
return true;
diff --git a/parse.c b/parse.c
index 547ee97..bc2dba9 100644
--- a/parse.c
+++ b/parse.c
@@ -279,6 +279,12 @@ static char *type_to_str(Type *t) {
return ret;
}
+static inline Location parser_mk_loc(Parser *p) {
+ Location loc = {0};
+ loc.file = p->file;
+ return loc;
+}
+
static inline void *parser_arr_add_(Parser *p, void **a, size_t sz) {
return arr_adda_(a, sz, p->allocr);
}
@@ -412,6 +418,7 @@ static bool parse_args(Parser *p, Argument **args) {
return false;
}
Argument *arg = parser_arr_add(p, args);
+ arg->where = parser_mk_loc(p);
arg->where.start = t->token;
/* named arguments */
if (t->token->kind == TOKEN_IDENT && token_is_kw(t->token + 1, KW_EQ)) {
@@ -437,6 +444,7 @@ static bool parse_args(Parser *p, Argument **args) {
static bool parse_type(Parser *p, Type *type) {
Tokenizer *t = p->tokr;
+ type->where = parser_mk_loc(p);
type->where.start = t->token;
type->flags = 0;
switch (t->token->kind) {
@@ -571,6 +579,7 @@ static bool parse_type(Parser *p, Type *type) {
struc->c.id = 0;
struc->fields = NULL;
struc->export.id = 0;
+ struc->where = parser_mk_loc(p);
struc->where.start = t->token;
++t->token;
@@ -779,6 +788,7 @@ static bool parse_block(Parser *p, Block *b) {
return false;
}
p->block = b;
+ b->where = parser_mk_loc(p);
b->where.start = t->token;
++t->token; /* move past { */
b->stmts = NULL;
@@ -942,12 +952,12 @@ static int op_precedence(Keyword op) {
}
static bool parse_expr(Parser *p, Expression *e, Token *end) {
-
Tokenizer *t = p->tokr;
-#if 0
+#if 1
{
Location where;
+ where.file = p->file;
where.start = t->token;
where.end = end;
printf("PARSING ");
@@ -958,6 +968,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
e->flags = 0;
e->type.flags = 0;
if (end == NULL) return false;
+ e->where = parser_mk_loc(p);
e->where.start = t->token;
if (end <= t->token) {
tokr_err(t, "Empty expression.");
@@ -1079,6 +1090,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
Expression *next = parser_new_expr(p);
next->flags = 0;
next->kind = EXPR_IF;
+ next->where = parser_mk_loc(p);
next->where.start = t->token;
curr->next_elif = next;
IfExpr *nexti = &next->if_;
@@ -1788,6 +1800,7 @@ static inline bool ends_decl(Token *t, DeclEndKind ends_with) {
static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 flags) {
Tokenizer *t = p->tokr;
+ d->where = parser_mk_loc(p);
d->where.start = t->token;
d->idents = NULL;
d->flags = 0;
@@ -1985,6 +1998,7 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
tokr_err(t, "Expected statement.");
return false;
}
+ s->where = parser_mk_loc(p);
s->where.start = t->token;
s->flags = 0;
*was_a_statement = true;
@@ -2029,13 +2043,13 @@ static bool parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
t->token = end + 1;
return false;
}
- if (p->file->pkg_name) {
+ if (p->parsed_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.");
+ info_print(p->parsed_file->pkg_name->where, "The package name was previously set here.");
t->token = end + 1;
return false;
}
- p->file->pkg_name = pkg_name;
+ p->parsed_file->pkg_name = pkg_name;
bool success = parse_expr(p, pkg_name, end);
t->token = end + 1;
*was_a_statement = false;
@@ -2083,7 +2097,8 @@ static bool parse_file(Parser *p, ParsedFile *f) {
Tokenizer *t = p->tokr;
f->stmts = NULL;
f->pkg_name = NULL;
- p->file = f;
+ p->file = t->file;
+ p->parsed_file = f;
bool ret = true;
while (t->token->kind != TOKEN_EOF) {
bool was_a_statement;
diff --git a/test.toc b/test.toc
index e50d6c5..de514ce 100644
--- a/test.toc
+++ b/test.toc
@@ -1,2 +1,8 @@
-addmul ::= fn (x:=0, y:=0) add := x+y, mul := x*y {
+addmul ::= fn (x::=0, y:=0)
+add := x+y, mul := x*y {
+
};
+
+main ::= fn() {
+ addmul(6,7);
+}; \ No newline at end of file
diff --git a/tokenizer.c b/tokenizer.c
index 103c534..9466ad8 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -190,18 +190,19 @@ static void tokenization_err_(
#endif
Tokenizer *t, const char *fmt, ...) {
va_list args;
- if (!t->err_ctx->enabled) return;
+ ErrCtx *ctx = t->err_ctx;
+ if (!ctx->enabled) return;
#if ERR_SHOW_SOURCE_LOCATION
- err_fprint("Generated by line %d of %s:\n", src_line, src_file);
+ err_fprint(ctx, "Generated by line %d of %s:\n", src_line, src_file);
#endif
va_start(args, fmt);
- err_text_err(t->err_ctx, "error");
- err_fprint(" at line %lu of %s:\n", (unsigned long)t->line, t->err_ctx->filename);
- err_vfprint(fmt, args);
+ err_text_err(ctx, "error");
+ err_fprint(ctx, " at line %lu of %s:\n", (unsigned long)t->line, t->file->filename);
+ err_vfprint(ctx, fmt, args);
va_end(args);
- err_fprint("\n");
- U32 pos = (U32)(t->s - t->err_ctx->str);
- err_print_pos_text(t->err_ctx, pos, pos + 1);
+ err_fprint(ctx, "\n");
+ U32 pos = (U32)(t->s - t->file->contents);
+ print_pos_highlight(err_ctx_file(ctx), ctx, t->file, pos, pos + 1);
while (*t->s) {
if (*t->s == '\n') {
tokr_nextchar(t);
@@ -223,9 +224,10 @@ static void tokr_err_(
const char *src_file, int src_line,
#endif
Tokenizer *t, const char *fmt, ...) {
- if (!t->err_ctx->enabled) return;
+ ErrCtx *ctx = t->err_ctx;
+ if (!ctx->enabled) return;
#if ERR_SHOW_SOURCE_LOCATION
- err_fprint("Generated by line %d of %s:\n", src_line, src_file);
+ err_fprint(ctx, "Generated by line %d of %s:\n", src_line, src_file);
#endif
va_list args;
va_start(args, fmt);
@@ -242,17 +244,16 @@ static void tokr_err_(
static void tokr_put_start_pos(Tokenizer *tokr, Token *t) {
t->pos.line = tokr->line;
- t->pos.ctx = tokr->err_ctx;
- t->pos.start = (U32)(tokr->s - t->pos.ctx->str);
+ t->pos.start = (U32)(tokr->s - tokr->file->contents);
}
static void tokr_put_end_pos(Tokenizer *tokr, Token *t) {
- t->pos.end = (U32)(tokr->s - t->pos.ctx->str);
+ t->pos.end = (U32)(tokr->s - tokr->file->contents);
}
static void tokr_get_start_pos(Tokenizer *tokr, Token *t) {
tokr->line = t->pos.line;
- tokr->s = t->pos.start + t->pos.ctx->str;
+ tokr->s = tokr->file->contents + t->pos.start;
}
/*
@@ -277,10 +278,10 @@ static Token *tokr_add(Tokenizer *t) {
return token;
}
-static bool tokenize_string(Tokenizer *t, char *str) {
+static bool tokenize_file(Tokenizer *t, File *file) {
int has_err = 0;
- t->s = str;
- t->err_ctx->str = str;
+ t->s = file->contents;
+ t->file = file;
t->line = 1;
while (1) {
if (*t->s == 0) break;
diff --git a/types.c b/types.c
index ee57dc3..7a18c72 100644
--- a/types.c
+++ b/types.c
@@ -1666,7 +1666,7 @@ static bool types_expr(Typer *tr, Expression *e) {
/* type this instance */
/* if anything happens, make sure we let the user know that this happened while generating a fn */
- ErrCtx *err_ctx = e->where.start->pos.ctx;
+ ErrCtx *err_ctx = e->where.file->ctx;
*(Location *)typer_arr_add(tr, &err_ctx->instance_stack) = e->where;
bool success = types_fn(tr, &c->instance->fn, &f->type, c->instance);
arr_remove_lasta(&err_ctx->instance_stack, tr->allocr);
@@ -2380,7 +2380,7 @@ static bool types_stmt(Typer *tr, Statement *s) {
return false;
}
- if (s->expr.type.kind == TYPE_TUPLE && !(s->flags & STMT_EXPR_NO_SEMICOLON)) {
+ if (s->expr.kind == EXPR_TUPLE && !(s->flags & STMT_EXPR_NO_SEMICOLON)) {
err_print(s->where, "Statement of a tuple is not allowed. Use a semicolon instead of a comma here.");
return false;
}
@@ -2467,7 +2467,7 @@ static bool types_file(Typer *tr, ParsedFile *f) {
memcpy(pkg_name_cstr, pkg_name_str, pkg_name_len);
pkg_name_cstr[pkg_name_len] = 0;
tr->pkg_name = pkg_name_cstr;
- char *pkg_file_name = err_malloc(pkg_name_len+5);
+ char *pkg_file_name = typer_malloc(tr, pkg_name_len+5);
sprintf(pkg_file_name, "%s.top", pkg_name_cstr);
pkg_fp = fopen(pkg_file_name, "wb");
if (!pkg_fp) {
@@ -2475,8 +2475,7 @@ static bool types_file(Typer *tr, ParsedFile *f) {
free(pkg_file_name);
return false;
}
- free(pkg_file_name);
- exptr_create(tr->exptr, pkg_fp);
+ exptr_create(tr->exptr, pkg_fp, pkg_file_name, tr->err_ctx);
exptr_start(tr->exptr, pkg_name_str, pkg_name_len);
}
arr_foreach(f->stmts, Statement, s) {
diff --git a/types.h b/types.h
index f593e22..27b375d 100644
--- a/types.h
+++ b/types.h
@@ -102,8 +102,6 @@ typedef U32 IdentID; /* identifier ID for cgen (anonymous variables). not to be
typedef struct ErrCtx {
- const char *filename;
- char *str; /* file contents, or NULL if none are available */
bool enabled;
bool color_enabled;
bool have_errored;
@@ -328,7 +326,6 @@ typedef struct StrLiteral {
} StrLiteral;
typedef struct {
- ErrCtx *ctx;
U32 line;
U32 start; /* index in ctx->str */
U32 end; /* exclusive */
@@ -348,16 +345,21 @@ typedef struct Token {
};
} Token;
+typedef struct {
+ ErrCtx *ctx;
+ const char *filename;
+ char *contents;
+} File;
typedef struct Location {
+ File *file;
/* if start is NULL, simple_location will be used. */
Token *start;
union {
Token *end; /* Exclusive */
struct {
- ErrCtx *ctx;
- U32 line;
- } *simple_location;
+ U32 line; /* if 0, this is a null location */
+ } simple_location;
};
} Location;
@@ -365,6 +367,7 @@ typedef struct Location {
typedef struct Tokenizer {
Allocator *allocr;
Token *tokens;
+ File *file;
char *s; /* string being parsed */
ErrCtx *err_ctx;
U32 line;
@@ -827,8 +830,9 @@ typedef struct ParsedFile {
typedef struct Parser {
Tokenizer *tokr;
Allocator *allocr;
+ File *file;
Block *block; /* which block are we in? NULL = file scope */
- ParsedFile *file;
+ ParsedFile *parsed_file;
} Parser;
typedef enum {
@@ -891,6 +895,7 @@ typedef struct Exporter {
FILE *out; /* .top (toc package) to output to */
bool started;
U64 ident_id;
+ File exporting_to;
FnExpr **exported_fns;
StructDef **exported_structs;
Identifier *exported_idents; /* (only those whose names are exported) */
@@ -899,6 +904,7 @@ typedef struct Exporter {
typedef struct Importer {
FILE *in;
+ File importing_from;
Package *pkg;
Allocator *allocr;
Identifier *ident_map; /* [i] = value of identifier with ID i */