#include #include #include #include "util.h" #include "symtable.h" typedef enum { internalSymbol, objectSymbol } symbolType; typedef struct entry { symbolType type; char *name; union { object (*function)(); object definition; } 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; } /* случај у којем тражени симбол не постоји у табели, и случај у којем * је он нађен враћају вредност на исти начин, али су гране тока * одвојене ради читљивости */ } int addSymbolInternal(char *symbol, object (*function)()) { int status = 1; entry **e = findEntry(&root, symbol); if (*e == NULL) { *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; } else { status = 0; } return status; } int addSymbolDefinition(char *symbol, object definition) { int status = 1; entry **e = findEntry(&root, symbol); if (*e == NULL) { *e = malloc(sizeof(entry)); (*e)->type = objectSymbol; (*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); strcpy((*e)->name, symbol); (*e)->value.definition = copyObject(definition); (*e)->left = (*e)->right = NULL; } else { status = 0; } 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); } }