Horizon
Loading...
Searching...
No Matches
sexpr.h
1/*
2 * Copyright (C) 2016 Mark Roszko <mark.roszko@gmail.com>
3 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef SEXPR_H_
20#define SEXPR_H_
21
22#include <cstdint>
23#include <string>
24#include <vector>
25#include "sexpr/isexprable.h"
26#include "sexpr/sexpr_exception.h"
27
28
29namespace SEXPR
30{
31 using std::int32_t;
32 using std::int64_t;
33
34 enum class SEXPR_TYPE : char
35 {
36 SEXPR_TYPE_LIST,
37 SEXPR_TYPE_ATOM_INTEGER,
38 SEXPR_TYPE_ATOM_DOUBLE,
39 SEXPR_TYPE_ATOM_STRING,
40 SEXPR_TYPE_ATOM_SYMBOL,
41 };
42
43 typedef std::vector< class SEXPR * > SEXPR_VECTOR;
44
45 class SEXPR
46 {
47 public:
48 virtual ~SEXPR() {};
49 bool IsList() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_LIST; }
50 bool IsSymbol() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL; }
51 bool IsString() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING; }
52 bool IsDouble() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE; }
53 bool IsInteger() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER; }
54 void AddChild( SEXPR* aChild );
55 SEXPR_VECTOR const * GetChildren() const;
56 SEXPR * GetChild( size_t aIndex ) const;
57 size_t GetNumberOfChildren() const;
58 int64_t GetLongInteger() const;
59 int32_t GetInteger() const;
60 float GetFloat() const;
61 double GetDouble() const;
62 std::string const & GetString() const;
63 std::string const & GetSymbol() const;
64 SEXPR_LIST* GetList();
65 std::string AsString( size_t aLevel = 0) const;
66 size_t GetLineNumber() const { return m_lineNumber; }
67
68 protected:
69 SEXPR_TYPE m_type;
70 SEXPR( SEXPR_TYPE aType, size_t aLineNumber );
71 SEXPR( SEXPR_TYPE aType );
72 size_t m_lineNumber;
73 };
74
75 struct SEXPR_INTEGER : public SEXPR
76 {
77 int64_t m_value;
78
79 SEXPR_INTEGER( int64_t aValue ) :
80 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER ), m_value( aValue ) {};
81
82 SEXPR_INTEGER( int64_t aValue, int aLineNumber ) :
83 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER, aLineNumber ), m_value( aValue ) {};
84 };
85
86 struct SEXPR_DOUBLE : public SEXPR
87 {
88 double m_value;
89
90 SEXPR_DOUBLE( double aValue ) :
91 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE ), m_value( aValue ) {};
92
93 SEXPR_DOUBLE( double aValue, int aLineNumber ) :
94 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE, aLineNumber ), m_value( aValue ) {};
95 };
96
97 struct SEXPR_STRING : public SEXPR
98 {
99 std::string m_value;
100
101 SEXPR_STRING( const std::string& aValue ) :
102 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING ), m_value( aValue ) {};
103
104 SEXPR_STRING( const std::string& aValue, int aLineNumber ) :
105 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING, aLineNumber ), m_value( aValue ) {};
106 };
107
108 struct SEXPR_SYMBOL : public SEXPR
109 {
110 std::string m_value;
111
112 SEXPR_SYMBOL( const std::string& aValue ) :
113 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL ), m_value( aValue ) {};
114
115 SEXPR_SYMBOL( const std::string& aValue, int aLineNumber ) :
116 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL, aLineNumber ), m_value( aValue ) {};
117 };
118
120 {
121 bool _Symbol;
122 const std::string& _String;
123 };
124
125 inline _OUT_STRING AsSymbol( const std::string& aString )
126 {
127 struct _OUT_STRING ret = { true, aString };
128 return ret;
129 }
130
131 inline _OUT_STRING AsString( const std::string& aString )
132 {
133 struct _OUT_STRING ret = { false, aString };
134 return ret;
135 }
136
138 {
139 bool _Symbol;
140 std::string& _String;
141 };
142
143 inline _IN_STRING AsSymbol( std::string& aString )
144 {
145 struct _IN_STRING ret = { true, aString };
146 return ret;
147 }
148
149 inline _IN_STRING AsString( std::string& aString )
150 {
151 struct _IN_STRING ret = { false, aString };
152 return ret;
153 }
154
156 {
157 public:
158 SEXPR_SCAN_ARG( int32_t* aValue ) :
159 type( Type::INT ) { u.int_value = aValue; }
160
161 SEXPR_SCAN_ARG( int64_t* aValue ) :
162 type( Type::LONGINT ) { u.lint_value = aValue; }
163
164 SEXPR_SCAN_ARG( double* aValue ) :
165 type( Type::DOUBLE ) { u.dbl_value = aValue; }
166
167 SEXPR_SCAN_ARG( std::string* aValue ) :
168 type( Type::STRING ) { u.str_value = aValue; }
169
170 SEXPR_SCAN_ARG( _IN_STRING& aValue ) :
171 type( Type::SEXPR_STRING ) { u.sexpr_str = &aValue; }
172
173 SEXPR_SCAN_ARG( const std::string* aValue ) :
174 type( Type::STRING_COMP ) { str_value = *aValue; }
175
176 SEXPR_SCAN_ARG( std::string aValue ) :
177 type( Type::STRING_COMP ) { str_value = aValue; }
178
179 SEXPR_SCAN_ARG( const char* aValue ) :
180 type( Type::STRING_COMP ) { str_value = aValue; }
181
182 private:
183 friend class SEXPR_LIST;
184
185 enum class Type : char { INT, DOUBLE, STRING, LONGINT, STRING_COMP, SEXPR_STRING };
186 Type type;
187
188 union
189 {
190 int64_t* lint_value;
191 int32_t* int_value;
192 double* dbl_value;
193 std::string* str_value;
194 _IN_STRING* sexpr_str;
195 } u;
196
197 std::string str_value;
198 };
199
201 {
202 public:
203 SEXPR_CHILDREN_ARG( int32_t aValue ) :
204 type( Type::INT ) { u.int_value = aValue; }
205
206 SEXPR_CHILDREN_ARG( int64_t aValue ) :
207 type( Type::LONGINT ) { u.lint_value = aValue; }
208
209 SEXPR_CHILDREN_ARG( double aValue ) :
210 type( Type::DOUBLE ) { u.dbl_value = aValue; }
211
212 SEXPR_CHILDREN_ARG( const std::string& aValue ) :
213 type( Type::STRING ) { str_value = aValue; }
214
215 SEXPR_CHILDREN_ARG( const char* aValue ) :
216 type( Type::STRING ) { str_value = aValue; }
217
218 SEXPR_CHILDREN_ARG( const _OUT_STRING& aValue ) :
219 type( Type::SEXPR_STRING ) { str_value = aValue._String; u.symbol = aValue._Symbol; }
220
221 SEXPR_CHILDREN_ARG( SEXPR* aPointer ) :
222 type( Type::SEXPR_ATOM ) { u.sexpr_ptr = aPointer; }
223
224 private:
225 friend class SEXPR_LIST;
226
227 enum class Type : char { INT, DOUBLE, STRING, LONGINT, SEXPR_STRING, SEXPR_ATOM };
228 Type type;
229
230 union
231 {
232 int64_t lint_value;
233 int32_t int_value;
234 double dbl_value;
235 SEXPR* sexpr_ptr;
236 bool symbol;
237 } u;
238
239 std::string str_value;
240 };
241
242 class SEXPR_LIST : public SEXPR
243 {
244 public:
245 SEXPR_LIST() : SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST ), m_inStreamChild( 0 ) {};
246
247 SEXPR_LIST( int aLineNumber ) :
248 SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST, aLineNumber), m_inStreamChild( 0 ) {};
249
250 template <typename... Args>
251 SEXPR_LIST( const Args&... args ) :
252 SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST ), m_inStreamChild( 0 )
253 {
254 AddChildren(args...);
255 };
256
257 SEXPR_VECTOR m_children;
258
259 template <typename... Args>
260 size_t Scan( const Args&... args )
261 {
262 SEXPR_SCAN_ARG arg_array[] = { args... };
263 return doScan( arg_array, sizeof...( Args ) );
264 }
265
266 template <typename... Args>
267 void AddChildren( const Args&... args )
268 {
269 SEXPR_CHILDREN_ARG arg_array[] = { args... };
270 doAddChildren( arg_array, sizeof...( Args ) );
271 }
272
273 virtual ~SEXPR_LIST();
274
275 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, double value );
276 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, float value );
277 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int64_t value );
278 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int32_t value );
279 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, std::string value );
280 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const _OUT_STRING setting );
281 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const ISEXPRABLE& obj );
282 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR_LIST* list2 );
283 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR* obj );
284 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, ISEXPRABLE& obj );
285 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, std::string& str );
286 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int32_t& inte );
287 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int64_t& inte );
288 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, float& inte );
289 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, double& inte );
290 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, const _IN_STRING is );
291
292 private:
293 int m_inStreamChild;
294 size_t doScan( const SEXPR_SCAN_ARG *args, size_t num_args );
295 void doAddChildren( const SEXPR_CHILDREN_ARG *args, size_t num_args );
296 };
297
298} // namespace SEXPR
299
300#endif
Definition isexprable.h:29
Definition sexpr.h:201
Definition sexpr.h:243
Definition sexpr.h:156
Definition sexpr.h:46
Definition sexpr.h:87
Definition sexpr.h:76
Definition sexpr.h:98
Definition sexpr.h:109
Definition sexpr.h:138
Definition sexpr.h:120