Implement reading lists and bools
This commit is contained in:
parent
46381cccef
commit
110a7c8433
4 changed files with 94 additions and 0 deletions
|
@ -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());
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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){};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue