Stop passing arena explicitly

This commit is contained in:
Konstantin Nazarov 2024-08-09 23:45:06 +01:00
parent b40f835bfb
commit 4c7b44ff01
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
15 changed files with 409 additions and 464 deletions

View file

@ -1,7 +1,10 @@
#include "arena.hpp"
#include "die.hpp"
#include "error.hpp"
static Arena* current_arena = 0;
GcRootBase::GcRootBase(PodObject* ptr, GcRootList* node)
: _ptr(ptr), _node(node) {}
@ -175,3 +178,11 @@ Result<PodObject*> Arena::gc_dict(PodDict* obj) {
return nobj;
// return ErrorCode::NotImplemented;
}
Arena& get_arena() {
if (current_arena == 0) die("Arena not set\n");
return *current_arena;
}
void set_arena(Arena& arena) { current_arena = &arena; }
Result<void> arena_gc() { return get_arena().gc(); }

View file

@ -13,6 +13,9 @@
class Arena;
class GcRootList;
Arena& get_arena();
void set_arena(Arena& arena);
class GcRootBase {
public:
friend class Arena;
@ -38,10 +41,8 @@ class GcRoot : public GcRootBase {
GcRoot(GcRoot&& rhs);
GcRoot& operator=(GcRoot&& rhs);
static Result<GcRoot<T>> create(T* ptr, Arena& arena);
Result<GcRoot<T>> copy(Arena& arena) const {
return GcRoot<T>::create((T*)_ptr, arena);
}
static Result<GcRoot<T>> create(T* ptr);
Result<GcRoot<T>> copy() const { return GcRoot<T>::create((T*)_ptr); }
T* get() { return (T*)_ptr; }
T& operator*() { return *(T*)_ptr; }
@ -50,8 +51,8 @@ class GcRoot : public GcRootBase {
template <class T>
requires std::derived_from<T, PodObject>
Result<GcRoot<T>> MkGcRoot(T* ptr, Arena& arena) {
return GcRoot<T>::create(ptr, arena);
Result<GcRoot<T>> MkGcRoot(T* ptr) {
return GcRoot<T>::create(ptr);
}
class GcRootList {
@ -184,17 +185,24 @@ class StaticArenaHeap : public ArenaHeap {
template <uint64_t size>
class StaticArena : public Arena {
public:
StaticArena() : Arena(&_heaps[0], &_heaps[1]) {}
StaticArena() : Arena(&_heaps[0], &_heaps[1]) { set_arena(*this); }
private:
StaticArenaHeap<(size - sizeof(Arena)) / 2> _heaps[2];
};
template <class T>
Result<T*> arena_alloc(uint64_t extra = 0) {
return get_arena().alloc<T>(extra);
}
Result<void> arena_gc();
template <class T>
requires std::derived_from<T, PodObject>
Result<GcRoot<T>> GcRoot<T>::create(T* ptr, Arena& arena) {
auto lst = TRY(arena.alloc<GcRootList>());
arena.add_root(lst);
Result<GcRoot<T>> GcRoot<T>::create(T* ptr) {
auto lst = TRY(arena_alloc<GcRootList>());
get_arena().add_root(lst);
return std::move(GcRoot<T>(ptr, lst));
}

View file

@ -8,56 +8,56 @@
Syntax::Syntax(String filename, String modulename, Value expression) {}
Result<Value> Syntax::get_value(Arena& arena) {
return Value::create(arena, _value->expression.get());
Result<Value> Syntax::get_value() {
return Value::create(_value->expression.get());
}
Result<Value> Value::create(Arena& arena, PodObject* obj) {
Result<Value> Value::create(PodObject* obj) {
switch (obj->header.tag) {
case Tag::Nil:
return Value(TRY(Nil::create(arena, (PodNil*)obj)));
return Value(TRY(Nil::create((PodNil*)obj)));
case Tag::Int64:
return Value(TRY(Int64::create(arena, (PodInt64*)obj)));
return Value(TRY(Int64::create((PodInt64*)obj)));
case Tag::Float:
return Value(TRY(Float::create(arena, (PodFloat*)obj)));
return Value(TRY(Float::create((PodFloat*)obj)));
case Tag::Bool:
return Value(TRY(Bool::create(arena, (PodBool*)obj)));
return Value(TRY(Bool::create((PodBool*)obj)));
case Tag::Array:
return Value(TRY(Array::create(arena, (PodArray*)obj)));
return Value(TRY(Array::create((PodArray*)obj)));
case Tag::ByteArray:
return Value(TRY(ByteArray::create(arena, (PodByteArray*)obj)));
return Value(TRY(ByteArray::create((PodByteArray*)obj)));
case Tag::Dict:
return Value(TRY(Dict::create(arena, (PodDict*)obj)));
return Value(TRY(Dict::create((PodDict*)obj)));
case Tag::String:
return Value(TRY(String::create(arena, (PodString*)obj)));
return Value(TRY(String::create((PodString*)obj)));
case Tag::Symbol:
return Value(TRY(Symbol::create(arena, (PodSymbol*)obj)));
return Value(TRY(Symbol::create((PodSymbol*)obj)));
case Tag::Syntax:
return Value(TRY(Syntax::create(arena, (PodSyntax*)obj)));
return Value(TRY(Syntax::create((PodSyntax*)obj)));
case Tag::Pair:
return Value(TRY(Pair::create(arena, (PodPair*)obj)));
return Value(TRY(Pair::create((PodPair*)obj)));
};
return Value();
}
Result<Symbol> Symbol::create(Arena& arena, String& rhs) {
Result<Symbol> Symbol::create(String& rhs) {
uint64_t rhs_size = rhs.size();
uint64_t res_size = rhs_size;
auto pod = TRY(arena.alloc<PodSymbol>(res_size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodSymbol>(res_size * sizeof(char32_t)));
pod->header.tag = Tag::Symbol;
pod->size = res_size;
memcpy(pod->data, rhs._value->data, sizeof(char32_t) * rhs_size);
return Symbol(TRY(MkGcRoot(pod, arena)));
return Symbol(TRY(MkGcRoot(pod)));
}
Result<ByteArray> ByteArray::create(Arena& arena, String& str) {
Result<ByteArray> ByteArray::create(String& str) {
uint64_t size = 0;
for (uint64_t i = 0; i < str.size(); i++) {
size += utf8_codepoint_size(TRY(str[i]));
}
auto pod = TRY(arena.alloc<PodByteArray>(size * sizeof(char)));
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char)));
pod->header.tag = Tag::ByteArray;
pod->size = size;
@ -68,94 +68,76 @@ Result<ByteArray> ByteArray::create(Arena& arena, String& str) {
res = utf8_write_codepoint(res, codepoint);
}
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
Result<Value> syntax_unwrap(Arena& arena, Value& val) {
Result<Value> syntax_unwrap(Value& val) {
Syntax* syntax = val.to<Syntax>();
if (syntax == 0) return val.copy(arena);
if (syntax == 0) return val.copy();
return syntax->get_value(arena);
return syntax->get_value();
}
Result<Value> Nil::copy(Arena& arena) const { return Value(Nil()); }
Result<Value> Nil::copy() const { return Value(Nil()); }
Result<Value> Int64::copy(Arena& arena) const {
return Value(Int64(TRY(_value.copy(arena))));
}
Result<Value> Float::copy(Arena& arena) const {
return Value(Float(TRY(_value.copy(arena))));
Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy()))); }
Result<Value> Float::copy() const { return Value(Float(TRY(_value.copy()))); }
Result<Value> Array::copy() const { return Value(Array(TRY(_value.copy()))); }
Result<Value> ByteArray::copy() const {
return Value(ByteArray(TRY(_value.copy())));
}
Result<Value> Array::copy(Arena& arena) const {
return Value(Array(TRY(_value.copy(arena))));
}
Result<Value> Dict::copy() const { return Value(Dict(TRY(_value.copy()))); }
Result<Value> ByteArray::copy(Arena& arena) const {
return Value(ByteArray(TRY(_value.copy(arena))));
}
Result<Value> String::copy() const { return Value(String(TRY(_value.copy()))); }
Result<Value> Dict::copy(Arena& arena) const {
return Value(Dict(TRY(_value.copy(arena))));
}
Result<Value> Symbol::copy() const { return Value(Symbol(TRY(_value.copy()))); }
Result<Value> String::copy(Arena& arena) const {
return Value(String(TRY(_value.copy(arena))));
}
Result<Value> Syntax::copy() const { return Value(Syntax(TRY(_value.copy()))); }
Result<Value> Symbol::copy(Arena& arena) const {
return Value(Symbol(TRY(_value.copy(arena))));
}
Result<Value> Pair::copy() const { return Value(Pair(TRY(_value.copy()))); }
Result<Value> Syntax::copy(Arena& arena) const {
return Value(Syntax(TRY(_value.copy(arena))));
}
Result<Value> Bool::copy() const { return Value(Bool(TRY(_value.copy()))); }
Result<Value> Pair::copy(Arena& arena) const {
return Value(Pair(TRY(_value.copy(arena))));
}
Result<Value> Bool::copy(Arena& arena) const {
return Value(Bool(TRY(_value.copy(arena))));
}
Result<Pair> Pair::create(Arena& arena, Value& first, Value& rest) {
auto pod = TRY(arena.alloc<PodPair>());
Result<Pair> Pair::create(Value& first, Value& rest) {
auto pod = TRY(arena_alloc<PodPair>());
pod->header.tag = Tag::Pair;
pod->first = first.pod();
pod->rest = rest.pod();
return Pair(TRY(MkGcRoot(pod, arena)));
return Pair(TRY(MkGcRoot(pod)));
}
Result<Value> Pair::first(Arena& arena) {
Result<Value> Pair::first() {
auto val = _value->first.get();
return Value::create(arena, val);
return Value::create(val);
}
Result<Value> Pair::rest(Arena& arena) {
Result<Value> Pair::rest() {
auto val = _value->rest.get();
return Value::create(arena, val);
return Value::create(val);
}
Result<Value> reverse(Arena& arena, Value& val) {
Result<Value> reverse(Value& val) {
if (!val.is<Pair>()) return ErrorCode::TypeMismatch;
auto res = Value(TRY(Nil::create(arena)));
auto cur = TRY(val.copy(arena));
auto res = Value(TRY(Nil::create()));
auto cur = TRY(val.copy());
while (!cur.is<Nil>()) {
if (!cur.is<Pair>()) return ErrorCode::TypeMismatch;
Pair& pair = *cur.to<Pair>();
Value first = TRY(pair.first(arena));
cur = TRY(pair.rest(arena));
res = TRY(Pair::create(arena, first, res));
Value first = TRY(pair.first());
cur = TRY(pair.rest());
res = TRY(Pair::create(first, res));
}
return res;
}
Result<void> debug_print(Arena& arena, String& val) {
auto ba = TRY(ByteArray::create(arena, val));
Result<void> debug_print(String& val) {
auto ba = TRY(ByteArray::create(val));
for (uint64_t i = 0; i < ba.size(); i++) {
std::cout << TRY(ba[i]);
@ -164,27 +146,27 @@ Result<void> debug_print(Arena& arena, String& val) {
return Result<void>();
}
Result<void> debug_print(Arena& arena, Value& val) {
auto w = Writer(arena);
Result<void> debug_print(Value& val) {
auto w = Writer();
auto s = TRY(w.write_one(val));
return debug_print(arena, s);
return debug_print(s);
}
Result<Value> Array::get(Arena& arena, uint64_t idx) {
Result<Value> Array::get(uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
auto val = _value->data[idx].get();
return Value::create(arena, val);
return Value::create(val);
}
Result<Value> Array::get(Arena& arena, Value& key) {
Result<Value> Array::get(Value& key) {
if (!key.is<Int64>()) return ErrorCode::TypeMismatch;
return get(arena, key.to<Int64>()->value());
return get(key.to<Int64>()->value());
}
Result<Array> Array::append(Arena& arena, Value& rhs) {
Result<Array> Array::append(Value& rhs) {
uint64_t res_size = size() + 1;
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(OffPtr<PodObject>)));
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(OffPtr<PodObject>)));
pod->header.tag = Tag::Array;
pod->size = res_size;
for (uint64_t i = 0; i < size(); i++) {
@ -192,7 +174,7 @@ Result<Array> Array::append(Arena& arena, Value& rhs) {
}
pod->data[size()] = rhs.pod();
return Array(TRY(MkGcRoot(pod, arena)));
return Array(TRY(MkGcRoot(pod)));
}
short cmp_tag(Tag lhs, Tag rhs) {
@ -201,29 +183,29 @@ short cmp_tag(Tag lhs, Tag rhs) {
return 0;
}
Result<Value> Dict::get(Arena& arena, Value& key) {
auto pos = TRY(find(arena, key));
Result<Value> Dict::get(Value& key) {
auto pos = TRY(find(key));
if (pos > size()) return ErrorCode::KeyError;
auto k = TRY(Value::create(arena, _value->data[pos * 2].get()));
auto k = TRY(Value::create(_value->data[pos * 2].get()));
if (TRY(k.cmp(arena, key)) != 0) {
if (TRY(k.cmp(key)) != 0) {
return ErrorCode::KeyError;
}
return TRY(Value::create(arena, _value->data[pos * 2 + 1].get()));
return TRY(Value::create(_value->data[pos * 2 + 1].get()));
}
Result<Dict> Dict::insert(Arena& arena, Value& key, Value& value) {
auto pos = TRY(find(arena, key));
Result<Dict> Dict::insert(Value& key, Value& value) {
auto pos = TRY(find(key));
auto s = size();
if (pos >= s) {
s += 1;
} else {
auto k = TRY(Value::create(arena, _value->data[pos * 2].get()));
if (TRY(k.cmp(arena, key)) != 0) s += 1;
auto k = TRY(Value::create(_value->data[pos * 2].get()));
if (TRY(k.cmp(key)) != 0) s += 1;
}
auto pod = TRY(arena.alloc<PodDict>(2 * s * sizeof(OffPtr<PodObject>)));
auto pod = TRY(arena_alloc<PodDict>(2 * s * sizeof(OffPtr<PodObject>)));
pod->header.tag = Tag::Dict;
pod->size = s;
@ -243,16 +225,16 @@ Result<Dict> Dict::insert(Arena& arena, Value& key, Value& value) {
}
}
return Dict(TRY(MkGcRoot(pod, arena)));
return Dict(TRY(MkGcRoot(pod)));
}
Result<uint64_t> Dict::find(Arena& arena, Value& key) {
Result<uint64_t> Dict::find(Value& key) {
uint64_t left = 0;
uint64_t right = size();
uint64_t pos = (left + right) / 2;
while (left < right) {
auto v = TRY(Value::create(arena, _value->data[pos * 2].get()));
auto c = TRY(v.cmp(arena, key));
auto v = TRY(Value::create(_value->data[pos * 2].get()));
auto c = TRY(v.cmp(key));
if (c == 0) {
return pos;
}
@ -267,17 +249,17 @@ Result<uint64_t> Dict::find(Arena& arena, Value& key) {
return left;
}
Result<short> Int64::cmp(Arena&, Float& rhs) {
Result<short> Int64::cmp(Float& rhs) {
return (_value->value > rhs._value->value) -
(_value->value < rhs._value->value);
}
Result<short> Float::cmp(Arena&, Int64& rhs) {
Result<short> Float::cmp(Int64& rhs) {
return (_value->value > rhs._value->value) -
(_value->value < rhs._value->value);
}
Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
Result<short> Dict::cmp(Dict& rhs) {
auto lsize = size() * 2;
auto rsize = rhs.size() * 2;
uint64_t i = 0;
@ -288,9 +270,9 @@ Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
short cmp = short(i == lsize) - short(j == rsize);
if (cmp != 0) return cmp;
Value lc = TRY(Value::create(arena, _value->data[i].get()));
Value rc = TRY(Value::create(arena, rhs._value->data[j].get()));
cmp = TRY(lc.cmp(arena, rc));
Value lc = TRY(Value::create(_value->data[i].get()));
Value rc = TRY(Value::create(rhs._value->data[j].get()));
cmp = TRY(lc.cmp(rc));
if (cmp != 0) return cmp;
i++;
j++;
@ -298,6 +280,4 @@ Result<short> Dict::cmp(Arena& arena, Dict& rhs) {
return 0;
}
Result<Value> Object::get(Arena& arena, Value& key) {
return ErrorCode::TypeMismatch;
}
Result<Value> Object::get(Value& key) { return ErrorCode::TypeMismatch; }

View file

@ -31,37 +31,25 @@ short cmp_tag(Tag lhs, Tag rhs);
class Object {
public:
virtual Tag tag() = 0;
virtual Result<Value> copy(Arena& arena) const = 0;
virtual Result<Value> copy() const = 0;
virtual PodObject* pod() = 0;
virtual void move(Object*) = 0;
virtual ~Object() = default;
virtual Result<short> cmp(Arena&, Object&) = 0;
virtual Result<short> cmp(Arena&, Nil&) { return cmp_tag(tag(), Tag::Nil); }
virtual Result<short> cmp(Arena&, Int64&) {
return cmp_tag(tag(), Tag::Int64);
}
virtual Result<short> cmp(Arena&, Float&) {
return cmp_tag(tag(), Tag::Float);
}
virtual Result<short> cmp(Arena&, Bool&) { return cmp_tag(tag(), Tag::Bool); }
virtual Result<short> cmp(Arena&, String&) {
return cmp_tag(tag(), Tag::String);
}
virtual Result<short> cmp(Arena&, Symbol&) {
return cmp_tag(tag(), Tag::Symbol);
}
virtual Result<short> cmp(Arena&, Syntax&) {
return cmp_tag(tag(), Tag::Syntax);
}
virtual Result<short> cmp(Arena&, Pair&) { return cmp_tag(tag(), Tag::Pair); }
virtual Result<short> cmp(Arena&, Array&) {
return cmp_tag(tag(), Tag::Array);
}
virtual Result<short> cmp(Arena&, ByteArray&) {
virtual Result<short> cmp(Object&) = 0;
virtual Result<short> cmp(Nil&) { return cmp_tag(tag(), Tag::Nil); }
virtual Result<short> cmp(Int64&) { return cmp_tag(tag(), Tag::Int64); }
virtual Result<short> cmp(Float&) { return cmp_tag(tag(), Tag::Float); }
virtual Result<short> cmp(Bool&) { return cmp_tag(tag(), Tag::Bool); }
virtual Result<short> cmp(String&) { return cmp_tag(tag(), Tag::String); }
virtual Result<short> cmp(Symbol&) { return cmp_tag(tag(), Tag::Symbol); }
virtual Result<short> cmp(Syntax&) { return cmp_tag(tag(), Tag::Syntax); }
virtual Result<short> cmp(Pair&) { return cmp_tag(tag(), Tag::Pair); }
virtual Result<short> cmp(Array&) { return cmp_tag(tag(), Tag::Array); }
virtual Result<short> cmp(ByteArray&) {
return cmp_tag(tag(), Tag::ByteArray);
}
virtual Result<Value> get(Arena& arena, Value& key);
virtual Result<Value> get(Value& key);
Object() = default;
Object(const Object&) = delete;
@ -76,23 +64,19 @@ class Nil : public Object {
virtual Tag tag() final { return Tag::Nil; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Nil& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Nil& rhs) final { return 0; }
static Result<Nil> create(Arena& arena, PodNil* obj) {
return Nil(TRY(MkGcRoot(obj, arena)));
}
static Result<Nil> create(PodNil* obj) { return Nil(TRY(MkGcRoot(obj))); }
static Result<Nil> create(Arena& arena) {
auto pod = TRY(arena.alloc<PodNil>());
static Result<Nil> create() {
auto pod = TRY(arena_alloc<PodNil>());
pod->header.tag = Tag::Nil;
return Nil(TRY(MkGcRoot(pod, arena)));
return Nil(TRY(MkGcRoot(pod)));
}
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
virtual void move(Object* obj) final { new (obj) Nil(std::move(_value)); }
@ -113,42 +97,40 @@ class Array : public Object {
virtual Tag tag() final { return Tag::Array; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Array& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Array& rhs) final { return 0; }
virtual void move(Object* obj) final { new (obj) Array(std::move(_value)); }
static Result<Array> create(Arena& arena, PodArray* obj) {
return Array(TRY(MkGcRoot(obj, arena)));
static Result<Array> create(PodArray* obj) {
return Array(TRY(MkGcRoot(obj)));
}
static Result<Array> create(Arena& arena) {
auto pod = TRY(arena.alloc<PodArray>());
static Result<Array> create() {
auto pod = TRY(arena_alloc<PodArray>());
pod->header.tag = Tag::Array;
pod->size = 0;
return Array(TRY(MkGcRoot(pod, arena)));
return Array(TRY(MkGcRoot(pod)));
}
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
Result<Value> get(Arena& arena, uint64_t idx);
virtual Result<Value> get(Arena& arena, Value& key) final;
Result<Value> get(uint64_t idx);
virtual Result<Value> get(Value& key) final;
Result<Array> append(Arena& arena, Value& rhs);
Result<Array> append(Value& rhs);
template <class V>
Result<Array> append(Arena& arena, const V& value);
Result<Array> append(const V& value);
Result<Array> concat(Arena& arena, Array& rhs) {
Result<Array> concat(Array& rhs) {
uint64_t rhs_size = rhs.size();
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
pod->size = res_size;
for (uint64_t i = 0; i < size(); i++) {
pod->data[i] = _value->data[i];
@ -157,19 +139,19 @@ class Array : public Object {
pod->data[i] = rhs._value->data[i];
}
return Array(TRY(MkGcRoot(pod, arena)));
return Array(TRY(MkGcRoot(pod)));
}
Result<Array> sub(Arena& arena, uint64_t start, uint64_t end) {
Result<Array> sub(uint64_t start, uint64_t end) {
if (start > end) return ErrorCode::IndexOutOfRange;
uint64_t res_size = end - start;
auto pod = TRY(arena.alloc<PodArray>(res_size * sizeof(PodObject*)));
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
pod->size = res_size;
for (uint64_t i = 0; i < end - start; i++) {
pod->data[i] = _value->data[start + i];
}
return Array(TRY(MkGcRoot(pod, arena)));
return Array(TRY(MkGcRoot(pod)));
}
private:
@ -189,95 +171,93 @@ class ByteArray : public Object {
virtual Tag tag() final { return Tag::ByteArray; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, ByteArray& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(ByteArray& rhs) final { return 0; }
virtual void move(Object* obj) final {
new (obj) ByteArray(std::move(_value));
}
static Result<ByteArray> create(Arena& arena, PodByteArray* obj) {
return ByteArray(TRY(MkGcRoot(obj, arena)));
static Result<ByteArray> create(PodByteArray* obj) {
return ByteArray(TRY(MkGcRoot(obj)));
}
static Result<ByteArray> create(Arena& arena, char* chars, int64_t size) {
auto pod = TRY(arena.alloc<PodByteArray>(size * sizeof(char)));
static Result<ByteArray> create(char* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char)));
pod->header.tag = Tag::ByteArray;
memcpy(pod->data, chars, size * sizeof(char32_t));
pod->size = size;
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
static Result<ByteArray> create(Arena& arena, const char* str) {
static Result<ByteArray> create(const char* str) {
uint64_t size = strlen(str);
auto pod = TRY(arena.alloc<PodByteArray>(size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char32_t)));
pod->header.tag = Tag::ByteArray;
memcpy(pod->data, str, size);
pod->size = size;
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
static Result<ByteArray> create(Arena& arena, String& str);
static Result<ByteArray> create(String& str);
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
Result<char> operator[](uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
return _value->data[idx];
}
Result<ByteArray> concat(Arena& arena, const char* rhs) {
Result<ByteArray> concat(const char* rhs) {
uint64_t rhs_size = strlen(rhs);
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodByteArray>(res_size * sizeof(char)));
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
memcpy(pod->data, rhs + lhs_size, sizeof(char) * rhs_size);
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
Result<ByteArray> concat(Arena& arena, const char* rhs, uint64_t rhs_size) {
Result<ByteArray> concat(const char* rhs, uint64_t rhs_size) {
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodByteArray>(res_size * sizeof(char)));
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
memcpy(pod->data, rhs + lhs_size, sizeof(char) * rhs_size);
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
Result<ByteArray> concat(Arena& arena, ByteArray& rhs) {
Result<ByteArray> concat(ByteArray& rhs) {
uint64_t rhs_size = rhs.size();
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodByteArray>(res_size * sizeof(char)));
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char) * rhs_size);
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
Result<ByteArray> sub(Arena& arena, uint64_t start, uint64_t end) {
Result<ByteArray> sub(uint64_t start, uint64_t end) {
if (start > end) return ErrorCode::IndexOutOfRange;
uint64_t res_size = end - start;
auto pod = TRY(arena.alloc<PodByteArray>(res_size * sizeof(char)));
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
pod->size = res_size;
memcpy(pod->data, _value->data + start, sizeof(char) * res_size);
return ByteArray(TRY(MkGcRoot(pod, arena)));
return ByteArray(TRY(MkGcRoot(pod)));
}
private:
@ -298,41 +278,37 @@ class Dict : public Object {
virtual Tag tag() final { return Tag::Dict; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Dict& rhs) final;
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Dict& rhs) final;
virtual void move(Object* obj) final { new (obj) Dict(std::move(_value)); }
static Result<Dict> create(Arena& arena, PodDict* obj) {
return Dict(TRY(MkGcRoot(obj, arena)));
}
static Result<Dict> create(PodDict* obj) { return Dict(TRY(MkGcRoot(obj))); }
static Result<Dict> create(Arena& arena) {
auto pod = TRY(arena.alloc<PodDict>());
static Result<Dict> create() {
auto pod = TRY(arena_alloc<PodDict>());
pod->header.tag = Tag::Dict;
pod->size = 0;
return Dict(TRY(MkGcRoot(pod, arena)));
return Dict(TRY(MkGcRoot(pod)));
}
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
virtual Result<Value> get(Arena& arena, Value& key) final;
virtual Result<Value> get(Value& key) final;
Result<Dict> insert(Arena& arena, Value& key, Value& value);
Result<Dict> insert(Value& key, Value& value);
template <class K, class V>
Result<Dict> insert(Arena& arena, const K& key, const V& value);
Result<Dict> insert(const K& key, const V& value);
Result<Dict> concat(Arena& arena, Dict& rhs) {
Result<Dict> concat(Dict& rhs) {
uint64_t rhs_size = rhs.size();
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
auto pod = TRY(arena_alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
pod->size = res_size;
for (uint64_t i = 0; i < 2 * size(); i++) {
@ -342,11 +318,11 @@ class Dict : public Object {
pod->data[i] = rhs._value->data[i];
}
return Dict(TRY(MkGcRoot(pod, arena)));
return Dict(TRY(MkGcRoot(pod)));
}
private:
Result<uint64_t> find(Arena& arena, Value& key);
Result<uint64_t> find(Value& key);
uint64_t size() { return _value->size; }
GcRoot<PodDict> _value;
@ -365,10 +341,8 @@ class String : public Object {
virtual Tag tag() final { return Tag::String; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, String& rhs) final {
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(String& rhs) final {
auto lsize = size();
auto rsize = rhs.size();
uint64_t i = 0;
@ -391,88 +365,88 @@ class String : public Object {
virtual void move(Object* obj) final { new (obj) String(std::move(_value)); }
static Result<String> create(Arena& arena, PodString* obj) {
return String(TRY(MkGcRoot(obj, arena)));
static Result<String> create(PodString* obj) {
return String(TRY(MkGcRoot(obj)));
}
static Result<String> create(Arena& arena, char32_t* chars, int64_t size) {
auto pod = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
static Result<String> create(char32_t* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodString>(size * sizeof(char32_t)));
pod->header.tag = Tag::String;
memcpy(pod->data, chars, size * sizeof(char32_t));
pod->size = size;
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
static Result<String> create(Arena& arena, const char* str) {
static Result<String> create(const char* str) {
uint64_t size = strlen(str);
auto pod = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodString>(size * sizeof(char32_t)));
pod->header.tag = Tag::String;
for (uint64_t i = 0; i < size; i++) pod->data[i] = str[i];
pod->size = size;
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
uint64_t size() { return _value->size; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
Result<char32_t> operator[](uint64_t idx) {
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
return _value->data[idx];
}
Result<String> concat(Arena& arena, const char* rhs) {
Result<String> concat(const char* rhs) {
uint64_t rhs_size = strlen(rhs);
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodString>(res_size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
pod->header.tag = Tag::String;
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
for (uint64_t i = 0; i < rhs_size; i++) pod->data[lhs_size + i] = rhs[i];
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
Result<String> concat(Arena& arena, const char32_t* rhs, uint64_t rhs_size) {
Result<String> concat(const char32_t* rhs, uint64_t rhs_size) {
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodString>(res_size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
pod->header.tag = Tag::String;
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
for (uint64_t i = 0; i < rhs_size; i++) pod->data[lhs_size + i] = rhs[i];
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
Result<String> concat(Arena& arena, String& rhs) {
Result<String> concat(String& rhs) {
uint64_t rhs_size = rhs.size();
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
auto pod = TRY(arena.alloc<PodString>(res_size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
pod->header.tag = Tag::String;
pod->size = res_size;
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char32_t) * rhs_size);
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
Result<String> sub(Arena& arena, uint64_t start, uint64_t end) {
Result<String> sub(uint64_t start, uint64_t end) {
if (start > end) return ErrorCode::IndexOutOfRange;
uint64_t res_size = end - start;
auto pod = TRY(arena.alloc<PodString>(res_size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
pod->header.tag = Tag::String;
pod->size = res_size;
memcpy(pod->data, _value->data + start, sizeof(char32_t) * res_size);
return String(TRY(MkGcRoot(pod, arena)));
return String(TRY(MkGcRoot(pod)));
}
friend class Symbol;
@ -488,10 +462,8 @@ class Symbol : public Object {
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Symbol; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Symbol& rhs) final {
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Symbol& rhs) final {
auto lsize = size();
auto rsize = rhs.size();
uint64_t i = 0;
@ -513,32 +485,32 @@ class Symbol : public Object {
}
virtual void move(Object* obj) final { new (obj) Symbol(std::move(_value)); }
static Result<Symbol> create(Arena& arena, PodSymbol* obj) {
return Symbol(TRY(MkGcRoot(obj, arena)));
static Result<Symbol> create(PodSymbol* obj) {
return Symbol(TRY(MkGcRoot(obj)));
}
static Result<Symbol> create(Arena& arena, char32_t* chars, int64_t size) {
auto pod = TRY(arena.alloc<PodSymbol>(size * sizeof(char32_t)));
static Result<Symbol> create(char32_t* chars, int64_t size) {
auto pod = TRY(arena_alloc<PodSymbol>(size * sizeof(char32_t)));
pod->header.tag = Tag::Symbol;
memcpy(pod->data, chars, size * sizeof(char32_t));
return Symbol(TRY(MkGcRoot(pod, arena)));
return Symbol(TRY(MkGcRoot(pod)));
}
static Result<Symbol> create(Arena& arena, const char* str) {
static Result<Symbol> create(const char* str) {
uint64_t size = strlen(str);
auto pod = TRY(arena.alloc<PodSymbol>(size * sizeof(char32_t)));
auto pod = TRY(arena_alloc<PodSymbol>(size * sizeof(char32_t)));
pod->header.tag = Tag::Symbol;
for (uint64_t i = 0; i < size; i++) pod->data[i] = str[i];
pod->size = size;
return Symbol(TRY(MkGcRoot(pod, arena)));
return Symbol(TRY(MkGcRoot(pod)));
}
static Result<Symbol> create(Arena& arena, String& rhs);
virtual Result<Value> copy(Arena& arena) const final;
static Result<Symbol> create(String& rhs);
virtual Result<Value> copy() const final;
uint64_t size() { return _value->size; }
@ -559,20 +531,18 @@ class Syntax : public Object {
Syntax(String filename, String modulename, Value expression);
virtual Tag tag() final { return Tag::Syntax; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Syntax& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Syntax& rhs) final { return 0; }
virtual void move(Object* obj) final { new (obj) Syntax(std::move(_value)); }
static Result<Syntax> create(Arena& arena, PodSyntax* obj) {
return Syntax(TRY(MkGcRoot(obj, arena)));
static Result<Syntax> create(PodSyntax* obj) {
return Syntax(TRY(MkGcRoot(obj)));
}
Result<Value> get_value(Arena& arena);
Result<Value> get_value();
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
private:
GcRoot<PodSyntax> _value;
@ -585,22 +555,18 @@ class Pair : public Object {
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Pair; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Pair& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Pair& rhs) final { return 0; }
virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); }
static Result<Pair> create(Arena& arena, PodPair* obj) {
return Pair(TRY(MkGcRoot(obj, arena)));
}
static Result<Pair> create(Arena& arena, Value& first, Value& rest);
static Result<Pair> create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); }
static Result<Pair> create(Value& first, Value& rest);
Result<Value> first(Arena& arena);
Result<Value> rest(Arena& arena);
Result<Value> first();
Result<Value> rest();
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
private:
GcRoot<PodPair> _value;
@ -615,32 +581,30 @@ class Int64 : public Object {
Int64(GcRoot<PodInt64>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Int64; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Int64& rhs) final {
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Int64& rhs) final {
return (_value->value > rhs._value->value) -
(_value->value < rhs._value->value);
}
virtual Result<short> cmp(Arena&, Float& rhs) final;
virtual Result<short> cmp(Float& rhs) final;
virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); }
static Result<Int64> create(Arena& arena, PodInt64* obj) {
return Int64(TRY(MkGcRoot(obj, arena)));
static Result<Int64> create(PodInt64* obj) {
return Int64(TRY(MkGcRoot(obj)));
}
static Result<Int64> create(Arena& arena, double val) {
auto pod = TRY(arena.alloc<PodInt64>());
static Result<Int64> create(double val) {
auto pod = TRY(arena_alloc<PodInt64>());
pod->header.tag = Tag::Int64;
pod->value = val;
return Int64(TRY(MkGcRoot(pod, arena)));
return Int64(TRY(MkGcRoot(pod)));
}
int64_t value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
private:
GcRoot<PodInt64> _value;
@ -655,32 +619,30 @@ class Float : public Object {
Float(GcRoot<PodFloat>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Float; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Float& rhs) final {
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Float& rhs) final {
return (_value->value > rhs._value->value) -
(_value->value < rhs._value->value);
}
virtual Result<short> cmp(Arena&, Int64& rhs) final;
virtual Result<short> cmp(Int64& rhs) final;
virtual void move(Object* obj) final { new (obj) Float(std::move(_value)); }
static Result<Float> create(Arena& arena, PodFloat* obj) {
return Float(TRY(MkGcRoot(obj, arena)));
static Result<Float> create(PodFloat* obj) {
return Float(TRY(MkGcRoot(obj)));
}
static Result<Float> create(Arena& arena, double val) {
auto pod = TRY(arena.alloc<PodFloat>());
static Result<Float> create(double val) {
auto pod = TRY(arena_alloc<PodFloat>());
pod->header.tag = Tag::Float;
pod->value = val;
return Float(TRY(MkGcRoot(pod, arena)));
return Float(TRY(MkGcRoot(pod)));
}
double value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
private:
GcRoot<PodFloat> _value;
@ -694,28 +656,24 @@ class Bool : public Object {
virtual Tag tag() final { return Tag::Bool; }
virtual PodObject* pod() final { return _value.get(); }
virtual Result<short> cmp(Arena& arena, Object& rhs) final {
return -TRY(rhs.cmp(arena, *this));
}
virtual Result<short> cmp(Arena&, Bool& rhs) final { return 0; }
virtual Result<short> cmp(Object& rhs) final { return -TRY(rhs.cmp(*this)); }
virtual Result<short> cmp(Bool& rhs) final { return 0; }
virtual void move(Object* obj) final { new (obj) Bool(std::move(_value)); }
static Result<Bool> create(Arena& arena, PodBool* obj) {
return Bool(TRY(MkGcRoot(obj, arena)));
}
static Result<Bool> create(PodBool* obj) { return Bool(TRY(MkGcRoot(obj))); }
static Result<Bool> create(Arena& arena, bool val) {
auto pod = TRY(arena.alloc<PodBool>());
static Result<Bool> create(bool val) {
auto pod = TRY(arena_alloc<PodBool>());
pod->header.tag = Tag::Bool;
pod->value = val;
return Bool(TRY(MkGcRoot(pod, arena)));
return Bool(TRY(MkGcRoot(pod)));
}
bool value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) const final;
virtual Result<Value> copy() const final;
private:
GcRoot<PodBool> _value;
@ -746,14 +704,14 @@ class Value {
return *this;
}
static Result<Value> create(Arena& arena, PodObject* obj);
static Result<Value> create(PodObject* obj);
static Result<Value> create(Arena& arena, const int64_t& value) {
return Value(TRY(Int64::create(arena, value)));
static Result<Value> create(const int64_t& value) {
return Value(TRY(Int64::create(value)));
}
static Result<Value> create(Arena& arena, const char* value) {
return Value(TRY(String::create(arena, value)));
static Result<Value> create(const char* value) {
return Value(TRY(String::create(value)));
}
template <class T>
@ -772,23 +730,21 @@ class Value {
Object& operator*() { return *(Object*)(buf); }
Object* operator->() { return (Object*)(buf); }
Result<short> cmp(Arena& arena, Value& rhs) {
return ((Object*)buf)->cmp(arena, *(Object*)rhs.buf);
Result<short> cmp(Value& rhs) {
return ((Object*)buf)->cmp(*(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);
Result<Value> get(Value& key) { return ((Object*)buf)->get(key); }
Result<Value> get(int64_t key) {
Value k = TRY(Int64::create(key));
return ((Object*)buf)->get(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) const { return ((Object*)buf)->copy(arena); }
Result<Value> copy() const { return ((Object*)buf)->copy(); }
private:
uint8_t buf[24];
@ -796,21 +752,21 @@ class Value {
Result<Value> syntax_unwrap(Value& val);
Result<Value> reverse(Arena& arena, Value& val);
Result<Value> reverse(Value& val);
Result<void> debug_print(Arena& arena, String& val);
Result<void> debug_print(Arena& arena, Value& val);
Result<void> debug_print(String& val);
Result<void> debug_print(Value& val);
template <class K, class V>
Result<Dict> Dict::insert(Arena& arena, const K& key, const V& value) {
Value k = TRY(Value::create(arena, key));
Value v = TRY(Value::create(arena, value));
Result<Dict> Dict::insert(const K& key, const V& value) {
Value k = TRY(Value::create(key));
Value v = TRY(Value::create(value));
return insert(arena, k, v);
return insert(k, v);
}
template <class V>
Result<Array> Array::append(Arena& arena, const V& value) {
Value v = TRY(Value::create(arena, value));
return append(arena, v);
Result<Array> Array::append(const V& value) {
Value v = TRY(Value::create(value));
return append(v);
}

View file

@ -8,9 +8,9 @@ struct Context {
maxreg(0),
maxconst(0) {}
static Result<Context> create(Arena& arena) {
auto env = TRY(Nil::create(arena));
auto constants = TRY(Array::create(arena));
static Result<Context> create() {
auto env = TRY(Nil::create());
auto constants = TRY(Array::create());
return Context(std::move(env), std::move(constants));
}
@ -27,7 +27,7 @@ bool is_primitive_op(Symbol& sym) {
}
Result<Value> Compiler::compile(Value& expr) {
auto context = TRY(Context::create(_arena));
auto context = TRY(Context::create());
TRY(compile_expr(context, expr));
return ErrorCode::NotImplemented;
@ -52,7 +52,7 @@ Result<Expression> Compiler::compile_expr(Context& context, Value& expr) {
}
Result<Expression> Compiler::compile_list(Context& context, Pair& expr) {
auto first = TRY(expr.first(_arena));
auto first = TRY(expr.first());
if (first.is<Symbol>()) {
Symbol& sym = *first.to<Symbol>();

View file

@ -13,12 +13,9 @@ struct Expression {
class Compiler {
public:
Compiler(Arena& arena) : _arena(arena) {}
Compiler() {}
Result<Value> compile(Value& expr);
Result<Expression> compile_expr(Context& context, Value& expr);
Result<Expression> compile_list(Context& context, Pair& expr);
private:
Arena& _arena;
};

View file

@ -73,16 +73,16 @@ Result<Value> Reader::read_one() {
}
Result<Value> Reader::read_multiple() {
Value res = TRY(Nil::create(_arena));
Value res = TRY(Nil::create());
while (1) {
forward_whitespace();
if (is_eof()) {
return reverse(_arena, res);
return reverse(res);
}
auto val = TRY(read_one());
res = Value(TRY(Pair::create(_arena, val, res)));
res = Value(TRY(Pair::create(val, res)));
}
return ErrorCode::ReadError;
@ -93,7 +93,7 @@ Result<Value> Reader::read_list() {
forward();
Value res = TRY(Nil::create(_arena));
Value res = TRY(Nil::create());
while (1) {
forward_whitespace();
@ -104,12 +104,12 @@ Result<Value> Reader::read_list() {
if (match(')')) {
forward();
return reverse(_arena, res);
return reverse(res);
}
auto val = TRY(read_one());
res = Value(TRY(Pair::create(_arena, val, res)));
res = Value(TRY(Pair::create(val, res)));
}
return ErrorCode::ReadError;
@ -120,7 +120,7 @@ Result<Value> Reader::read_dict() {
forward();
auto res = TRY(Dict::create(_arena));
auto res = TRY(Dict::create());
while (1) {
forward_whitespace();
@ -137,7 +137,7 @@ Result<Value> Reader::read_dict() {
auto val1 = TRY(read_one());
auto val2 = TRY(read_one());
res = TRY(res.insert(_arena, val1, val2));
res = TRY(res.insert(val1, val2));
}
return ErrorCode::ReadError;
@ -146,12 +146,12 @@ Result<Value> Reader::read_bool() {
if (match("true")) {
forward(4);
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
return Value(TRY(Bool::create(_arena, true)));
return Value(TRY(Bool::create(true)));
}
if (match("false")) {
forward(5);
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
return Value(TRY(Bool::create(_arena, false)));
return Value(TRY(Bool::create(false)));
}
return ErrorCode::ReadError;
@ -175,13 +175,13 @@ Result<Value> Reader::read_string() {
forward();
String result = TRY(String::create(_arena, ""));
String result = TRY(String::create(""));
for (size_t i = 0; i < position_.offset - start - 1; i++) {
char32_t cur = TRY(_str[start + i]);
if (cur != '\\') {
// TODO: optimize this
result = TRY(result.concat(_arena, &cur, 1));
result = TRY(result.concat(&cur, 1));
continue;
}
++i;
@ -189,32 +189,32 @@ Result<Value> Reader::read_string() {
char32_t next = TRY(_str[start + i]);
if (next == '\0') {
result = TRY(result.concat(_arena, "\0"));
result = TRY(result.concat("\0"));
continue;
}
switch (next) {
case 'b':
result = TRY(result.concat(_arena, "\b"));
result = TRY(result.concat("\b"));
continue;
case 'f':
result = TRY(result.concat(_arena, "\f"));
result = TRY(result.concat("\f"));
continue;
case 'n':
result = TRY(result.concat(_arena, "\n"));
result = TRY(result.concat("\n"));
continue;
case 'r':
result = TRY(result.concat(_arena, "\r"));
result = TRY(result.concat("\r"));
continue;
case 't':
result = TRY(result.concat(_arena, "\t"));
result = TRY(result.concat("\t"));
continue;
case 'v':
result = TRY(result.concat(_arena, "\v"));
result = TRY(result.concat("\v"));
continue;
}
result = TRY(result.concat(_arena, "\\"));
result = TRY(result.concat(_arena, &next, 1));
result = TRY(result.concat("\\"));
result = TRY(result.concat(&next, 1));
}
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
@ -274,12 +274,12 @@ Result<Value> Reader::read_number() {
buf[position_.offset - start] = '\0';
if (is_float) {
res = Value(TRY(Float::create(_arena, strtod(buf, 0))));
res = Value(TRY(Float::create(strtod(buf, 0))));
if (match("f64")) {
forward(3);
}
} else {
res = Value(TRY(Int64::create(_arena, strtoll(buf, 0, 10))));
res = Value(TRY(Int64::create(strtoll(buf, 0, 10))));
}
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
@ -296,11 +296,11 @@ Result<Value> Reader::read_symbol() {
size_t end = position_.offset;
String str = TRY(_str.sub(_arena, start, end));
String str = TRY(_str.sub(start, end));
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
return Value(TRY(Symbol::create(_arena, str)));
return Value(TRY(Symbol::create(str)));
}
char32_t Reader::get(size_t offset) {
@ -409,17 +409,17 @@ bool Reader::forward_exponent() {
return forward_decimal_number();
}
Result<Value> read_one(Arena& arena, Value& value) {
Result<Value> read_one(Value& value) {
if (!value.is<String>()) return ErrorCode::TypeMismatch;
auto r = Reader(arena, *value.to<String>());
auto r = Reader(*value.to<String>());
return r.read_one();
}
Result<Value> read_one(Arena& arena, String& value) {
auto r = Reader(arena, value);
Result<Value> read_one(String& value) {
auto r = Reader(value);
return r.read_one();
}
Result<Value> read_one(Arena& arena, const char* value) {
auto s = TRY(String::create(arena, value));
auto r = Reader(arena, s);
Result<Value> read_one(const char* value) {
auto s = TRY(String::create(value));
auto r = Reader(s);
return r.read_one();
}

View file

@ -5,7 +5,7 @@
class Reader {
public:
Reader(Arena& arena, String& str) : _arena(arena), _str(str) {}
Reader(String& str) : _str(str) {}
Result<Value> read_one();
Result<Value> read_multiple();
@ -38,11 +38,10 @@ class Reader {
bool match(const char* str);
bool match(char c);
Arena& _arena;
String& _str;
SourcePosition position_{1, 1, 0};
};
Result<Value> read_one(Arena& arena, Value& value);
Result<Value> read_one(Arena& arena, String& value);
Result<Value> read_one(Arena& arena, const char* value);
Result<Value> read_one(Value& value);
Result<Value> read_one(String& value);
Result<Value> read_one(const char* value);

View file

@ -9,19 +9,19 @@
StaticArena<64 * 1024 * 1024> arena;
int main() {
auto s = DIEX(String::create(arena, "(+ 1 2 3)"));
auto reader = Reader(arena, s);
auto s = DIEX(String::create("(+ 1 2 3)"));
auto reader = Reader(s);
auto r = DIEX(reader.read_one());
auto writer = Writer(arena);
auto writer = Writer();
auto s2 = DIEX(writer.write_one(r));
DIEX(arena.gc());
DIEX(arena_gc());
DIEX(debug_print(arena, s2));
DIEX(debug_print(s2));
Compiler c = Compiler(arena);
Compiler c = Compiler();
auto compiled = DIEX(c.compile(r));
return 0;

View file

@ -33,7 +33,7 @@ Result<String> Writer::write_int64(Int64& val) {
sprintf(tmp, "%lu", val.value());
size_t len = strlen(tmp);
return String::create(_arena, tmp);
return String::create(tmp);
}
bool needs_dot(char* str) {
@ -58,17 +58,15 @@ Result<String> Writer::write_float(Float& val) {
len += 2;
}
return String::create(_arena, tmp);
return String::create(tmp);
}
Result<String> Writer::write_nil(Nil& val) {
return String::create(_arena, "nil");
}
Result<String> Writer::write_nil(Nil& val) { return String::create("nil"); }
Result<String> Writer::write_bool(Bool& val) {
if (val.value()) return String::create(_arena, "true");
if (val.value()) return String::create("true");
return String::create(_arena, "false");
return String::create("false");
}
Result<String> Writer::write_bytearray(ByteArray& val) {
@ -76,7 +74,7 @@ Result<String> Writer::write_bytearray(ByteArray& val) {
}
Result<String> Writer::write_string(String& val) {
String res = TRY(String::create(_arena, "\""));
String res = TRY(String::create("\""));
// TODO: optimize this
for (uint64_t i = 0; i < val.size(); i++) {
@ -103,13 +101,13 @@ Result<String> Writer::write_string(String& val) {
};
if (replace != 0) {
res = TRY(res.concat(_arena, replace));
res = TRY(res.concat(replace));
} else {
res = TRY(res.concat(_arena, &c, 1));
res = TRY(res.concat(&c, 1));
}
}
res = TRY(res.concat(_arena, "\""));
res = TRY(res.concat("\""));
return res;
}
@ -127,7 +125,7 @@ int is_valid_symbol_char(char32_t codepoint) {
}
Result<String> Writer::write_symbol(Symbol& val) {
String res = TRY(String::create(_arena, ""));
String res = TRY(String::create(""));
// TODO: optimize this
for (uint64_t i = 0; i < val.size(); i++) {
@ -135,7 +133,7 @@ Result<String> Writer::write_symbol(Symbol& val) {
if (!is_valid_symbol_char(c)) return ErrorCode::InvalidSymbol;
res = TRY(res.concat(_arena, &c, 1));
res = TRY(res.concat(&c, 1));
}
return res;
@ -146,9 +144,9 @@ Result<String> Writer::write_syntax(Syntax& val) {
}
Result<String> Writer::write_pair(Pair& val) {
String res = TRY(String::create(_arena, "("));
String res = TRY(String::create("("));
Value cur = TRY(val.copy(_arena));
Value cur = TRY(val.copy());
bool is_first = true;
while (!cur.is<Nil>()) {
@ -156,65 +154,65 @@ Result<String> Writer::write_pair(Pair& val) {
Pair& pair = *cur.to<Pair>();
Value first = TRY(pair.first(_arena));
if (!is_first) res = TRY(res.concat(_arena, " "));
Value first = TRY(pair.first());
if (!is_first) res = TRY(res.concat(" "));
String first_str = TRY(write_one(first));
res = TRY(res.concat(_arena, first_str));
res = TRY(res.concat(first_str));
cur = TRY(pair.rest(_arena));
cur = TRY(pair.rest());
is_first = false;
}
res = TRY(res.concat(_arena, ")"));
res = TRY(res.concat(")"));
return res;
}
Result<String> Writer::write_array(Array& val) {
String res = TRY(String::create(_arena, "["));
String res = TRY(String::create("["));
bool is_first = true;
for (uint64_t i = 0; i < val.size(); i++) {
Value cur = TRY(val.get(_arena, i));
Value cur = TRY(val.get(i));
if (!is_first) res = TRY(res.concat(_arena, " "));
if (!is_first) res = TRY(res.concat(" "));
String first_str = TRY(write_one(cur));
res = TRY(res.concat(_arena, first_str));
res = TRY(res.concat(first_str));
is_first = false;
}
res = TRY(res.concat(_arena, "]"));
res = TRY(res.concat("]"));
return res;
}
Result<String> Writer::write_dict(Dict& val) {
String res = TRY(String::create(_arena, "{"));
String res = TRY(String::create("{"));
bool is_first = true;
for (uint64_t i = 0; i < val.size(); i++) {
Value k = TRY(Value::create(_arena, val._value->data[i * 2].get()));
Value v = TRY(Value::create(_arena, val._value->data[i * 2 + 1].get()));
Value k = TRY(Value::create(val._value->data[i * 2].get()));
Value v = TRY(Value::create(val._value->data[i * 2 + 1].get()));
if (!is_first) res = TRY(res.concat(_arena, " "));
if (!is_first) res = TRY(res.concat(" "));
String first_str = TRY(write_one(k));
res = TRY(res.concat(_arena, first_str));
res = TRY(res.concat(first_str));
res = TRY(res.concat(_arena, " "));
res = TRY(res.concat(" "));
String second_str = TRY(write_one(v));
res = TRY(res.concat(_arena, second_str));
res = TRY(res.concat(second_str));
is_first = false;
}
res = TRY(res.concat(_arena, "}"));
res = TRY(res.concat("}"));
return res;
}
Result<String> write_one(Arena& arena, Value& value) {
auto w = Writer(arena);
Result<String> write_one(Value& value) {
auto w = Writer();
return w.write_one(value);
}

View file

@ -5,7 +5,7 @@
class Writer {
public:
Writer(Arena& arena) : _arena(arena){};
Writer(){};
Result<String> write_one(Value& obj);
Result<String> write_multiple(Value& obj);
@ -22,17 +22,15 @@ class Writer {
Result<String> write_dict(Dict& val);
Result<String> write_symbol(Symbol& val);
Result<String> write_syntax(Syntax& val);
Arena& _arena;
};
Result<String> write_one(Arena& arena, Value& value);
Result<String> write_one(Value& value);
template <class T>
Result<String> write_one(Arena& arena, T& value)
Result<String> write_one(T& value)
requires std::derived_from<T, Object>
{
auto w = Writer(arena);
auto v = DIEX(value.copy(arena));
auto w = Writer();
auto v = DIEX(value.copy());
return w.write_one(v);
}

View file

@ -7,20 +7,20 @@
StaticArena<64 * 1024 * 1024> arena;
TEST_CASE(array_append) {
auto a = DIEX(Array::create(arena));
auto a = DIEX(Array::create());
a = DIEX(a.append(arena, 1));
a = DIEX(a.append(arena, 2));
a = DIEX(a.append(arena, 3));
a = DIEX(a.append(1));
a = DIEX(a.append(2));
a = DIEX(a.append(3));
DIEX(arena.gc());
DIEX(arena_gc());
auto s = DIEX(write_one(arena, a));
auto s = DIEX(write_one(a));
DIEX(arena.gc());
DIEX(arena_gc());
ASSERT_EQUALS(s, "[1 2 3]");
auto v = DIEX(a.get(arena, 1));
auto v = DIEX(a.get(1));
ASSERT_EQUALS(v, 2);
}

View file

@ -7,33 +7,33 @@
StaticArena<64 * 1024 * 1024> arena;
TEST_CASE(dict_insert) {
auto d = DIEX(Dict::create(arena));
auto d = DIEX(Dict::create());
d = DIEX(d.insert(arena, 1, 2));
d = DIEX(d.insert(arena, 1, 3));
d = DIEX(d.insert(arena, 3, 3));
d = DIEX(d.insert(arena, 0, 4));
d = DIEX(d.insert(arena, 0, 5));
d = DIEX(d.insert(arena, 2, 6));
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));
DIEX(arena.gc());
DIEX(arena_gc());
auto s = DIEX(write_one(arena, d));
auto s = DIEX(write_one(d));
DIEX(arena.gc());
DIEX(arena_gc());
ASSERT_EQUALS(s, "{0 5 1 3 2 6 3 3}");
}
TEST_CASE(dict_read) {
auto v = DIEX(read_one(arena, "{}"));
auto s = DIEX(write_one(arena, v));
auto v = DIEX(read_one("{}"));
auto s = DIEX(write_one(v));
ASSERT_EQUALS(s, "{}");
v = DIEX(read_one(arena, "{1 2 3 4}"));
s = DIEX(write_one(arena, v));
v = DIEX(read_one("{1 2 3 4}"));
s = DIEX(write_one(v));
ASSERT_EQUALS(s, "{1 2 3 4}");
auto vv = DIEX(v.get(arena, 1));
auto vv = DIEX(v.get(1));
ASSERT_EQUALS(vv, 2);
}

View file

@ -7,14 +7,14 @@
StaticArena<64 * 1024 * 1024> arena;
TEST_CASE(symbol_basic) {
auto a = DIEX(Symbol::create(arena, "foo"));
auto b = DIEX(Symbol::create(arena, "foo"));
auto a = DIEX(Symbol::create("foo"));
auto b = DIEX(Symbol::create("foo"));
ASSERT_EQUALS(a, b);
auto s = DIEX(write_one(arena, a));
auto s = DIEX(write_one(a));
DIEX(arena.gc());
DIEX(arena_gc());
ASSERT_EQUALS(s, "foo");
}

View file

@ -43,38 +43,36 @@ bool run_tests() {
#define TEST_CASE(fun_) TEST_CASE_IMPL(MACRO_CONCAT(fun_, _COUNTER_))
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);
}
Result<Value> to_value(Value& val) { return val.copy(); }
Result<Value> to_value(const Value& val) { return val.copy(); }
template <class T>
requires std::derived_from<T, Object>
Result<Value> to_value(Arena& arena, T& val) {
return val.copy(arena);
Result<Value> to_value(T& val) {
return val.copy();
}
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);
Result<Value> to_value(T& val) {
return Value::create(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);
Result<Value> to_value(T val) {
return Value::create(val);
}
#define ASSERT_EQUALS(lhs, rhs) \
do { \
auto lv = DIEX(to_value(arena, lhs)); \
auto rv = DIEX(to_value(arena, rhs)); \
short c = DIEX(lv.cmp(arena, rv)); \
auto lv = DIEX(to_value(lhs)); \
auto rv = DIEX(to_value(rhs)); \
short c = DIEX(lv.cmp(rv)); \
if (c != 0) { \
fprintf(stderr, "Values not equal at %s:%d\n", __FILE__, __LINE__); \
debug_print(arena, lv); \
debug_print(arena, rv); \
debug_print(lv); \
debug_print(rv); \
exit(EXIT_FAILURE); \
} \
} while (0)