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 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<Value> Dict::get(const Value& key) const {
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 this_size = TRY(size());
auto s = this_size;
@ -777,6 +777,10 @@ Result<Dict> Dict::insert(const Value& key, const Value& value) {
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 {
uint64_t left = 0;
uint64_t right = TRY(size());
@ -953,6 +957,10 @@ Result<Value> Object::get(const Value& key) const {
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::second() 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> 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> second() const;
virtual Result<Value> 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<PodDict>&& val) : _value(std::move(val)) {}
@ -396,11 +399,12 @@ class Dict : public Object {
Result<Dict> copy() const;
virtual Result<Value> get(const Value& key) const final;
Result<Dict> insert(const Value& key, const Value& value);
Result<Dict> set(const Value& key, const Value& value) const;
virtual Result<Value> set_value(const Value& key,
const Value& value) const final;
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) {
uint64_t rhs_size = TRY(rhs.size());
@ -1273,11 +1277,14 @@ class Value {
return ((Object*)buf)->div(*(Object*)rhs.buf);
}
Result<Value> get(Value& key) { return ((Object*)buf)->get(key); }
Result<Value> get(int64_t key) {
Result<Value> get(Value& key) const { return ((Object*)buf)->get(key); }
Result<Value> get(int64_t key) const {
Value k = TRY(Int64::create(key));
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> second() const { return ((Object*)buf)->second(); }
Result<Value> third() const { return ((Object*)buf)->third(); }
@ -1310,11 +1317,11 @@ Result<void> debug_print(const T& val)
}
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 v = TRY(Value::create(value));
return insert(k, v);
return set(k, v);
}
template <class V>

View file

@ -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<int64_t> 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;
}

View file

@ -278,7 +278,7 @@ Result<Value> 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

View file

@ -127,6 +127,24 @@ Result<StackFrame> stdlib_get(const StackFrame& stack) {
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) {
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),

View file

@ -14,6 +14,7 @@ enum class StdlibFunctionId : uint64_t {
List,
Array,
Get,
Set,
SrcLoc,
Size,
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 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<void>();
}

View file

@ -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());