util.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #ifndef HEADER_SEXP_UTIL_HPP
  17. #define HEADER_SEXP_UTIL_HPP
  18. #include <sexp/value.hpp>
  19. namespace sexp {
  20. class Value;
  21. inline Value& car(Value& sx) { return sx.get_car(); }
  22. inline Value& cdr(Value& sx) { return sx.get_cdr(); }
  23. inline Value& caar(Value& sx) { return sx.get_car().get_car(); }
  24. inline Value& cadr(Value& sx) { return sx.get_car().get_cdr(); }
  25. inline Value& cdar(Value& sx) { return sx.get_cdr().get_car(); }
  26. inline Value& cddr(Value& sx) { return sx.get_cdr().get_cdr(); }
  27. inline Value& caaar(Value& sx) { return sx.get_car().get_car().get_car(); }
  28. inline Value& caadr(Value& sx) { return sx.get_car().get_car().get_cdr(); }
  29. inline Value& cadar(Value& sx) { return sx.get_car().get_cdr().get_car(); }
  30. inline Value& caddr(Value& sx) { return sx.get_car().get_cdr().get_cdr(); }
  31. inline Value& cdaar(Value& sx) { return sx.get_cdr().get_car().get_car(); }
  32. inline Value& cdadr(Value& sx) { return sx.get_cdr().get_car().get_cdr(); }
  33. inline Value& cddar(Value& sx) { return sx.get_cdr().get_cdr().get_car(); }
  34. inline Value& cdddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr(); }
  35. inline Value& caaaar(Value& sx) { return sx.get_car().get_car().get_car().get_car(); }
  36. inline Value& caaadr(Value& sx) { return sx.get_car().get_car().get_car().get_cdr(); }
  37. inline Value& caadar(Value& sx) { return sx.get_car().get_car().get_cdr().get_car(); }
  38. inline Value& caaddr(Value& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); }
  39. inline Value& cadaar(Value& sx) { return sx.get_car().get_cdr().get_car().get_car(); }
  40. inline Value& cadadr(Value& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); }
  41. inline Value& caddar(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); }
  42. inline Value& cadddr(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); }
  43. inline Value& cdaaar(Value& sx) { return sx.get_cdr().get_car().get_car().get_car(); }
  44. inline Value& cdaadr(Value& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); }
  45. inline Value& cdadar(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); }
  46. inline Value& cdaddr(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); }
  47. inline Value& cddaar(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); }
  48. inline Value& cddadr(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); }
  49. inline Value& cdddar(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); }
  50. inline Value& cddddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); }
  51. inline Value const& car(Value const& sx) { return sx.get_car(); }
  52. inline Value const& cdr(Value const& sx) { return sx.get_cdr(); }
  53. inline Value const& caar(Value const& sx) { return sx.get_car().get_car(); }
  54. inline Value const& cadr(Value const& sx) { return sx.get_car().get_cdr(); }
  55. inline Value const& cdar(Value const& sx) { return sx.get_cdr().get_car(); }
  56. inline Value const& cddr(Value const& sx) { return sx.get_cdr().get_cdr(); }
  57. inline Value const& caaar(Value const& sx) { return sx.get_car().get_car().get_car(); }
  58. inline Value const& caadr(Value const& sx) { return sx.get_car().get_car().get_cdr(); }
  59. inline Value const& cadar(Value const& sx) { return sx.get_car().get_cdr().get_car(); }
  60. inline Value const& caddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr(); }
  61. inline Value const& cdaar(Value const& sx) { return sx.get_cdr().get_car().get_car(); }
  62. inline Value const& cdadr(Value const& sx) { return sx.get_cdr().get_car().get_cdr(); }
  63. inline Value const& cddar(Value const& sx) { return sx.get_cdr().get_cdr().get_car(); }
  64. inline Value const& cdddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr(); }
  65. inline Value const& caaaar(Value const& sx) { return sx.get_car().get_car().get_car().get_car(); }
  66. inline Value const& caaadr(Value const& sx) { return sx.get_car().get_car().get_car().get_cdr(); }
  67. inline Value const& caadar(Value const& sx) { return sx.get_car().get_car().get_cdr().get_car(); }
  68. inline Value const& caaddr(Value const& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); }
  69. inline Value const& cadaar(Value const& sx) { return sx.get_car().get_cdr().get_car().get_car(); }
  70. inline Value const& cadadr(Value const& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); }
  71. inline Value const& caddar(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); }
  72. inline Value const& cadddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); }
  73. inline Value const& cdaaar(Value const& sx) { return sx.get_cdr().get_car().get_car().get_car(); }
  74. inline Value const& cdaadr(Value const& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); }
  75. inline Value const& cdadar(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); }
  76. inline Value const& cdaddr(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); }
  77. inline Value const& cddaar(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); }
  78. inline Value const& cddadr(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); }
  79. inline Value const& cdddar(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); }
  80. inline Value const& cddddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); }
  81. int list_length(Value const& sx);
  82. Value const& list_ref(Value const& sx, int index);
  83. bool is_list(Value const& sx);
  84. Value const& assoc_ref(Value const& sx, std::string const& key);
  85. class ListIterator
  86. {
  87. private:
  88. Value const* cur;
  89. public:
  90. ListIterator() :
  91. cur(nullptr)
  92. {}
  93. ListIterator(Value const& sx) :
  94. cur(!sx.is_cons() ? nullptr : &sx)
  95. {}
  96. bool operator==(ListIterator const& rhs) const { return cur == rhs.cur; }
  97. bool operator!=(ListIterator const& rhs) const { return cur != rhs.cur; }
  98. Value const& operator*() const { return cur->get_car(); /* NOLINT */ }
  99. Value const* operator->() const { return &cur->get_car(); }
  100. ListIterator& operator++()
  101. {
  102. if (cur)
  103. {
  104. cur = &cur->get_cdr();
  105. if (!cur->is_cons())
  106. {
  107. // if the list is malformed we stop at the last valid element
  108. // and silently ignore the rest
  109. cur = nullptr;
  110. }
  111. }
  112. return *this;
  113. }
  114. ListIterator operator++(int)
  115. {
  116. ListIterator tmp = *this;
  117. operator++();
  118. return tmp;
  119. }
  120. };
  121. class ListAdapter
  122. {
  123. private:
  124. Value const& m_sx;
  125. public:
  126. ListAdapter(Value const& sx) :
  127. m_sx(sx)
  128. {}
  129. ListIterator begin() const { return ListIterator(m_sx); }
  130. ListIterator end() const { return ListIterator(); }
  131. };
  132. } // namespace sexp
  133. #endif
  134. /* EOF */