summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--err.c43
-rw-r--r--location.c16
-rw-r--r--tokenizer.c54
-rw-r--r--types.c2
-rw-r--r--types.h24
5 files changed, 65 insertions, 74 deletions
diff --git a/err.c b/err.c
index a98a822..764d80e 100644
--- a/err.c
+++ b/err.c
@@ -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);
diff --git a/location.c b/location.c
index 481c033..a7ac4cd 100644
--- a/location.c
+++ b/location.c
@@ -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;
diff --git a/types.c b/types.c
index b5ba6c9..9c9208c 100644
--- a/types.c
+++ b/types.c
@@ -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);
diff --git a/types.h b/types.h
index 4082dd6..d9b5f0d 100644
--- a/types.h
+++ b/types.h
@@ -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;