Implement "set" function in the stdlib

This commit is contained in:
Konstantin Nazarov 2024-09-18 19:53:12 +01:00
parent 6ff2084d09
commit b967aa6768
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
8 changed files with 56 additions and 21 deletions

View file

@ -723,7 +723,7 @@ Result<Dict> Dict::create(const Array& arr) {
auto key = TRY(Value::create(arr._value->data[2 * i].get())); auto key = TRY(Value::create(arr._value->data[2 * i].get()));
auto value = TRY(Value::create(arr._value->data[2 * i + 1].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); return std::move(res);
@ -743,7 +743,7 @@ Result<Value> Dict::get(const Value& key) const {
return TRY(Value::create(_value->data[pos * 2 + 1].get())); return TRY(Value::create(_value->data[pos * 2 + 1].get()));
} }
Result<Dict> Dict::insert(const Value& key, const Value& value) { Result<Dict> Dict::set(const Value& key, const Value& value) const {
auto pos = TRY(find(key)); auto pos = TRY(find(key));
auto this_size = TRY(size()); auto this_size = TRY(size());
auto s = this_size; auto s = this_size;
@ -777,6 +777,10 @@ Result<Dict> Dict::insert(const Value& key, const Value& value) {
return Dict(TRY(MkGcRoot(pod))); return Dict(TRY(MkGcRoot(pod)));
} }
Result<Value> Dict::set_value(const Value& key, const Value& value) const {
return Value(TRY(set(key, value)));
}
Result<uint64_t> Dict::find(const Value& key) const { Result<uint64_t> Dict::find(const Value& key) const {
uint64_t left = 0; uint64_t left = 0;
uint64_t right = TRY(size()); uint64_t right = TRY(size());
@ -953,6 +957,10 @@ Result<Value> Object::get(const Value& key) const {
return ERROR(TypeMismatch); return ERROR(TypeMismatch);
} }
Result<Value> Object::set_value(const Value& key, const Value& value) const {
return ERROR(TypeMismatch);
}
Result<Value> Object::first() const { return ERROR(TypeMismatch); } Result<Value> Object::first() const { return ERROR(TypeMismatch); }
Result<Value> Object::second() const { return ERROR(TypeMismatch); } Result<Value> Object::second() const { return ERROR(TypeMismatch); }
Result<Value> Object::third() const { return ERROR(TypeMismatch); } Result<Value> Object::third() const { return ERROR(TypeMismatch); }

View file

@ -124,6 +124,7 @@ class Object {
virtual Result<Value> div_inv(const Float&) const; virtual Result<Value> div_inv(const Float&) const;
virtual Result<Value> get(const Value& key) const; virtual Result<Value> get(const Value& key) const;
virtual Result<Value> set_value(const Value& key, const Value& value) const;
virtual Result<Value> first() const; virtual Result<Value> first() const;
virtual Result<Value> second() const; virtual Result<Value> second() const;
virtual Result<Value> third() const; virtual Result<Value> third() const;
@ -361,6 +362,8 @@ class ByteArray : public Object {
class Dict : public Object { class Dict : public Object {
public: public:
friend class Writer; friend class Writer;
using Object::get;
Dict() {} Dict() {}
Dict(Dict&& rhs) : _value(std::move(rhs._value)) {} Dict(Dict&& rhs) : _value(std::move(rhs._value)) {}
Dict(GcRoot<PodDict>&& val) : _value(std::move(val)) {} Dict(GcRoot<PodDict>&& val) : _value(std::move(val)) {}
@ -396,11 +399,12 @@ class Dict : public Object {
Result<Dict> copy() const; Result<Dict> copy() const;
virtual Result<Value> get(const Value& key) const final; virtual Result<Value> get(const Value& key) const final;
Result<Dict> set(const Value& key, const Value& value) const;
Result<Dict> insert(const Value& key, const Value& value); virtual Result<Value> set_value(const Value& key,
const Value& value) const final;
template <class K, class V> template <class K, class V>
Result<Dict> insert(const K& key, const V& value); Result<Dict> set(const K& key, const V& value) const;
Result<Dict> concat(Dict& rhs) { Result<Dict> concat(Dict& rhs) {
uint64_t rhs_size = TRY(rhs.size()); uint64_t rhs_size = TRY(rhs.size());
@ -1273,11 +1277,14 @@ class Value {
return ((Object*)buf)->div(*(Object*)rhs.buf); return ((Object*)buf)->div(*(Object*)rhs.buf);
} }
Result<Value> get(Value& key) { return ((Object*)buf)->get(key); } Result<Value> get(Value& key) const { return ((Object*)buf)->get(key); }
Result<Value> get(int64_t key) { Result<Value> get(int64_t key) const {
Value k = TRY(Int64::create(key)); Value k = TRY(Int64::create(key));
return ((Object*)buf)->get(k); return ((Object*)buf)->get(k);
} }
Result<Value> set(Value& key, Value& value) const {
return ((Object*)buf)->set_value(key, value);
}
Result<Value> first() const { return ((Object*)buf)->first(); } Result<Value> first() const { return ((Object*)buf)->first(); }
Result<Value> second() const { return ((Object*)buf)->second(); } Result<Value> second() const { return ((Object*)buf)->second(); }
Result<Value> third() const { return ((Object*)buf)->third(); } Result<Value> third() const { return ((Object*)buf)->third(); }
@ -1310,11 +1317,11 @@ Result<void> debug_print(const T& val)
} }
template <class K, class V> template <class K, class V>
Result<Dict> Dict::insert(const K& key, const V& value) { Result<Dict> Dict::set(const K& key, const V& value) const {
Value k = TRY(Value::create(key)); Value k = TRY(Value::create(key));
Value v = TRY(Value::create(value)); Value v = TRY(Value::create(value));
return insert(k, v); return set(k, v);
} }
template <class V> template <class V>

View file

@ -64,7 +64,7 @@ struct Context {
int64_t i = TRY(constants.size()); int64_t i = TRY(constants.size());
constants = TRY(constants.append(val)); 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; return i;
} }
@ -85,7 +85,7 @@ struct Context {
int64_t i = maxreg; 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++; maxreg++;
return i; return i;
@ -94,7 +94,7 @@ struct Context {
Result<int64_t> update_var(const Value& sym) { Result<int64_t> update_var(const Value& sym) {
int64_t i = maxreg; 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++; maxreg++;
return i; return i;
@ -134,7 +134,7 @@ struct Context {
int64_t i = TRY(closures.size()); int64_t i = TRY(closures.size());
closures = TRY(closures.append(sym)); 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; return i;
} }

View file

@ -278,7 +278,7 @@ Result<Value> Reader::read_dict_data() {
auto val1 = TRY(read_one()); auto val1 = TRY(read_one());
auto val2 = 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 // We should never get here

View file

@ -127,6 +127,24 @@ Result<StackFrame> stdlib_get(const StackFrame& stack) {
return res; return res;
} }
Result<StackFrame> 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<StackFrame> stdlib_srcloc(const StackFrame& stack) { Result<StackFrame> stdlib_srcloc(const StackFrame& stack) {
auto params = TRY(stack.get(0)); auto params = TRY(stack.get(0));
auto size = TRY(params.size()); auto size = TRY(params.size());
@ -255,6 +273,7 @@ static StdlibFunctionEntry function_entries[] = {
STDLIB_FUNCTION(list, List), STDLIB_FUNCTION(list, List),
STDLIB_FUNCTION(array, Array), STDLIB_FUNCTION(array, Array),
STDLIB_FUNCTION(get, Get), STDLIB_FUNCTION(get, Get),
STDLIB_FUNCTION(set, Set),
STDLIB_FUNCTION(srcloc, SrcLoc), STDLIB_FUNCTION(srcloc, SrcLoc),
STDLIB_FUNCTION(size, Size), STDLIB_FUNCTION(size, Size),
STDLIB_FUNCTION(map, Map), STDLIB_FUNCTION(map, Map),

View file

@ -14,6 +14,7 @@ enum class StdlibFunctionId : uint64_t {
List, List,
Array, Array,
Get, Get,
Set,
SrcLoc, SrcLoc,
Size, Size,
Map, Map,

View file

@ -211,7 +211,7 @@ Result<void> VM::vm_global_store(Opcode& oc) {
Value sym = TRY(get(oc.arg1().is_const, (uint64_t)oc.arg1().arg)); 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)); 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()); _stack = TRY(_stack.incpc());
return Result<void>(); return Result<void>();
} }

View file

@ -9,12 +9,12 @@ StaticArena<64 * 1024 * 1024> arena;
TEST_CASE(dict_insert) { TEST_CASE(dict_insert) {
auto d = DIEX(Dict::create()); auto d = DIEX(Dict::create());
d = DIEX(d.insert(1, 2)); d = DIEX(d.set(1, 2));
d = DIEX(d.insert(1, 3)); d = DIEX(d.set(1, 3));
d = DIEX(d.insert(3, 3)); d = DIEX(d.set(3, 3));
d = DIEX(d.insert(0, 4)); d = DIEX(d.set(0, 4));
d = DIEX(d.insert(0, 5)); d = DIEX(d.set(0, 5));
d = DIEX(d.insert(2, 6)); d = DIEX(d.set(2, 6));
DIEX(arena_gc()); DIEX(arena_gc());