-
Notifications
You must be signed in to change notification settings - Fork 0
/
tree.hpp
347 lines (306 loc) · 7.88 KB
/
tree.hpp
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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#ifndef _TREE_H_
#define _TREE_H_ 1
#include <iostream>
#include "compiler/symb_tab/symbol_table.hpp"
#define NOIMPLEMENT \
cout << "Sin implementacion." << endl; \
exit(1);
#define llog(s, e) \
\
cout << s \
<< endl; \
\
if (e != 0) \
exit(e);
#if (defined(DEBUG) && (DEBUG == true))
#define dlog(s, e) log(s, e)
#else
#define dlog(s, e)
#endif
#include <map>
#include <string.h> // this is for strcpy
#include <vector>
using namespace std;
/**
* Operaciones de operandos
*/
enum optypes
{
Store,
Load,
Plus,
Minus,
Times,
Slash,
Mod,
And,
Or,
BitAnd,
BitOr,
BitXor,
BitShiftL,
BitShiftR,
Eq,
Neq,
Less,
LessEq,
Gtr,
GtrEq,
Lea
};
/**
* Indica a los nodos donde se cargara o almacenara el valor de la variable o constante
*
* Por lo general si se carga una variable, se hara en registro
* pero cuando son de otro tipo, por ejemplo: float, se debe cargar a a pila del FPU
* para poder usarlo
*/
enum LoadStorePlace
{
REG,
MEMO,
STACK,
S_FPU //pila de la FPU
};
void randomString(int size, char *output);
string *_to_reg_(int r, int offset);
string *_to_reg_(int r);
bool sreq(Struct *, Struct *);
class ExternSymbols
{
public:
ExternSymbols()
{
symbols = (string **)malloc(sizeof(string) * 1000);
};
void add(string *sym)
{
symbols[s] = sym;
s++;
};
void dump()
{
cout << "; simbolos externos (" << s << ")" << endl;
for (int i = 0; i < s; ++i)
{
cout << "extern " << *symbols[i] << endl;
}
};
int s = 0;
string **symbols;
};
class Rand_label
{
public:
static string *newLabel(int size)
{
char *r = (char *)malloc(sizeof(char) * size);
string tokens("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_");
for (int x = 0; x < size; x++)
{
r[x] = tokens[rand() % 63];
}
r[size] = '\0';
return new string(r);
};
};
class StringLiterals
{
public:
StringLiterals(){};
string *add(string *n_string)
{
string *key = new string("sl_");
key->append(Rand_label::newLabel(s > 50 ? 20 : 10)->c_str());
cout << "; ID " << *key << endl;
//string nc(Rand_label::newLabel(20)->c_str());
this->string_lits.insert(make_pair(*key, n_string));
s++;
return key;
};
void dump()
{
cout << "; strings literals (" << s << ")" << endl;
for (const pair<string, string *> &p : string_lits)
{
std::cout << p.first << " db " << *p.second << ",0" << std::endl;
}
};
int s = 0;
map<string, string *> string_lits;
};
enum EffectiveType
{
Reg,
Num
};
enum EffectivePartLoadMode
{
Sub,
Add,
Mul,
Div
};
const char *modoToString(EffectivePartLoadMode mode);
class EffectivePart
{
public:
EffectivePart();
EffectivePart(int);
EffectivePart(int, EffectiveType);
EffectivePart(int, EffectivePartLoadMode);
EffectivePart(int, EffectiveType,EffectivePartLoadMode);
int load;
EffectivePartLoadMode mode = Add;
EffectiveType type = Reg;
};
class EffectiveAddr
{
public:
EffectiveAddr(){};
// bool withDir = false;
bool withBp = false;
//int count = 0;
//int *regs = nullptr;
//vector<EffectivePart *> regis;
//vector<EffectivePart *> addrs;
vector<EffectivePart *> parts;
//int dir;
/**
*
*/
char *toString();
};
class LoadOpt
{
public:
LoadOpt() { effectivea = new EffectiveAddr; };
int reg = -1;
EffectiveAddr *effectivea = nullptr;
EffectiveAddr *secundary_effectivea = nullptr;
};
class StoreOpt
{
public:
StoreOpt() { aefective = new EffectiveAddr; };
int dir = -1;
EffectiveAddr *aefective = nullptr;
};
class OpResult
{
int reg = -1;
};
class NODE;
class STAT;
class BLOCK;
class EXPR;
typedef ::NODE *AST;
class NODE
{ //friend AST BinOpNode(optypes op, AST left, AST right);
//friend class BINOPNODE;
//friend class ASSIGNMENT;
public:
Obj *obj = new Obj(0, new string(), new Struct());
int type;
NODE() { defined = 0; }
virtual void load(int R) = 0;
virtual void lea(int R){};
virtual void store(int R){};
// Generate code for loading value of a node into register R
//protected:
int value; // value derived from this node
int defined; // 1 if value is defined
bool ifReturnOfFunc = false;
LoadStorePlace loadPlace = LoadStorePlace::REG;
LoadStorePlace storePlace = LoadStorePlace::MEMO;
LoadOpt *loadOpt = new LoadOpt();
StoreOpt *storeOpt = new StoreOpt;
OpResult *opResult = new OpResult;
virtual void operation(optypes O, int R) = 0;
virtual void loadreg(int R) { dlog("LOAD REG EMPTY", 0); }
virtual void leareg(int R) { dlog("LEA REG EMPTY", 0); }
virtual void storereg(int R) { dlog("STORE REG EMPTY", 0); }
};
class EXPR : public NODE
{
};
class STAT : public EXPR
{
};
class BLOCK : public STAT
{
public:
virtual void add(AST E)=0;
};
class AstHandler
{
public:
virtual AST CreatePrintNode(AST ex){NOIMPLEMENT};
virtual NODE *CreateStatementBlock(){NOIMPLEMENT};
virtual void StatementBlockAdd(AST BS, AST S){NOIMPLEMENT};
virtual AST AssignmentNode(AST left, AST right){NOIMPLEMENT};
virtual NODE *FuncDeclNode(string *name){NOIMPLEMENT};
virtual AST FuncCall(AST f_node, bool){NOIMPLEMENT};
virtual AST ProcCall(AST f_node){NOIMPLEMENT};
virtual void FuncCallAddArg(AST BS, AST S){NOIMPLEMENT};
virtual void SetValueAsReturnOfFunn(AST){NOIMPLEMENT};
virtual Obj *GetObjOfNode(NODE *n){NOIMPLEMENT};
virtual void SetObjOfNode(NODE *n, Obj *o){NOIMPLEMENT};
//expre
virtual AST MemberNode(AST obj, AST propery){NOIMPLEMENT};
virtual AST BinOpNode(optypes op, AST left, AST right){NOIMPLEMENT};
// Creates an AST for the binary operation "left op right"
virtual AST VarNode(string *name){NOIMPLEMENT};
// Creates an AST for a variable factor with specified name
virtual AST DesfRefVarNode(AST name){NOIMPLEMENT};
virtual AST RefVarNode(AST name){NOIMPLEMENT};
virtual AST ConstNode(int value){NOIMPLEMENT};
virtual AST ConstFloatNode(float value){NOIMPLEMENT};
virtual AST ConstStringNode(string *value){NOIMPLEMENT};
// Creates an AST for a constant factor with specified value
virtual AST ReturnNode(AST toReturn){NOIMPLEMENT};
virtual AST ReturnNode(){NOIMPLEMENT};
virtual AST EmptyNode(){NOIMPLEMENT};
// Creates an empty node
virtual AST CreateIfNode(AST){NOIMPLEMENT};
virtual AST CreateIfElseNode(AST, AST){NOIMPLEMENT};
/**
*
* Comienza la generacion de codigo a partir de el AST recolectado.
*
*/
virtual void GenerateCode(AST A, ExternSymbols *, StringLiterals *){NOIMPLEMENT};
};
/*
AST CreatePrintNode(AST ex);
NODE *CreateStatementBlock();
void StatementBlockAdd(AST BS, AST S);
AST AssignmentNode(AST left, AST right);
NODE *FuncDeclNode(string *name);
AST FuncCall(AST f_node, bool);
AST ProcCall(AST f_node);
void FuncCallAddArg(AST BS, AST S);
void SetValueAsReturnOfFunn(AST);
Obj *GetObjOfNode(NODE *n);
void SetObjOfNode(NODE *n, Obj *o);
//expre
AST BinOpNode(optypes op, AST left, AST right);
// Creates an AST for the binary operation "left op right"
AST VarNode(string *name);
// Creates an AST for a variable factor with specified name
AST DesfRefVarNode(AST name);
AST RefVarNode(AST name);
AST ConstNode(int value);
AST ConstFloatNode(float value);
AST ConstStringNode(string *value);
// Creates an AST for a constant factor with specified value
AST ReturnNode(AST toReturn);
AST ReturnNode();
AST EmptyNode();
// creates an empty node
AST CreateIfNode(AST);
AST CreateIfElseNode(AST, AST);
void GenerateCode(AST A, ExternSymbols *, StringLiterals *);
// Generates code from AST A
*/
#endif