Skip to content
Snippets Groups Projects
symbol_table_print.c 8.85 KiB
Newer Older
Clemens Paumgarten's avatar
Clemens Paumgarten committed
#include <stdio.h>
#include<assert.h>

#include "mcc/dynamic_array.h"
#include "mcc/symbol_table.h"
#include "mcc/symbol_table_print.h"

Clemens Paumgarten's avatar
Clemens Paumgarten committed
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");
Clemens Paumgarten's avatar
Clemens Paumgarten committed
     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");
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            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); 
                break;   
Clemens Paumgarten's avatar
Clemens Paumgarten committed
                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);
                    }
                    fprintf(out,"\n");
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            fprintf(out,"\n");
    }
    for (int i = 0; i < symbol_table->inner_tables->size; i++) {     
FlorianKrull's avatar
FlorianKrull committed
		mcc_symbol_table_print(symbol_table->inner_tables->arr[i],out);
Clemens Paumgarten's avatar
Clemens Paumgarten committed
void mcc_symbol_table_print_error(struct mcc_symbol_table_error_collector *ec, FILE *out) {
    // for now only one error in collector
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    struct mcc_semantic_error *error = ec -> errors -> arr[0];
Clemens Paumgarten's avatar
Clemens Paumgarten committed

    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;
Clemens Paumgarten's avatar
Clemens Paumgarten committed
        }

        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++) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
        struct mcc_type_check *tc = (struct mcc_type_check *) type_check_arry -> arr[i];
Clemens Paumgarten's avatar
Clemens Paumgarten committed

        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;
        }
    }
}