C compiler with embedded metalanguage.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

95 linhas
2.2 KiB

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
// Scope definition
/** A scope is a set of identifiers */
typedef struct scope {
size_t scopeSize;
char **identifiers;
struct scope *parent;
} scope_t ;
scope_t *actualScope = 0;
/** 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;
}
int pushScope(void) {
/* A new scope is initialized */
scope_t* newScope = malloc(sizeof(scope_t));
newScope->scopeSize = 0;
newScope->identifiers = 0;
newScope->parent = actualScope;
actualScope = newScope;
/* Everything was done well*/
return 1;
}
int popScope(void) {
assert(actualScope);
scope_t *parent = actualScope->parent;
free(actualScope->identifiers);
free(actualScope);
actualScope = parent;
return 1;
}
int isTypedefed(char *s) {
for (scope_t *scope = actualScope ; scope ; scope = scope->parent) {
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;
}