Files
zig/stage0/common.h
Motiejus Jakštys 0ac1c87225 unify error handling: SET_ERROR(ctx, msg) for both parser and astgen
Replace parser's fail() and astgen's flag-only SET_ERROR(ag) with a
single SET_ERROR(ctx, msg) macro in common.h that stores the error
message in ctx->err_buf and sets ctx->has_compile_errors.  Both Parser
and AstGenCtx now carry the same err_buf[ERR_BUF_SIZE] field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:02:00 +00:00

73 lines
3.9 KiB
C

// common.h — must be included before any system headers.
#ifndef _ZIG0_COMMON_H__
#define _ZIG0_COMMON_H__
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define SLICE(Type) \
struct Type##Slice { \
uint32_t len; \
uint32_t cap; \
Type* arr; \
}
#define ARR_INIT(Type, initial_cap) \
({ \
Type* arr = calloc(initial_cap, sizeof(Type)); \
if (!arr) \
exit(1); \
arr; \
})
#define SLICE_INIT(Type, initial_cap) \
{ .len = 0, .cap = (initial_cap), .arr = ARR_INIT(Type, initial_cap) }
#define SLICE_RESIZE(Type, slice, new_cap) \
({ \
const uint32_t cap = (new_cap); \
Type* new_arr = realloc((slice)->arr, cap * sizeof(Type)); \
if (new_arr == NULL) { \
free((slice)->arr); \
exit(1); \
} \
(slice)->arr = new_arr; \
(slice)->cap = cap; \
})
#define SLICE_ENSURE_CAPACITY(Type, slice, additional) \
({ \
if ((slice)->len + (additional) > (slice)->cap) { \
SLICE_RESIZE(Type, slice, \
((slice)->cap * 2 > (slice)->len + (additional)) \
? (slice)->cap * 2 \
: (slice)->len + (additional)); \
} \
})
#define SLICE_APPEND(Type, slice, item) \
({ \
SLICE_ENSURE_CAPACITY(Type, slice, 1); \
(slice)->arr[(slice)->len++] = (item); \
})
#define ERR_BUF_SIZE 200
// SET_ERROR: mark a context as having encountered an error and record a
// diagnostic message. Both Parser and AstGenCtx carry the same two fields:
// bool has_compile_errors;
// char err_buf[ERR_BUF_SIZE];
#define SET_ERROR(ctx, msg) \
do { \
const char* _err_msg = (msg); \
size_t _err_len = strlen(_err_msg); \
if (_err_len >= ERR_BUF_SIZE) \
_err_len = ERR_BUF_SIZE - 1; \
memcpy((ctx)->err_buf, _err_msg, _err_len); \
(ctx)->err_buf[_err_len] = '\0'; \
(ctx)->has_compile_errors = true; \
} while (0)
#endif