138 lines
2.2 KiB
C
138 lines
2.2 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(add(CDR(parameters))) != 0)
|
|
{
|
|
NUM(result) = NUM(CAR(parameters))/NUM(add(CDR(parameters)));
|
|
}
|
|
else
|
|
{
|
|
TYPE(result) = errorObject;
|
|
ERR(result) = divisionByZeroError;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|