163 lines
3 KiB
C
163 lines
3 KiB
C
#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;
|
||
}
|