Stop passing arena explicitly
This commit is contained in:
parent
b40f835bfb
commit
4c7b44ff01
15 changed files with 409 additions and 464 deletions
|
@ -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(); }
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
186
src/common.cpp
186
src/common.cpp
|
@ -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; }
|
||||
|
|
386
src/common.hpp
386
src/common.hpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
12
src/vli.cpp
12
src/vli.cpp
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue