diff --git a/src/common.cpp b/src/common.cpp index 6e17c9a..8e90cb6 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -692,6 +692,31 @@ Result Array::get(const Value& key) const { return get(key.to()->value()); } +Result Array::set(uint64_t idx, const Value& value) const { + uint64_t res_size = TRY(size()); + if (idx >= res_size) return ERROR(IndexOutOfRange); + + auto pod = TRY(arena_alloc(res_size * sizeof(OffPtr))); + pod->header.tag = Tag::Array; + pod->size = res_size; + for (uint64_t i = 0; i < res_size; i++) { + pod->data[i] = _value->data[i].get(); + } + pod->data[idx] = value.pod(); + + return Array(TRY(MkGcRoot(pod))); +} + +Result Array::set(const Value& key, const Value& value) const { + if (!key.is()) return ERROR(TypeMismatch); + + return set(key.to()->value(), value); +} + +Result Array::set_value(const Value& key, const Value& value) const { + return Value(TRY(set(key, value))); +} + Result Array::append(const Value& rhs) const { uint64_t res_size = TRY(size()) + 1; auto size = TRY(this->size()); diff --git a/src/common.hpp b/src/common.hpp index be57978..0fc5d17 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -210,6 +210,10 @@ class Array : public Object { Result get(uint64_t idx) const; virtual Result get(const Value& key) const final; + Result set(uint64_t idx, const Value& value) const; + Result set(const Value& key, const Value& value) const; + virtual Result set_value(const Value& key, + const Value& value) const final; Result append(const Value& rhs) const; template diff --git a/test/collections.vli b/test/collections.vli index 1f0f616..0fe25ef 100644 --- a/test/collections.vli +++ b/test/collections.vli @@ -10,6 +10,12 @@ (assert (= (get {1 2 3 4} 3) 4)) +(assert (= (set {:foo 1} :bar 2) + {:foo 1 :bar 2})) + +(assert (= (set [1 2] 1 42) + [1 42])) + ;; Accessing collections by symbol (assert (= (get {:foo 1 :bar 2} :bar) 2))