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
22namespace sexp {
23
24class Value;
25
26inline Value& car(Value& sx) { return sx.get_car(); }
27inline Value& cdr(Value& sx) { return sx.get_cdr(); }
28inline Value& caar(Value& sx) { return sx.get_car().get_car(); }
29inline Value& cadr(Value& sx) { return sx.get_car().get_cdr(); }
30inline Value& cdar(Value& sx) { return sx.get_cdr().get_car(); }
31inline Value& cddr(Value& sx) { return sx.get_cdr().get_cdr(); }
32inline Value& caaar(Value& sx) { return sx.get_car().get_car().get_car(); }
33inline Value& caadr(Value& sx) { return sx.get_car().get_car().get_cdr(); }
34inline Value& cadar(Value& sx) { return sx.get_car().get_cdr().get_car(); }
35inline Value& caddr(Value& sx) { return sx.get_car().get_cdr().get_cdr(); }
36inline Value& cdaar(Value& sx) { return sx.get_cdr().get_car().get_car(); }
37inline Value& cdadr(Value& sx) { return sx.get_cdr().get_car().get_cdr(); }
38inline Value& cddar(Value& sx) { return sx.get_cdr().get_cdr().get_car(); }
39inline Value& cdddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr(); }
40inline Value& caaaar(Value& sx) { return sx.get_car().get_car().get_car().get_car(); }
41inline Value& caaadr(Value& sx) { return sx.get_car().get_car().get_car().get_cdr(); }
42inline Value& caadar(Value& sx) { return sx.get_car().get_car().get_cdr().get_car(); }
43inline Value& caaddr(Value& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); }
44inline Value& cadaar(Value& sx) { return sx.get_car().get_cdr().get_car().get_car(); }
45inline Value& cadadr(Value& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); }
46inline Value& caddar(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); }
47inline Value& cadddr(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); }
48inline Value& cdaaar(Value& sx) { return sx.get_cdr().get_car().get_car().get_car(); }
49inline Value& cdaadr(Value& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); }
50inline Value& cdadar(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); }
51inline Value& cdaddr(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); }
52inline Value& cddaar(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); }
53inline Value& cddadr(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); }
54inline Value& cdddar(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); }
55inline Value& cddddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); }
56
57inline Value const& car(Value const& sx) { return sx.get_car(); }
58inline Value const& cdr(Value const& sx) { return sx.get_cdr(); }
59inline Value const& caar(Value const& sx) { return sx.get_car().get_car(); }
60inline Value const& cadr(Value const& sx) { return sx.get_car().get_cdr(); }
61inline Value const& cdar(Value const& sx) { return sx.get_cdr().get_car(); }
62inline Value const& cddr(Value const& sx) { return sx.get_cdr().get_cdr(); }
63inline Value const& caaar(Value const& sx) { return sx.get_car().get_car().get_car(); }
64inline Value const& caadr(Value const& sx) { return sx.get_car().get_car().get_cdr(); }
65inline Value const& cadar(Value const& sx) { return sx.get_car().get_cdr().get_car(); }
66inline Value const& caddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr(); }
67inline Value const& cdaar(Value const& sx) { return sx.get_cdr().get_car().get_car(); }
68inline Value const& cdadr(Value const& sx) { return sx.get_cdr().get_car().get_cdr(); }
69inline Value const& cddar(Value const& sx) { return sx.get_cdr().get_cdr().get_car(); }
70inline Value const& cdddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr(); }
71inline Value const& caaaar(Value const& sx) { return sx.get_car().get_car().get_car().get_car(); }
72inline Value const& caaadr(Value const& sx) { return sx.get_car().get_car().get_car().get_cdr(); }
73inline Value const& caadar(Value const& sx) { return sx.get_car().get_car().get_cdr().get_car(); }
74inline Value const& caaddr(Value const& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); }
75inline Value const& cadaar(Value const& sx) { return sx.get_car().get_cdr().get_car().get_car(); }
76inline Value const& cadadr(Value const& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); }
77inline Value const& caddar(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); }
78inline Value const& cadddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); }
79inline Value const& cdaaar(Value const& sx) { return sx.get_cdr().get_car().get_car().get_car(); }
80inline Value const& cdaadr(Value const& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); }
81inline Value const& cdadar(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); }
82inline Value const& cdaddr(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); }
83inline Value const& cddaar(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); }
84inline Value const& cddadr(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); }
85inline Value const& cdddar(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); }
86inline Value const& cddddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); }
87
88int list_length(Value const& sx);
89Value const& list_ref(Value const& sx, int index);
90bool is_list(Value const& sx);
91Value const& assoc_ref(Value const& sx, std::string const& key);
92
93class ListIterator
94{
95private:
96 Value const* cur;
97
98public:
99 ListIterator() :
100 cur(nullptr)
101 {}
102
103 ListIterator(Value const& sx) :
104 cur(!sx.is_cons() ? nullptr : &sx)
105 {}
106
107 bool operator==(ListIterator const& rhs) const { return cur == rhs.cur; }
108 bool operator!=(ListIterator const& rhs) const { return cur != rhs.cur; }
109
110 Value const& operator*() const { return cur->get_car(); /* NOLINT */ }
111 Value const* operator->() const { return &cur->get_car(); }
112
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
128 ListIterator operator++(int)
129 {
130 ListIterator tmp = *this;
131 operator++();
132 return tmp;
133 }
134};
135
136class ListAdapter
137{
138private:
139 Value const& m_sx;
140
141public:
142 ListAdapter(Value const& sx) :
143 m_sx(sx)
144 {}
145
146 ListIterator begin() const { return ListIterator(m_sx); }
147 ListIterator end() const { return ListIterator(); }
148};
149
150} // namespace sexp
151
152#endif
153
154/* EOF */
155