Allow creating dicts with "dict" function

This commit is contained in:
Konstantin Nazarov 2024-08-28 21:51:25 +01:00
parent bb5e124706
commit f78b6e67cd
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
4 changed files with 26 additions and 0 deletions

View file

@ -395,6 +395,21 @@ short cmp_tag(Tag lhs, Tag rhs) {
return 0;
}
Result<Dict> Dict::create(const Array& arr) {
if (arr.size() % 2 != 0) return ERROR(KeyError);
Dict res = TRY(Dict::create());
for (uint64_t i = 0; i < arr.size() / 2; i++) {
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));
}
return std::move(res);
}
Result<Value> Dict::get(const Value& key) const {
auto pos = TRY(find(key));
if (pos >= size()) return ERROR(KeyError);

View file

@ -149,6 +149,8 @@ class Nil : public Object {
class Array : public Object {
public:
friend class Dict;
Array() {}
Array(Array&& rhs) : _value(std::move(rhs._value)) {}
Array(GcRoot<PodArray>&& val) : _value(std::move(val)) {}
@ -356,6 +358,8 @@ class Dict : public Object {
static Result<Dict> create(PodDict* obj) { return Dict(TRY(MkGcRoot(obj))); }
static Result<Dict> create(const Array& arr);
static Result<Dict> create() {
auto pod = TRY(arena_alloc<PodDict>());
pod->header.tag = Tag::Dict;

View file

@ -64,6 +64,11 @@ Result<Value> stdlib_assert(const Array& params) {
return Value(TRY(Nil::create()));
}
Result<Value> stdlib_dict(const Array& params) {
Value d = TRY(Dict::create(params));
return d;
}
#define STDLIB_FUNCTION(name, id) \
[(uint64_t)StdlibFunctionId::id] = {#name, StdlibFunctionId::id, \
stdlib_##name}
@ -74,6 +79,7 @@ static StdlibFunctionEntry function_entries[] = {
STDLIB_FUNCTION(println, PrintLn),
STDLIB_FUNCTION(prn, Prn),
STDLIB_FUNCTION(assert, Assert),
STDLIB_FUNCTION(dict, Dict),
[(uint64_t)StdlibFunctionId::Max] = {0, StdlibFunctionId::Max,
stdlib_unknown},
};

View file

@ -10,6 +10,7 @@ enum class StdlibFunctionId : uint64_t {
PrintLn,
Prn,
Assert,
Dict,
Max,
};