Implement reading lists and bools

This commit is contained in:
Konstantin Nazarov 2024-07-27 19:40:13 +01:00
parent 46381cccef
commit 110a7c8433
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
4 changed files with 94 additions and 0 deletions

View file

@ -18,6 +18,8 @@ Result<Value> Value::create(Arena& arena, PodObject* obj) {
return Value(TRY(Int64::create(arena, (PodInt64*)obj)));
case Tag::Float:
return Value(TRY(Float::create(arena, (PodFloat*)obj)));
case Tag::Bool:
return Value(TRY(Bool::create(arena, (PodBool*)obj)));
case Tag::String:
return Value(TRY(String::create(arena, (PodString*)obj)));
case Tag::Symbol:
@ -62,6 +64,10 @@ Result<Value> Pair::copy(Arena& arena) {
return Value(Pair(TRY(_value.copy(arena))));
}
Result<Value> Bool::copy(Arena& arena) {
return Value(Bool(TRY(_value.copy(arena))));
}
Result<Pair> Pair::create(Arena& arena, Value& first, Value& rest) {
auto pod = TRY(arena.alloc<PodPair>());
pod->first = OffPtr<PodObject>(pod, first.pod());

View file

@ -17,11 +17,15 @@ class Object {
virtual Tag tag() = 0;
virtual Result<Value> copy(Arena& arena) = 0;
virtual PodObject* pod() = 0;
virtual ~Object() = default;
Object() = default;
Object(const Object&) = delete;
};
class Nil : public Object {
public:
Nil() {}
Nil(Nil&& rhs) : _value(std::move(rhs._value)) {}
Nil(GcRoot<PodNil>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Nil; }
@ -46,6 +50,7 @@ class Nil : public Object {
class String : public Object {
public:
String() {}
String(String&& rhs) : _value(std::move(rhs._value)) {}
String(GcRoot<PodString>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::String; }
virtual PodObject* pod() final { return _value.get(); }
@ -88,6 +93,7 @@ class String : public Object {
class Symbol : public Object {
public:
Symbol() {}
Symbol(Symbol&& rhs) : _value(std::move(rhs._value)) {}
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Symbol; }
virtual PodObject* pod() final { return _value.get(); }
@ -113,6 +119,7 @@ class Symbol : public Object {
class Syntax : public Object {
public:
Syntax() {}
Syntax(Syntax&& rhs) : _value(std::move(rhs._value)) {}
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
Syntax(String filename, String modulename, Value expression);
virtual Tag tag() final { return Tag::Syntax; }
@ -133,6 +140,7 @@ class Syntax : public Object {
class Pair : public Object {
public:
Pair() {}
Pair(Pair&& rhs) : _value(std::move(rhs._value)) {}
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Pair; }
virtual PodObject* pod() final { return _value.get(); }
@ -154,6 +162,7 @@ class Pair : public Object {
class Int64 : public Object {
public:
Int64() {}
Int64(Int64&& rhs) : _value(std::move(rhs._value)) {}
Int64(GcRoot<PodInt64>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Int64; }
virtual PodObject* pod() final { return _value.get(); }
@ -180,6 +189,7 @@ class Int64 : public Object {
class Float : public Object {
public:
Float() {}
Float(Float&& rhs) : _value(std::move(rhs._value)) {}
Float(GcRoot<PodFloat>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Float; }
virtual PodObject* pod() final { return _value.get(); }
@ -203,6 +213,34 @@ class Float : public Object {
GcRoot<PodFloat> _value;
};
class Bool : public Object {
public:
Bool() {}
Bool(Bool&& rhs) : _value(std::move(rhs._value)) {}
Bool(GcRoot<PodBool>&& val) : _value(std::move(val)) {}
virtual Tag tag() final { return Tag::Bool; }
virtual PodObject* pod() final { return _value.get(); }
static Result<Bool> create(Arena& arena, PodBool* obj) {
return Bool(TRY(MkGcRoot(obj, arena)));
}
static Result<Bool> create(Arena& arena, bool val) {
auto pod = TRY(arena.alloc<PodBool>());
pod->value = val;
return Bool(TRY(MkGcRoot(pod, arena)));
}
bool value() { return _value->value; }
virtual Result<Value> copy(Arena& arena) final;
private:
GcRoot<PodBool> _value;
};
// note: this class doesn't perform proper destruction of objects in some cases
class Value {
public:

View file

@ -9,6 +9,7 @@ enum class Tag : uint8_t {
Nil,
Int64,
Float,
Bool,
String,
Symbol,
Syntax,
@ -66,6 +67,13 @@ class PodFloat final : public PodObject {
double value;
};
class PodBool final : public PodObject {
public:
PodBool() : PodObject(Tag::Bool){};
bool value;
};
class PodString final : public PodObject {
public:
PodString() : PodObject(Tag::String){};

View file

@ -83,3 +83,45 @@ Result<Value> Reader::read_multiple() {
return ErrorCode::ReadError;
}
Result<Value> Reader::read_list() {
if (!match('(')) return ErrorCode::ReadError;
forward();
Value res = TRY(Nil::create(_arena));
while (1) {
forward_whitespace();
if (is_eof()) {
return ErrorCode::ReadError;
}
if (match(')')) {
forward();
return reverse(_arena, res);
}
auto val = TRY(read_one());
res = Value(TRY(Pair::create(_arena, val, res)));
}
return ErrorCode::ReadError;
}
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)));
}
if (match("false")) {
forward(5);
if (!is_separator(get()) && !is_eof()) return ErrorCode::ReadError;
return Value(TRY(Bool::create(_arena, false)));
}
return ErrorCode::ReadError;
}