harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 03744ea230c5064adf9820d6390b46ecb5e1e503
parent 7c0ed9d0d8cca8f786d60b14602de9e6bf53e606
Author: Armin Weigl <tb46305@gmail.com>
Date:   Wed,  3 Aug 2022 19:32:49 +0200

eval: generate error messages

Signed-off-by: Armin Weigl <tb46305@gmail.com>

Diffstat:
Msrc/eval.c | 30++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/eval.c b/src/eval.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> @@ -11,6 +12,26 @@ #include "types.h" #include "util.h" +static void +error(struct context *ctx, const struct location loc, char *fmt, ...) +{ + va_list ap, copy; + va_start(ap, fmt); + + va_copy(copy, ap); + size_t sz = vsnprintf(NULL, 0, fmt, copy); + va_end(copy); + + char *msg = xcalloc(1, sz + 1); + vsnprintf(msg, sz + 1, fmt, ap); + va_end(ap); + + struct errors *next = *ctx->next = xcalloc(1, sizeof(struct errors)); + next->loc = loc; + next->msg = msg; + ctx->next = &next->next; +} + static enum eval_result eval_access(struct context *ctx, struct expression *in, struct expression *out) { @@ -32,7 +53,7 @@ eval_access(struct context *ctx, struct expression *in, struct expression *out) } for (size_t i = tmp.constant.uval; i > 0; --i) { if (array == NULL) { - // out of bounds + error(ctx, in->loc, "slice or array access out of bounds"); return EVAL_INVALID; } array = array->next; @@ -182,12 +203,14 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou } else if (type_is_signed(lvalue.result)) { uintmax_t r = itrunc(rvalue.result, irval); if (r == 0) { + error(ctx, in->loc, "division by zero"); return EVAL_INVALID; } ival = itrunc(lvalue.result, ilval) / r; } else { uintmax_t r = itrunc(rvalue.result, urval); if (r == 0) { + error(ctx, in->loc, "division by zero"); return EVAL_INVALID; } uval = itrunc(lvalue.result, ulval) / r; @@ -212,12 +235,14 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou if (type_is_signed(lvalue.result)) { uintmax_t r = itrunc(rvalue.result, irval); if (r == 0) { + error(ctx, in->loc, "division by zero"); return EVAL_INVALID; } ival = itrunc(lvalue.result, ilval) % itrunc(rvalue.result, irval); } else { uintmax_t r = itrunc(rvalue.result, urval); if (r == 0) { + error(ctx, in->loc, "division by zero"); return EVAL_INVALID; } uval = itrunc(lvalue.result, ulval) % itrunc(rvalue.result, urval); @@ -448,6 +473,7 @@ eval_type_assertion(struct context *ctx, struct expression *in, out->constant = val.constant.tagged.value->constant; return EVAL_OK; } else { + error(ctx, in->loc, "type assertion failed"); return EVAL_INVALID; } } @@ -925,7 +951,7 @@ eval_expr(struct context *ctx, struct expression *in, struct expression *out) case EXPR_VAEND: case EXPR_VASTART: case EXPR_YIELD: - // Excluded from translation-compatible subset + error(ctx, in->loc, "unvailable at translation time"); return EVAL_INVALID; } assert(0); // Unreachable