diff --git a/table.c b/table.c index cc2cb2a..07f7548 100644 --- a/table.c +++ b/table.c @@ -1,19 +1,31 @@ -#include +#include "table.h" #include #include /*At the start of the execution : the whole array is empty*/ -symbolTable = malloc(sizeof(symbol) * START_TABLE_SIZE); +static Symbol* symbolTable; -currentIndex = 0; -maxIndex = START_TABLE_SIZE; +/*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); +} -currentDepth = 0; /* Error display */ void error(char* mess){ - printf("ERROR : %s\n", &mess); + printf("ERROR : %s\n", mess); exit(-1); } @@ -35,7 +47,7 @@ Symbol getStruct(char* name){ /* Returns the index with this name*/ int getIndex(char* name){ for(int i=0; i < currentIndex; i++){ - if (strcmp(symbolTable[i].name, &name) == 0){ + if (strcmp(symbolTable[i].name, name) == 0){ return i; } } @@ -44,70 +56,65 @@ int getIndex(char* name){ /* removes all symbols associated with the current Depth*/ void clearOutOfScopeVariable(){ - for(int i=0; i < currentIndex; i++){ - if (symbolTable[i].depth == currentDepth){ - suppressElement(i); + 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++; } - error("No index found"); + + int delta = currentIndex - i ; // the number of elements we remove + 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; } /* Toggles the init state of the symbol */ void toggleInit(char *name){ - symbolTable[getIndex(&symbolTable, currentIndex, &name)].init = true; + symbolTable[getIndex(name)].init = true; } +/*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(Symbol element){ +void addElement(char* name, enumVarType type){ + + Symbol element = createNewStructure(name, type); //checks for overflow checkArraySanity(); - if (currentIndex == 0){ - symbolTable[0] = element; - } else { - symbolTable[currentIndex].name = element.name; - symbolTable[currentIndex].init = element.init; - symbolTable[currentIndex].varType = element.varType; - symbolTable[currentIndex].offset = initOffset(currentIndex -1); // TODO replace with ESP - symbolTable[currentIndex].depth = element.depth; - } - - //TODO add ESP increment - + symbolTable[currentIndex] = element; currentIndex ++; + + esp += memorySizes[type]; } - -// TODO replace with ESP -/* Calcule l'offset à partir de l'offset de l'élément précédent */ -int initOffset(int index){ - switch (symbolTable[index].varType){ - case INT: - return (symbolTable[index].offset + 1); - break; - case FLOAT: - return (symbolTable[index].offset + 1); - break; - default: - error("Impossible to compute the new offset"); - } -} - - -/* Removes an element */ -void suppressElement(int index){ - for(int i = index; i < (currentIndex - 1); i ++){ - symbolTable[i] = symbolTable[i+1]; - } - currentIndex --; - - // checks if there is a need to reduce the size of the array - checkArraySanity(); -} - - /*Checks for the length of the array and reallocates if necessary*/ void checkArraySanity(){ if (currentIndex == maxIndex){ @@ -121,22 +128,67 @@ void checkArraySanity(){ /*reallocates the array with the specified size*/ void reallocateArray(int size){ - Symbol* newSymbolTable = malloc(sizeof (symbol) * size); // we double the size of the array - Symbol* oldSymbolTable = symbolTable; // we double the size of the array - free(oldSymbolTable); + Symbol *temp = (Symbol *)realloc(symbolTable, (sizeof(Symbol) * size)); - for(int i = 0; i < currentIndex; i++){ - newSymbolTable[i] = oldSymbolTable[i]; + if (temp != NULL){ + symbolTable = temp; + } + else { + error("Cannot allocate more memory.\n"); } - - symbolTable = newSymbolTable; } + +/*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", currentDepth, currentIndex); + 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(); +} + +void line(){ + printf("---------------------------------\n"); +} +void doubleLine(){ + printf("============================================================\n"); +} + +int main(){ + initSymbolTable(); + addElement("variable1", INT); + displayTable(); + increaseDepth(); + displayTable(); + toggleInit("variable1"); + displayTable(); + addElement("variable2", INT); + displayTable(); + addElement("variable3", FLOAT); + displayTable(); + decreaseDepth(); + displayTable(); + addElement("variable4", INT); + displayTable(); } \ No newline at end of file diff --git a/table.h b/table.h index 958ab18..554a363 100644 --- a/table.h +++ b/table.h @@ -4,23 +4,18 @@ #include #include -enum enumVarType {INT, FLOAT}; // a adapter /*defined constants*/ -#define START_TABLE_SIZE 128; +#define START_TABLE_SIZE 128 +#define NAME_MAX_LENGTH 30 -/*indexes in the array*/ -static int currentIndex; // the next to index to be used -static int maxIndex; -static symbol* symbolTable; +// a list of all type +typedef enum enumVarType {INT, FLOAT} enumVarType; // TODO : update -// stack pointers -static int esp; -static int ebp; - -static int currentDepth; +// a list of all type's sizes +int memorySizes[2] ={1,1}; // TODO : update typedef struct { - char* name; + char name[NAME_MAX_LENGTH]; bool init; enumVarType varType; int offset; @@ -29,18 +24,73 @@ typedef struct { // TODO : move comments here +/*============================ + Array and Reallocation + ============================*/ + +/*reallocates the array with the specified size*/ void reallocateArray(int size); + +/*Checks for the length of the array and reallocates if necessary*/ void checkArraySanity(); -void suppressElement(int index); -int initOffset(int index); -void addElement(Symbol element); -void toggleInit(char *name); -int getIndex(char* name); -Symbol getStruct(char* name); -void error(char* mess); -int getOffset(char* name); + +/* /!\ To be called at the beginning + * Initializes the array of Symbols*/ +void initSymbolTable(); + + +/*============================ + Element Management + ============================*/ + +/* removes all symbols associated with the current Depth*/ void clearOutOfScopeVariable(); + + +/* Adds an element */ +void addElement(char* name, enumVarType type); + +/*creates a new structure and updates variables*/ +Symbol createNewStructure(char* name, enumVarType type); + + +/*============================ + Element Edition + ============================*/ + +/* Toggles the init state of the symbol */ +void toggleInit(char *name); + +/*============================ + Element Acess + ============================*/ + +/* Returns the index with this name*/ +int getIndex(char* name); + +/* Returns the structure with this name */ +Symbol getStruct(char* name); + +/* Returns the offset from EBP to the symbol in the stack */ +int getOffset(char* name); + + +/*========================== + Flow/Block control + =========================*/ + +/*increases the depth (i.e. when entering a block)*/ void increaseDepth(); + +/*decreases the depth (i.e. when leaving a block)*/ void decreaseDepth(); +/*============================================ + Display, Todo : put in another .h file + ============================================*/ + +void error(char* mess); +void line(); +void doubleLine(); + #endif