harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit e53dc8299d6493abf22127e2f67d4f27026134de
parent a15c7d28380586cdb938737346c4b80c9cef482a
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed,  3 Feb 2021 17:15:18 -0500

gen: implement string comparisons

Diffstat:
Mrt/Makefile | 3++-
Art/strcmp.ha | 18++++++++++++++++++
Msrc/gen.c | 28++++++++++++++++++++++++++--
Mtests/04-strings.ha | 7+++++++
4 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/rt/Makefile b/rt/Makefile @@ -4,7 +4,8 @@ libhart_srcs+=\ rt/malloc.ha \ rt/memcpy.ha \ rt/memset.ha \ - rt/rtmain.ha + rt/rtmain.ha \ + rt/strcmp.ha libhart.a: harec $(libhart_srcs) $(libhart_objs) $(rtstart) @printf 'HAREC\t$@\n' diff --git a/rt/strcmp.ha b/rt/strcmp.ha @@ -0,0 +1,18 @@ +type string = struct { + data: *[*]u8, + length: size, + capacity: size, +}; + +export fn strcmp(_a: str, _b: str) bool = { + if (len(_a) != len(_b)) { + return false; + }; + let a = (&_a: *string).data, b = (&_b: *string).data; + for (let i = 0z; i < len(_a); i += 1z) { + if (a[i] != b[i]) { + return false; + }; + }; + return true; +}; diff --git a/src/gen.c b/src/gen.c @@ -788,9 +788,16 @@ gen_expr_binarithm(struct gen_context *ctx, } struct qbe_value lvalue = {0}, rvalue = {0}, result = {0}; - gen_temp(ctx, &lvalue, ltype, "lvalue.%d"); - gen_temp(ctx, &rvalue, rtype, "rvalue.%d"); gen_temp(ctx, &result, etype, "result.%d"); + if (type_is_aggregate(expr->binarithm.lvalue->result)) { + alloc_temp(ctx, &lvalue, expr->binarithm.lvalue->result, "lvalue.%d"); + alloc_temp(ctx, &rvalue, expr->binarithm.lvalue->result, "rvalue.%d"); + qval_deref(&lvalue); + qval_deref(&rvalue); + } else { + gen_temp(ctx, &lvalue, ltype, "lvalue.%d"); + gen_temp(ctx, &rvalue, rtype, "rvalue.%d"); + } gen_expression(ctx, expr->binarithm.lvalue, &lvalue); gen_expression(ctx, expr->binarithm.rvalue, &rvalue); @@ -809,6 +816,23 @@ gen_expr_binarithm(struct gen_context *ctx, break; } + if (type_dealias(expr->binarithm.lvalue->result)->storage + == TYPE_STORAGE_STRING) { + struct qbe_value rtfunc = {0}; + rtfunc.kind = QV_GLOBAL; + rtfunc.name = strdup("rt.strcmp"); + rtfunc.type = &qbe_long; + pushi(ctx->current, &result, Q_CALL, + &rtfunc, &lvalue, &rvalue, NULL); + if (expr->binarithm.op == BIN_NEQUAL) { + struct qbe_value temp = {0}; + constw(&temp, 1); + pushi(ctx->current, &result, Q_XOR, &result, &temp, NULL); + } + gen_store(ctx, out, &result); + return; + } + pushi(ctx->current, &result, binarithm_for_op(expr->binarithm.op, ltype, type_is_signed(expr->binarithm.lvalue->result)), diff --git a/tests/04-strings.ha b/tests/04-strings.ha @@ -58,9 +58,16 @@ fn concat() void = { }; }; +fn equality() void = { + assert("foo" != "bar"); + assert("foo" != "foobar"); + assert("foobar" == "foobar"); +}; + export fn main() void = { measurements(); charptr(); storage(); concat(); + equality(); };