#include #include #include #include "util.h" #include "symtable.h" typedef struct entry { symbolType type; char *name; union { object (*function)(); object variable; } value; struct entry *left; struct entry *right; } entry; /* овај тип служи за имплементирање табеле симбола који могу бити дефинисани * или путем интерне функције написане у интерпретеру, или је дефинисан * коришћењем самог Ћирилисп интерпретера */ entry *root = NULL; entry **findEntry(entry **current, char *symbol) { int cond; if (*current == NULL) { return current; } else if ((cond = strcmp(symbol, (*current)->name)) < 0) { return findEntry(&(*current)->left, symbol); } else if (cond > 0) { return findEntry(&(*current)->right, symbol); } else { return current; } /* случај у којем тражени симбол не постоји у табели, и случај у којем * је он нађен враћају вредност на исти начин, али су гране тока * одвојене ради читљивости */ } void freeEntry(entry **current) { free((*current)->name); if ((*current)->type == variableSymbol) { deleteObject((*current)->value.variable); } } symbolType typeOf(char *symbol) { entry **e = findEntry(&root, symbol); return (*e)->type; } int addSymbolInternal(char *symbol, object (*function)()) { int status = 1; entry **e = findEntry(&root, symbol); if (*e != NULL) { status = 0; freeEntry(e); } else { *e = malloc(sizeof(entry)); } (*e)->type = internalSymbol; (*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); strcpy((*e)->name, symbol); (*e)->value.function = function; (*e)->left = (*e)->right = NULL; return status; } int addSymbolVariable(char *symbol, object variable) { int status = 1; entry **e = findEntry(&root, symbol); if (*e != NULL) { status = 0; freeEntry(e); } else { *e = malloc(sizeof(entry)); } (*e)->type = variableSymbol; (*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); strcpy((*e)->name, symbol); (*e)->value.variable = copyObject(variable); (*e)->left = (*e)->right = NULL; return status; } int symbolExists(char *symbol) { int status = 1; entry **e = findEntry(&root, symbol); if (*e == NULL) { return 0; } else { return 1; } return status; } object (*internalFunction(char *symbol)) (object) { entry **e = findEntry(&root, symbol); if (*e == NULL || (*e)->type != internalSymbol) { return NULL; } else { return ((*e)->value.function); } } object referVariable(char *symbol) { object result; entry **e = findEntry(&root, symbol); if (*e == NULL || (*e)->type != variableSymbol) { TYPE(result) = errorObject; ERR(result) = unrecognizedSymbolError; } else { result = (*e)->value.variable; } return result; }