#pragma once #define TYPE(x) ((x).type) #define CONS(x) ((x).value.consCell) #define CAR(x) (((x).value.consCell)->car) #define CDR(x) (((x).value.consCell)->cdr) #define SYM(x) ((x).value.symbol) #define BOOL(x) ((x).value.boolean) #define ERR(x) ((x).value.err) #define PROC(x) ((x).value.proc) #define PROC_TYPE(x) ((x).value.proc->type) #define PROC_BUILTIN(x) ((x).value.proc->value.builtin) #define PROC_COMP_ARGS(x) ((x).value.proc->value.compound.args) #define PROC_COMP_BODY(x) ((x).value.proc->value.compound.body) #define NUM(x) ((x).value.num) #define NUM_TYPE(x) ((x).value.num.type) #define NUM_NUMER(x) ((x).value.num.value.fraction.numerator) #define NUM_DENOM(x) ((x).value.num.value.fraction.denominator) #define NUM_REAL(x) ((x).value.num.value.real) typedef enum { nilObject, consObject, numberObject, symbolObject, procedureObject, boolObject, errorObject } dataType; typedef enum { improperListError, typeError, unrecognizedSymbolError, notApplicableError, divisionByZeroError, argumentNumberError, maxRecursionDepthError, syntaxError } error; typedef enum { fractionNum, realNum } numType; typedef enum { builtinProc, compoundProc } procType; typedef struct number number; typedef struct object object; typedef struct cons cons; typedef struct procedure procedure; struct number { numType type; union { long double real; struct { long long int numerator; long long int denominator; } fraction; } value; }; struct object { dataType type; union { error err; char *symbol; cons *consCell; number num; procedure *proc; int boolean; } value; }; struct cons { object car; object cdr; }; struct procedure { procType type; union { object (*builtin)(object); struct { object args; object body; } compound; } value; }; int isSpecialForm(char *symbol); int properList(object list); int listLength(object list); void deleteObject(object input); object copyObject(object input); object longlongToNumber(long long int input); object shortenFractionNum(object a); object exactToInexactNum(object a); object inexactToExactNum(object a); object plusNum(object a, object b); object minusNum(object a); object timesNum(object a, object b); object inverseNum(object a); procedure *createProcedure();