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