summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-06-21 01:05:00 +0100
committerubq323 <ubq323@ubq323.website>2024-06-21 01:05:00 +0100
commit5298940fc7798455d701d075b910e0545d3f6048 (patch)
treeebdded23f23468d164dd3c073c27185360b3f66c
parenta03973653262fbbfed7ce42dfa39646d16bdc98f (diff)
proper equality for values; deduplicate constants in compilation
-rw-r--r--val.c11
-rw-r--r--val.h1
-rw-r--r--vm.c11
3 files changed, 22 insertions, 1 deletions
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();