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 | |
26 | inline Value& car(Value& sx) { return sx.get_car(); } |
27 | inline Value& cdr(Value& sx) { return sx.get_cdr(); } |
28 | inline Value& caar(Value& sx) { return sx.get_car().get_car(); } |
29 | inline Value& cadr(Value& sx) { return sx.get_car().get_cdr(); } |
30 | inline Value& cdar(Value& sx) { return sx.get_cdr().get_car(); } |
31 | inline Value& cddr(Value& sx) { return sx.get_cdr().get_cdr(); } |
32 | inline Value& caaar(Value& sx) { return sx.get_car().get_car().get_car(); } |
33 | inline Value& caadr(Value& sx) { return sx.get_car().get_car().get_cdr(); } |
34 | inline Value& cadar(Value& sx) { return sx.get_car().get_cdr().get_car(); } |
35 | inline Value& caddr(Value& sx) { return sx.get_car().get_cdr().get_cdr(); } |
36 | inline Value& cdaar(Value& sx) { return sx.get_cdr().get_car().get_car(); } |
37 | inline Value& cdadr(Value& sx) { return sx.get_cdr().get_car().get_cdr(); } |
38 | inline Value& cddar(Value& sx) { return sx.get_cdr().get_cdr().get_car(); } |
39 | inline Value& cdddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr(); } |
40 | inline Value& caaaar(Value& sx) { return sx.get_car().get_car().get_car().get_car(); } |
41 | inline Value& caaadr(Value& sx) { return sx.get_car().get_car().get_car().get_cdr(); } |
42 | inline Value& caadar(Value& sx) { return sx.get_car().get_car().get_cdr().get_car(); } |
43 | inline Value& caaddr(Value& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); } |
44 | inline Value& cadaar(Value& sx) { return sx.get_car().get_cdr().get_car().get_car(); } |
45 | inline Value& cadadr(Value& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); } |
46 | inline Value& caddar(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); } |
47 | inline Value& cadddr(Value& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); } |
48 | inline Value& cdaaar(Value& sx) { return sx.get_cdr().get_car().get_car().get_car(); } |
49 | inline Value& cdaadr(Value& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); } |
50 | inline Value& cdadar(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); } |
51 | inline Value& cdaddr(Value& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); } |
52 | inline Value& cddaar(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); } |
53 | inline Value& cddadr(Value& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); } |
54 | inline Value& cdddar(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); } |
55 | inline Value& cddddr(Value& sx) { return sx.get_cdr().get_cdr().get_cdr().get_cdr(); } |
56 | |
57 | inline Value const& car(Value const& sx) { return sx.get_car(); } |
58 | inline Value const& cdr(Value const& sx) { return sx.get_cdr(); } |
59 | inline Value const& caar(Value const& sx) { return sx.get_car().get_car(); } |
60 | inline Value const& cadr(Value const& sx) { return sx.get_car().get_cdr(); } |
61 | inline Value const& cdar(Value const& sx) { return sx.get_cdr().get_car(); } |
62 | inline Value const& cddr(Value const& sx) { return sx.get_cdr().get_cdr(); } |
63 | inline Value const& caaar(Value const& sx) { return sx.get_car().get_car().get_car(); } |
64 | inline Value const& caadr(Value const& sx) { return sx.get_car().get_car().get_cdr(); } |
65 | inline Value const& cadar(Value const& sx) { return sx.get_car().get_cdr().get_car(); } |
66 | inline Value const& caddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr(); } |
67 | inline Value const& cdaar(Value const& sx) { return sx.get_cdr().get_car().get_car(); } |
68 | inline Value const& cdadr(Value const& sx) { return sx.get_cdr().get_car().get_cdr(); } |
69 | inline Value const& cddar(Value const& sx) { return sx.get_cdr().get_cdr().get_car(); } |
70 | inline Value const& cdddr(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr(); } |
71 | inline Value const& caaaar(Value const& sx) { return sx.get_car().get_car().get_car().get_car(); } |
72 | inline Value const& caaadr(Value const& sx) { return sx.get_car().get_car().get_car().get_cdr(); } |
73 | inline Value const& caadar(Value const& sx) { return sx.get_car().get_car().get_cdr().get_car(); } |
74 | inline Value const& caaddr(Value const& sx) { return sx.get_car().get_car().get_cdr().get_cdr(); } |
75 | inline Value const& cadaar(Value const& sx) { return sx.get_car().get_cdr().get_car().get_car(); } |
76 | inline Value const& cadadr(Value const& sx) { return sx.get_car().get_cdr().get_car().get_cdr(); } |
77 | inline Value const& caddar(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_car(); } |
78 | inline Value const& cadddr(Value const& sx) { return sx.get_car().get_cdr().get_cdr().get_cdr(); } |
79 | inline Value const& cdaaar(Value const& sx) { return sx.get_cdr().get_car().get_car().get_car(); } |
80 | inline Value const& cdaadr(Value const& sx) { return sx.get_cdr().get_car().get_car().get_cdr(); } |
81 | inline Value const& cdadar(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_car(); } |
82 | inline Value const& cdaddr(Value const& sx) { return sx.get_cdr().get_car().get_cdr().get_cdr(); } |
83 | inline Value const& cddaar(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_car(); } |
84 | inline Value const& cddadr(Value const& sx) { return sx.get_cdr().get_cdr().get_car().get_cdr(); } |
85 | inline Value const& cdddar(Value const& sx) { return sx.get_cdr().get_cdr().get_cdr().get_car(); } |
86 | inline 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: |
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 | |
136 | class ListAdapter |
137 | { |
138 | private: |
139 | Value const& m_sx; |
140 | |
141 | public: |
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 |