Implement input of dicts and arrays in REPL
This commit is contained in:
parent
94b8f21a82
commit
09693768f8
6 changed files with 83 additions and 6 deletions
|
@ -65,6 +65,7 @@ set(LISP_TESTS
|
|||
logic
|
||||
dict
|
||||
function
|
||||
collections
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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};
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue