cirilisp/util.h

217 lines
5.1 KiB
C
Raw Normal View History

#pragma once
#include <wchar.h>
#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)
2019-01-29 23:54:32 +01:00
#define BOOL(x) ((x).value.boolean)
#define ERR(x) ((x).value.err)
#define SIGERR(error) \
{\
object __result;\
TYPE(__result) = errorObject;\
ERR(__result) = malloc((strlen(commonErrs[error]) + 1) *\
sizeof(char));\
strcpy(ERR(__result), commonErrs[error]);\
return __result;\
}
#define CPYERR(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,
2019-01-29 23:54:32 +01:00
boolObject,
stringObject,
charObject,
errorObject,
EOFObject
} dataType;
typedef enum
{
improperListError,
improperDotNotation,
typeError,
unrecognizedSymbolError,
notApplicableError,
divisionByZeroError,
argumentNumberError,
maxRecursionDepthError,
invalidCharacterError,
invalidHashSequenceError,
unexpectedEOFError,
unmatchedParenError,
outOfMemoryError
} error;
extern char *commonErrs[];
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
{
char *err;
char *symbol;
char *string;
wchar_t character;
cons *consCell;
number num;
procedure *proc;
2019-01-29 23:54:32 +01:00
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;
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 у зависности од односа истих, претпоставља
* да су објекти бројеви */
int integer(object a);
/* проверава да ли је дати број разломачки и такође цео, претпоставља да је
* дати објекат број */
object intToBool(int boolean);
procedure *createProcedure();