From f372586069ea0a92db65bc90cf844c1a35187430 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 24 Oct 2021 09:26:25 +0200 Subject: Remove constant duplication on compile time --- src/bytecode/chunk.h | 14 ++++++-------- src/bytecode/objects.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 8 deletions(-) (limited to 'src/bytecode') diff --git a/src/bytecode/chunk.h b/src/bytecode/chunk.h index aafa0ec..5fbc000 100755 --- a/src/bytecode/chunk.h +++ b/src/bytecode/chunk.h @@ -34,9 +34,7 @@ chunk_free(Chunk *chunk) { array_free(chunk->code); for (size_t i = 0; i < array_size(chunk->constants); i++) { Object obj = chunk->constants[i]; - if (IS_STRING(obj) || IS_SYMBOL(obj)) { - array_free(obj.text); - } + object_free(obj); } array_free(chunk->constants); array_free(chunk->lines); @@ -52,12 +50,12 @@ add_code(Chunk *chunk, u8 byte, size_t line, size_t col) { size_t add_constant(Chunk *chunk, Object obj) { - // FIXME?: Since we are using a single byte to store constant indices, we - // can only have 256 stored constants. If we need more we may need to add - // another instruction OP_CONSTANT_16 to have at least two bytes for - // constants. Alternatively, we could make that the default. Either way, for - // now it's fine. size_t pos = array_size(chunk->constants); + for (size_t i = 0; i < pos; i++) { + if (object_equal(obj, chunk->constants[i])) { + return i; + } + } array_push(chunk->constants, obj); return pos; } diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h index 17809d5..fc5e069 100755 --- a/src/bytecode/objects.h +++ b/src/bytecode/objects.h @@ -121,4 +121,42 @@ display(Object obj) { return; } +void +object_free(Object obj) { + if (IS_STRING(obj) || IS_SYMBOL(obj)) { + array_free(obj.text); + } +} + +bool +object_equal(Object a, Object b) { + if (a.type != b.type) { + return false; + } + switch (a.type) { + case OBJ_TYPE_TRUE: + case OBJ_TYPE_FALSE: { + return true; + } break; + case OBJ_TYPE_FIXNUM: { + return a.fixnum == b.fixnum; + } break; + case OBJ_TYPE_SYMBOL: + case OBJ_TYPE_STRING: { + if (array_size(a.text) != array_size(b.text)) { + return false; + } + for (size_t i = 0; i < array_size(a.text); i++) { + if (a.text[i] != b.text[i]) { + return false; + } + } + } break; + default: { + return false; + } break; + } + return true; +} + #endif // BDL_OBJECTS_H -- cgit v1.2.1