Add byte arrays

This commit is contained in:
Konstantin Nazarov 2024-07-28 15:42:18 +01:00
parent 1c2f272c1d
commit cdcd111fb2
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
5 changed files with 118 additions and 2 deletions

View file

@ -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))));
} }

View file

@ -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() {}

View file

@ -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){};

View file

@ -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};
}; };

View file

@ -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;
} }