diff options
| author | Mistivia <i@mistivia.com> | 2025-03-25 13:07:21 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-03-25 13:07:21 +0800 |
| commit | fb7664e087cb1afb64aae2128365f703beb30b57 (patch) | |
| tree | 6d4e2a4cc695052e489ec9e3fd28538a79a08f4c /src/as_tokenizer.c | |
| parent | dc87ff4b0c9f311be7fad652594e3766a4ddb0c6 (diff) | |
add result style error handling
Diffstat (limited to 'src/as_tokenizer.c')
| -rw-r--r-- | src/as_tokenizer.c | 43 |
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) { |
