Use recursion for reading lists

This commit is contained in:
Konstantin Nazarov 2024-09-04 23:18:57 +01:00
parent 8f10ca2b50
commit 8515d45b1e
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
3 changed files with 49 additions and 38 deletions

View file

@ -88,31 +88,36 @@ Result<Value> Reader::read_multiple() {
return ERROR(ReadError); return ERROR(ReadError);
} }
Result<Value> Reader::read_list() { Result<Value> Reader::read_list_rec(SourcePosition& end) {
if (!match('(')) return ERROR(ReadError); forward_whitespace();
forward(); if (is_eof()) {
return ERROR(ReadError);
Value res = 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 = Value(TRY(Pair::create(val, res)));
} }
return ERROR(ReadError); if (match(')')) {
forward();
end = position_;
return Value(TRY(Nil::create()));
}
auto val = TRY(read_one());
auto rest = TRY(read_list_rec(end));
auto res = Value(TRY(Pair::create(val, rest)));
return res;
}
Result<Value> Reader::read_list() {
if (!match('(')) return ERROR(ReadError);
// SourcePosition start = position_;
forward();
SourcePosition end = position_;
auto res = read_list_rec(end);
return res;
} }
Result<Value> Reader::read_array_code() { Result<Value> Reader::read_array_code() {
@ -517,22 +522,22 @@ bool Reader::forward_exponent() {
return forward_decimal_number(); return forward_decimal_number();
} }
Result<Value> read_one(const Value& value, bool as_code) { Result<Value> read_one(const Value& value, bool syntax, bool as_code) {
if (!value.is<String>()) return ERROR(TypeMismatch); if (!value.is<String>()) return ERROR(TypeMismatch);
auto r = Reader(*value.to<String>(), as_code); auto r = Reader(*value.to<String>(), syntax, as_code);
return r.read_one(); return r.read_one();
} }
Result<Value> read_one(const String& value, bool as_code) { Result<Value> read_one(const String& value, bool syntax, bool as_code) {
auto r = Reader(value, as_code); auto r = Reader(value, syntax, as_code);
return r.read_one(); return r.read_one();
} }
Result<Value> read_one(const char* value, bool as_code) { Result<Value> read_one(const char* value, bool syntax, bool as_code) {
auto s = TRY(String::create(value)); auto s = TRY(String::create(value));
auto r = Reader(s, as_code); auto r = Reader(s, syntax, as_code);
return r.read_one(); return r.read_one();
} }
Result<Value> read_multiple(const String& value, bool as_code) { Result<Value> read_multiple(const String& value, bool syntax, bool as_code) {
auto r = Reader(value, as_code); auto r = Reader(value, syntax, as_code);
return r.read_multiple(); return r.read_multiple();
} }

View file

@ -5,8 +5,8 @@
class Reader { class Reader {
public: public:
Reader(const String& str, bool as_code = true) Reader(const String& str, bool syntax = true, bool as_code = true)
: _str(str), _as_code(as_code) {} : _str(str), _syntax(syntax), _as_code(as_code) {}
Result<Value> read_one(); Result<Value> read_one();
Result<Value> read_multiple(); Result<Value> read_multiple();
@ -28,6 +28,7 @@ class Reader {
bool is_string_start(); bool is_string_start();
Result<Value> read_list(); Result<Value> read_list();
Result<Value> read_list_rec(SourcePosition& end);
Result<Value> read_string(); Result<Value> read_string();
Result<Value> read_array(); Result<Value> read_array();
Result<Value> read_array_code(); Result<Value> read_array_code();
@ -45,12 +46,17 @@ class Reader {
bool match(char c); bool match(char c);
const String& _str; const String& _str;
bool _syntax;
bool _as_code; bool _as_code;
SourcePosition position_{1, 1, 0}; SourcePosition position_{1, 1, 0};
}; };
Result<Value> read_one(const Value& value, bool as_code = true); Result<Value> read_one(const Value& value, bool syntax = true,
Result<Value> read_one(const String& value, bool as_code = true); bool as_code = true);
Result<Value> read_one(const char* value, bool as_code = true); Result<Value> read_one(const String& value, bool syntax = true,
bool as_code = true);
Result<Value> read_one(const char* value, bool syntax = true,
bool as_code = true);
Result<Value> read_multiple(const String& value, bool as_code = true); Result<Value> read_multiple(const String& value, bool syntax = true,
bool as_code = true);

View file

@ -26,11 +26,11 @@ TEST_CASE(dict_insert) {
} }
TEST_CASE(dict_read) { TEST_CASE(dict_read) {
auto v = DIEX(read_one("{}", false)); auto v = DIEX(read_one("{}", false, false));
auto s = DIEX(write_one(v)); auto s = DIEX(write_one(v));
ASSERT_EQUALS(s, "{}"); ASSERT_EQUALS(s, "{}");
v = DIEX(read_one("{1 2 3 4}", false)); v = DIEX(read_one("{1 2 3 4}", false, false));
s = DIEX(write_one(v)); s = DIEX(write_one(v));
ASSERT_EQUALS(s, "{1 2 3 4}"); ASSERT_EQUALS(s, "{1 2 3 4}");