Add byte arrays
This commit is contained in:
parent
1c2f272c1d
commit
cdcd111fb2
5 changed files with 118 additions and 2 deletions
|
@ -20,6 +20,8 @@ Result<Value> Value::create(Arena& arena, PodObject* obj) {
|
|||
return Value(TRY(Float::create(arena, (PodFloat*)obj)));
|
||||
case Tag::Bool:
|
||||
return Value(TRY(Bool::create(arena, (PodBool*)obj)));
|
||||
case Tag::ByteArray:
|
||||
return Value(TRY(ByteArray::create(arena, (PodByteArray*)obj)));
|
||||
case Tag::String:
|
||||
return Value(TRY(String::create(arena, (PodString*)obj)));
|
||||
case Tag::Symbol:
|
||||
|
@ -59,6 +61,10 @@ Result<Value> Float::copy(Arena& arena) {
|
|||
return Value(Float(TRY(_value.copy(arena))));
|
||||
}
|
||||
|
||||
Result<Value> ByteArray::copy(Arena& arena) {
|
||||
return Value(ByteArray(TRY(_value.copy(arena))));
|
||||
}
|
||||
|
||||
Result<Value> String::copy(Arena& arena) {
|
||||
return Value(String(TRY(_value.copy(arena))));
|
||||
}
|
||||
|
|
|
@ -47,6 +47,102 @@ class Nil : public Object {
|
|||
GcRoot<PodNil> _value;
|
||||
};
|
||||
|
||||
class ByteArray : public Object {
|
||||
public:
|
||||
ByteArray() {}
|
||||
ByteArray(ByteArray&& rhs) : _value(std::move(rhs._value)) {}
|
||||
ByteArray(GcRoot<PodByteArray>&& val) : _value(std::move(val)) {}
|
||||
|
||||
ByteArray& operator=(ByteArray&& rhs) {
|
||||
_value = std::move(rhs._value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual Tag tag() final { return Tag::String; }
|
||||
virtual PodObject* pod() final { return _value.get(); }
|
||||
|
||||
static Result<ByteArray> create(Arena& arena, PodByteArray* obj) {
|
||||
return ByteArray(TRY(MkGcRoot(obj, arena)));
|
||||
}
|
||||
static Result<ByteArray> create(Arena& arena, char* chars, int64_t size) {
|
||||
auto pod = TRY(arena.alloc<PodByteArray>(size * sizeof(char)));
|
||||
|
||||
memcpy(pod->data, chars, size * sizeof(char32_t));
|
||||
pod->size = size;
|
||||
|
||||
return ByteArray(TRY(MkGcRoot(pod, arena)));
|
||||
}
|
||||
|
||||
static Result<ByteArray> create(Arena& arena, const char* str) {
|
||||
uint64_t size = strlen(str);
|
||||
auto pod = TRY(arena.alloc<PodByteArray>(size * sizeof(char32_t)));
|
||||
|
||||
memcpy(pod->data, str, size);
|
||||
pod->size = size;
|
||||
|
||||
return ByteArray(TRY(MkGcRoot(pod, arena)));
|
||||
}
|
||||
|
||||
uint64_t size() { return _value->size; }
|
||||
virtual Result<Value> copy(Arena& arena) final;
|
||||
|
||||
Result<char32_t> operator[](uint64_t idx) {
|
||||
if (idx >= _value->size) return ErrorCode::IndexOutOfRange;
|
||||
return _value->data[idx];
|
||||
}
|
||||
|
||||
Result<ByteArray> concat(Arena& arena, 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)));
|
||||
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)));
|
||||
}
|
||||
|
||||
Result<ByteArray> concat(Arena& arena, 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)));
|
||||
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)));
|
||||
}
|
||||
|
||||
Result<ByteArray> concat(Arena& arena, 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)));
|
||||
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)));
|
||||
}
|
||||
|
||||
Result<ByteArray> sub(Arena& arena, 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)));
|
||||
pod->size = res_size;
|
||||
memcpy(pod->data, _value->data + start, sizeof(char) * res_size);
|
||||
|
||||
return ByteArray(TRY(MkGcRoot(pod, arena)));
|
||||
}
|
||||
|
||||
private:
|
||||
GcRoot<PodByteArray> _value;
|
||||
};
|
||||
|
||||
class String : public Object {
|
||||
public:
|
||||
String() {}
|
||||
|
|
|
@ -14,6 +14,7 @@ enum class Tag : uint8_t {
|
|||
Symbol,
|
||||
Syntax,
|
||||
Pair,
|
||||
ByteArray,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -74,6 +75,14 @@ class PodBool final : public PodObject {
|
|||
bool value;
|
||||
};
|
||||
|
||||
class PodByteArray final : public PodObject {
|
||||
public:
|
||||
PodByteArray() : PodObject(Tag::ByteArray){};
|
||||
|
||||
uint64_t size;
|
||||
char data[];
|
||||
};
|
||||
|
||||
class PodString final : public PodObject {
|
||||
public:
|
||||
PodString() : PodObject(Tag::String){};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class Reader {
|
||||
public:
|
||||
Reader(Arena& arena, String&& str) : _arena(arena), _str(std::move(str)) {}
|
||||
Reader(Arena& arena, String& str) : _arena(arena), _str(str) {}
|
||||
|
||||
Result<Value> read_one();
|
||||
Result<Value> read_multiple();
|
||||
|
@ -39,6 +39,6 @@ class Reader {
|
|||
bool match(char c);
|
||||
|
||||
Arena& _arena;
|
||||
String _str;
|
||||
String& _str;
|
||||
SourcePosition position_{1, 1, 0};
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "arena.hpp"
|
||||
#include "common.hpp"
|
||||
#include "reader.hpp"
|
||||
|
||||
StaticArena<64 * 1024 * 1024> arena;
|
||||
|
||||
|
@ -26,5 +27,9 @@ int main() {
|
|||
}
|
||||
std::cout << "root count: " << arena.root_count() << "\n";
|
||||
|
||||
auto s = DIEIF(String::create(arena, "(1 2 3 \"foo\")"));
|
||||
auto reader = Reader(arena, s);
|
||||
|
||||
auto r = DIEIF(reader.read_one());
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue