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)));
|
return Value(TRY(Float::create(arena, (PodFloat*)obj)));
|
||||||
case Tag::Bool:
|
case Tag::Bool:
|
||||||
return Value(TRY(Bool::create(arena, (PodBool*)obj)));
|
return Value(TRY(Bool::create(arena, (PodBool*)obj)));
|
||||||
|
case Tag::ByteArray:
|
||||||
|
return Value(TRY(ByteArray::create(arena, (PodByteArray*)obj)));
|
||||||
case Tag::String:
|
case Tag::String:
|
||||||
return Value(TRY(String::create(arena, (PodString*)obj)));
|
return Value(TRY(String::create(arena, (PodString*)obj)));
|
||||||
case Tag::Symbol:
|
case Tag::Symbol:
|
||||||
|
@ -59,6 +61,10 @@ Result<Value> Float::copy(Arena& arena) {
|
||||||
return Value(Float(TRY(_value.copy(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) {
|
Result<Value> String::copy(Arena& arena) {
|
||||||
return Value(String(TRY(_value.copy(arena))));
|
return Value(String(TRY(_value.copy(arena))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,102 @@ class Nil : public Object {
|
||||||
GcRoot<PodNil> _value;
|
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 {
|
class String : public Object {
|
||||||
public:
|
public:
|
||||||
String() {}
|
String() {}
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum class Tag : uint8_t {
|
||||||
Symbol,
|
Symbol,
|
||||||
Syntax,
|
Syntax,
|
||||||
Pair,
|
Pair,
|
||||||
|
ByteArray,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -74,6 +75,14 @@ class PodBool final : public PodObject {
|
||||||
bool value;
|
bool value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PodByteArray final : public PodObject {
|
||||||
|
public:
|
||||||
|
PodByteArray() : PodObject(Tag::ByteArray){};
|
||||||
|
|
||||||
|
uint64_t size;
|
||||||
|
char data[];
|
||||||
|
};
|
||||||
|
|
||||||
class PodString final : public PodObject {
|
class PodString final : public PodObject {
|
||||||
public:
|
public:
|
||||||
PodString() : PodObject(Tag::String){};
|
PodString() : PodObject(Tag::String){};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
class Reader {
|
class Reader {
|
||||||
public:
|
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_one();
|
||||||
Result<Value> read_multiple();
|
Result<Value> read_multiple();
|
||||||
|
@ -39,6 +39,6 @@ class Reader {
|
||||||
bool match(char c);
|
bool match(char c);
|
||||||
|
|
||||||
Arena& _arena;
|
Arena& _arena;
|
||||||
String _str;
|
String& _str;
|
||||||
SourcePosition position_{1, 1, 0};
|
SourcePosition position_{1, 1, 0};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "arena.hpp"
|
#include "arena.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "reader.hpp"
|
||||||
|
|
||||||
StaticArena<64 * 1024 * 1024> arena;
|
StaticArena<64 * 1024 * 1024> arena;
|
||||||
|
|
||||||
|
@ -26,5 +27,9 @@ int main() {
|
||||||
}
|
}
|
||||||
std::cout << "root count: " << arena.root_count() << "\n";
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue