#pragma once #include #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 STR(x) ((x).value.string) #define CHR(x) ((x).value.character) #define BOOL(x) ((x).value.boolean) #define ERR(x) ((x).value.err) #define SIGERR(error) \ {\ object __result;\ TYPE(__result) = errorObject;\ ERR(__result) = error;\ return __result;\ } #define PROC(x) ((x).value.proc) #define PROC_TYPE(x) ((x).value.proc->type) #define PROC_SPECIAL(x) ((x).value.proc->isSpecialForm) #define PROC_BUILTIN(x) ((x).value.proc->value.builtin.pointer) #define PROC_COMP_ARGS(x) ((x).value.proc->value.compound.args) #define PROC_COMP_BODY(x) ((x).value.proc->value.compound.body) #define PROC_COMP_ENV(x) ((x).value.proc->value.compound.environment) #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, unspecifiedObject, consObject, numberObject, symbolObject, procedureObject, boolObject, stringObject, charObject, errorObject, EOFObject } dataType; typedef enum { improperListError, improperDotNotation, typeError, unrecognizedSymbolError, notApplicableError, divisionByZeroError, argumentNumberError, maxRecursionDepthError, invalidCharacterError, invalidHashSequenceError, unexpectedEOFError, unmatchedParenError, } error; typedef enum { fractionNum, realNum } numType; typedef enum { builtinProc, compoundProc } procType; typedef struct entry entry; typedef struct frame frame; typedef frame *env; 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; char *string; wchar_t character; cons *consCell; number num; procedure *proc; int boolean; } value; }; struct cons { object car; object cdr; }; struct entry { char *name; object value; struct entry *left; struct entry *right; }; /* овај тип служи за имплементирање табеле симбола који помажу да се стварају * променљиве и процедуре у ћирилиспу */ struct frame { entry *table; /* Макрои у табели се налазе као конс структуре где је car форма маркоа * представљена у листи (м а1 а2 . остало) а cdr је дефиниција макроа * представљена као симболички израз */ env enclosing; }; struct procedure { procType type; int isSpecialForm; union { struct { object (*pointer)(object); } builtin; struct { object args; object body; env environment; } compound; } value; }; env globalEnv; /******************************* функције везане за окружења */ env createEnvironment(env enclosing); void removeEnvironment(env input); void addSymbolInternal(char *symbol, object (*function)(), int isSpecialForm); void addSymbolVariable(char *symbol, object variable, env currentEnv); /* функције помоћу којих се дефинишу нове променљиве: addSymbolVariable се * позива током корисничких дефиниција у програму, док се addSymbolInternal * користи у init.c да би се дефинисале "уграђене" процедуре */ object referVariable(char *symbol, env currentEnv); /* враћа вредност на коју се односи име симбола у табели */ /******************************* */ int properList(object list); int listLength(object list); int improperListLength(object list); /* уколико објекат није конс, враћа 1, уколико јесте, враћа дужину крње листе * укључујући задњи члан, уколико је дата правилна листа, нил се и даље рачуна * као члан */ 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); int cmp(object a, object b); /* пореди два броја и враћа -1, 0, 1 у зависности од односа истих, претпоставља * да су објекти бројеви */ object intToBool(int boolean); procedure *createProcedure();