diff options
-rw-r--r-- | err.c | 43 | ||||
-rw-r--r-- | location.c | 16 | ||||
-rw-r--r-- | tokenizer.c | 54 | ||||
-rw-r--r-- | types.c | 2 | ||||
-rw-r--r-- | types.h | 24 |
5 files changed, 65 insertions, 74 deletions
@@ -55,44 +55,37 @@ static void err_vfprint(const char *fmt, va_list args) { } static void err_print_header_(Location where) { - if (!where.ctx) + if (!where.first) err_fprint(TEXT_ERROR("error") ":\n"); else { -#if ERR_EMACS - err_fprint("%s:%lu: " TEXT_ERROR("error") ":\n", where.ctx->filename, (unsigned long)where.line); -#else - err_fprint(TEXT_ERROR("error") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); -#endif + SourcePos first_pos = where.first->pos; + err_fprint(TEXT_ERROR("error") " at line %lu of %s:\n", (unsigned long)first_pos.line, first_pos.ctx->filename); } } static void info_print_header_(Location where) { - if (!where.ctx) + if (!where.first) err_fprint(TEXT_INFO("info") ":\n"); else { -#if ERR_EMACS - err_fprint("%s:%lu: " TEXT_INFO("info") ":\n", where.ctx->filename, (unsigned long)where.line); -#else - err_fprint(TEXT_INFO("info") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); -#endif + SourcePos first_pos = where.first->pos; + err_fprint(TEXT_INFO("info") " at line %lu of %s:\n", (unsigned long)first_pos.line, first_pos.ctx->filename); } } static void warn_print_header_(Location where) { - if (!where.ctx) + if (!where.first) err_fprint(TEXT_WARN("warning") ":\n"); else { -#if ERR_EMACS - err_fprint("%s:%lu: " TEXT_WARN("warning") ":\n", where.ctx->filename, (unsigned long)where.line); -#else - err_fprint(TEXT_WARN("warning") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); -#endif + SourcePos first_pos = where.first->pos; + err_fprint(TEXT_WARN("warning") " at line %lu of %s:\n", (unsigned long)first_pos.line, first_pos.ctx->filename); } } static void err_print_location_text(Location where) { - if (where.ctx) { - const char *text = where.ctx->str + where.pos; + if (where.first) { + SourcePos first_pos = where.first->pos; + ErrCtx *ctx = first_pos.ctx; + const char *text = ctx->str + first_pos.start; const char *end = strchr(text, '\n'); int has_newline = end != NULL; if (!has_newline) @@ -111,7 +104,7 @@ static void err_print_location_text(Location where) { } static void err_print_footer_(Location where) { - ErrCtx *ctx = where.ctx; + ErrCtx *ctx = where.first->pos.ctx; err_fprint("\n"); err_print_location_text(where); if (ctx) { @@ -126,7 +119,7 @@ static void err_print_footer_(Location where) { static void err_vprint(Location where, const char *fmt, va_list args) { - if (where.ctx && !where.ctx->enabled) return; + if (location_is_ctx_disabled(where)) return; err_print_header_(where); err_vfprint(fmt, args); err_print_footer_(where); @@ -140,7 +133,7 @@ static void err_print_( Location where, const char *fmt, ...) { va_list args; #if ERR_SHOW_SOURCE_LOCATION - if (where.ctx && !where.ctx->enabled) return; + if (location_is_ctx_disabled(where)) return; if (file) err_fprint("Generated by line %d of %s:\n", line, file); #endif @@ -157,7 +150,7 @@ static void err_print_( static void info_print(Location where, const char *fmt, ...) { va_list args; - if (where.ctx && !where.ctx->enabled) return; + if (location_is_ctx_disabled(where)) return; va_start(args, fmt); info_print_header_(where); err_vfprint(fmt, args); @@ -171,7 +164,7 @@ static void warn_print_( #endif Location where, const char *fmt, ...) { va_list args; - if (where.ctx && !where.ctx->enabled) return; + if (location_is_ctx_disabled(where)) return; #if ERR_SHOW_SOURCE_LOCATION if (file) err_fprint("Generated by line %d of %s:\n", line, file); @@ -3,26 +3,28 @@ This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -static bool location_after(Location a, Location b) { /* a is after b? */ - assert(a.ctx == b.ctx); - return a.pos > b.pos; -} static Location const LOCATION_NONE = {0}; /* for debugging */ static void fprint_location(FILE *out, Location location) { - if (!location.ctx) { + if (!location.first) { fprintf(out, "No location available."); return; } - char *str = location.ctx->str + location.pos; + /* TODO: show end */ + char *str = location.first->pos.ctx->str + location.first->pos.start; char *newline = strchr(str, '\n'); if (newline) *newline = 0; - fprintf(out, "Line %ld: %s\n", (long)location.line, str); + fprintf(out, "Line %ld: %s\n", (long)location.first->pos.line, str); if (newline) *newline = '\n'; } static void print_location(Location location) { fprint_location(stdout, location); } + + +static bool location_is_ctx_disabled(Location location) { + return location.first && !location.first->pos.ctx->enabled; +} diff --git a/tokenizer.c b/tokenizer.c index fd1d2d7..14cfcae 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -82,7 +82,7 @@ static const char *token_kind_to_str(TokenKind t) { } static void fprint_token(FILE *out, Token *t) { - fprintf(out, "l%lu-", (unsigned long)t->where.line); + fprintf(out, "l%lu-", (unsigned long)t->pos.line); switch (t->kind) { case TOKEN_KW: fprintf(out, "keyword: %s", kw_to_str(t->kw)); @@ -145,39 +145,23 @@ static char tokr_esc_seq(Tokenizer *t) { } -/* to be used during tokenization */ -static void tokenization_err(Tokenizer *t, const char *fmt, ...) { - va_list args; - Location where; - where.line = t->line; - where.ctx = t->err_ctx; - where.pos = (U32)(t->s - where.ctx->str); - va_start(args, fmt); - err_vprint(where, fmt, args); - va_end(args); - char *end_of_line = strchr(t->s, '\n'); - if (end_of_line) { - t->s = end_of_line; - ++t->s; /* move past newline */ - } else { - t->s = strchr(t->s, '\0'); - } - ++t->line; -} -/* to be used after tokenization */ static void tokr_err_( #if ERR_SHOW_SOURCE_LOCATION const char *src_file, int src_line, #endif Tokenizer *t, const char *fmt, ...) { #if ERR_SHOW_SOURCE_LOCATION - if (t->token->where.ctx && !t->token->where.ctx->enabled) return; + if (!t->token->pos.ctx->enabled) return; err_fprint("At line %d of %s:\n", src_line, src_file); #endif + Location where; + where.first = t->token; + where.last = t->token; + va_list args; va_start(args, fmt); - err_vprint(t->token->where, fmt, args); + err_vprint(where, fmt, args); va_end(args); } @@ -187,15 +171,19 @@ static void tokr_err_( #define tokr_err tokr_err_ #endif -static void tokr_put_location(Tokenizer *tokr, Token *t) { - t->where.line = tokr->line; - t->where.ctx = tokr->err_ctx; - t->where.pos = (U32)(tokr->s - t->where.ctx->str); +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); } -static void tokr_get_location(Tokenizer *tokr, Token *t) { - tokr->line = t->where.line; - tokr->s = t->where.pos + t->where.ctx->str; +static void tokr_put_end_pos(Tokenizer *tokr, Token *t) { + t->pos.end = (U32)(tokr->s - t->pos.ctx->str); +} + +static void tokr_get_start_pos(Tokenizer *tokr, Token *t) { + tokr->line = t->pos.line; + tokr->s = t->pos.start + t->pos.ctx->str; } /* @@ -216,7 +204,7 @@ static inline void *tokr_malloc(Tokenizer *t, size_t bytes) { static Token *tokr_add(Tokenizer *t) { Token *token = arr_add(&t->tokens); - tokr_put_location(t, token); + tokr_put_start_pos(t, token); return token; } @@ -256,7 +244,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { ++comment_level; } else { if (*t->s == 0) { - tokenization_err(t, "End of file reached inside multi-line comment."); + tokr_err(t, "End of file reached inside multi-line comment."); return false; } @@ -279,7 +267,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { if (direct != DIRECT_COUNT) { /* it's a directive */ Token *token = tokr_add(t); - tokr_put_location(t, token); + tokr_put_start_pos(t, token); token->where.pos = (U32)(start_s - token->where.ctx->str); token->kind = TOKEN_DIRECT; token->direct = direct; @@ -408,7 +408,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { if (!type_of_fn(tr, d->expr.fn, t, 0)) return false; return true; } else { - if (location_after(d->where, where)) { + if (where.start <= d->where.end) { char *s = ident_to_str(i); err_print(where, "Use of identifier %s before its declaration.\nNote that it is only possible to use a constant function before it is directly declared (e.g. x ::= fn() {}).", s); info_print(d->where, "%s will be declared here.", s); @@ -81,17 +81,11 @@ typedef U32 IdentID; /* identifier ID for cgen (anonymous variables). not to be #endif -typedef struct Location { - U32 line; - U32 pos; /* position in ctx->str */ - struct ErrCtx *ctx; -} Location; - typedef struct ErrCtx { const char *filename; char *str; /* file contents */ bool enabled; - Location *instance_stack; /* stack of locations which generate the instances we're dealing with */ + struct Location *instance_stack; /* stack of locations which generate the instances we're dealing with */ } ErrCtx; @@ -301,10 +295,17 @@ typedef struct StrLiteral { size_t len; } StrLiteral; +typedef struct { + ErrCtx *ctx; + U32 line; + U32 start; /* index in ctx->str */ + U32 end; +} SourcePos; + /* NOTE: Location is typedef'd in util/err.c */ typedef struct Token { TokenKind kind; - Location where; + SourcePos pos; union { Keyword kw; Directive direct; @@ -315,6 +316,13 @@ typedef struct Token { }; } Token; + +typedef struct Location { + Token *first; + Token *last; /* Included */ +} Location; + + typedef struct Tokenizer { Allocator *allocr; Token *tokens; |