diff --git a/scope.c b/scope.c new file mode 100644 index 0000000..94d45b9 --- /dev/null +++ b/scope.c @@ -0,0 +1,141 @@ +#include +#include +#include + +// Scoope definition + +/** A scope is a set of identifiers */ +typedef struct { + size_t scopeSize; + char** identifiers; +} scope_t ; + +scope_t* actualScope; + +/** Add a new specifier to a scope */ +int addId(char *name) { + ssize_t l = 0; + ssize_t r = actualScope->scopeSize - 1; + while ( l <= r ) { + ssize_t c = (l+r)/2; + int result = strcmp(name, actualScope->identifiers[c]); + if (result > 0) { + l = c + 1; + } else if (result < 0) { + r = c - 1; + } else { + /* Symbol found */ + fprintf(stderr, "\nConflicting types for '%s' \n", name); + exit(0); + return -1; + } + } + + /* Symbol does not exist */ + char* newSpecfier = strdup(name); + actualScope->identifiers = realloc(actualScope->identifiers, sizeof(*actualScope->identifiers)*(actualScope->scopeSize + 1)); + memmove(actualScope->identifiers + l + 1, actualScope->identifiers + l, sizeof(*actualScope->identifiers)*(actualScope->scopeSize - l)); + actualScope->scopeSize++; + actualScope->identifiers[l] = newSpecfier; + return 1; +} + +/** A new scopeList is pushed on an other scope : we have a stack of scopeList */ +typedef struct { + size_t stackSize; + scope_t** scopeList; +} stackS_t; + +stackS_t *scopeStack; +int zebi; + +/** Functions */ +void initScope() { + scopeStack = malloc(sizeof(scopeStack)); + scopeStack->stackSize = 0; + actualScope = malloc(sizeof(actualScope)); + actualScope->scopeSize = 0; + scopeStack->scopeList = malloc(sizeof(scopeStack->scopeList)); + scopeStack->scopeList[0] = actualScope; +} + +int pushScope() { + + /* A new scope is initialized */ + scope_t* newScope = malloc(sizeof(scope_t)); + newScope->scopeSize = 0; + newScope->identifiers = malloc(sizeof(newScope->identifiers)); + + /* A memory area is given in the stack */ + scopeStack->scopeList = realloc(scopeStack->scopeList, sizeof(**scopeStack->scopeList)*(scopeStack->stackSize + 1)); + + /* And finally, actualScope is the stack that was just pushed */ + scopeStack->stackSize++; + scopeStack->scopeList[scopeStack->stackSize] = newScope; + actualScope = newScope; + + /* Everything was done well*/ + return 1; +} + +int popScope() { + + /* Verifying that we don't pop the last scope */ + if (scopeStack->stackSize > 0) { + + /* Removing the last scope */ + scope_t* lastScope = malloc(sizeof(actualScope)); + lastScope = scopeStack->scopeList[scopeStack->stackSize]; + free(lastScope->identifiers); + free(lastScope); + scopeStack->stackSize--; + + /* Setting the actual scope */ + actualScope = malloc(sizeof(actualScope)); + actualScope = scopeStack->scopeList[scopeStack->stackSize]; + if (actualScope == NULL) printf("LE C C NULL\n"); + return 1; + + } else { + + /* Error */ + fprintf(stderr, "\nCan't pop the last scope\n"); + exit(0); + return -1; + + } + +} + +int isTypedefed(char *s) { + + /** Latest scopes prevail */ + if (scopeStack->scopeList == NULL) printf("null"); + for (int i = scopeStack->stackSize ; i != 0 ; i--) { + scope_t* scope = malloc(sizeof(scopeStack->scopeList[i])); + scope = scopeStack->scopeList[i]; + + if (scope->scopeSize) { + ssize_t l = 0; + ssize_t r = scope->scopeSize - 1; + while ( l <= r ) { + ssize_t c = (l+r)/2; + int result = strcmp(s, scope->identifiers[c]); + if (result > 0) { + l = c + 1; + } else if (result < 0) { + r = c - 1; + } else { + /* Symbol found */ + return 1; + } + } + } + } + + /* Symbol not found */ + return 0; + +} + +