Newer
Older
#include <stdio.h>
#include<assert.h>
#include "mcc/dynamic_array.h"
#include "mcc/symbol_table.h"
#include "mcc/symbol_table_print.h"
static char *type_to_string(enum mcc_ast_data_type type){
switch (type)
{
case MCC_AST_DATA_TYPE_INT: return "int";
case MCC_AST_DATA_TYPE_STRING: return "string";
case MCC_AST_DATA_TYPE_BOOL: return "bool";
case MCC_AST_DATA_TYPE_FLOAT: return "float";
case MCC_AST_DATA_TYPE_VOID : return "void";
default: return "unknown";
}
}
static char *symbol_type_to_string(enum mcc_symbol_type type){
switch (type)
{
case MCC_SYMBOL_TYPE_VARIABLE: return "variable";
case MCC_SYMBOL_TYPE_ARRAY: return "array";
case MCC_SYMBOL_TYPE_FUNCTION: return "function";
case MCC_SYMBOL_TYPE_BUILTIN_FUNCTION : return "builtin function";
default: return "unknown";
}
}
void mcc_symbol_table_print(struct mcc_symbol_table *symbol_table, FILE *out){
printf("----------------------------------\n");
printf("Table: %s // Child of: %s\n", symbol_table ? symbol_table->sym_table_name : "no name",
symbol_table->parent ? symbol_table->parent->sym_table_name : "no parent");
printf("----------------------------------\n");
for(int i = 0; i < symbol_table->symbols->size; i++){
struct mcc_symbol *sym = (struct mcc_symbol *) symbol_table->symbols->arr[i];
if(sym->symbol_type != MCC_SYMBOL_TYPE_FUNCTION){
fprintf(out,"\t");
fprintf(out,"%*s | ", 15, symbol_type_to_string(sym->symbol_type));
fprintf(out,"%*s | ", 6, type_to_string(sym->data_type));
switch(sym->symbol_type){
case MCC_SYMBOL_TYPE_BUILTIN_FUNCTION:
case MCC_SYMBOL_TYPE_VARIABLE:
fprintf(out,"%s", sym->variable_name);
case MCC_SYMBOL_TYPE_ARRAY:
fprintf(out,"%s[%ld]", sym->variable_name, sym->array_size);
break;
case MCC_SYMBOL_TYPE_FUNCTION:
if(sym->func_arguments){
fprintf(out,"%s(", sym->variable_name);
for(int j = 0; j < sym->func_arguments -> size; j++){
struct mcc_symbol_function_argument *fp =
(struct mcc_symbol_function_argument *) sym ->func_arguments -> arr[j];
fprintf(out,"%s", type_to_string(fp -> arg_type));
if (j + 1 < sym->func_arguments->size) {
fprintf(out,", ");
}
}
fprintf(out,")");
}else{
fprintf(out,"%s()", sym->variable_name);
}
for (int i = 0; i < symbol_table->inner_tables->size; i++) {
mcc_symbol_table_print(symbol_table->inner_tables->arr[i],out);
void mcc_symbol_table_print_error(struct mcc_symbol_table_error_collector *ec, FILE *out) {
// for now only one error in collector
struct mcc_semantic_error *error = ec -> errors -> arr[0];
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
if (error != NULL) {
char *error_message = "\n";
switch (error ->error_type) {
case MCC_SEMANTIC_ERROR_VARIABLE_ALREADY_DECLARED:
error_message = "Variable arleady declared\n";
break;
case MCC_SEMANTIC_ERROR_ARRAY_ALREADY_DECLARED:
error_message = "Array already declared\n";
break;
case MCC_SEMANTIC_ERROR_FUNC_ALREADY_DECLARED:
error_message = "Function already declared\n";
break;
case MCC_SEMANTIC_ERROR_FUNC_NOT_DECLARED:
error_message = "Function not declared\n";
break;
case MCC_SEMANTIC_ERROR_INVALID_ARGUMENT_TYPE:
error_message = "Wrong type of argument\n";
break;
case MCC_SEMANTIC_ERROR_INVALID_NUM_OF_ARGUMENTS:
error_message = "Wrong number of arguments\n";
break;
case MCC_SEMANTIC_ERROR_VARIABLE_NOT_DECLARED:
error_message = "Variable not declared\n";
break;
case MCC_SEMANTIC_ERROR_ARRAY_SIZE_DEFINITION:
error_message = "Array size definition must be an int\n";
break;
case MCC_SEMANTIC_ERROR_ARRAY_OPERATIONS:
error_message = "Operations not allowed on array\n";
break;
case MCC_SEMANTIC_ERROR_TYPE_ASSIGNMENT:
error_message = "Wrong type assigned\n";
break;
case MCC_SEMANTIC_ERROR_MAIN_MISSING:
error_message = "Main missing\n";
break;
case MCC_SEMANTIC_ERROR_CONDITION_BOOL_EXPECTED:
error_message = "Condition must result in a bool\n";
break;
case MCC_SEMANTIC_ERROR_UNARY_OP_EXPECTED_BOOL:
error_message = "Boolean expected\n";
break;
case MCC_SEMANTIC_ERROR_UNARY_OP_EXPECTED_NUMBER:
error_message = "Number type expected\n";
break;
case MCC_SEMANTIC_ERROR_BINARY_OP_HANDSIDE_SAME_TYPE:
error_message = "Both parts of binary operator must be of same type\n";
break;
case MCC_SEMANTIC_ERROR_BINARY_OP_HANDSIDE_BOOL_TYPE:
error_message = "Bool expected in binary operator\n";
break;
case MCC_SEMANTIC_ERROR_BINARY_OP_HANDSIDE_NUMBER_TYPE:
error_message = "Number type expected in binary operator\n";
break;
case MCC_SEMANTIC_ERROR_BINARY_OP_DIV_BY_0:
error_message = "Division by 0 not allowed\n";
break;
case MCC_SEMANTIC_ERROR_INVALID_RETURN_TYPE_IN_NON_VOID_FUNCTION:
error_message = "Invlaid return type in non void function\n";
break;
case MCC_SEMANTIC_ERROR_NO_RETURN_IN_NON_VOID_FUNCTION:
error_message = "No return in non void function \n";
break;
case MCC_SEMANTIC_ERORR_ARRAY_REASSIGNMENT:
error_message = "No Array reassignment allowed \n";
break;
case MCC_SEMANTIC_ERROR_ARRAY_INDEX:
error_message = "Array index must be of type int \n";
break;
case MCC_SEMANTIC_ERROR_IDENTIFIER_NOT_AN_ARRAY:
error_message = "Variable not an array \n";
break;
}
fprintf(out, "Error in line %d and col %d \n", error ->sloc ->end_line, error -> sloc -> end_col);
fprintf(out, "%s \n", error_message);
}
}
void mcc_symbol_table_print_type_check_trace(struct mcc_symbol_table_error_collector *ec, FILE *out) {
assert(ec);
Dynamic_Array *type_check_arry = ec -> type_tracer;
if (type_check_arry == NULL) {
return;
}
for (int i = 0; i < type_check_arry -> size; i++) {
struct mcc_type_check *tc = (struct mcc_type_check *) type_check_arry -> arr[i];
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
int sloc = tc ->sloc ->end_line;
const char* expected = type_to_string(tc -> target_type);
const char* recieved = type_to_string(tc -> receiving_type);
switch (tc ->type) {
case MCC_SEMANTIC_TYPE_CHECK_RETURN:
fprintf(out, "Check valid return type @ line %d: Expected: %s - Received: %s \n",
sloc, expected, recieved);
break;
case MCC_SEMANTIC_TYPE_CHECK_UNARY:
fprintf(out, "Check valid unary operator type @ line %d: Expected: %s - Received: %s \n",
sloc, expected, recieved);
break;
case MCC_SEMANTIC_TYPE_CHECK_ARG_TYPE:
fprintf(out, "Check valid arg type @ line %d: Expected: %s - Received: %s \n",
sloc, expected, recieved);
break;
case MCC_SEMANTIC_TYPE_CHECK_CONDITION_BOOL:
fprintf(out, "Check condtion to be boolean @ line %d: Expected: %s - Received: %s \n",
sloc, expected, recieved);
break;
case MCC_SEMANIC_TYPE_CHECK_BINARY_HANDSIDE_BOTH:
fprintf(out, "Check binary operator both handsides same type @ line %d: Expected (lhs): %s - Received (rhs): %s \n",
sloc, expected, recieved);
break;
case MCC_SEMANIC_TYPE_CHECK_ASSIGNMENT:
fprintf(out, "Check valid assignment type @ line %d: Expected (lhs): %s - Received (rhs): %s \n",
sloc, expected, recieved);
break;
default:
continue;
}
}
}