From 5298940fc7798455d701d075b910e0545d3f6048 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Fri, 21 Jun 2024 01:05:00 +0100 Subject: proper equality for values; deduplicate constants in compilation --- val.c | 11 +++++++++++ val.h | 1 + vm.c | 11 ++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/val.c b/val.c index 19f96a0..5a20d09 100644 --- a/val.c +++ b/val.c @@ -81,6 +81,17 @@ bool is_truthy(Val v) { return true; } +bool val_equal(Val a, Val b) { + if (a.ty != b.ty) return false; + switch (a.ty) { + case TY_NIL: return true; + case TY_NUM: return AS_NUM(a) == AS_NUM(b); + case TY_BOOL: return AS_BOOL(a) == AS_BOOL(b); + case TY_OBJ: return AS_OBJ(a) == AS_OBJ(b); + default: return false; + } +} + const char *typename_str(Val v) { switch(v.ty) { diff --git a/val.h b/val.h index aa20b48..1db122b 100644 --- a/val.h +++ b/val.h @@ -31,6 +31,7 @@ void println_val(Val v); const char *typename_str(Val v); bool is_truthy(Val v); +bool val_equal(Val a, Val b); typedef enum { diff --git a/vm.c b/vm.c index e969692..1dc40e0 100644 --- a/vm.c +++ b/vm.c @@ -27,11 +27,15 @@ size_t chunk_wbc(State *S, Chunk *ch, uint8_t byte) { return ix; } size_t chunk_wconst(State *S, Chunk *ch, Val v) { + for (int i = 0; i < ch->consts.len; i ++) + if (val_equal(v, ch->consts.d[i])) return i; + if (ch->consts.len == ch->consts.cap) { size_t newsz = (ch->consts.cap == 0 ? 8 : ch->consts.cap *2); ch->consts.d = RENEW_ARR(S, ch->consts.d, Val, ch->consts.cap, newsz); ch->consts.cap = newsz; } + size_t ix = ch->consts.len; ch->consts.d[ix] = v; ch->consts.len ++; @@ -149,11 +153,16 @@ int runvm(State *S) { ARITH_OP(OP_SUB, -) ARITH_OP(OP_MUL, *) ARITH_OP(OP_DIV, /) - BOOL_OP(OP_EQU, ==) BOOL_OP(OP_CMP, <) #undef BINARY_OP #undef ARITH_OP #undef BOOL_OP + case OP_EQU: { + Val b = POP(); + Val a = POP(); + PUSH(VAL_BOOL(val_equal(a,b))); + break; + } case OP_MOD: { Val b = POP(); Val a = POP(); -- cgit v1.2.3