#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|