cirilisp/symtable.c

163 lines
3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}