From b967aa6768a9fdba6e1bb7c7b81d06ab07684a9c Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Wed, 18 Sep 2024 19:53:12 +0100 Subject: [PATCH] Implement "set" function in the stdlib --- src/common.cpp | 12 ++++++++++-- src/common.hpp | 21 ++++++++++++++------- src/compiler.cpp | 8 ++++---- src/reader.cpp | 2 +- src/stdlib.cpp | 19 +++++++++++++++++++ src/stdlib.hpp | 1 + src/vm.cpp | 2 +- test/dict.cpp | 12 ++++++------ 8 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index e6ec737..6e17c9a 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -723,7 +723,7 @@ Result Dict::create(const Array& arr) { auto key = TRY(Value::create(arr._value->data[2 * i].get())); auto value = TRY(Value::create(arr._value->data[2 * i + 1].get())); - res = TRY(res.insert(key, value)); + res = TRY(res.set(key, value)); } return std::move(res); @@ -743,7 +743,7 @@ Result Dict::get(const Value& key) const { return TRY(Value::create(_value->data[pos * 2 + 1].get())); } -Result Dict::insert(const Value& key, const Value& value) { +Result Dict::set(const Value& key, const Value& value) const { auto pos = TRY(find(key)); auto this_size = TRY(size()); auto s = this_size; @@ -777,6 +777,10 @@ Result Dict::insert(const Value& key, const Value& value) { return Dict(TRY(MkGcRoot(pod))); } +Result Dict::set_value(const Value& key, const Value& value) const { + return Value(TRY(set(key, value))); +} + Result Dict::find(const Value& key) const { uint64_t left = 0; uint64_t right = TRY(size()); @@ -953,6 +957,10 @@ Result Object::get(const Value& key) const { return ERROR(TypeMismatch); } +Result Object::set_value(const Value& key, const Value& value) const { + return ERROR(TypeMismatch); +} + Result Object::first() const { return ERROR(TypeMismatch); } Result Object::second() const { return ERROR(TypeMismatch); } Result Object::third() const { return ERROR(TypeMismatch); } diff --git a/src/common.hpp b/src/common.hpp index 0bc4914..be57978 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -124,6 +124,7 @@ class Object { virtual Result div_inv(const Float&) const; virtual Result get(const Value& key) const; + virtual Result set_value(const Value& key, const Value& value) const; virtual Result first() const; virtual Result second() const; virtual Result third() const; @@ -361,6 +362,8 @@ class ByteArray : public Object { class Dict : public Object { public: friend class Writer; + using Object::get; + Dict() {} Dict(Dict&& rhs) : _value(std::move(rhs._value)) {} Dict(GcRoot&& val) : _value(std::move(val)) {} @@ -396,11 +399,12 @@ class Dict : public Object { Result copy() const; virtual Result get(const Value& key) const final; - - Result insert(const Value& key, const Value& value); + Result set(const Value& key, const Value& value) const; + virtual Result set_value(const Value& key, + const Value& value) const final; template - Result insert(const K& key, const V& value); + Result set(const K& key, const V& value) const; Result concat(Dict& rhs) { uint64_t rhs_size = TRY(rhs.size()); @@ -1273,11 +1277,14 @@ class Value { return ((Object*)buf)->div(*(Object*)rhs.buf); } - Result get(Value& key) { return ((Object*)buf)->get(key); } - Result get(int64_t key) { + Result get(Value& key) const { return ((Object*)buf)->get(key); } + Result get(int64_t key) const { Value k = TRY(Int64::create(key)); return ((Object*)buf)->get(k); } + Result set(Value& key, Value& value) const { + return ((Object*)buf)->set_value(key, value); + } Result first() const { return ((Object*)buf)->first(); } Result second() const { return ((Object*)buf)->second(); } Result third() const { return ((Object*)buf)->third(); } @@ -1310,11 +1317,11 @@ Result debug_print(const T& val) } template -Result Dict::insert(const K& key, const V& value) { +Result Dict::set(const K& key, const V& value) const { Value k = TRY(Value::create(key)); Value v = TRY(Value::create(value)); - return insert(k, v); + return set(k, v); } template diff --git a/src/compiler.cpp b/src/compiler.cpp index 0bf4807..e94a065 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -64,7 +64,7 @@ struct Context { int64_t i = TRY(constants.size()); constants = TRY(constants.append(val)); - constants_dict = TRY(constants_dict.insert(val, TRY(Value::create(i)))); + constants_dict = TRY(constants_dict.set(val, TRY(Value::create(i)))); return i; } @@ -85,7 +85,7 @@ struct Context { int64_t i = maxreg; - variables_dict = TRY(variables_dict.insert(sym, TRY(Value::create(i)))); + variables_dict = TRY(variables_dict.set(sym, TRY(Value::create(i)))); maxreg++; return i; @@ -94,7 +94,7 @@ struct Context { Result update_var(const Value& sym) { int64_t i = maxreg; - variables_dict = TRY(variables_dict.insert(sym, TRY(Value::create(i)))); + variables_dict = TRY(variables_dict.set(sym, TRY(Value::create(i)))); maxreg++; return i; @@ -134,7 +134,7 @@ struct Context { int64_t i = TRY(closures.size()); closures = TRY(closures.append(sym)); - closures_dict = TRY(closures_dict.insert(sym, TRY(Value::create(i)))); + closures_dict = TRY(closures_dict.set(sym, TRY(Value::create(i)))); return i; } diff --git a/src/reader.cpp b/src/reader.cpp index 52e1524..bb076f9 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -278,7 +278,7 @@ Result Reader::read_dict_data() { auto val1 = TRY(read_one()); auto val2 = TRY(read_one()); - res = TRY(res.insert(val1, val2)); + res = TRY(res.set(val1, val2)); } // We should never get here diff --git a/src/stdlib.cpp b/src/stdlib.cpp index d3cf993..e111bd9 100644 --- a/src/stdlib.cpp +++ b/src/stdlib.cpp @@ -127,6 +127,24 @@ Result stdlib_get(const StackFrame& stack) { return res; } +Result stdlib_set(const StackFrame& stack) { + auto params = TRY(stack.get(0)); + auto size = TRY(params.size()); + if (size != 3) return ERROR(ArgumentCountMismatch); + + Value collection = TRY(params.get(0)); + Value key = TRY(params.get(1)); + Value value = TRY(params.get(2)); + + collection = TRY(collection.set(key, value)); + + auto res = TRY(stack.set(0, collection)); + + res = TRY(res.ret(0)); + + return res; +} + Result stdlib_srcloc(const StackFrame& stack) { auto params = TRY(stack.get(0)); auto size = TRY(params.size()); @@ -255,6 +273,7 @@ static StdlibFunctionEntry function_entries[] = { STDLIB_FUNCTION(list, List), STDLIB_FUNCTION(array, Array), STDLIB_FUNCTION(get, Get), + STDLIB_FUNCTION(set, Set), STDLIB_FUNCTION(srcloc, SrcLoc), STDLIB_FUNCTION(size, Size), STDLIB_FUNCTION(map, Map), diff --git a/src/stdlib.hpp b/src/stdlib.hpp index b12e7d7..668efb3 100644 --- a/src/stdlib.hpp +++ b/src/stdlib.hpp @@ -14,6 +14,7 @@ enum class StdlibFunctionId : uint64_t { List, Array, Get, + Set, SrcLoc, Size, Map, diff --git a/src/vm.cpp b/src/vm.cpp index 7b5fe8e..0c9a690 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -211,7 +211,7 @@ Result VM::vm_global_store(Opcode& oc) { Value sym = TRY(get(oc.arg1().is_const, (uint64_t)oc.arg1().arg)); Value val = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg)); - _globals = TRY(_globals.insert(sym, val)); + _globals = TRY(_globals.set(sym, val)); _stack = TRY(_stack.incpc()); return Result(); } diff --git a/test/dict.cpp b/test/dict.cpp index cc1e51f..5ecb61d 100644 --- a/test/dict.cpp +++ b/test/dict.cpp @@ -9,12 +9,12 @@ StaticArena<64 * 1024 * 1024> arena; TEST_CASE(dict_insert) { auto d = DIEX(Dict::create()); - d = DIEX(d.insert(1, 2)); - d = DIEX(d.insert(1, 3)); - d = DIEX(d.insert(3, 3)); - d = DIEX(d.insert(0, 4)); - d = DIEX(d.insert(0, 5)); - d = DIEX(d.insert(2, 6)); + d = DIEX(d.set(1, 2)); + d = DIEX(d.set(1, 3)); + d = DIEX(d.set(3, 3)); + d = DIEX(d.set(0, 4)); + d = DIEX(d.set(0, 5)); + d = DIEX(d.set(2, 6)); DIEX(arena_gc());