cirilisp/internals.c

153 lines
2.4 KiB
C

#include "util.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)
{
NUM(result) = 0LL;
}
else
{
object first, rest;
first = CAR(parameters);
rest = add(CDR(parameters));
NUM(result) = NUM(first) + NUM(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)
{
NUM(result) = -NUM(CAR(parameters));
}
else
{
NUM(result) = NUM(CAR(parameters)) - NUM(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)
{
NUM(result) = 1LL;
}
else
{
object first, rest;
first = CAR(parameters);
rest = multiply(CDR(parameters));
NUM(result) = NUM(first) * NUM(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)
{
if (NUM(CAR(parameters)) != 0)
{
NUM(result) = 1/NUM(CAR(parameters));
}
else
{
TYPE(result) = errorObject;
ERR(result) = divisionByZeroError;
}
}
else
{
if (NUM(multiply(CDR(parameters))) != 0)
{
NUM(result) = NUM(CAR(parameters))/NUM(multiply(CDR(parameters)));
}
else
{
TYPE(result) = errorObject;
ERR(result) = divisionByZeroError;
}
}
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;
}