#include "table.h" #include #include /*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 (symbolTable[i].name == name){ return symbolTable[i]; } } error("No structure found"); } /* 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"); } /* 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 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(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(char* name, enumVarType type){ Symbol element = createNewStructure(name, type); //checks for overflow checkArraySanity(); symbolTable[currentIndex] = element; currentIndex ++; esp += memorySizes[type]; } /*Checks for the length of the array and reallocates if necessary*/ void checkArraySanity(){ if (currentIndex == maxIndex){ reallocateArray(maxIndex * 2); } else { if (currentIndex < maxIndex / 2){ 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", 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(); }