"...git@git.uibk.ac.at:c102348/olat-ci-cd-testing-project.git" did not exist on "74b0679b83d990e5bee68bf97cd10e2b048b1c0f"
Newer
Older
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "mcc/ast.h"
#include "mcc/symbol_table_parse.h"
#include "utils/unused.h"
// ------------------------------------------------------------ Variable
int mcc_symbol_table_add_variable_declaration(
struct mcc_ast_declaration *declaration,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec) {
assert(declaration);
assert(symbol_table);
assert(ec);
struct mcc_symbol *vs = mcc_symbol_new_symbol_variable(declaration->ident->i_value, declaration->type);
// check if already declared
if(mcc_symbol_table_get_symbol(symbol_table, vs->variable_name, false) == NULL) {
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
mcc_symbol_table_insert_symbol(symbol_table, vs);
return 0;
} else {
mcc_symbol_table_add_error(ec, mcc_symbol_table_new_error(&(declaration->node.sloc),
MCC_SEMANTIC_ERROR_VARIABLE_ALREADY_DECLARED));
return 1;
}
}
// ------------------------------------------------------------ Array
// returns 1 if error
int mcc_symbol_table_check_array_declaration_size(
struct mcc_ast_declaration *declaration,
struct mcc_symbol_table_error_collector *ec) {
if(declaration->arr_literal != NULL) {
// check if size is int
if(declaration->arr_literal->type != MCC_AST_DATA_TYPE_INT) {
mcc_symbol_table_add_error(
ec,
mcc_symbol_table_new_error(&(declaration->node.sloc), MCC_SEMANTIC_ERROR_ARRAY_SIZE_DEFINITION));
return 1;
}
}
return 0;
}
int mcc_symbol_table_add_array_declaration(
struct mcc_ast_declaration *declaration,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec) {
assert(declaration);
assert(symbol_table);
assert(ec);
if(mcc_symbol_table_check_array_declaration_size(declaration, ec) == 1) {
return 1;
}
struct mcc_symbol *vs = mcc_symbol_new_symbol_array(
declaration->ident->i_value,
declaration->type,
declaration->arr_literal->i_value);
vs->symbol_type = MCC_SYMBOL_TYPE_ARRAY;
// check if already declared
if(mcc_symbol_table_get_symbol(symbol_table, vs->variable_name, false) == NULL) {
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
// add array declaration to symbol table
mcc_symbol_table_insert_symbol(symbol_table, vs);
return 0;
} else {
mcc_symbol_table_add_error(ec, mcc_symbol_table_new_error(&(declaration->node.sloc),
MCC_SEMANTIC_ERROR_ARRAY_ALREADY_DECLARED));
return 1;
}
}
// ---------------------------------------------------------- Statement
int mcc_symbol_table_parse_compound_statement(
struct mcc_ast_statement *statement,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec
) {
assert(statement);
assert(statement->type == MCC_AST_STATEMENT_TYPE_COMPOUND);
assert(symbol_table);
assert(ec);
struct mcc_ast_statement_list *stl = statement->statement_list;
if(stl == NULL){
return 0;
}
while(stl->statement != NULL ) {
int create_new = 0;
if (stl -> statement -> type == MCC_AST_STATEMENT_TYPE_COMPOUND) {
create_new = 1;
}
int statement_result = mcc_symbol_table_parse_statement(
stl->statement,
symbol_table,
ec,
create_new
);
if(statement_result == 1) {
return 1;
}
if (stl->next == NULL){
break;
} else{
stl = stl->next;
}
}
return 0;
}
int mcc_symbol_table_parse_statement(
struct mcc_ast_statement *statement,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec,
int create_new) {
assert(statement);
assert(symbol_table);
assert(ec);
struct mcc_symbol_table *table = symbol_table;
if (create_new) {
table = mcc_symbol_table_create_inner_table(symbol_table,symbol_table->parent->sym_table_name);
}
switch(statement->type) {
case MCC_AST_STATEMENT_TYPE_RETURN:
case MCC_AST_STATEMENT_TYPE_EXPRESSION:
return mcc_symbol_table_validate_expression(statement->expression, table, ec);
case MCC_AST_STATEMENT_TYPE_WHILE:
if(mcc_symbol_table_validate_expression(
if (mcc_symbol_table_validate_condition_to_type_bool(
statement -> while_condition,
ec
) == 0) {
return mcc_symbol_table_parse_statement(
statement->while_stmt, table, ec, 1);
} else {
return 1;
}
} else {
return 1;
}
case MCC_AST_STATEMENT_TYPE_IF:
if (mcc_symbol_table_validate_condition_to_type_bool(
statement -> if_condition,
ec
) == 0) {
return mcc_symbol_table_parse_statement(
} else {
return 1;
}
} else {
return 1;
}
case MCC_AST_STATEMENT_TYPE_DECL:
if (statement->declaration->arr_literal != NULL) {
// array declaration
return mcc_symbol_table_add_array_declaration(statement->declaration, table, ec);
return mcc_symbol_table_add_variable_declaration(statement->declaration, table, ec);
return mcc_symbol_table_validate_assignment_semantic(statement->assignment, table, ec);
case MCC_AST_STATEMENT_TYPE_ASSGN_ARR:
return mcc_symbol_table_validate_assignment_array(statement->assignment, table, ec);
case MCC_AST_STATEMENT_TYPE_COMPOUND:
return mcc_symbol_table_parse_compound_statement(
statement,
ec
);
default:
return 0;
}
}
// ---------------------------------------------------------- Function
int mcc_symbol_table_parse_function(
struct mcc_ast_function *func_def,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec
) {
assert(func_def);
assert(symbol_table);
assert(ec);
// create new scope and parse function
struct mcc_symbol_table *sub_table = mcc_symbol_table_create_inner_table(symbol_table,func_def->identifier->i_value);
// add params to sub table
if (func_def -> parameter != NULL && func_def -> parameter -> parameters -> size > 0) {
struct mcc_ast_parameter *p = func_def -> parameter;
for (int i = 0; i < p -> parameters -> size; i++) {
struct mcc_ast_declaration *declaration = p -> parameters -> arr[i];
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
// at this point symbol table is still empty -> adding won't result in an error
if (declaration -> arr_literal != NULL) {
// array declaration
mcc_symbol_table_add_array_declaration(declaration, sub_table, ec);
} else {
// variable declaration
mcc_symbol_table_add_variable_declaration(declaration, sub_table, ec);
}
}
}
int valid_function_body = mcc_symbol_table_parse_statement(func_def -> statement, sub_table, ec, 0);
if (valid_function_body == 0) {
// valid function body - check if return type of non-void function is correct
if (func_def -> return_type != MCC_AST_DATA_TYPE_VOID) {
valid_function_body = mcc_symbol_table_validate_statement_return(
func_def -> statement,
func_def -> return_type,
sub_table,
ec
);
}
}
return valid_function_body;
}
int mcc_symbol_table_add_function_declaration(
struct mcc_ast_function *func_def,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec) {
assert(symbol_table);
assert(ec);
assert(func_def);
struct mcc_symbol *fs = mcc_symbol_new_symbol_function(
func_def->identifier->i_value,
func_def->return_type,
func_def->parameter);
// check if already declared
if(mcc_symbol_table_get_symbol(symbol_table, fs -> variable_name, true) == NULL) {
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
mcc_symbol_table_insert_symbol(symbol_table, fs);
return 0;
} else {
// already declared - create already declared error message
mcc_symbol_table_add_error(ec, mcc_symbol_table_new_error(&(func_def->node.sloc),
MCC_SEMANTIC_ERROR_FUNC_ALREADY_DECLARED));
return 1;
}
}
// ---------------------------------------------------------- Program
void mcc_add_builtin_function(
struct mcc_symbol_table *symbol_table,
char *variable_name,
enum mcc_ast_data_type return_type,
enum mcc_ast_data_type param_type) {
struct mcc_symbol *symbol = malloc(sizeof(*symbol));
symbol -> variable_name = variable_name;
symbol -> data_type = return_type;
symbol -> symbol_type = MCC_SYMBOL_TYPE_BUILTIN_FUNCTION;
symbol -> func_arguments = mcc_create_dynamic_array(5);
if (param_type != MCC_AST_DATA_TYPE_VOID) {
struct mcc_symbol_function_argument *fp = malloc(sizeof(*fp));
fp -> arg_type = param_type;
mcc_add_to_array(symbol -> func_arguments, fp);
}
symbol_table -> inner_tables -> arr[0] = NULL;
mcc_symbol_table_insert_symbol(symbol_table,symbol);
}
void mcc_symbol_table_add_builtins(struct mcc_symbol_table *symbol_table) {
mcc_add_builtin_function(symbol_table,"print_nl",MCC_AST_DATA_TYPE_VOID,MCC_AST_DATA_TYPE_VOID);
mcc_add_builtin_function(symbol_table,"print",MCC_AST_DATA_TYPE_VOID,MCC_AST_DATA_TYPE_STRING);
mcc_add_builtin_function(symbol_table,"print_int",MCC_AST_DATA_TYPE_VOID,MCC_AST_DATA_TYPE_INT);
mcc_add_builtin_function(symbol_table,"print_float",MCC_AST_DATA_TYPE_VOID,MCC_AST_DATA_TYPE_FLOAT);
mcc_add_builtin_function(symbol_table,"read_int",MCC_AST_DATA_TYPE_INT,MCC_AST_DATA_TYPE_VOID);
mcc_add_builtin_function(symbol_table,"read_float",MCC_AST_DATA_TYPE_FLOAT,MCC_AST_DATA_TYPE_VOID);
}
int mcc_symbol_table_parse_program(
struct mcc_ast_program *program,
struct mcc_symbol_table *symbol_table,
struct mcc_symbol_table_error_collector *ec) {
assert(program);
int function_parse = 0;
for(int i = 0; i < program -> function_def -> size; i++) {
function_parse = mcc_symbol_table_add_function_declaration(program->function_def -> arr[i], symbol_table, ec);
if (function_parse) break;
}
// if everything so far ok
if (function_parse == 0) {
// parse all functions
for(int i = 0; i < program-> function_def -> size; i++) {
function_parse = mcc_symbol_table_parse_function(program->function_def -> arr[i], symbol_table, ec);
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
if (function_parse) break;
}
}
return function_parse;
}
struct mcc_symbol_table *mcc_symbol_table_build_program(struct mcc_ast_program *program, struct mcc_symbol_table_error_collector *ec) {
assert(program);
struct mcc_symbol_table *st = mcc_symbol_table_new_table(NULL);
mcc_symbol_table_add_builtins(st);
if (mcc_symbol_table_parse_program(program, st, ec) == 0) {
// check if main exists
if (mcc_symbol_table_validate_main(program, st, ec) == 0) {
return st;
} else {
return NULL;
}
} else {
return NULL;
}
}
struct mcc_symbol_table *mcc_symbol_table_build_function(struct mcc_ast_function *function, struct mcc_symbol_table_error_collector *ec) {
assert(function);
struct mcc_symbol_table *st = mcc_symbol_table_new_table(NULL);
mcc_symbol_table_add_builtins(st);
int parse_function = mcc_symbol_table_add_function_declaration(function, st, ec);
if (parse_function == 0) {
if (mcc_symbol_table_parse_function(function, st, ec) == 0) {
return st;
} else {
// handle error collection
return NULL;
}
} else {
// handle error collection
return NULL;
}
}