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) {
}