-
Notifications
You must be signed in to change notification settings - Fork 0
/
semantic.h
342 lines (305 loc) · 9.64 KB
/
semantic.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
/**
* @file semantic.h
* @author Jakub Všetečka <[email protected]>
* @brief Header file for semantic analysis.
* @version 0.1
* @date 2023-11-24
*
* @copyright Copyright (c) 2023
* Project: IFJ compiler
*
*/
#ifndef SEMANTIC_H
#define SEMANTIC_H
#include <stdio.h>
#include <stdlib.h>
#include "scanner.h"
#include "psa.h"
#include "utils.h"
#include "error.h"
#include "stack.h"
#include "symtable.h"
extern symtable_stack *sym_st;
#define RED "\x1B[31m"
#define GREEN "\x1B[32m"
#define YELLOW "\x1B[33m"
#define BLUE "\x1B[34m"
#define MAGENTA "\x1B[35m"
#define CYAN "\x1B[36m"
#define RESET "\x1B[0m"
typedef enum
{
STARTING,
LET,
VAR,
VAR_ID,
VAR_TYPE,
VAR_ASSIGN1,
VAR_ASSIGN2,
VAR_EXP,
VAR_ADD,
FUNC_ID,
FUNC_HEADER_DONE,
P_NAME,
P_ID,
P_TYPE,
R_TYPE,
R_EXP,
FUNC_BODY_DONE,
COND_EXP,
IF_START,
ELSE_IF_START,
ELSE_IF_AFTER_COND,
ELSE_START,
IF_END,
FUNC_IF_FOUND,
FUNC_ELSE,
WHILE_START,
WHILE_COND,
WHILE_END,
LET_IN_IF,
LOAD_IDENTIF,
IDENTIF_EXP,
FUNC_CALL_PSA,
PUSH_SCOPE,
POP_SCOPE,
SEM_NONE
} Control_state;
/**
* @brief Prints out sym_items attributes.
*
* @param items
*/
void print_items(sym_items *items);
/**
* @brief Stores current tokne to the token_stack. Loads next token.
*
* @param token Pointer to the current token. New token will be stored here.
* @param token_stack Pointer to the token stack.
*/
void push_token_get_next(Token *token, Token_stack *token_stack);
/**
* @brief Finds the function definition in the program.
*
* @param token Pointer to the current token.
* @param name Name of the function.
* @param psa_item Pointer to the symtable_item where the function definition will be stored.
*
* @return true if the function was found.
*/
bool get_func_definition(Token *token, char *name, symtable_item *psa_item);
/**
* @brief Converts token type to expression type.
*
* @param token Pointer to the token.
* @return Expression_type
*/
Expression_type get_expression_type(Token *token);
/**
* @brief Checks if the expression type is valid for the given ideticator type.
*
* @param t_exp Expression type.
* @param t_id Identifier type.
* @return true if the expression type is valid for the given ideticator type.
*/
bool check_ret_values(Expression_type t_exp, Expression_type t_id);
// SEMANTIC RULES
/**
* @brief Prepares semantic analysis for an 'if' block in a function.
* Resets the 'found_else' flag in the current scope.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_if_start(Token *token, sym_items *items);
/**
* @brief Marks the presence of an 'else' block in the current function scope.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_else(Token *token, sym_items *items);
/**
* @brief Initializes semantic analysis at the start of parsing.
* Resets the function item in sym_items to null.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_start(Token *token, sym_items *items);
/**
* @brief Manages the semantic analysis of a function call.
* Parses the call expression and validates its correctness.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_call_psa(Token *token, sym_items *items);
/**
* @brief Handles expressions involving identifiers.
* Validates type compatibility and marks the variable as initialized.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_identif_exp(Token *token, sym_items *items);
/**
* @brief Loads a variable identifier for semantic analysis.
* Validates the existence and mutability of the variable.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_load_identif(Token *token, sym_items *items);
/**
* @brief Finalizes the semantic analysis of a function body.
* Validates the presence of a return statement and resets scope attributes.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_body_done(Token *token, sym_items *items);
/**
* @brief Handles let declarations within 'if' blocks.
* Validates the let variable and sets up a new scope for the block.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_let_in_if(Token *token, sym_items *items);
/**
* @brief Validates the conditional expression in if/while statements.
* Ensures the expression type is boolean and compatible with the condition context.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_cond_exp(Token *token, sym_items *items);
/**
* @brief Handles return expressions in functions.
* Validates the expression type against the function's return type and marks the return as found.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_r_exp(Token *token, sym_items *items);
/**
* @brief Pops the current scope from the symbol table stack.
* Handles return logic for functions, updating attributes in the parent scope.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_pop_scope(Token *token, sym_items *items);
/**
* @brief Creates and pushes a new scope onto the symbol table stack.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_push_scope(Token *token, sym_items *items);
/**
* @brief Finalizes the function header and adds the function to the symbol table.
* Initializes a new scope and adds parameters as local variables to this scope.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_header_done(Token *token, sym_items *items);
/**
* @brief Sets the return type for a function based on the given token.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_r_type(Token *token, sym_items *items);
/**
* @brief Determines and sets the type for a function parameter.
* Ensures the parameter's name and ID do not conflict and checks for duplicate parameters.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_p_type(Token *token, sym_items *items);
/**
* @brief Sets the identifier for a function parameter.
* Validates and initializes a corresponding variable item in sym_items.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_p_id(Token *token, sym_items *items);
/**
* @brief Assigns a name to a function parameter.
* Adds the parameter to the function's data and sets its name.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_p_name(Token *token, sym_items *items);
/**
* @brief Initializes a function item and sets its identifier.
* Checks for function name conflicts before setting the ID in sym_items.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_func_id(Token *token, sym_items *items);
/**
* @brief Adds the processed variable to the symbol table.
* Handles both new variables and parameters being converted to local variables.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_var_add(Token *token, sym_items *items);
/**
* @brief Handles the variable initialization expression.
* Evaluates the expression type, ensuring compatibility with the variable's declared type.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_var_exp(Token *token, sym_items *items);
/**
* @brief Sets the data type for a variable based on the token's expression type.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_var_type(Token *token, sym_items *items);
/**
* @brief Validates and sets the identifier for a variable.
* Checks for naming conflicts and sets the variable ID in sym_items.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_var_id(Token *token, sym_items *items);
/**
* @brief Manages the semantics of a non-constant variable declaration.
* Initializes a new variable item as non-constant in sym_items.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_var(Token *token, sym_items *items);
/**
* @brief Handles the semantics of a constant variable declaration ('let').
* Initializes a new variable item as constant in sym_items.
*
* @param token Pointer to the current token.
* @param items Pointer to the sym_items structure.
*/
void sem_let(Token *token, sym_items *items);
/**
* @brief Checks if the expression is convertable to the variable type. This behavior is defined in the documentation only for implicit type conversion of literals Int -> Double.
*
* @param variable_type type of the variable being assigned to
* @param expression_type type of the expression being assigned
* @param is_expression_literal true if the expression is a literal
* @return true
* @return false
*/
bool isTypeConvertable(Expression_type variable_type, Expression_type expression_type, bool is_expression_literal);
#endif // SEMANTIC_H