-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatetypes.h
executable file
·276 lines (197 loc) · 5.98 KB
/
datetypes.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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#ifndef _DATETYPES_H
#define _DATETYPES_H
#include <string>
#include "enviroment.h"
class Enviroment;
using namespace std;
/*! @brief Abstraktní prataťka všech datových typů
*/
class Elem {
public:
Elem() {
this->line = 0;
this->col = 0;
}
//! Vrátí tisknutelnou reprezentaci Elem.
//! Je používáno při debuggingu a funkcí print
virtual string printable() = 0;
//! funkce whois() vrátí textový identifikátor datového typu. Používá se
//! kvůli dynamickému typování lispu
virtual string whois() = 0;
virtual ~Elem()=0;
//! Vrátí kopii objektu
virtual Elem* copy() = 0;
//! Číslo řádku (kvůli zobrazuje se v chybových hláškách)
int line;
//! Pozice na řádku @sa this->line
int col;
};
//! Třída pro symboly (názvy proměnných a funkcí)
class LSymbol : public Elem {
public:
LSymbol() {
}
//! Vytvoří nový LSymbol z jeho textové reprezentace (tokenu)
LSymbol(string & tokRepr);
virtual string printable();
virtual string whois();
virtual Elem* copy();
//! název symbolu (obsah je definován v Enviroment->symbols)
string name;
private:
};
//! Celočíselný datový typ.
class LInt : public Elem {
public:
LInt() {
this->repr = 0;
}
LInt(const int num) {
this->repr = num;
}
LInt(string & tokRepr);
virtual string printable();
virtual string whois();
virtual Elem* copy();
//! Vnitřní reprezentace
int repr;
private:
};
//! Seznam - linked list
class LList : public Elem {
public:
LList(LList&);
LList() {
this->car = NULL;
this->cdr = NULL;
}
virtual string printable();
virtual string whois();
virtual Elem* copy();
// přidá prvek na konec seznamu
void add(Elem * e);
//! vrátí délku seznamu
int len();
//! vrátí ukazatel na poslední prvek seznamu
LList * last();
//! obsah tohoto prvku @sa this->cdr
Elem * car;
//! odkaz na následující prvek @sa this->car
LList * cdr;
};
//! Datový typ pro řetězce
class LString : public Elem {
public:
LString() {
}
LString(string & tokRepr);
virtual string printable();
virtual string whois();
virtual Elem* copy();
//! vnitřní reprezentace řetezce
string repr;
private:
};
//! Společný datový typ pro primitivní a lispovské funkce a makra.
class LFunction : public Elem {
public:
// všecky druhy funkcí se volají s stejným API:
virtual Elem * call(LList * params, Enviroment *) = 0;
//! Název přeřazený funkci (nepoviné, zobrazuje se v chybových hláškách)
string name;
};
//! Primitivní funkce (v C)
class LFunctionC : public LFunction {
public:
LFunctionC(Elem * (*funct)(LList *, Enviroment * env)) {
// cout << "added FC: " << funct << endl;
this->funct = funct;
}
virtual string printable();
virtual string whois();
virtual Elem* copy();
Elem * call(LList * params, Enviroment *);
//! Ukazatel na funkci v C (všecky mají stejné c-API)
Elem * (*funct)(LList *, Enviroment *);
};
//! Lispovská funkce
class LFunctionL : public LFunction {
public:
LFunctionL() {
}
LFunctionL(LList * params, LList * funct) {
// cout << "added FL: " << funct << "params: " << params->printable() << "funct: " << funct->printable() << endl;
this->params = params;
this->funct = funct;
}
virtual string printable();
virtual string whois();
virtual Elem* copy();
Elem * call(LList * params, Enviroment * env);
//! seznam parametrů
LList * params;
//! seznam reprezentující tělo funkce
LList * funct;
};
//! Lispovské makro
class LFunctionM : public LFunction {
public:
LFunctionM() {
}
LFunctionM(LList * params, LList * funct) {
// cout << "added M: " << funct << "$ " << params->printable() << " $ " << funct->printable() << endl;
this->params = params;
this->funct = funct;
}
virtual string printable();
virtual string whois();
virtual Elem* copy();
Elem * call(LList * params, Enviroment * env);
//! seznam parametrů
LList * params;
//! tělo makra
LList * funct;
};
//! Datový typ pro logické hodnoty
class LBool : public Elem {
public:
LBool() {
}
LBool(bool val);
virtual string printable();
virtual string whois();
virtual Elem* copy();
//! vnitřní reprezentace
bool val;
};
// HELPERS:
/*! Pomocná funkce pro kontrolu počtu parametrů v primitivních funkcích.
* @param n - požadovaný počet parametrů
* @param params - parametry předané primitivní funkci
* @return - nic nevrací, v případě že počty parametrů sobě neoodpovídají, vyvolá
* vyjímku TypeException
*/
void Nparams(int n, LList * params);
/*! šablona pro dynamickou kontrolu typů a přetypovávání
* @param x - proměnná, jejíž typ se bude kontrolovat
* @param ident - textový identifikátor požadovaného typu
* @return ukazatel na správný typ (místo obecného Elem*)
*/
template <typename T>
T * expect_X(Elem * x, string ident);
/*! Bere jako parametr ukazatel na obecný typ Elem, a v případě že jecíl ukazatele
* typu LBool tak vrátí přetypovaný ukazatel na tu hodnotu. Jinak vyhodí vyjímku
* TypeException
* @param x - ukazatel na obecný typ Elem *
* @return - ukazatel na konkrétní typ LBool *
*/
LBool * expect_LBool(Elem * x);
LInt * expect_LInt(Elem * x); //!< @sa expect_LBool
LList * expect_LList(Elem * x); //!< @sa expect_LBool
LString * expect_LString(Elem * x); //!< @sa expect_LBool
LSymbol * expect_LSymbol(Elem * x); //!< @sa expect_LBool
//LFunction * expect_Lfunction(Elem * x);//!< @sa expect_LBool
LFunctionC * expect_LfunctionC(Elem * x); //!< @sa expect_LBool
LFunctionL * expect_LfunctionL(Elem * x); //!< @sa expect_LBool
LFunctionM * expect_LfunctionM(Elem * x); //!< @sa expect_LBool
#endif /* _DATETYPES_H */