harec

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

commit 974918dca34966951efd639c251073f8d91d1baa
parent 80798fcd9838192c7e56f83c9e0bb824bc76e9b2
Author: Sebastian <sebastian@sebsite.pw>
Date:   Thu,  5 Jan 2023 17:59:56 -0500

eval: add string comparison

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

Diffstat:
Msrc/eval.c | 27++++++++++++++++++++++++---
Mtests/04-strings.ha | 4++++
2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/eval.c b/src/eval.c @@ -317,8 +317,18 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou bval = ftrunc(lvalue.result, flval) == ftrunc(rvalue.result, frval); } else if (type_is_signed(lvalue.result)) { bval = itrunc(lvalue.result, ilval) == itrunc(rvalue.result, irval); - } else { + } else if (type_is_integer(lvalue.result) + || type_dealias(lvalue.result)->storage == STORAGE_POINTER) { bval = itrunc(lvalue.result, ulval) == itrunc(rvalue.result, urval); + } else { + assert(type_dealias(lvalue.result)->storage == STORAGE_STRING); + if (lvalue.constant.string.len != rvalue.constant.string.len) { + bval = false; + } else { + bval = memcmp(lvalue.constant.string.value, + rvalue.constant.string.value, + lvalue.constant.string.len) == 0; + } } break; case BIN_LESS: @@ -356,8 +366,18 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou bval = ftrunc(lvalue.result, flval) != ftrunc(rvalue.result, frval); } else if (type_is_signed(lvalue.result)) { bval = itrunc(lvalue.result, ilval) != itrunc(rvalue.result, irval); - } else { + } else if (type_is_integer(lvalue.result) + || type_dealias(lvalue.result)->storage == STORAGE_POINTER) { bval = itrunc(lvalue.result, ulval) != itrunc(rvalue.result, urval); + } else { + assert(type_dealias(lvalue.result)->storage == STORAGE_STRING); + if (lvalue.constant.string.len != rvalue.constant.string.len) { + bval = true; + } else { + bval = memcmp(lvalue.constant.string.value, + rvalue.constant.string.value, + lvalue.constant.string.len) != 0; + } } break; } @@ -365,7 +385,8 @@ eval_binarithm(struct context *ctx, struct expression *in, struct expression *ou out->constant.fval = ftrunc(in->result, fval); } else if (type_is_signed(in->result)) { out->constant.ival = itrunc(in->result, ival); - } else if (type_dealias(in->result)->storage == STORAGE_BOOL) { + } else if (type_dealias(in->result)->storage == STORAGE_BOOL + || type_dealias(in->result)->storage == STORAGE_STRING) { out->constant.bval = bval; } else { assert(type_is_integer(in->result) diff --git a/tests/04-strings.ha b/tests/04-strings.ha @@ -57,6 +57,10 @@ fn equality() void = { assert("foo" != "foobar"); assert("foobar" == "foobar"); assert("foo\0bar" != "foo\0foo"); + static assert("foo" != "bar"); + static assert("foo" != "foobar"); + static assert("foobar" == "foobar"); + static assert("foo\0bar" != "foo\0foo"); }; fn raw() void = {