2019-01-07 01:04:40 +01:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2019-02-03 18:57:49 +01:00
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
2019-01-14 03:16:25 +01:00
|
|
|
|
#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)
|
2019-02-03 18:57:49 +01:00
|
|
|
|
#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)
|
2019-01-16 23:24:23 +01:00
|
|
|
|
#define ERR(x) ((x).value.err)
|
2019-01-14 03:16:25 +01:00
|
|
|
|
|
2019-02-03 18:57:49 +01:00
|
|
|
|
#define SIGERR(error) \
|
2019-02-18 23:20:44 +01:00
|
|
|
|
{\
|
|
|
|
|
object __result;\
|
|
|
|
|
TYPE(__result) = errorObject;\
|
|
|
|
|
ERR(__result) = malloc((strlen(commonErrs[error]) + 1) *\
|
|
|
|
|
sizeof(char));\
|
|
|
|
|
strcpy(ERR(__result), commonErrs[error]);\
|
|
|
|
|
return __result;\
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define CPYERR(error) \
|
2019-02-03 18:57:49 +01:00
|
|
|
|
{\
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object __result;\
|
|
|
|
|
TYPE(__result) = errorObject;\
|
|
|
|
|
ERR(__result) = error;\
|
|
|
|
|
return __result;\
|
2019-02-03 18:57:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-27 16:31:32 +01:00
|
|
|
|
#define PROC(x) ((x).value.proc)
|
|
|
|
|
#define PROC_TYPE(x) ((x).value.proc->type)
|
2019-02-13 12:09:35 +01:00
|
|
|
|
#define PROC_SPECIAL(x) ((x).value.proc->isSpecialForm)
|
2019-02-09 14:06:53 +01:00
|
|
|
|
#define PROC_BUILTIN(x) ((x).value.proc->value.builtin.pointer)
|
2019-01-27 16:31:32 +01:00
|
|
|
|
#define PROC_COMP_ARGS(x) ((x).value.proc->value.compound.args)
|
|
|
|
|
#define PROC_COMP_BODY(x) ((x).value.proc->value.compound.body)
|
2019-02-05 16:35:05 +01:00
|
|
|
|
#define PROC_COMP_ENV(x) ((x).value.proc->value.compound.environment)
|
2019-01-27 16:31:32 +01:00
|
|
|
|
|
2019-01-20 23:48:12 +01:00
|
|
|
|
#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)
|
|
|
|
|
|
2019-01-07 01:04:40 +01:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
nilObject,
|
2019-02-03 18:57:49 +01:00
|
|
|
|
unspecifiedObject,
|
2019-01-07 01:04:40 +01:00
|
|
|
|
consObject,
|
|
|
|
|
numberObject,
|
2019-01-14 03:16:25 +01:00
|
|
|
|
symbolObject,
|
2019-01-27 16:31:32 +01:00
|
|
|
|
procedureObject,
|
2019-01-29 23:54:32 +01:00
|
|
|
|
boolObject,
|
2019-02-03 18:57:49 +01:00
|
|
|
|
stringObject,
|
|
|
|
|
charObject,
|
2019-02-09 19:55:51 +01:00
|
|
|
|
errorObject,
|
|
|
|
|
EOFObject
|
2019-01-07 01:04:40 +01:00
|
|
|
|
} dataType;
|
|
|
|
|
|
2019-01-16 23:24:23 +01:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
improperListError,
|
2019-02-06 16:44:39 +01:00
|
|
|
|
improperDotNotation,
|
2019-01-16 23:24:23 +01:00
|
|
|
|
typeError,
|
|
|
|
|
unrecognizedSymbolError,
|
|
|
|
|
notApplicableError,
|
|
|
|
|
divisionByZeroError,
|
2019-01-20 14:12:47 +01:00
|
|
|
|
argumentNumberError,
|
2019-01-27 16:31:32 +01:00
|
|
|
|
maxRecursionDepthError,
|
2019-02-03 18:57:49 +01:00
|
|
|
|
invalidCharacterError,
|
|
|
|
|
invalidHashSequenceError,
|
|
|
|
|
unexpectedEOFError,
|
|
|
|
|
unmatchedParenError,
|
2019-02-18 01:17:47 +01:00
|
|
|
|
outOfMemoryError
|
2019-01-16 23:24:23 +01:00
|
|
|
|
} error;
|
|
|
|
|
|
2019-02-18 23:20:44 +01:00
|
|
|
|
extern char *commonErrs[];
|
|
|
|
|
|
2019-01-20 23:48:12 +01:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
fractionNum,
|
|
|
|
|
realNum
|
|
|
|
|
} numType;
|
|
|
|
|
|
2019-01-27 16:31:32 +01:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
builtinProc,
|
|
|
|
|
compoundProc
|
|
|
|
|
} procType;
|
|
|
|
|
|
2019-02-05 16:35:05 +01:00
|
|
|
|
typedef struct entry entry;
|
|
|
|
|
typedef struct frame frame;
|
|
|
|
|
typedef frame *env;
|
|
|
|
|
|
2019-01-27 16:31:32 +01:00
|
|
|
|
typedef struct number number;
|
|
|
|
|
typedef struct object object;
|
|
|
|
|
typedef struct cons cons;
|
|
|
|
|
typedef struct procedure procedure;
|
|
|
|
|
|
|
|
|
|
struct number
|
2019-01-20 23:48:12 +01:00
|
|
|
|
{
|
|
|
|
|
numType type;
|
|
|
|
|
union
|
|
|
|
|
{
|
|
|
|
|
long double real;
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
long long int numerator;
|
|
|
|
|
long long int denominator;
|
|
|
|
|
} fraction;
|
|
|
|
|
} value;
|
2019-01-27 16:31:32 +01:00
|
|
|
|
};
|
2019-01-20 23:48:12 +01:00
|
|
|
|
|
2019-01-14 03:16:25 +01:00
|
|
|
|
struct object
|
2019-01-07 01:04:40 +01:00
|
|
|
|
{
|
|
|
|
|
dataType type;
|
2019-01-14 03:16:25 +01:00
|
|
|
|
union
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
char *err;
|
2019-01-14 03:16:25 +01:00
|
|
|
|
char *symbol;
|
2019-02-03 18:57:49 +01:00
|
|
|
|
char *string;
|
|
|
|
|
wchar_t character;
|
2019-01-14 03:16:25 +01:00
|
|
|
|
cons *consCell;
|
2019-01-20 23:48:12 +01:00
|
|
|
|
number num;
|
2019-01-27 16:31:32 +01:00
|
|
|
|
procedure *proc;
|
2019-01-29 23:54:32 +01:00
|
|
|
|
int boolean;
|
2019-01-14 03:16:25 +01:00
|
|
|
|
} value;
|
|
|
|
|
};
|
2019-01-07 01:04:40 +01:00
|
|
|
|
|
2019-01-14 03:16:25 +01:00
|
|
|
|
struct cons
|
2019-01-07 01:04:40 +01:00
|
|
|
|
{
|
|
|
|
|
object car;
|
|
|
|
|
object cdr;
|
2019-01-14 03:16:25 +01:00
|
|
|
|
};
|
2019-01-07 01:04:40 +01:00
|
|
|
|
|
2019-02-05 16:35:05 +01:00
|
|
|
|
struct entry
|
|
|
|
|
{
|
|
|
|
|
char *name;
|
|
|
|
|
object value;
|
|
|
|
|
struct entry *left;
|
|
|
|
|
struct entry *right;
|
|
|
|
|
};
|
|
|
|
|
/* овај тип служи за имплементирање табеле симбола који помажу да се стварају
|
|
|
|
|
* променљиве и процедуре у ћирилиспу */
|
|
|
|
|
|
|
|
|
|
struct frame
|
|
|
|
|
{
|
|
|
|
|
entry *table;
|
|
|
|
|
env enclosing;
|
|
|
|
|
};
|
|
|
|
|
|
2019-01-27 16:31:32 +01:00
|
|
|
|
struct procedure
|
|
|
|
|
{
|
|
|
|
|
procType type;
|
2019-02-13 12:09:35 +01:00
|
|
|
|
int isSpecialForm;
|
2019-01-27 16:31:32 +01:00
|
|
|
|
union
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
object (*pointer)(object);
|
|
|
|
|
} builtin;
|
2019-01-27 16:31:32 +01:00
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
object args;
|
|
|
|
|
object body;
|
2019-02-05 16:35:05 +01:00
|
|
|
|
env environment;
|
2019-01-27 16:31:32 +01:00
|
|
|
|
} compound;
|
|
|
|
|
} value;
|
|
|
|
|
};
|
|
|
|
|
|
2019-02-05 16:35:05 +01:00
|
|
|
|
/******************************* функције везане за окружења */
|
|
|
|
|
env createEnvironment(env enclosing);
|
|
|
|
|
void removeEnvironment(env input);
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
void addSymbolInternal(char *symbol, object (*function)(), int isSpecialForm);
|
2019-02-05 16:35:05 +01:00
|
|
|
|
void addSymbolVariable(char *symbol, object variable, env currentEnv);
|
|
|
|
|
/* функције помоћу којих се дефинишу нове променљиве: addSymbolVariable се
|
|
|
|
|
* позива током корисничких дефиниција у програму, док се addSymbolInternal
|
|
|
|
|
* користи у init.c да би се дефинисале "уграђене" процедуре */
|
|
|
|
|
|
|
|
|
|
object referVariable(char *symbol, env currentEnv);
|
|
|
|
|
/* враћа вредност на коју се односи име симбола у табели */
|
|
|
|
|
/******************************* */
|
|
|
|
|
|
2019-01-14 03:16:25 +01:00
|
|
|
|
int properList(object list);
|
|
|
|
|
int listLength(object list);
|
2019-02-10 22:21:20 +01:00
|
|
|
|
int improperListLength(object list);
|
|
|
|
|
/* уколико објекат није конс, враћа 1, уколико јесте, враћа дужину крње листе
|
|
|
|
|
* укључујући задњи члан, уколико је дата правилна листа, нил се и даље рачуна
|
|
|
|
|
* као члан */
|
2019-01-14 03:16:25 +01:00
|
|
|
|
void deleteObject(object input);
|
|
|
|
|
object copyObject(object input);
|
2019-08-25 14:34:38 +02:00
|
|
|
|
object quoteExpression(object input);
|
2019-01-20 23:48:12 +01:00
|
|
|
|
|
|
|
|
|
object longlongToNumber(long long int input);
|
|
|
|
|
object shortenFractionNum(object a);
|
|
|
|
|
object exactToInexactNum(object a);
|
2019-01-21 18:44:56 +01:00
|
|
|
|
object inexactToExactNum(object a);
|
2019-01-20 23:48:12 +01:00
|
|
|
|
object plusNum(object a, object b);
|
|
|
|
|
object minusNum(object a);
|
|
|
|
|
object timesNum(object a, object b);
|
|
|
|
|
object inverseNum(object a);
|
2019-02-07 23:07:02 +01:00
|
|
|
|
int cmp(object a, object b);
|
|
|
|
|
/* пореди два броја и враћа -1, 0, 1 у зависности од односа истих, претпоставља
|
|
|
|
|
* да су објекти бројеви */
|
2019-02-18 01:17:47 +01:00
|
|
|
|
int integer(object a);
|
|
|
|
|
/* проверава да ли је дати број разломачки и такође цео, претпоставља да је
|
|
|
|
|
* дати објекат број */
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
|
|
|
|
object intToBool(int boolean);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
|
|
|
|
|
procedure *createProcedure();
|