diff --git a/CMakeLists.txt b/CMakeLists.txt index aa73c32..3e5b31b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set(LISP_TESTS logic dict function + collections ) diff --git a/src/common.cpp b/src/common.cpp index d930da0..db504bf 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -229,7 +229,7 @@ Result Stack::settop(uint64_t idx) { return Result(); } -Result Pair::create(Value& first, Value& rest) { +Result Pair::create(const Value& first, const Value& rest) { auto pod = TRY(arena_alloc()); pod->header.tag = Tag::Pair; pod->first = first.pod(); diff --git a/src/common.hpp b/src/common.hpp index bd4db7a..4d4233c 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -674,7 +674,7 @@ class Pair : public Object { virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); } static Result create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); } - static Result create(Value& first, Value& rest); + static Result create(const Value& first, const Value& rest); static Result create(const Array& arr); virtual Result get(const Value& key) const final; diff --git a/src/reader.cpp b/src/reader.cpp index b597b05..d0e5698 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -115,7 +115,35 @@ Result Reader::read_list() { return ERROR(ReadError); } -Result Reader::read_array() { +Result 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 Reader::read_array_data() { if (!match('[')) return ERROR(ReadError); forward(); @@ -142,7 +170,43 @@ Result Reader::read_array() { return ERROR(ReadError); } -Result Reader::read_dict() { +Result Reader::read_array() { + if (_as_code) return read_array_code(); + + return read_array_data(); +} + +Result 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 Reader::read_dict_data() { if (!match('{')) return ERROR(ReadError); forward(); @@ -169,6 +233,13 @@ Result Reader::read_dict() { return ERROR(ReadError); } + +Result Reader::read_dict() { + if (_as_code) return read_dict_code(); + + return read_dict_data(); +} + Result Reader::read_bool() { if (match("true")) { forward(4); diff --git a/src/reader.hpp b/src/reader.hpp index 01d7d2f..67225fe 100644 --- a/src/reader.hpp +++ b/src/reader.hpp @@ -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 read_one(); Result read_multiple(); @@ -29,7 +30,11 @@ class Reader { Result read_list(); Result read_string(); Result read_array(); + Result read_array_code(); + Result read_array_data(); Result read_dict(); + Result read_dict_code(); + Result read_dict_data(); Result read_number(); Result read_symbol(); Result read_bool(); @@ -40,6 +45,7 @@ class Reader { bool match(char c); const String& _str; + bool _as_code; SourcePosition position_{1, 1, 0}; }; diff --git a/src/stdlib.cpp b/src/stdlib.cpp index ce0308f..06b4e8a 100644 --- a/src/stdlib.cpp +++ b/src/stdlib.cpp @@ -75,7 +75,6 @@ Result stdlib_list(const Array& params) { } Result stdlib_array(const Array& params) { - debug_print(params); Array array_copy = TRY(params.copy()); return Value(std::move(array_copy)); }