harec

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

commit 13688980dfdc1652ae8c008e30533a95447b72bd
parent 20c786e75ade06281a003645740915edce78688c
Author: Sebastian <sebastian@sebsite.pw>
Date:   Mon,  9 May 2022 21:24:08 -0400

eval: support len expr

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Msrc/eval.c | 27++++++++++++++++++++++++++-
Mtests/01-arrays.ha | 2++
Mtests/04-strings.ha | 2++
3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/eval.c b/src/eval.c @@ -1,5 +1,6 @@ #include <assert.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include "check.h" @@ -505,9 +506,33 @@ eval_measurement(struct context *ctx, struct expression *in, struct expression * assert(in->type == EXPR_MEASURE); out->type = EXPR_CONSTANT; out->result = &builtin_type_size; + struct expression obj = {0}; + enum eval_result res; switch (in->measure.op) { case M_LEN: - assert(0); // TODO + res = eval_expr(ctx, in->measure.value, &obj); + if (res != EVAL_OK) { + return res; + } + + switch (obj.result->storage) { + case STORAGE_ARRAY: + case STORAGE_SLICE: + break; + case STORAGE_STRING: + out->constant.uval = obj.constant.string.len; + return EVAL_OK; + default: + abort(); // Invariant + } + + uintmax_t len = 0; + for (struct array_constant *c = obj.constant.array; + c != NULL; c = c->next) { + len++; + } + out->constant.uval = len; + return EVAL_OK; case M_SIZE: out->constant.uval = in->measure.dimensions.size; return EVAL_OK; diff --git a/tests/01-arrays.ha b/tests/01-arrays.ha @@ -23,6 +23,8 @@ fn measurements() void = { let x = [1, 2, 3]; assert(len(x) == 3); assert(size([3]int) == size(int) * 3); + + static assert(len([1, 2, 3]) == 3); }; fn storage() void = { diff --git a/tests/04-strings.ha b/tests/04-strings.ha @@ -9,6 +9,8 @@ fn measurements() void = { if (size(*u8) > size(size)) size(*u8) else size(size); assert(&x: uintptr: size % align == 0); + + static assert(len("Hello!") == 6); }; fn storage() void = {