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