Add test for dictionary "get()"

This commit is contained in:
Konstantin Nazarov 2024-08-03 18:53:14 +01:00
parent a52e4d278c
commit b0166cc7da
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
5 changed files with 70 additions and 57 deletions

View file

@ -39,7 +39,7 @@ class GcRoot : public GcRootBase {
GcRoot& operator=(GcRoot&& rhs);
static Result<GcRoot<T>> create(T* ptr, Arena& arena);
Result<GcRoot<T>> copy(Arena& arena) {
Result<GcRoot<T>> copy(Arena& arena) const {
return GcRoot<T>::create((T*)_ptr, arena);
}

View file

@ -78,44 +78,44 @@ Result<Value> syntax_unwrap(Arena& arena, Value& val) {
return syntax->get_value(arena);
}
Result<Value> Nil::copy(Arena& arena) { return Value(Nil()); }
Result<Value> Nil::copy(Arena& arena) const { return Value(Nil()); }
Result<Value> Int64::copy(Arena& arena) {
Result<Value> Int64::copy(Arena& arena) const {
return Value(Int64(TRY(_value.copy(arena))));
}
Result<Value> Float::copy(Arena& arena) {
Result<Value> Float::copy(Arena& arena) const {
return Value(Float(TRY(_value.copy(arena))));
}
Result<Value> Array::copy(Arena& arena) {
Result<Value> Array::copy(Arena& arena) const {
return Value(Array(TRY(_value.copy(arena))));
}
Result<Value> ByteArray::copy(Arena& arena) {
Result<Value> ByteArray::copy(Arena& arena) const {
return Value(ByteArray(TRY(_value.copy(arena))));
}
Result<Value> Dict::copy(Arena& arena) {
Result<Value> Dict::copy(Arena& arena) const {
return Value(Dict(TRY(_value.copy(arena))));
}
Result<Value> String::copy(Arena& arena) {
Result<Value> String::copy(Arena& arena) const {
return Value(String(TRY(_value.copy(arena))));
}
Result<Value> Symbol::copy(Arena& arena) {
Result<Value> Symbol::copy(Arena& arena) const {
return Value(Symbol(TRY(_value.copy(arena))));
}
Result<Value> Syntax::copy(Arena& arena) {
Result<Value> Syntax::copy(Arena& arena) const {
return Value(Syntax(TRY(_value.copy(arena))));
}
Result<Value> Pair::copy(Arena& arena) {
Result<Value> Pair::copy(Arena& arena) const {
return Value(Pair(TRY(_value.copy(arena))));
}
Result<Value> Bool::copy(Arena& arena) {
Result<Value> Bool::copy(Arena& arena) const {
return Value(Bool(TRY(_value.copy(arena))));
}
@ -176,6 +176,11 @@ Result<Value> Array::get(Arena& arena, uint64_t idx) {
return Value::create(arena, val);
}
Result<Value> Array::get(Arena& arena, Value& key) {
if (!key.is<Int64>()) return ErrorCode::TypeMismatch;
return get(arena, key.to<Int64>()->value());
}
Result<Array> Array::append(Arena& arena, Value& rhs) {
uint64_t res_size = size() + 1;
@ -293,3 +298,7 @@ Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
}
return 0;
}
Result<Value> Object::get(Arena& arena, Value& key) {
return ErrorCode::TypeMismatch;
}

View file

@ -6,6 +6,7 @@
#include <iostream>
#include "arena.hpp"
#include "error.hpp"
#include "pod.hpp"
#include "utf8.hpp"
@ -30,7 +31,7 @@ short cmp_tag(Tag lhs, Tag rhs);
class Object {
public:
virtual Tag tag() = 0;
virtual Result<Value> copy(Arena& arena) = 0;
virtual Result<Value> copy(Arena& arena) const = 0;
virtual PodObject* pod() = 0;
virtual void move(Object*) = 0;
virtual ~Object() = default;
@ -60,6 +61,7 @@ class Object {
virtual Result<short> cmp(Arena&, ByteArray&) {
return cmp_tag(tag(), Tag::ByteArray);
}
virtual Result<Value> get(Arena& arena, Value& key);
Object() = default;
Object(const Object&) = delete;
@ -90,7 +92,7 @@ class Nil : public Object {
return Nil(TRY(MkGcRoot(pod, arena)));
}
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
virtual void move(Object* obj) final { new (obj) Nil(std::move(_value)); }
@ -132,9 +134,10 @@ class Array : public Object {
}
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
Result<Value> get(Arena& arena, uint64_t idx);
virtual Result<Value> get(Arena& arena, Value& key) final;
Result<Array> append(Arena& arena, Value& rhs);
@ -214,7 +217,7 @@ class ByteArray : public Object {
static Result<ByteArray> create(Arena& arena, String& str);
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
Result<char> operator[](uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
@ -307,9 +310,9 @@ class Dict : public Object {
return Dict(TRY(MkGcRoot(pod, arena)));
}
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
Result<Value> get(Arena& arena, Value& key);
virtual Result<Value> get(Arena& arena, Value& key) final;
Result<Dict> insert(Arena& arena, Value& key, Value& value);
@ -400,7 +403,7 @@ class String : public Object {
}
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
Result<char32_t> operator[](uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
@ -493,7 +496,7 @@ class Symbol : public Object {
}
static Result<Symbol> create(Arena& arena, String& rhs);
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
uint64_t size() { return _value->size; }
@ -527,7 +530,7 @@ class Syntax : public Object {
Result<Value> get_value(Arena& arena);
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
private:
GcRoot<PodSyntax> _value;
@ -555,7 +558,7 @@ class Pair : public Object {
Result<Value> first(Arena& arena);
Result<Value> rest(Arena& arena);
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
private:
GcRoot<PodPair> _value;
@ -595,7 +598,7 @@ class Int64 : public Object {
int64_t value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
private:
GcRoot<PodInt64> _value;
@ -635,7 +638,7 @@ class Float : public Object {
double value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
private:
GcRoot<PodFloat> _value;
@ -670,7 +673,7 @@ class Bool : public Object {
bool value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) final;
virtual Result<Value> copy(Arena& arena) const final;
private:
GcRoot<PodBool> _value;
@ -731,11 +734,19 @@ class Value {
return ((Object*)buf)->cmp(arena, *(Object*)rhs.buf);
}
Result<Value> get(Arena& arena, Value& key) {
return ((Object*)buf)->get(arena, key);
}
Result<Value> get(Arena& arena, int64_t key) {
Value k = TRY(Int64::create(arena, key));
return ((Object*)buf)->get(arena, k);
}
// TODO: cmp() probably doesn't need arena parameter
// Result<bool> operator==(Value& rhs) { return TRY(cmp(rhs)) == 0; }
// Result<bool> operator!=(Value& rhs) { return TRY(cmp(rhs)) != 0; }
Result<Value> copy(Arena& arena) { return ((Object*)buf)->copy(arena); }
Result<Value> copy(Arena& arena) const { return ((Object*)buf)->copy(arena); }
private:
uint8_t buf[24];

View file

@ -33,4 +33,7 @@ TEST_CASE(dict_read) {
v = DIEX(read_one(arena, "{1 2 3 4}"));
s = DIEX(write_one(arena, v));
ASSERT_EQUALS(s, "{1 2 3 4}");
auto vv = DIEX(v.get(arena, 1));
ASSERT_EQUALS(vv, 2);
}

View file

@ -3,6 +3,7 @@
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <type_traits>
#include "common.hpp"
#include "result.hpp"
@ -42,44 +43,33 @@ bool run_tests() {
#define TEST_CASE(fun_) TEST_CASE_IMPL(MACRO_CONCAT(fun_, _COUNTER_))
template <class T>
struct Capture {
Capture(T& value) : value(value) {}
T& value;
};
template <class T>
struct Capture<T&> {
Capture(T& value) : value(value) {}
T& value;
};
template <class T>
struct Capture<T&&> {
Capture(T&& value) : value(value) {}
T value;
};
Value& to_value(Arena& arena, Value& val) { return val; }
template <class T>
requires std::derived_from<T, Object>
Value to_value(Arena& arena, T& val) {
return DIEX(val.copy(arena));
Result<Value> to_value(Arena& arena, Value& val) { return val.copy(arena); }
Result<Value> to_value(Arena& arena, const Value& val) {
return val.copy(arena);
}
template <class T>
requires(!std::derived_from<T, Object>)
Value to_value(Arena& arena, T& val) {
return DIEX(Value::create(arena, val));
requires std::derived_from<T, Object>
Result<Value> to_value(Arena& arena, T& val) {
return val.copy(arena);
}
template <class T>
requires(!std::derived_from<T, Object> && !std::is_fundamental<T>::value)
Result<Value> to_value(Arena& arena, T& val) {
return Value::create(arena, val);
}
template <class T>
requires(!std::derived_from<T, Object> && std::is_fundamental<T>::value)
Result<Value> to_value(Arena& arena, T val) {
return Value::create(arena, val);
}
#define ASSERT_EQUALS(lhs, rhs) \
do { \
auto l = Capture(lhs); \
auto r = Capture(rhs); \
auto lv = to_value(arena, l.value); \
auto rv = to_value(arena, r.value); \
auto lv = DIEX(to_value(arena, lhs)); \
auto rv = DIEX(to_value(arena, rhs)); \
short c = DIEX(lv.cmp(arena, rv)); \
if (c != 0) { \
fprintf(stderr, "Values not equal at %s:%d\n", __FILE__, __LINE__); \