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:
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 = {