cirilisp/symtable.c

163 lines
3 KiB
C
Raw Normal View History

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