Implement input of dicts and arrays in REPL

This commit is contained in:
Konstantin Nazarov 2024-09-01 23:02:21 +01:00
parent 94b8f21a82
commit 09693768f8
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
6 changed files with 83 additions and 6 deletions

View file

@ -65,6 +65,7 @@ set(LISP_TESTS
logic
dict
function
collections
)

View file

@ -229,7 +229,7 @@ Result<void> Stack::settop(uint64_t idx) {
return Result<void>();
}
Result<Pair> Pair::create(Value& first, Value& rest) {
Result<Pair> Pair::create(const Value& first, const Value& rest) {
auto pod = TRY(arena_alloc<PodPair>());
pod->header.tag = Tag::Pair;
pod->first = first.pod();

View file

@ -674,7 +674,7 @@ class Pair : public Object {
virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); }
static Result<Pair> create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); }
static Result<Pair> create(Value& first, Value& rest);
static Result<Pair> create(const Value& first, const Value& rest);
static Result<Pair> create(const Array& arr);
virtual Result<Value> get(const Value& key) const final;

View file

@ -115,7 +115,35 @@ Result<Value> Reader::read_list() {
return ERROR(ReadError);
}
Result<Value> Reader::read_array() {
Result<Value> Reader::read_array_code() {
if (!match('[')) return ERROR(ReadError);
forward();
auto sym = Value(TRY(Symbol::create("array")));
auto res = Value(TRY(Pair::create(sym, TRY(Nil::create()))));
while (1) {
forward_whitespace();
if (is_eof()) {
return ERROR(ReadError);
}
if (match(']')) {
forward();
return reverse(res);
}
auto val = TRY(read_one());
res = TRY(Pair::create(val, res));
}
return ERROR(ReadError);
}
Result<Value> Reader::read_array_data() {
if (!match('[')) return ERROR(ReadError);
forward();
@ -142,7 +170,43 @@ Result<Value> Reader::read_array() {
return ERROR(ReadError);
}
Result<Value> Reader::read_dict() {
Result<Value> Reader::read_array() {
if (_as_code) return read_array_code();
return read_array_data();
}
Result<Value> Reader::read_dict_code() {
if (!match('{')) return ERROR(ReadError);
forward();
auto sym = Value(TRY(Symbol::create("dict")));
auto res = Value(TRY(Pair::create(sym, TRY(Nil::create()))));
while (1) {
forward_whitespace();
if (is_eof()) {
return ERROR(ReadError);
}
if (match('}')) {
forward();
return reverse(res);
}
auto val1 = TRY(read_one());
auto val2 = TRY(read_one());
res = TRY(Pair::create(val1, res));
res = TRY(Pair::create(val2, res));
}
return ERROR(ReadError);
}
Result<Value> Reader::read_dict_data() {
if (!match('{')) return ERROR(ReadError);
forward();
@ -169,6 +233,13 @@ Result<Value> Reader::read_dict() {
return ERROR(ReadError);
}
Result<Value> Reader::read_dict() {
if (_as_code) return read_dict_code();
return read_dict_data();
}
Result<Value> Reader::read_bool() {
if (match("true")) {
forward(4);

View file

@ -5,7 +5,8 @@
class Reader {
public:
Reader(const String& str) : _str(str) {}
Reader(const String& str, bool as_code = true)
: _str(str), _as_code(as_code) {}
Result<Value> read_one();
Result<Value> read_multiple();
@ -29,7 +30,11 @@ class Reader {
Result<Value> read_list();
Result<Value> read_string();
Result<Value> read_array();
Result<Value> read_array_code();
Result<Value> read_array_data();
Result<Value> read_dict();
Result<Value> read_dict_code();
Result<Value> read_dict_data();
Result<Value> read_number();
Result<Value> read_symbol();
Result<Value> read_bool();
@ -40,6 +45,7 @@ class Reader {
bool match(char c);
const String& _str;
bool _as_code;
SourcePosition position_{1, 1, 0};
};

View file

@ -75,7 +75,6 @@ Result<Value> stdlib_list(const Array& params) {
}
Result<Value> stdlib_array(const Array& params) {
debug_print(params);
Array array_copy = TRY(params.copy());
return Value(std::move(array_copy));
}