From ae6f86e4f7497a498a926ae59f44164fc93d939a Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sun, 4 Aug 2024 01:03:01 +0100 Subject: [PATCH] Add symbol comparison and test for it --- CMakeLists.txt | 1 + src/common.hpp | 31 ++++++++++++++++++++++++++++++- test/symbol.cpp | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 test/symbol.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 824a46a..5934c14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ enable_testing() set(CPP_TESTS dict array + symbol ) diff --git a/src/common.hpp b/src/common.hpp index c850b73..07fd6e6 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -480,8 +480,26 @@ class Symbol : public Object { virtual Result cmp(Arena& arena, Object& rhs) final { return -TRY(rhs.cmp(arena, *this)); } - virtual Result cmp(Arena&, Symbol& rhs) final { return 0; } + virtual Result cmp(Arena&, Symbol& rhs) final { + auto lsize = size(); + auto rsize = rhs.size(); + uint64_t i = 0; + uint64_t j = 0; + while (1) { + if (i == lsize && j == lsize) return 0; + short cmp = short(i == lsize) - short(j == rsize); + if (cmp != 0) return cmp; + + char32_t lc = _value->data[i]; + char32_t rc = rhs._value->data[j]; + cmp = (lc > rc) - (lc < rc); + if (cmp != 0) return cmp; + i++; + j++; + } + return 0; + } virtual void move(Object* obj) final { new (obj) Symbol(std::move(_value)); } static Result create(Arena& arena, PodSymbol* obj) { @@ -497,6 +515,17 @@ class Symbol : public Object { return Symbol(TRY(MkGcRoot(pod, arena))); } + static Result create(Arena& arena, const char* str) { + uint64_t size = strlen(str); + auto pod = TRY(arena.alloc(size * sizeof(char32_t))); + pod->header.tag = Tag::Symbol; + + for (uint64_t i = 0; i < size; i++) pod->data[i] = str[i]; + pod->size = size; + + return Symbol(TRY(MkGcRoot(pod, arena))); + } + static Result create(Arena& arena, String& rhs); virtual Result copy(Arena& arena) const final; diff --git a/test/symbol.cpp b/test/symbol.cpp new file mode 100644 index 0000000..adcc705 --- /dev/null +++ b/test/symbol.cpp @@ -0,0 +1,20 @@ +#include "common.hpp" +#include "die.hpp" +#include "reader.hpp" +#include "test.hpp" +#include "writer.hpp" + +StaticArena<64 * 1024 * 1024> arena; + +TEST_CASE(array_append) { + auto a = DIEX(Symbol::create(arena, "foo")); + auto b = DIEX(Symbol::create(arena, "foo")); + + ASSERT_EQUALS(a, b); + + auto s = DIEX(write_one(arena, a)); + + DIEX(arena.gc()); + + ASSERT_EQUALS(s, "foo"); +}