-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerator.h
395 lines (348 loc) · 8.92 KB
/
generator.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
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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/**
* @file generator.h
* @author Tomáš Hobza ([email protected])
* @brief Header file for the ifjcode2023 code generator.
* @version 0.1
* @date 2023-11-24
*
* @copyright Copyright (c) 2023
* Project: IFJ compiler
*
*/
#ifndef GENERATOR_H
#define GENERATOR_H
#include <stdio.h>
#include <stdlib.h>
#include "error.h"
#include "symtable.h"
#include "scanner.h"
#include "stack.h"
extern FILE *out_code_file;
extern FILE *while_def_out_code_file;
extern bool is_in_loop;
typedef enum
{
EMPTY,
// -
CREATEFRAME, // 0
PUSHFRAME, // 1
POPFRAME, // 2
RETURN, // 3
CLEARS, // 4
ADDS, // 5
SUBS, // 6
DIVS, // 7
IDIVS, // 8
MULS, // 9
LTS, // 10
EQS, // 11
GTS, // 12
ANDS, // 13
ORS, // 14
NOTS, // 15
INT2FLOATS, // 16
FLOAT2INTS, // 17
INT2CHARS, // 18
STRI2INTS, // 19
BREAK, // 20
// <label>
CALL, // 21
LABEL, // 22
JUMP, // 23
JUMPIFEQS, // 24
JUMPIFNEQS, // 25
// <var>
DEFVAR, // 26
POPS, // 27
// <symb>
PUSHS, // 28
WRITE, // 29
EXIT, // 30
DPRINT, // 31
// <var> <type>
READ, // 32
// <var> <symb>
MOVE, // 33
INT2FLOAT, // 34
FLOAT2INT, // 35
INT2CHAR, // 36
STRI2INT, // 37
STRLEN, // 38
TYPE, // 39
// <var> <symb> <symb>
ADD, // 40
SUB, // 41
DIV, // 42
IDIV, // 43
MUL, // 44
LT, // 45
GT, // 46
EQ, // 47
AND, // 48
OR, // 49
NOT, // 50
CONCAT, // 51
GETCHAR, // 52
SETCHAR, // 53
// <label> <symb> <symb>
JUMPIFEQ, // 54
JUMPIFNEQ, // 55
} Instruction;
typedef enum
{
B_WRITE,
B_READ,
B_INT2DOUBLE,
B_DOUBLE2INT,
B_LENGTH,
B_SUBSTRING,
B_ORD,
B_CHR,
B_INVALID
} BuiltinFunc;
/**
* @brief Generates a label operand for IFJcode23.
*
* @param name Name of the label.
* @return char*
*/
char *label(char *name);
/**
* @brief Generates a type operand for IFJcode23.
*
* @param type Type of the expression.
* @return char*
*/
char *type(Expression_type type);
/**
* @brief Generates a variable operand for IFJcode23.
*
* @param id Token with the id of the variable.
* @param scope -1 for temporary, 0 for global, 1+ for local
* @param has_suffix Whether the variable has a suffix with the scope index
* @return char*
*/
char *variable(char *id, int scope, bool has_suffix);
/**
* @brief Generates a symbol operand for IFJcode23.
*
* @param token Token with type and value.
* @return char*
*/
char *literal(Token token);
/**
* @brief Generates a symbol operand for IFJcode23.
*
* @param symbol Token with type and value.
* @return char*
*/
char *symbol(Token symbol);
/**
* @brief Returns the format of symb for IFJcode23.
*
* @param token Token with type and value.
* @return char* - string with the variable in the format for IFJcode23
*/
char *symb_resolve(Token token);
/**
* @brief Returns the format of the literal for IFJcode23.
*
* @param token Token record of the literal.
* @return char* - string with the literal in the format for IFJcode23
*/
char *format_token(Token token);
/**
* @brief -
*
* @param inst
*/
void handle_0_operand_instructions(Instruction inst);
/**
* @brief <label>/<var>/<symb>
*
* @param inst
* @param symb
*/
void handle_1_operand_instructions(Instruction inst, char *op1);
/**
* @brief <var> <symb>/<var> <type>
*
* @param inst
* @param var
* @param symb
*/
void handle_2_operand_instructions(Instruction inst, char *op1, char *op2);
/**
* @brief <var> <symb> <symb>/<label> <symb> <symb>
*
* @param inst
* @param var
* @param symb1
* @param symb2
*/
void handle_3_operand_instructions(Instruction inst, char *op1, char *op2, char *op3);
/**
* @brief Based on the number of operands provided, calls the appropriate function to handle the instruction.
*
* @param inst Instruction to be handled.
* @param operands Array of operands.
* @param operands_count Number of operands in the array.
*/
void processInstruction(Instruction inst, char **operands, int operands_count);
/**
* @brief Macro that generates the IFJcode23 instruction based on the given arguments.
*/
#define generate_instruction(instruction, ...) \
do \
{ \
char *operands[] = {__VA_ARGS__}; \
processInstruction(instruction, operands, sizeof(operands) / sizeof(char *)); \
} while (0)
/**
* @brief Prints the output code to stdout.
*/
void print_out_code();
/**
* @brief Generates the header of the IFJcode23 function.
*
* @param func_item symtable item of the function.
*/
void generate_func_header(symtable_item func_item);
/**
* @brief Generates the end of the IFJcode23 function.
*
* @param func_item symtable item of the function.
*/
void generate_func_end(symtable_item func_item);
/**
* @brief Generates the IFJcode23 built-in function call.
*
* @param func Token record of the function.
*/
void generate_builtin_func_call(Token func, int param_count);
/**
* @brief Generates the IFJcode23 if header.
*/
void generate_if_start();
/**
* @brief Generates the IFJcode23 the else part of the elseif.
*/
void generate_elseif_else();
/**
* @brief Generates the IFJcode23 the if part of the elseif.
*/
void generate_elseif_if();
/**
* @brief Generates the IFJcode23 else header.
*/
void generate_else();
/**
* @brief Generates the IFJcode23 if end.
*/
void generate_if_end();
/**
* @brief Generates the IFJcode23 while header.
*/
void generate_while_start();
/**
* @brief Generates the IFJcode23 while condition.
*/
void generate_while_condition();
/**
* @brief Generates the IFJcode23 while end.
*
*/
void generate_while_end();
/**
* @brief Generates implicit initialization for a variable if it is not already initialized.
*
* This function checks if the given variable (var_item) has been initialized.
* If not, and if the variable's type allows nil initialization
* (e.g., TYPE_INT_NIL, TYPE_DOUBLE_NIL, TYPE_STRING_NIL, TYPE_BOOL_NIL),
* it generates an implicit initialization instruction with a nil value.
* This ensures variables with potentially nullable types are correctly initialized to nil
* if no explicit initialization is provided in the source code.
*
* @param var_item The symtable_item representing the variable to be initialized.
* It contains information about the variable's initialization state and type.
*/
void generate_implicit_init(symtable_item var_item);
/**
* @brief Generates the IFJcode23 a temporary variable initialization.
*/
void generate_temp_pop();
/**
* @brief Generates the IFJcode23 a temporary variable push.
*/
void generate_temp_push();
/**
* @brief Generates the IFJcode23 for the nil coelacing operation.
*/
void generate_nil_coelacing();
/**
* @brief Generates the IFJcode23 for the string concat operation.
*/
void generate_string_concat();
/// UTILITY FUNCTIONS
/**
* @brief Converts the instruction to string.
*
* @param in Instruction to be converted.
* @return char* - string with the instruction
*/
char *instructionToString(Instruction in);
/**
* @brief Converts the string to instruction.
*
* @param str String to be converted.
* @return Instruction - instruction
*/
Instruction stringToInstruction(char *str);
/**
* @brief Checks if the token is a built-in function.
*
* @param token Function id token
* @return true
* @return false
*/
bool isBuiltInFunction(Token token);
/**
* @brief Gets the intruction associated with the built-in function.
*
* @param token
* @return char*
*/
BuiltinFunc getBuiltInFunctionName(Token token);
/**
* @brief Returns the data type of the read function
*
* @param token
* @return Token
*/
Expression_type getReadType(Token token);
/**
* @brief Replaces the special characters in the string with their escape sequences.
*
* @param input
* @return char*
*/
char *escapeString(char *input);
/**
* @brief Copies the contents of the source file to the destination file.
*
* @param source
* @param destination
*/
void copyFileContents(FILE *source, FILE *destination);
#define HANDLE_DEFVAR(provided_code) \
do \
{ \
FILE *temp = out_code_file; \
if (is_in_loop) \
{ \
out_code_file = while_def_out_code_file; \
} \
provided_code; \
out_code_file = temp; \
} while (0)
#endif // GENERATOR_H