124 lines
3.1 KiB
C
124 lines
3.1 KiB
C
#include "symbol_table.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
void init_table(SymbolTable *table) {
|
|
table->index = 0;
|
|
table->temp_index = SYMBOL_TABLE_SIZE - 1;
|
|
}
|
|
|
|
void init_symbol_item(SymbolItem *symbol_item, size_t name_size) {
|
|
symbol_item->type = 0;
|
|
symbol_item->name = malloc(name_size);
|
|
symbol_item->address = 0;
|
|
symbol_item->init = 0;
|
|
}
|
|
|
|
int has_symbol(SymbolTable* table, char *name) {
|
|
for (int i = 0; i < table->index; i++) {
|
|
if (strcmp(table->table[i].name, name) == 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
|
|
if (strcmp(table->table[i].name, name) == 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int add_symbol(SymbolTable *table, enum Type type, char *name) {
|
|
if (table->index > table->temp_index) {
|
|
return -2;
|
|
}
|
|
if (has_symbol(table, name)) {
|
|
return -1;
|
|
}
|
|
SymbolItem newItem;
|
|
init_symbol_item(&newItem, strlen(name));
|
|
newItem.type = type;
|
|
newItem.name = name;
|
|
newItem.address = table->index;
|
|
newItem.init = 0;
|
|
|
|
table->table[table->index] = newItem;
|
|
table->index++;
|
|
return 0;
|
|
}
|
|
|
|
const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type) {
|
|
if (table->temp_index < table->index) {
|
|
return NULL;
|
|
}
|
|
|
|
SymbolItem *newItem = &table->table[table->temp_index];
|
|
init_symbol_item(newItem, 10);
|
|
newItem->type = type;
|
|
sprintf(newItem->name, "_temp%d", table->temp_index);
|
|
newItem->address = table->temp_index;
|
|
newItem->init = 0;
|
|
|
|
table->temp_index--;
|
|
return newItem;
|
|
}
|
|
|
|
int mark_symbol_initialized(SymbolTable *table, char *name) {
|
|
struct SymbolItem *item = get_symbol_item(table, name);
|
|
if (item != NULL) {
|
|
if (item->init == 1) {
|
|
return -2;
|
|
}
|
|
item->init = 1;
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
char* type_to_string(enum Type type) {
|
|
if (type == TYPE_CONST) {
|
|
return "const";
|
|
} else {
|
|
return " int ";
|
|
}
|
|
}
|
|
|
|
void print_table(SymbolTable *table) {
|
|
printf("Variables:\n");
|
|
printf("%10s | %5s | %3s | %1s\n", "name", "type", "@", "I");
|
|
for (int i = 0; i < table->index; i++) {
|
|
print_item(&table->table[i]);
|
|
}
|
|
printf("Temporary variables:\n");
|
|
for (int i = SYMBOL_TABLE_SIZE - 1; i > table->temp_index; i--) {
|
|
print_item(&table->table[i]);
|
|
}
|
|
}
|
|
|
|
void print_item(struct SymbolItem *item) {
|
|
if (item == NULL) {
|
|
printf("NULL");
|
|
}
|
|
else {
|
|
printf("%10s | %5s | %3d | %1d\n",
|
|
item->name,
|
|
type_to_string(item->type),
|
|
item->address,
|
|
item->init);
|
|
}
|
|
}
|
|
|
|
SymbolItem *get_symbol_item(SymbolTable *table, const char *name) {
|
|
for (int i = 0; i < table->index; i++) {
|
|
if (strcmp(table->table[i].name, name) == 0) {
|
|
return &table->table[i];
|
|
}
|
|
}
|
|
for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
|
|
if (strcmp(table->table[i].name, name) == 0) {
|
|
return &table->table[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|