aboutsummaryrefslogtreecommitdiff
path: root/src/as_tokenizer.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-03-25 13:07:21 +0800
committerMistivia <i@mistivia.com>2025-03-25 13:07:21 +0800
commitfb7664e087cb1afb64aae2128365f703beb30b57 (patch)
tree6d4e2a4cc695052e489ec9e3fd28538a79a08f4c /src/as_tokenizer.c
parentdc87ff4b0c9f311be7fad652594e3766a4ddb0c6 (diff)
add result style error handling
Diffstat (limited to 'src/as_tokenizer.c')
-rw-r--r--src/as_tokenizer.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/src/as_tokenizer.c b/src/as_tokenizer.c
index 6c40b9f..f2c3ccb 100644
--- a/src/as_tokenizer.c
+++ b/src/as_tokenizer.c
@@ -71,8 +71,9 @@ int is_part_of_identifier(int c) {
return 0;
}
-struct token * next_token_impl(struct allocator * alct, struct input_stream * s) {
- struct token * t = allocate(alct, sizeof(struct token));
+struct result next_token_impl(struct allocator * alct, struct input_stream * s) {
+ const char *errmsg;
+ struct token * t = allocate(alct, sizeof(struct token));
int c;
while (1) {
c = input_stream_peek_char(s);
@@ -82,12 +83,12 @@ struct token * next_token_impl(struct allocator * alct, struct input_stream * s)
if (c == '\n') {
input_stream_next_char(s);
*t = (struct token){.type = TK_NEWLINE, .line = s->line, .col = s->col};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
if (c == ':') {
input_stream_next_char(s);
*t = (struct token){.type = TK_COLON, .line = s->line, .col = s->col};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
if (c == ' ' || c == '\t') {
input_stream_next_char(s);
@@ -104,17 +105,17 @@ struct token * next_token_impl(struct allocator * alct, struct input_stream * s)
}
}
*t = (struct token){.type = TK_ARG, .ival = ival, .line = s->line, .col = s->col};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
if (is_start_of_identifier(c)) {
size_t line = s->line;
size_t col = s->col;
char *sval = allocate(alct, 256);
size_t i = 0;
- while(1) {
+ while (1) {
if (i >= 255) {
- fprintf(stderr, "error: identifier too long\n");
- exit(1);
+ errmsg = safe_sprintf(alct, "error: identifier too long\n");
+ return (struct result){.value = NULL, .errmsg = errmsg};
}
input_stream_next_char(s);
sval[i++] = c;
@@ -126,34 +127,36 @@ struct token * next_token_impl(struct allocator * alct, struct input_stream * s)
sval[i] = '\0';
if (isOp(sval)) {
*t = (struct token){.type = TK_OP, .sval = sval, .line = line, .col = col};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
*t = (struct token){.type = TK_TAG, .sval = sval, .line = line, .col = col};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
- fprintf(stderr, "error: invalid character %c at line %d, col %d\n", c, s->line, s->col);
+ errmsg = safe_sprintf(alct, "error: invalid character %c at line %d, col %d\n", c, s->line, s->col);
+ return (struct result){.value = NULL, .errmsg = errmsg};
}
// end of file
*t = (struct token){.type = TK_ENDOFFILE};
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
-struct token * next_token(struct allocator * alct, struct token_stream * ts) {
+struct result next_token(struct allocator * alct, struct token_stream * ts) {
if (ts->buf != NULL) {
struct token * t = ts->buf;
ts->buf = NULL;
- return t;
+ return (struct result){.value = t, .errmsg = NULL};
}
- struct token * t = next_token_impl(alct, ts->s);
- return t;
+ return next_token_impl(alct, ts->s);
}
-struct token * peek_token(struct allocator * alct, struct token_stream * ts) {
+struct result peek_token(struct allocator * alct, struct token_stream * ts) {
if (ts->buf != NULL) {
- return ts->buf;
+ return (struct result){.value = ts->buf, .errmsg = NULL};
}
- ts->buf = next_token_impl(alct, ts->s);
- return ts->buf;
+ struct result result = next_token_impl(alct, ts->s);
+ if (result.errmsg != NULL) return result;
+ ts->buf = result.value;
+ return result;
}
void print_token(struct token * t) {