1 // SExp - A S-Expression Parser for C++ 2 // Copyright (C) 2015 Ingo Ruhnke <grumbel@gmail.com> 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 #ifndef HEADER_SEXP_UTIL_HPP 18 #define HEADER_SEXP_UTIL_HPP 19 20 #include <sexp/value.hpp> 21 22 namespace sexp { 23 24 class Value; 25 car(Value & sx)26inline Value& car(Value& sx) { return sx.get_car(); } cdr(Value & sx)27inline Value& cdr(Value& sx) { return sx.get_cdr(); } caar(Value & sx)28inline Value& caar(Value& sx) { return sx.get_car().get_car(); } cadr(Value & sx)29inline Value& cadr(Value& sx) { return sx.get_car().get_cdr(); } cdar(Value & sx)30inline Value& cdar(Value& sx) { return sx.get_cdr().get_car(); } cddr(Value & sx)31inline Value& cddr(Value& sx) { return sx.get_cdr().get_cdr(); } caaar(Value & sx)32inline Value& caaar(Value& sx) { return sx.get_car().get_car().get_car(); } caadr(Value & sx)33inline Value& caadr(Value& sx) { return sx.get_car().get_car().get_cdr(); } cadar(Value & sx)34inline Value& cadar(Value& sx) { return sx.get_car().get_cdr().get_car(); } caddr(Value & sx)35inline Value& caddr(Value& sx) { return sx.get_car().get_cdr().get_cdr(); } cdaar(Value & sx)36inline Value& cdaar(Value& sx) { return sx.get_cdr().get_car().get_car(); } cdadr(Value & sx)37inline Value& cdadr(Value& sx) { return sx.get_cdr().get_car().get_cdr(); } cddar(Value & sx)38inline Value& cddar(Value& sx) { return sx.get_cdr().get_cdr().get_car(); } cdddr(Value & sx)39inline Value& cdddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr(); } caaaar(Value & sx)40inline Value& caaaar(Value& sx) { return sx.get_car().get_car().get_car().get_car(); } caaadr(Value & sx)41inline Value& caaadr(Value& sx) { return sx.get_car().get_car().get_car().get_cdr(); } caadar(Value & sx)42inline Value& caadar(Value& sx) { return sx.get_car().get_car().get_cdr().get_car(); } caaddr(Value & sx)43inline Value& caaddr(Value& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); } cadaar(Value & sx)44inline Value& cadaar(Value& sx) { return sx.get_car().get_cdr().get_car().get_car(); } cadadr(Value & sx)45inline Value& cadadr(Value& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); } caddar(Value & sx)46inline Value& caddar(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); } cadddr(Value & sx)47inline Value& cadddr(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); } cdaaar(Value & sx)48inline Value& cdaaar(Value& sx) { return sx.get_cdr().get_car().get_car().get_car(); } cdaadr(Value & sx)49inline Value& cdaadr(Value& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); } cdadar(Value & sx)50inline Value& cdadar(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); } cdaddr(Value & sx)51inline Value& cdaddr(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); } cddaar(Value & sx)52inline Value& cddaar(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); } cddadr(Value & sx)53inline Value& cddadr(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); } cdddar(Value & sx)54inline Value& cdddar(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); } cddddr(Value & sx)55inline Value& cddddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); } 56 car(Value const & sx)57inline Value const& car(Value const& sx) { return sx.get_car(); } cdr(Value const & sx)58inline Value const& cdr(Value const& sx) { return sx.get_cdr(); } caar(Value const & sx)59inline Value const& caar(Value const& sx) { return sx.get_car().get_car(); } cadr(Value const & sx)60inline Value const& cadr(Value const& sx) { return sx.get_car().get_cdr(); } cdar(Value const & sx)61inline Value const& cdar(Value const& sx) { return sx.get_cdr().get_car(); } cddr(Value const & sx)62inline Value const& cddr(Value const& sx) { return sx.get_cdr().get_cdr(); } caaar(Value const & sx)63inline Value const& caaar(Value const& sx) { return sx.get_car().get_car().get_car(); } caadr(Value const & sx)64inline Value const& caadr(Value const& sx) { return sx.get_car().get_car().get_cdr(); } cadar(Value const & sx)65inline Value const& cadar(Value const& sx) { return sx.get_car().get_cdr().get_car(); } caddr(Value const & sx)66inline Value const& caddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr(); } cdaar(Value const & sx)67inline Value const& cdaar(Value const& sx) { return sx.get_cdr().get_car().get_car(); } cdadr(Value const & sx)68inline Value const& cdadr(Value const& sx) { return sx.get_cdr().get_car().get_cdr(); } cddar(Value const & sx)69inline Value const& cddar(Value const& sx) { return sx.get_cdr().get_cdr().get_car(); } cdddr(Value const & sx)70inline Value const& cdddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr(); } caaaar(Value const & sx)71inline Value const& caaaar(Value const& sx) { return sx.get_car().get_car().get_car().get_car(); } caaadr(Value const & sx)72inline Value const& caaadr(Value const& sx) { return sx.get_car().get_car().get_car().get_cdr(); } caadar(Value const & sx)73inline Value const& caadar(Value const& sx) { return sx.get_car().get_car().get_cdr().get_car(); } caaddr(Value const & sx)74inline Value const& caaddr(Value const& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); } cadaar(Value const & sx)75inline Value const& cadaar(Value const& sx) { return sx.get_car().get_cdr().get_car().get_car(); } cadadr(Value const & sx)76inline Value const& cadadr(Value const& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); } caddar(Value const & sx)77inline Value const& caddar(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); } cadddr(Value const & sx)78inline Value const& cadddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); } cdaaar(Value const & sx)79inline Value const& cdaaar(Value const& sx) { return sx.get_cdr().get_car().get_car().get_car(); } cdaadr(Value const & sx)80inline Value const& cdaadr(Value const& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); } cdadar(Value const & sx)81inline Value const& cdadar(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); } cdaddr(Value const & sx)82inline Value const& cdaddr(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); } cddaar(Value const & sx)83inline Value const& cddaar(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); } cddadr(Value const & sx)84inline Value const& cddadr(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); } cdddar(Value const & sx)85inline Value const& cdddar(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); } cddddr(Value const & sx)86inline Value const& cddddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); } 87 88 int list_length(Value const& sx); 89 Value const& list_ref(Value const& sx, int index); 90 bool is_list(Value const& sx); 91 Value const& assoc_ref(Value const& sx, std::string const& key); 92 93 class ListIterator 94 { 95 private: 96 Value const* cur; 97 98 public: ListIterator()99 ListIterator() : 100 cur(nullptr) 101 {} 102 ListIterator(Value const & sx)103 ListIterator(Value const& sx) : 104 cur(!sx.is_cons() ? nullptr : &sx) 105 {} 106 operator ==(ListIterator const & rhs) const107 bool operator==(ListIterator const& rhs) const { return cur == rhs.cur; } operator !=(ListIterator const & rhs) const108 bool operator!=(ListIterator const& rhs) const { return cur != rhs.cur; } 109 operator *() const110 Value const& operator*() const { return cur->get_car(); /* NOLINT */ } operator ->() const111 Value const* operator->() const { return &cur->get_car(); } 112 operator ++()113 ListIterator& operator++() 114 { 115 if (cur) 116 { 117 cur = &cur->get_cdr(); 118 if (!cur->is_cons()) 119 { 120 // if the list is malformed we stop at the last valid element 121 // and silently ignore the rest 122 cur = nullptr; 123 } 124 } 125 return *this; 126 } 127 operator ++(int)128 ListIterator operator++(int) 129 { 130 ListIterator tmp = *this; 131 operator++(); 132 return tmp; 133 } 134 }; 135 136 class ListAdapter 137 { 138 private: 139 Value const& m_sx; 140 141 public: ListAdapter(Value const & sx)142 ListAdapter(Value const& sx) : 143 m_sx(sx) 144 {} 145 begin() const146 ListIterator begin() const { return ListIterator(m_sx); } end() const147 ListIterator end() const { return ListIterator(); } 148 }; 149 150 } // namespace sexp 151 152 #endif 153 154 /* EOF */ 155