Projet-Systemes-Informatiques/table.c
2023-04-18 09:44:04 +02:00

253 lines
No EOL
6 KiB
C

#include "table.h"
#include <stdlib.h>
#include <string.h>
#define VERBOSITY 1 // 1 -> displays the table, 0 no display
int memorySizes[2] = {1,1};
int tempCounter = 0;
/*At the start of the execution : the whole array is empty*/
static Symbol* symbolTable;
/*indexes in the array*/
static int currentIndex = 0; // the next to index to be used
static int maxIndex = START_TABLE_SIZE;
// stack pointers
static int esp = 0;
static int ebp = 0;
static int currentDepth = 0;
/* /!\ To be called at the beginning
* Initializes the array of Symbols*/
void initSymbolTable(){
symbolTable = malloc(sizeof(Symbol) * START_TABLE_SIZE);
}
/* Error display */
void error(char* mess){
printf("ERROR : %s\n", mess);
exit(-1);
}
/* Returns the offset from EBP to the symbol in the stack */
int getOffset(char* name){
return (ebp + getStruct(name).offset);
}
/* Returns the structure with this name */
Symbol getStruct(char* name){
for(int i=0; i < currentIndex; i++){
if (strcmp(symbolTable[i].name, name) == 0){
return symbolTable[i];
}
}
error("No structure found");
return (createNewStructure("error", 0));
}
/* Returns the index with this name*/
int getIndex(char* name){
for(int i=0; i < currentIndex; i++){
if (strcmp(symbolTable[i].name, name) == 0){
return i;
}
}
error("No index found");
return (0);
}
/* removes all symbols associated with the current Depth*/
void clearOutOfScopeVariable(){
int i = 0;
int memoryFreed = 0;
// we get to the first symbol that we need to remove
while(i < currentIndex) {
if (symbolTable[i].depth == currentDepth) {
break;
}
i++;
}
int futureCurrentIndex = i;
while(i < currentIndex) {
memoryFreed += memorySizes[symbolTable[i].varType];
i++;
}
// now we remove all the symbols
currentIndex = futureCurrentIndex;
checkArraySanity();
// and we free their memory (i.e. decrease esp)
esp -= memoryFreed;
if (VERBOSITY) {
printf("\n\nclearOutOfScopeVariable::After");
displayTable();
}
}
/* sets the init state of the symbol to true */
void setInit(char *name){
symbolTable[getIndex(name)].init = true;
if (VERBOSITY) {
printf("\n\nsetInit %s", name);
displayTable();
}
}
/*creates a new structure and updates variables*/
Symbol createNewStructure(char* name, enumVarType type){
Symbol s;
strcpy(s.name,name);
s.init = false;
s.varType = type;
s.offset = esp; // the offset is the current esp
s.depth = currentDepth;
return s;
}
/* Adds an element */
void addElement(char* name, enumVarType type){
Symbol element = createNewStructure(name, type);
//checks for overflow
checkArraySanity();
symbolTable[currentIndex] = element;
currentIndex ++;
esp += memorySizes[type];
if (VERBOSITY) {
printf("\n\nAddElement %s", name);
displayTable();
}
}
/* Adds an element and returns the offset of it */
int addElementAndGetAddress(char* name, enumVarType type){
addElement(name,type);
return getOffset(name);
}
/* Adds a temporary Int element and returns the offset of it */
int addTempINTAndGetAddress(){
char name[NAME_MAX_LENGTH];
if (tempCounter == 0){
// we create the first temporary variable and use it
addElement("0_TEMP",INT);
strcpy(name, "0_TEMP");
} else if (tempCounter == 1) {
// we create the second temporary variable and use it
addElement("1_TEMP",INT);
strcpy(name, "1_TEMP");
} else {
// we use the right temporary variable
sprintf(name, "%d_TEMP", tempCounter % 2);
}
tempCounter++;
return getOffset(name);
}
/* removes all symbols */
void flushSymbolTable(){
currentIndex = 0;
checkArraySanity();
if (VERBOSITY) {
printf("\n\nflushSymbolTable::After");
displayTable();
}
}
/*Checks for the length of the array and reallocates if necessary*/
void checkArraySanity(){
if (currentIndex == maxIndex){
reallocateArray(maxIndex * 2);
} else {
if (currentIndex < maxIndex / 2 && maxIndex / 2 > START_TABLE_SIZE){
reallocateArray(maxIndex / 2);
}
}
}
/*reallocates the array with the specified size*/
void reallocateArray(int size){
Symbol *temp = (Symbol *)realloc(symbolTable, (sizeof(Symbol) * size));
if (temp != NULL){
symbolTable = temp;
}
else {
error("Cannot allocate more memory.\n");
}
}
/*increases the depth (i.e. when entering a block)*/
void increaseDepth(){
currentDepth++;
}
/*decreases the depth (i.e. when leaving a block)*/
void decreaseDepth(){
clearOutOfScopeVariable();
currentDepth--;
}
/*displays the entire table at this moment including all information
* regarding the symbols and the current depth*/
void displayTable(){
printf("\n");
doubleLine();
printf("Table of Symbols, depth = %d, length = %d, ESP = %d, EBP = %d\n", currentDepth, currentIndex, esp ,ebp);
printf("Name | init?, varType, offset, depth\n");
doubleLine();
for (int i = 0; i < currentIndex; ++i) {
Symbol a = symbolTable[i];
printf("%s | %d, %d, %d, %d\n", a.name, a.init, a.varType, a.offset, a.depth);
if (i != currentIndex -1) {
line();
}
}
doubleLine();
}
/*removes all temporary variables used for INTs*/
void suppressTempINTElement(){
if (tempCounter == 1){
suppressElement("0_TEMP");
} else {
if (tempCounter > 1){
suppressElement("0_TEMP");
suppressElement("1_TEMP");
}
}
}
/*removes one element*/
void suppressElement(char* name){
for(int i = getIndex(name); i < (currentIndex - 1); i ++){
symbolTable[i] = symbolTable[i+1];
}
currentIndex--;
checkArraySanity();
}
void line(){
printf("---------------------------------\n");
}
void doubleLine(){
printf("============================================================\n");
}