Horizon
sexpr.h
1/*
2 * Copyright (C) 2016 Mark Roszko <mark.roszko@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 2 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
18#ifndef SEXPR_H_
19#define SEXPR_H_
20
21#include <cstdint>
22#include <string>
23#include <vector>
24#include "sexpr/isexprable.h"
25#include "sexpr/sexpr_exception.h"
26
27
28namespace SEXPR
29{
30 using std::int32_t;
31 using std::int64_t;
32
33 enum class SEXPR_TYPE : char
34 {
35 SEXPR_TYPE_LIST,
36 SEXPR_TYPE_ATOM_INTEGER,
37 SEXPR_TYPE_ATOM_DOUBLE,
38 SEXPR_TYPE_ATOM_STRING,
39 SEXPR_TYPE_ATOM_SYMBOL,
40 };
41
42 typedef std::vector< class SEXPR * > SEXPR_VECTOR;
43
44 class SEXPR
45 {
46 protected:
47 SEXPR_TYPE m_type;
48 SEXPR( SEXPR_TYPE aType, size_t aLineNumber );
49 SEXPR( SEXPR_TYPE aType );
50 size_t m_lineNumber;
51
52 public:
53 virtual ~SEXPR() {};
54 bool IsList() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_LIST; }
55 bool IsSymbol() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL; }
56 bool IsString() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING; }
57 bool IsDouble() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE; }
58 bool IsInteger() const { return m_type == SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER; }
59 void AddChild( SEXPR* aChild );
60 SEXPR_VECTOR const * GetChildren() const;
61 SEXPR * GetChild( size_t aIndex ) const;
62 size_t GetNumberOfChildren() const;
63 int64_t GetLongInteger() const;
64 int32_t GetInteger() const;
65 float GetFloat() const;
66 double GetDouble() const;
67 std::string const & GetString() const;
68 std::string const & GetSymbol() const;
69 SEXPR_LIST* GetList();
70 std::string AsString( size_t aLevel = 0);
71 size_t GetLineNumber() { return m_lineNumber; }
72 };
73
74 struct SEXPR_INTEGER : public SEXPR
75 {
76 int64_t m_value;
77
78 SEXPR_INTEGER( int64_t aValue ) :
79 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER ), m_value( aValue ) {};
80
81 SEXPR_INTEGER( int64_t aValue, int aLineNumber ) :
82 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_INTEGER, aLineNumber ), m_value( aValue ) {};
83 };
84
85 struct SEXPR_DOUBLE : public SEXPR
86 {
87 double m_value;
88
89 SEXPR_DOUBLE( double aValue ) :
90 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE ), m_value( aValue ) {};
91
92 SEXPR_DOUBLE( double aValue, int aLineNumber ) :
93 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_DOUBLE, aLineNumber ), m_value( aValue ) {};
94 };
95
96 struct SEXPR_STRING : public SEXPR
97 {
98 std::string m_value;
99
100 SEXPR_STRING( std::string aValue ) :
101 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING ), m_value(aValue) {};
102
103 SEXPR_STRING( std::string aValue, int aLineNumber ) :
104 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_STRING, aLineNumber ), m_value( aValue ) {};
105 };
106
107 struct SEXPR_SYMBOL : public SEXPR
108 {
109 std::string m_value;
110
111 SEXPR_SYMBOL( std::string aValue ) :
112 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL ), m_value( aValue ) {};
113
114 SEXPR_SYMBOL( std::string aValue, int aLineNumber ) :
115 SEXPR( SEXPR_TYPE::SEXPR_TYPE_ATOM_SYMBOL, aLineNumber ), m_value( aValue ) {};
116 };
117
119 {
120 bool _Symbol;
121 const std::string& _String;
122 };
123
124 inline _OUT_STRING AsSymbol( const std::string& aString )
125 {
126 struct _OUT_STRING ret = { true, aString };
127 return ret;
128 }
129
130 inline _OUT_STRING AsString( const std::string& aString )
131 {
132 struct _OUT_STRING ret = { false, aString };
133 return ret;
134 }
135
137 {
138 bool _Symbol;
139 std::string& _String;
140 };
141
142 inline _IN_STRING AsSymbol( std::string& aString )
143 {
144 struct _IN_STRING ret = { true, aString };
145 return ret;
146 }
147
148 inline _IN_STRING AsString( std::string& aString )
149 {
150 struct _IN_STRING ret = { false, aString };
151 return ret;
152 }
153
155 {
156 friend class SEXPR_LIST;
157
158 public:
159 SEXPR_SCAN_ARG( int32_t* aValue ) :
160 type( Type::INT ) { u.int_value = aValue; }
161
162 SEXPR_SCAN_ARG( int64_t* aValue ) :
163 type( Type::LONGINT ) { u.lint_value = aValue; }
164
165 SEXPR_SCAN_ARG( double* aValue ) :
166 type( Type::DOUBLE ) { u.dbl_value = aValue; }
167
168 SEXPR_SCAN_ARG( std::string* aValue ) :
169 type( Type::STRING ) { u.str_value = aValue; }
170
171 SEXPR_SCAN_ARG( _IN_STRING& aValue ) :
172 type( Type::SEXPR_STRING ) { u.sexpr_str = &aValue; }
173
174 SEXPR_SCAN_ARG( const std::string* aValue ) :
175 type( Type::STRING_COMP ) { str_value = *aValue; }
176
177 SEXPR_SCAN_ARG( std::string aValue ) :
178 type( Type::STRING_COMP ) { str_value = aValue; }
179
180 SEXPR_SCAN_ARG( const char* aValue ) :
181 type( Type::STRING_COMP ) { str_value = aValue; }
182
183 private:
184 enum class Type : char { INT, DOUBLE, STRING, LONGINT, STRING_COMP, SEXPR_STRING };
185 Type type;
186
187 union
188 {
189 int64_t* lint_value;
190 int32_t* int_value;
191 double* dbl_value;
192 std::string* str_value;
193 _IN_STRING* sexpr_str;
194 } u;
195
196 std::string str_value;
197 };
198
200 {
201 friend class SEXPR_LIST;
202
203 public:
204 SEXPR_CHILDREN_ARG( int32_t aValue ) :
205 type( Type::INT ) { u.int_value = aValue; }
206
207 SEXPR_CHILDREN_ARG( int64_t aValue ) :
208 type( Type::LONGINT ) { u.lint_value = aValue; }
209
210 SEXPR_CHILDREN_ARG( double aValue ) :
211 type( Type::DOUBLE ) { u.dbl_value = aValue; }
212
213 SEXPR_CHILDREN_ARG( std::string aValue ) :
214 type( Type::STRING ) { str_value = aValue; }
215
216 SEXPR_CHILDREN_ARG( const char* aValue ) :
217 type( Type::STRING ) { str_value = aValue; }
218
219 SEXPR_CHILDREN_ARG( const _OUT_STRING& aValue ) :
220 type( Type::SEXPR_STRING ) { str_value = aValue._String; u.symbol = aValue._Symbol; }
221
222 SEXPR_CHILDREN_ARG( SEXPR* aPointer ) :
223 type( Type::SEXPR_ATOM ) { u.sexpr_ptr = aPointer; }
224
225 private:
226 enum class Type : char { INT, DOUBLE, STRING, LONGINT, SEXPR_STRING, SEXPR_ATOM };
227 Type type;
228
229 union
230 {
231 int64_t lint_value;
232 int32_t int_value;
233 double dbl_value;
234 SEXPR* sexpr_ptr;
235 bool symbol;
236 } u;
237
238 std::string str_value;
239 };
240
241 class SEXPR_LIST : public SEXPR
242 {
243 public:
244 SEXPR_LIST() : SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST ), m_inStreamChild( 0 ) {};
245
246 SEXPR_LIST( int aLineNumber ) :
247 SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST, aLineNumber), m_inStreamChild( 0 ) {};
248
249 template <typename... Args>
250 SEXPR_LIST( const Args&... args ) :
251 SEXPR( SEXPR_TYPE::SEXPR_TYPE_LIST ), m_inStreamChild( 0 )
252 {
253 AddChildren(args...);
254 };
255
256 SEXPR_VECTOR m_children;
257
258 template <typename... Args>
259 size_t Scan( const Args&... args )
260 {
261 SEXPR_SCAN_ARG arg_array[] = { args... };
262 return doScan( arg_array, sizeof...( Args ) );
263 }
264
265 template <typename... Args>
266 void AddChildren( const Args&... args )
267 {
268 SEXPR_CHILDREN_ARG arg_array[] = { args... };
269 doAddChildren( arg_array, sizeof...( Args ) );
270 }
271
272 virtual ~SEXPR_LIST();
273
274 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, double value );
275 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, float value );
276 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int64_t value );
277 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, int32_t value );
278 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, std::string value );
279 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const _OUT_STRING setting );
280 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, const ISEXPRABLE& obj );
281 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR_LIST* list2 );
282 friend SEXPR_LIST& operator<< ( SEXPR_LIST& list, SEXPR* obj );
283 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, ISEXPRABLE& obj );
284 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, std::string& str );
285 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int32_t& inte );
286 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, int64_t& inte );
287 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, float& inte );
288 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, double& inte );
289 friend SEXPR_LIST& operator>> ( SEXPR_LIST& input, const _IN_STRING is );
290
291 private:
292 int m_inStreamChild;
293 size_t doScan( const SEXPR_SCAN_ARG *args, size_t num_args );
294 void doAddChildren( const SEXPR_CHILDREN_ARG *args, size_t num_args );
295 };
296}
297
298#endif
Definition: isexprable.h:29
Definition: sexpr.h:200
Definition: sexpr.h:242
Definition: sexpr.h:155
Definition: sexpr.h:45
Definition: sexpr.h:86
Definition: sexpr.h:75
Definition: sexpr.h:97
Definition: sexpr.h:108
Definition: sexpr.h:137
Definition: sexpr.h:119