Skip to content
Snippets Groups Projects
symbol_table.c 4.81 KiB
Newer Older
Clemens Paumgarten's avatar
Clemens Paumgarten committed
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "mcc/symbol_table.h"

// ---------------------------------------------------------- CONSTANTS

const int MCC_SYMBOL_TABLE_SYMBOL_SIZE = 100;
const int MCC_SYMBOL_TABLE_CHILDREN_SIZE = 5;
const int MCC_FUNC_ARG_SIZE = 5;

// ---------------------------------------------------------- Symbol

struct mcc_symbol *mcc_symbol_new_symbol_variable(char* variable_name, enum mcc_ast_data_type data_type) {
    assert(variable_name);

    struct mcc_symbol *symbol = malloc(sizeof(*symbol));

    symbol -> variable_name = variable_name;
    symbol -> data_type = data_type;
    symbol -> symbol_type = MCC_SYMBOL_TYPE_VARIABLE;
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    symbol -> func_arguments = NULL;
Clemens Paumgarten's avatar
Clemens Paumgarten committed

    return symbol;
}

struct mcc_symbol *mcc_symbol_new_symbol_array(char* variable_name, enum mcc_ast_data_type data_type, long array_size) {
    assert(variable_name);

    struct mcc_symbol *symbol = malloc(sizeof(*symbol));

    symbol -> variable_name = variable_name;
    symbol -> data_type = data_type;
    symbol -> array_size = array_size;
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    symbol -> func_arguments = NULL;
Clemens Paumgarten's avatar
Clemens Paumgarten committed

    return symbol;
}


struct mcc_symbol *mcc_symbol_new_symbol_function(
        char* variable_name,
        enum mcc_ast_data_type data_type,
        struct mcc_ast_parameter *parameter) {
    assert(variable_name);

    struct mcc_symbol *symbol = malloc(sizeof(*symbol));

    symbol -> variable_name = variable_name;
    symbol -> data_type = data_type;
    symbol -> symbol_type = MCC_SYMBOL_TYPE_FUNCTION;

    symbol -> func_arguments = mcc_create_dynamic_array(MCC_FUNC_ARG_SIZE);

    if (parameter != NULL) {
        for (int i = 0; i < parameter -> parameters -> size; i++) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            struct mcc_symbol_function_argument *fp = malloc(sizeof(*fp));
            struct mcc_ast_declaration *d = (struct mcc_ast_declaration *) parameter -> parameters -> arr[i];

            fp -> arg_type = d ->type;
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            mcc_add_to_array(symbol -> func_arguments, fp);
        }
    }

    return symbol;
}

void mcc_symbol_delete_symbol(void *symbol) {
    struct mcc_symbol *s = (struct mcc_symbol *) symbol;

    if (s != NULL) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
        if (s -> func_arguments != NULL) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
            mcc_delete_array(s ->func_arguments, NULL);
        }
    }
}

// ---------------------------------------------------------- Symbol Table

struct mcc_symbol_table *mcc_symbol_table_new_table(
        struct mcc_symbol_table *parent) {

    struct mcc_symbol_table *table = malloc(sizeof(*table));

Clemens Paumgarten's avatar
Clemens Paumgarten committed
    table -> inner_tables = mcc_create_dynamic_array(MCC_SYMBOL_TABLE_CHILDREN_SIZE);
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    table -> symbols = mcc_create_dynamic_array(MCC_SYMBOL_TABLE_SYMBOL_SIZE);
    table -> parent = parent;

    return table;
}

struct mcc_symbol_table *mcc_symbol_table_get_inner_table_by_name(struct mcc_symbol_table *table, char *name) {
    struct mcc_symbol_table *result = NULL;

    if (strcmp(table -> sym_table_name, name) == 0) {
        return table;
    }


    if (table -> inner_tables -> size < 1) {
        return NULL;
    }

    for (int i = 0; i < table -> inner_tables -> size; i++) {
        struct mcc_symbol_table *t = (struct mcc_symbol_table *) table -> inner_tables -> arr[i];
        result = mcc_symbol_table_get_inner_table_by_name(t, name);

        if (result != NULL) break;
    }

    return result;
}

Clemens Paumgarten's avatar
Clemens Paumgarten committed
void mcc_symbol_table_delete_table(void *table) {
    // Delete symbols
    assert(table);

Clemens Paumgarten's avatar
Clemens Paumgarten committed
    struct mcc_symbol_table *st = (struct mcc_symbol_table *) table;

Clemens Paumgarten's avatar
Clemens Paumgarten committed
    mcc_delete_array(st -> symbols, mcc_symbol_delete_symbol);
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    mcc_delete_array(st -> inner_tables, mcc_symbol_table_delete_table);
Clemens Paumgarten's avatar
Clemens Paumgarten committed

    free(table);
Clemens Paumgarten's avatar
Clemens Paumgarten committed
}

struct mcc_symbol_table *mcc_symbol_table_create_inner_table(struct mcc_symbol_table *parent, char *name) {
    assert(parent);

    char *symbole_name;
    symbole_name = name;

    if(symbole_name == NULL){
        symbole_name = parent->sym_table_name;
    }

    struct mcc_symbol_table *child = mcc_symbol_table_new_table(parent);

    child->sym_table_name = symbole_name;

    mcc_add_to_array(parent -> inner_tables, child);

    return child;
}

int mcc_symbol_table_insert_symbol(struct mcc_symbol_table *table, struct mcc_symbol *symbol) {
    assert(table);
    assert(symbol);

    return mcc_add_to_array(table -> symbols, symbol);
}

Clemens Paumgarten's avatar
Clemens Paumgarten committed
struct mcc_symbol *mcc_symbol_table_get_symbol(struct mcc_symbol_table *symbol_table, char *symbol_name, bool propagate) {
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    for (int i = 0; i < symbol_table -> symbols -> size; i++) {
        struct mcc_symbol *s = symbol_table -> symbols -> arr[i];

        if (strcmp(s -> variable_name, symbol_name) == 0) {
            return s;
        }
    }

    // not found in current symbol table
Clemens Paumgarten's avatar
Clemens Paumgarten committed
    if (propagate == true && symbol_table -> parent != NULL) {
        struct mcc_symbol *s = mcc_symbol_table_get_symbol(symbol_table->parent, symbol_name, propagate);
Clemens Paumgarten's avatar
Clemens Paumgarten committed

        return s;
    }

    return NULL;
}