107 lines
1.8 KiB
C
107 lines
1.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "util.h"
|
|
#include "symtable.h"
|
|
|
|
object apply(object function, object parameters);
|
|
|
|
object eval(object input)
|
|
{
|
|
object result;
|
|
|
|
if (TYPE(input) == nilObject || TYPE(input) == numberObject ||
|
|
TYPE(input) == errorObject)
|
|
{
|
|
result = copyObject(input);
|
|
}
|
|
else if (TYPE(input) == symbolObject)
|
|
{
|
|
if (symbolExists(SYM(input)))
|
|
{
|
|
if (typeOf(SYM(input)) == variableSymbol)
|
|
{
|
|
result = referVariable(SYM(input));
|
|
}
|
|
else
|
|
{
|
|
result = copyObject(input);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = unrecognizedSymbolError;
|
|
}
|
|
}
|
|
else if (TYPE(input) == consObject)
|
|
{
|
|
if (!properList(input))
|
|
{
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = improperListError;
|
|
}
|
|
else
|
|
{
|
|
object *currentCell = &input;
|
|
int noErrors = 1;
|
|
while (TYPE(*currentCell) != nilObject)
|
|
{
|
|
if (TYPE(CAR(input)) != symbolObject ||
|
|
!isSpecialForm(SYM(CAR(input))))
|
|
{
|
|
CAR(*currentCell) =
|
|
eval(CAR(*currentCell));
|
|
}
|
|
|
|
if (TYPE(CAR(*currentCell)) == errorObject)
|
|
{
|
|
noErrors = 0;
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = ERR(CAR(*currentCell));
|
|
break;
|
|
}
|
|
currentCell = &CDR(*currentCell);
|
|
}
|
|
|
|
if (noErrors)
|
|
{
|
|
result = apply(CAR(input), CDR(input));
|
|
}
|
|
}
|
|
}
|
|
|
|
deleteObject(input);
|
|
return result;
|
|
}
|
|
|
|
object apply(object function, object parameters)
|
|
{
|
|
object result;
|
|
|
|
if (TYPE(function) != symbolObject)
|
|
{
|
|
deleteObject(function);
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = notApplicableError;
|
|
}
|
|
else if (symbolExists(SYM(function)))
|
|
{
|
|
object(*f)();
|
|
if ((f = internalFunction(SYM(function))) != NULL)
|
|
{
|
|
result = f(parameters);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
deleteObject(function);
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = unrecognizedSymbolError;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|