cirilisp/internals.c

212 lines
3.4 KiB
C
Raw Normal View History

#include "symtable.h"
#include "util.h"
#include "eval.h"
int allNumbers(object list)
{
object *currentCell = &list;
while (TYPE(*currentCell) != nilObject)
{
if (TYPE(CAR(*currentCell)) != numberObject)
{
return 0;
}
currentCell = &CDR(*currentCell);
}
return 1;
}
object add(object parameters)
{
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else if (listLength(parameters) == 0)
{
result = longlongToNumber(0LL);
}
else
{
object first, rest;
first = CAR(parameters);
rest = add(CDR(parameters));
result = plusNum(first, rest);
}
return result;
}
object subtract(object parameters)
{
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else if (listLength(parameters) == 0)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (listLength(parameters) == 1)
{
result = minusNum(CAR(parameters));
}
else
{
result = plusNum(CAR(parameters),
minusNum(add(CDR(parameters))));
}
return result;
}
object multiply(object parameters)
{
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else if (listLength(parameters) == 0)
{
result = longlongToNumber(1LL);
}
else
{
object first, rest;
first = CAR(parameters);
rest = multiply(CDR(parameters));
result = timesNum(first,rest);
}
return result;
}
object divide(object parameters)
{
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else if (listLength(parameters) == 0)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (listLength(parameters) == 1)
{
result = inverseNum(CAR(parameters));
}
else
{
object check = inverseNum(multiply(CDR(parameters)));
if (TYPE(check) != errorObject)
{
result = timesNum(CAR(parameters),
inverseNum(multiply(CDR(parameters))));
}
else
{
result = check;
}
result = shortenFractionNum(result);
}
return result;
}
object exactToInexact(object parameters)
{
object result;
if (listLength(parameters) != 1)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (TYPE(CAR(parameters)) != numberObject)
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else
{
result = exactToInexactNum(CAR(parameters));
}
return result;
}
object inexactToExact(object parameters)
{
object result;
if (listLength(parameters) != 1)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (TYPE(CAR(parameters)) != numberObject)
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else
{
result = inexactToExactNum(CAR(parameters));
}
return result;
}
object quote(object parameters)
{
object result;
if (listLength(parameters) != 1)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else
{
result = copyObject(CAR(parameters));
}
return result;
}
object define(object parameters)
{
object result;
if (listLength(parameters) != 2)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (TYPE(CAR(parameters)) == symbolObject)
{
result = copyObject(CAR(parameters));
addSymbolVariable(SYM(result),
eval(copyObject(CAR(CDR(parameters)))));
}
return result;
}