Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tac.c 7.87 KiB
#include <stdlib.h>
#include <assert.h>

#include "mcc/tac.h"
#include "mcc/tac_string_builder.h"

// --------------------------------------------- Error Collector

// struct mcc_tac_error_collector *mcc_tac_new_error_collector() {
//     struct mcc_tac_error_collector *ec = malloc(sizeof(*ec));

//     if (ec == NULL) return NULL;

//     ec -> errors = mcc_create_dynamic_array(MCC_TAC_ERROR_SIZE);

//     return ec;
// }

// int mcc_tac_add_error(struct mcc_tac_error_collector *ec, struct mcc_tac_error *e) {
//     assert(ec);
//     assert(e);

//     return mcc_add_to_array(ec -> errors, e);
// }

// struct mcc_tac_error *mcc_tac_new_error(struct mcc_ast_source_location *sloc, enum mcc_tac_error_type error_type) {
//     struct mcc_tac_error *e = malloc(sizeof(*e));

//     e -> sloc = sloc;
//     e -> error_type = error_type;

//     return e;
// }

// --------------------------------------------- TAC Object

struct mcc_tac *mcc_tac_new(struct mcc_tac *prev_tac, struct mcc_symbol_table *st) {
    struct mcc_tac *tac = malloc(sizeof(tac));

    if(!tac) {
        return NULL;
    }

    tac->prev = prev_tac;
    tac->next = NULL;

    if(prev_tac != NULL) {
        prev_tac->next = tac;
    }

    tac -> tac_entries = mcc_create_dynamic_array(MCC_TAC_ENTRY_SIZE);
    tac -> temporary_count = 0;
    tac -> label_count = 0;

    tac -> root_table = st;
    tac -> current_symbol_table = st;
    tac -> current_symbol_index = 0;

    return tac;
}

struct mcc_tac_entry *mcc_tac_new_entry(
        enum mcc_tac_operation tac_op,
        char *arg1,
        char *arg2,
        char *result
) {
    struct mcc_tac_entry *te = malloc(sizeof(*te));

    te -> tac_op = tac_op;
    te -> arg1 = arg1;
    te -> arg2 = arg2;
    te -> result = result;

    return te;
}

int mcc_tac_add_entry(struct mcc_tac *tac, struct mcc_tac_entry *te) {
    return mcc_add_to_array(tac -> tac_entries, te);
}

int mcc_tac_create_and_add_new_entry(
        enum mcc_tac_operation tac_op,
        char *arg1,
        char *arg2,
        char *result,
        struct mcc_tac *tac) {
    struct mcc_tac_entry *te = mcc_tac_new_entry(tac_op, arg1, arg2, result);

    return mcc_tac_add_entry(tac, te);
}

int mcc_tac_create_and_add_new_entry_temp(
        enum mcc_tac_operation tac_op,
        char *arg1,
        char *arg2,
        struct mcc_tac *tac) {
        
        char *result = mcc_tac_new_temporary_string(tac);
        struct mcc_tac_entry *te = mcc_tac_new_entry(tac_op, arg1, arg2, result);

        return mcc_tac_add_entry(tac, te);
}


void mcc_tac_delete_entry(void *te) {
    struct mcc_tac_entry *tac_entry = (struct mcc_tac_entry *) te;

    free(tac_entry);
}

void mcc_tac_delete(struct mcc_tac *tac) {
    if(tac->next!= NULL) {
        mcc_tac_delete(tac->next);
    }

    mcc_delete_array(tac->tac_entries, mcc_tac_delete_entry);

    free(tac);
}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_literal(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_INT:
            return MCC_TAC_INT;
        case MCC_AST_DATA_TYPE_BOOL:
            return MCC_TAC_BOOL;
        case MCC_AST_DATA_TYPE_FLOAT:
            return MCC_TAC_FLOAT;
        case MCC_AST_DATA_TYPE_STRING:
            return MCC_TAC_STRING;
        default: break;
    }
    return MCC_TAC_UNKNOWN;
}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_ident(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_INT:
            return MCC_TAC_IDENTIFIER_INT;
        case MCC_AST_DATA_TYPE_BOOL:
            return MCC_TAC_IDENTIFIER_BOOL;
        case MCC_AST_DATA_TYPE_FLOAT:
            return MCC_TAC_IDENTIFIER_FLOAT;
        case MCC_AST_DATA_TYPE_STRING:
            return MCC_TAC_IDENTIFIER_STRING;
        default: break;
    }
    return MCC_TAC_UNKNOWN;
}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_param(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_INT:
            return MCC_TAC_PARAM_INT;
        case MCC_AST_DATA_TYPE_BOOL:
            return MCC_TAC_PARAM_BOOL;
        case MCC_AST_DATA_TYPE_FLOAT:
            return MCC_TAC_PARAM_FLOAT;
        case MCC_AST_DATA_TYPE_STRING:
            return MCC_TAC_PARAM_INT;
        default: break;
    }
    return MCC_TAC_UNKNOWN;
}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_unary(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_INT:
            return MCC_TAC_MINUS_INT_UN;
        case MCC_AST_DATA_TYPE_BOOL:
            return MCC_TAC_PARAM_BOOL;
        case MCC_TAC_MINUS_FLOAT_UN:
            return MCC_TAC_NOT;
        default: break;
    }
    return MCC_TAC_UNKNOWN;
}


enum mcc_tac_operation mcc_convert_ast_type_to_tac_binary(enum mcc_ast_binary_op binary_op,enum mcc_ast_data_type type) {
   switch (binary_op) {
	case MCC_AST_BINARY_OP_ADD:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_PLUS_INT
		           : MCC_TAC_PLUS_FLOAT;
	case MCC_AST_BINARY_OP_SUB:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_MINUS_INT_BIN
		           : MCC_TAC_MINUS_FLOAT_BIN;
	case MCC_AST_BINARY_OP_MUL:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_MUL_INT
		           : MCC_TAC_MUL_FLOAT;
	case MCC_AST_BINARY_OP_DIV:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_DIV_INT
		           : MCC_TAC_DIV_FLOAT;

	case MCC_AST_BINARY_OP_LESS:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_LT
		           : MCC_TAC_LT_FLOAT;
	case MCC_AST_BINARY_OP_GREATER:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_GT
		           : MCC_TAC_GT_FLOAT;
	case MCC_AST_BINARY_OP_LESS_EQUALS:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_LTEQ
		           : MCC_TAC_LTEQ_FLOAT;
	case MCC_AST_BINARY_OP_GREATER_EQUALS:
		return (type == MCC_AST_DATA_TYPE_INT)
		           ? MCC_TAC_GTEQ
		           : MCC_TAC_GTEQ_FLOAT;

	case MCC_AST_BINARY_OP_EQUALS:
		if (type == MCC_AST_DATA_TYPE_BOOL) {
			return MCC_TAC_EQ_BOOL;
		} else if (type == MCC_AST_DATA_TYPE_INT) {
			return MCC_TAC_EQ;
		} else {
			return MCC_TAC_EQ_FLOAT;
		}
	case MCC_AST_BINARY_OP_NOT_EQUALS:
		if (type == MCC_AST_DATA_TYPE_BOOL) {
			return MCC_TAC_NEQ_BOOL;
		} else if (type == MCC_AST_DATA_TYPE_INT) {
			return MCC_TAC_NEQ;
		} else {
			return MCC_TAC_NEQ_FLOAT;
		}
	case MCC_AST_BINARY_OP_AND: return MCC_TAC_AND;
	case MCC_AST_BINARY_OP_OR: return MCC_TAC_OR;
	default: break;
	}
    return MCC_TAC_UNKNOWN;
}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_load(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_BOOL: return MCC_TAC_LOAD_BOOL;
        case MCC_AST_DATA_TYPE_INT: return MCC_TAC_LOAD_INT;
        case MCC_AST_DATA_TYPE_FLOAT: return MCC_TAC_LOAD_FLOAT;
        case MCC_AST_DATA_TYPE_STRING: return MCC_TAC_LOAD_STRING;
        default: break;
        }
	return MCC_TAC_UNKNOWN;

}

enum mcc_tac_operation mcc_convert_ast_type_to_tac_store(enum mcc_ast_data_type type) {
    switch (type) {
        case MCC_AST_DATA_TYPE_BOOL: return MCC_TAC_STORE_BOOL;
        case MCC_AST_DATA_TYPE_INT: return MCC_TAC_STORE_INT;
        case MCC_AST_DATA_TYPE_FLOAT: return MCC_TAC_STORE_FLOAT;
        case MCC_AST_DATA_TYPE_STRING: return MCC_TAC_STORE_STRING;
        default: break;
        }
        return MCC_TAC_UNKNOWN;

}

void mcc_tac_enter_next_deeper_scope(struct mcc_tac *tac) {
    struct mcc_symbol_table *next_curr = tac -> current_symbol_table -> inner_tables -> arr[tac -> current_symbol_index];

    tac -> current_symbol_table = next_curr;
    tac -> current_symbol_index = 0;
}

void mcc_tac_exit_to_outer_scoper(struct mcc_tac *tac, int tac_st_index) {
    struct mcc_symbol_table *root = tac -> current_symbol_table -> parent;

    tac -> current_symbol_table = root -> inner_tables -> arr[tac_st_index];
    tac -> current_symbol_index = tac_st_index;
}

void mcc_tac_jump_to_next_inner_st(struct mcc_tac *tac) {

}

void mcc_tac_jump_to_prev_inner_st(struct mcc_tac *tac) {

}