forked from cparse/cparse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontainers.h
248 lines (199 loc) · 5.85 KB
/
containers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#ifndef CONTAINERS_H_
#define CONTAINERS_H_
#include <map>
#include <list>
#include <vector>
#include <string>
#include <memory>
namespace cparse {
template <typename T>
struct Container {
protected:
std::shared_ptr<T> ref;
public:
Container() : ref(std::make_shared<T>()) {}
Container(const T& t) : ref(std::make_shared<T>(t)) {}
public:
operator T*() const { return ref.get(); }
friend bool operator==(Container<T> first, Container<T> second) {
return first.ref == second.ref;
}
};
struct Iterator;
struct Iterable : public TokenBase {
virtual ~Iterable() {}
Iterable() {}
Iterable(tokType_t type) : TokenBase(type) {}
virtual Iterator* getIterator() const = 0;
};
// Iterator super class.
struct Iterator : public Iterable {
Iterator() : Iterable(IT) {}
virtual ~Iterator() {}
// Return the next position of the iterator.
// When it reaches the end it should return NULL
// and reset the iterator automatically.
virtual packToken* next() = 0;
virtual void reset() = 0;
Iterator* getIterator() const;
};
struct TokenMap;
typedef std::map<std::string, packToken> TokenMap_t;
struct MapData_t {
TokenMap_t map;
TokenMap* parent;
MapData_t();
MapData_t(TokenMap* p);
MapData_t(const MapData_t& other);
~MapData_t();
MapData_t& operator=(const MapData_t& other);
};
struct TokenMap : public Container<MapData_t>, public Iterable {
// Static factories:
static TokenMap empty;
static TokenMap& base_map();
static TokenMap& default_global();
static packToken default_constructor(TokenMap scope);
public:
// Attribute getters for the `MapData_t` content:
TokenMap_t& map() const { return ref->map; }
TokenMap* parent() const { return ref->parent; }
public:
// Implement the Iterable Interface:
struct MapIterator : public Iterator {
const TokenMap_t& map;
TokenMap_t::const_iterator it = map.begin();
packToken last;
MapIterator(const TokenMap_t& map) : map(map) {}
packToken* next();
void reset();
TokenBase* clone() const {
return new MapIterator(*this);
}
};
Iterator* getIterator() const {
return new MapIterator(map());
}
public:
TokenMap(TokenMap* parent = &TokenMap::base_map())
: Container(parent), Iterable(MAP) {
// For the TokenBase super class
this->type = MAP;
}
TokenMap(const TokenMap& other) : Container(other) {
this->type = MAP;
}
virtual ~TokenMap() {}
public:
// Implement the TokenBase abstract class
TokenBase* clone() const {
return new TokenMap(*this);
}
public:
packToken* find(const std::string& key);
const packToken* find(const std::string& key) const;
TokenMap* findMap(const std::string& key);
void assign(std::string key, TokenBase* value);
void insert(std::string key, TokenBase* value);
TokenMap getChild();
packToken& operator[](const std::string& str);
void erase(std::string key);
};
// Build a TokenMap which is a child of default_global()
struct GlobalScope : public TokenMap {
GlobalScope() : TokenMap(&TokenMap::default_global()) {}
};
typedef std::vector<packToken> TokenList_t;
struct TokenList : public Container<TokenList_t>, public Iterable {
static packToken default_constructor(TokenMap scope);
public:
// Attribute getter for the `TokenList_t` content:
TokenList_t& list() const { return *ref; }
public:
struct ListIterator : public Iterator {
TokenList_t* list;
uint64_t i = 0;
ListIterator(TokenList_t* list) : list(list) {}
packToken* next();
void reset();
TokenBase* clone() const {
return new ListIterator(*this);
}
};
Iterator* getIterator() const {
return new ListIterator(&list());
}
public:
TokenList() { this->type = LIST; }
virtual ~TokenList() {}
packToken& operator[](const uint64_t idx) const {
if (list().size() <= idx) {
throw std::out_of_range("List index out of range!");
}
return list()[idx];
}
void push(packToken val) const { list().push_back(val); }
packToken pop() const {
packToken back = list().back();
list().pop_back();
return back;
}
public:
// Implement the TokenBase abstract class
TokenBase* clone() const {
return new TokenList(*this);
}
};
class Tuple : public TokenList {
public:
Tuple() { this->type = TUPLE; }
Tuple(const TokenBase* first) {
this->type = TUPLE;
list().push_back(packToken(first->clone()));
}
Tuple(const packToken first) : Tuple(first.token()) {}
Tuple(const TokenBase* first, const TokenBase* second) {
this->type = TUPLE;
list().push_back(packToken(first->clone()));
list().push_back(packToken(second->clone()));
}
Tuple(const packToken first, const packToken second)
: Tuple(first.token(), second.token()) {}
public:
// Implement the TokenBase abstract class
TokenBase* clone() const {
return new Tuple(*this);
}
};
// This Special Tuple is to be used only as syntactic sugar, and
// constructed only with the operator `:`, i.e.:
// - passing key-word arguments: func(1, 2, optional_arg:10)
// - slicing lists or strings: my_list[2:10:2] (not implemented)
//
// STuple means one of:
// - Special Tuple, Syntactic Tuple or System Tuple
//
// I haven't decided yet. Suggestions accepted.
class STuple : public Tuple {
public:
STuple() { this->type = STUPLE; }
STuple(const TokenBase* first) {
this->type = STUPLE;
list().push_back(packToken(first->clone()));
}
STuple(const packToken first) : STuple(first.token()) {}
STuple(const TokenBase* first, const TokenBase* second) {
this->type = STUPLE;
list().push_back(packToken(first->clone()));
list().push_back(packToken(second->clone()));
}
STuple(const packToken first, const packToken second)
: STuple(first.token(), second.token()) {}
public:
// Implement the TokenBase abstract class
TokenBase* clone() const {
return new STuple(*this);
}
};
} // namespace cparse
#endif // CONTAINERS_H_