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

Clemens Paumgarten's avatar
Clemens Paumgarten committed
#include "tac_build.h"
#include "symbol_table.h"
FlorianKrull's avatar
FlorianKrull committed

Clemens Paumgarten's avatar
Clemens Paumgarten committed
// -------------------------------- parse expression

void mcc_tac_parse_expression(struct mcc_ast_expression *expression, struct mcc_tac *tac) {
    assert(expression);
    assert(tac);

    switch (expression -> type) {
        case MCC_AST_EXPRESSION_TYPE_IDENTIFIER: {
        case MCC_AST_EXPRESSION_TYPE_LITERAL :
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            break;
        case MCC_AST_EXPRESSION_TYPE_CALL_EXPRESSION :

            break;
        case MCC_AST_EXPRESSION_TYPE_UNARY_OP :
            //struct mcc_tac_entry *tac_unary = mcc_tac_new_entry();
            
            break;
        case MCC_AST_EXPRESSION_TYPE_BINARY_OP :

            break;
        case MCC_AST_EXPRESSION_TYPE_PARENTH :

            break;
        case MCC_AST_EXPRESSION_TYPE_BRACKET :
Clemens Paumgarten's avatar
Clemens Paumgarten committed
        default:
            return;
krf41037's avatar
krf41037 committed
    }
Clemens Paumgarten's avatar
Clemens Paumgarten committed
}
Clemens Paumgarten's avatar
Clemens Paumgarten committed
// -------------------------------- parse statement
FlorianKrull's avatar
FlorianKrull committed

Clemens Paumgarten's avatar
Clemens Paumgarten committed
void mcc_tac_parse_statement_list(struct mcc_ast_statement_list *stl, struct mcc_tac *tac) {
    assert(stl);
    assert(tac);


    while (stl != NULL) {
        mcc_tac_parse_statement(stl -> statement, tac);
        stl = stl -> next;
    }
}

struct mcc_tac *mcc_tac_parse_statement(struct mcc_ast_statement *statement, struct mcc_tac *tac) {
        switch (statement -> type) {
            case MCC_AST_STATEMENT_TYPE_COMPOUND:
                mcc_tac_parse_statement_list(statement -> statement_list, tac);
                break;
            case MCC_AST_STATEMENT_TYPE_IF: {

                // evaluate if expression
                mcc_tac_parse_expression(statement -> while_condition, tac);

                char *last_temp = tac -> last_temporary;

                // now do that jump / jumpfalse stuff here
                char *if_label = mcc_tac_new_label_string(tac);

                mcc_tac_create_and_add_new_entry(MCC_TAC_JMP_FALSE, last_temp, NULL, if_label, tac);

                //scope go to deeper scope and save current index
                int current_scope_index = tac -> current_symbol_index;
                mcc_tac_enter_next_deeper_scope(tac);

                mcc_tac_parse_statement(statement -> if_stmt, tac);

                //go back to previous scope
                mcc_tac_exit_to_outer_scoper(tac, current_scope_index);
                tac -> current_symbol_index++;

                char *else_label= mcc_tac_new_label_string(tac);
                mcc_tac_create_and_add_new_entry(MCC_TAC_JMP, NULL, NULL, else_label, tac);

                if (statement -> else_stmt != NULL) {
                    // jump last label

                    current_scope_index = tac -> current_symbol_index;
                    mcc_tac_enter_next_deeper_scope(tac);

                    mcc_tac_parse_statement(statement -> else_stmt, tac);

                    //go back to previous scope
                    mcc_tac_exit_to_outer_scoper(tac, current_scope_index);
                    tac -> current_symbol_index++;
                }

            } break;
            case MCC_AST_STATEMENT_TYPE_EXPRESSION:
                mcc_tac_parse_expression(statement -> expression, tac);
                break;
            case MCC_AST_STATEMENT_TYPE_WHILE: {
                mcc_tac_parse_expression(statement -> while_condition, tac);

                char *last_temp = tac -> last_temporary;

                char *while_label = mcc_tac_new_label_string(tac);
                mcc_tac_create_and_add_new_entry(MCC_TAC_JMP_FALSE, last_temp, NULL, while_label, tac);

                int current_scope_index = tac -> current_symbol_index;
                mcc_tac_enter_next_deeper_scope(tac);

                mcc_tac_parse_statement(statement -> if_stmt, tac);

                //go back to previous scope
                mcc_tac_exit_to_outer_scoper(tac, current_scope_index);
                tac -> current_symbol_index++;
            } break;
            case MCC_AST_STATEMENT_TYPE_DECL: {
                    // Check nicht ganz um was es da geht

//                struct mCc_ast_literal *array_size = statement->declaration->array_size;
//                if (array_size) {
//                    builder->current_variable_count += atoi(array_size->value);
//                    create_and_add_line(builder, MCC_TAC_OPERATION_ARRAY_DECLARATION,
//                                        array_size->value, NULL,
//                                        statement->declaration->identifier->name);
//                }
//                break;
//            }
            } break;
            case MCC_AST_STATEMENT_TYPE_ASSGN_ARR:
            case MCC_AST_STATEMENT_TYPE_ASSGN: {
                // get type
                struct mcc_ast_assignment *a = statement -> assignment;
                char *result = statement -> assignment -> identifier ->i_value;
                enum mcc_ast_data_type assignment_type =
                        mcc_symbol_table_get_symbol(
                                tac->current_symbol_table,
                                result,
                                true) -> data_type;


                enum mcc_tac_operation tac_op = convert_ast_type_to_tac_operation(assignment_type);
                if (a -> type == MCC_AST_ASSIGNMENT_TYPE_ARRAY) {
                    mcc_tac_parse_expression(a -> array_ass.index, tac);

                    char *arg2 = tac -> last_temporary;

                    mcc_tac_parse_expression(a -> array_ass.rhs, tac);

                    char *arg1 = tac -> last_temporary;
                    mcc_tac_create_and_add_new_entry(tac_op, arg1, arg2, result, tac);

                } else {

                    // evaluate expression
                    mcc_tac_parse_expression(a -> normal_ass.rhs, tac);

                    char *arg1 = tac -> last_temporary;
                    mcc_tac_create_and_add_new_entry(tac_op, arg1, NULL, result, tac);
                }
            } break;
            case MCC_AST_STATEMENT_TYPE_RETURN: {
                // TODO: get symbol table name from a seperate variable (tac -> root_table)
                // get expression type
                enum mcc_ast_data_type return_type = mcc_symbol_table_get_expression_return_type(
                        statement -> expression,
                        tac -> current_symbol_table
                );

                enum mcc_tac_operation tac_op = convert_ast_type_to_tac_operation(return_type);

                mcc_tac_parse_expression(statement -> expression, tac);
                char *arg1 = tac -> last_temporary;

                char *result = mcc_tac_new_return_function_name(tac -> current_symbol_table -> sym_table_name)
                mcc_tac_create_and_add_new_entry(MCC_TAC_RETURN, arg1, NULL, result, tac);

            } break;
Clemens Paumgarten's avatar
Clemens Paumgarten committed
}

// -------------------------------- parse function

int mcc_tac_parse_function(struct mcc_ast_function *f, struct mcc_tac *tac) {
    assert(f);
    assert(tac);

    // TODO: do something with params

    if (f->statement != NULL) {
        mcc_tac_parse_statement(f -> statement, tac);
Clemens Paumgarten's avatar
Clemens Paumgarten committed

Clemens Paumgarten's avatar
Clemens Paumgarten committed
// start parsing program
struct mcc_tac *mcc_tac_build(struct mcc_ast_program *program, struct mcc_symbol_table *st) {
    struct mcc_tac *tac = mcc_tac_new(NULL, st);
Clemens Paumgarten's avatar
Clemens Paumgarten committed

    struct mcc_ast_function *f = NULL;
    // look for main an start parsing program
    for (int i = 0; i < program -> function_def -> size; i++) {
        f = program -> function_def -> arr[i];

        if (strcmp(f -> identifier -> i_value, "main") == 0) {
            struct mcc_symbol_table *t =  mcc_symbol_table_get_inner_table_by_name(st, "main");

            if (t != NULL) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    }

    return tac;
}


//char *ast_literal_to_char(struct mcc_ast_expression *expr, struct mcc_tac *tac){
//    char *string;
//    switch (expr->literal->type) {
//        case MCC_AST_DATA_TYPE_INT:
//            string = malloc(sizeof(char) * (myLog10(expr->literal->i_value, 0) + 2)); // why log10?
//            sprintf(string, "%ld", expr->literal->i_value);
//            break;
//
//        case MCC_AST_DATA_TYPE_FLOAT:
//            string = malloc(sizeof(char) * 64);
//            sprintf(string, "%lf", expr->literal->f_value);
//            break;
//
//        case MCC_AST_DATA_TYPE_STRING:
//            string = expr->literal->s_value;
//            break;
//
//        case MCC_AST_DATA_TYPE_BOOL:
//            string = expr->literal->b_value ? "1" : "0";
//            break;
//        case MCC_AST_DATA_TYPE_VOID:
//            string = "void";
//            break;
//
//        default:
//            string = "Error ast_literal_to_char";
//    }
//
//    return string;
//}
//
//static struct mcc_tac *new_tac_binary(struct mcc_ast_expression *expr) {
//    struct mcc_tac *tac_bin = mcc_new_tac();
//
//    if(expr->lhs->type == MCC_AST_EXPRESSION_TYPE_LITERAL ){
//        tac_bin->arg1 = ast_literal_to_char(expr->lhs,tac);
//    }
//    if(expr->rhs->type == MCC_AST_EXPRESSION_TYPE_LITERAL){
//        // TODO literal to char
//        tac_bin->arg2 = ast_literal_to_char(expr->rhs,tac);
//    }
//
//}
//
//struct mcc_tac *mcc_create_tac(struct mcc_ast_expression *expr, struct mcc_tac *tac) {
//    struct mcc_tac *next_tac = malloc(sizeof(*next_tac));
//
//    // add new tac object to linked list
//    next_tac -> prev = tac;
//    next_tac -> next = NULL;
//    tac -> next = next_tac;
//
//
//
//
////    struct mcc_tac *tac_bin;
////    switch (expr->type)  {
////
////    case MCC_AST_EXPRESSION_TYPE_PARENTH:
////        mcc_create_tac(expr->expression,tac);
////        break;
////    case MCC_AST_EXPRESSION_TYPE_BINARY_OP:
////        if(expr->lhs->type == MCC_AST_EXPRESSION_TYPE_LITERAL ){
////            tac_bin->arg1 = ast_literal_to_char(expr->lhs,tac);
////        }
////        if(expr->rhs->type == MCC_AST_EXPRESSION_TYPE_LITERAL){
////            // TODO literal to char
////            tac_bin->arg2 = ast_literal_to_char(expr->rhs,tac);
////        }
////    case MCC_AST_EXPRESSION_TYPE_CALL_EXPRESSION:
////    case MCC_AST_EXPRESSION_TYPE_UNARY_OP:
////    case MCC_AST_EXPRESSION_TYPE_LITERAL:
////    //TODO parse MCC_AST types to MCC_TAC_OP types
////
////        break;
////
////    default:
////        break;
////    }
//}