Омогућена делимична елиминација репних позива, измењена "примени" функција
This commit is contained in:
parent
b136002d40
commit
a765bf886f
4
Makefile
4
Makefile
|
@ -9,8 +9,8 @@ LIBPREFIX = $(PREFIX)/lib
|
||||||
|
|
||||||
# флегови за C компајлер и линкер
|
# флегови за C компајлер и линкер
|
||||||
CPPFLAGS = -D_POSIX_C_SOURCE=2 -DDESTDIR=\"$(DESTDIR)\" -DVERSION=\"$(VERSION)\"
|
CPPFLAGS = -D_POSIX_C_SOURCE=2 -DDESTDIR=\"$(DESTDIR)\" -DVERSION=\"$(VERSION)\"
|
||||||
# CFLAGS = -g -std=c99 -pedantic -Wall -Wextra -O0 -fexec-charset=UTF-8 -finput-charset=UTF-8 -fwide-exec-charset=UTF-32LE
|
# CFLAGS = -g -std=c99 -pedantic -Wall -Wextra -Wno-maybe-uninitialized -O0 -fexec-charset=UTF-8 -finput-charset=UTF-8 -fwide-exec-charset=UTF-32LE
|
||||||
CFLAGS = -std=c99 -pedantic -Wall -Wextra -O3 -fexec-charset=UTF-8 -finput-charset=UTF-8 -fwide-exec-charset=UTF-32LE
|
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Wno-maybe-uninitialized -O3 -fexec-charset=UTF-8 -finput-charset=UTF-8 -fwide-exec-charset=UTF-32LE
|
||||||
LDFLAGS = -lm -lc
|
LDFLAGS = -lm -lc
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
|
|
199
eval.c
199
eval.c
|
@ -11,85 +11,6 @@ int maxRecursionDepth = 10000;
|
||||||
|
|
||||||
object apply(object function, object parameters, env currentEnv);
|
object apply(object function, object parameters, env currentEnv);
|
||||||
|
|
||||||
object Eval(object input, env currentEnv)
|
|
||||||
{
|
|
||||||
object result;
|
|
||||||
|
|
||||||
if (TYPE(input) == symbolObject)
|
|
||||||
{
|
|
||||||
result = referVariable(SYM(input), currentEnv);
|
|
||||||
}
|
|
||||||
else if (TYPE(input) == consObject)
|
|
||||||
{
|
|
||||||
if (!properList(input))
|
|
||||||
{
|
|
||||||
deleteObject(input);
|
|
||||||
SIGERR(improperListError);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int regularEvalOrder = 1;
|
|
||||||
CAR(input) = Eval(CAR(input), currentEnv);
|
|
||||||
if (TYPE(CAR(input)) == errorObject)
|
|
||||||
{
|
|
||||||
result = copyObject(CAR(input));
|
|
||||||
deleteObject(input);
|
|
||||||
CPYERR(ERR(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE(CAR(input)) == procedureObject &&
|
|
||||||
PROC_SPECIAL(CAR(input)))
|
|
||||||
{
|
|
||||||
regularEvalOrder = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
object *currentCell = &CDR(input);
|
|
||||||
int noErrors = 1;
|
|
||||||
if (regularEvalOrder)
|
|
||||||
{
|
|
||||||
while (TYPE(*currentCell) != nilObject)
|
|
||||||
{
|
|
||||||
CAR(*currentCell) =
|
|
||||||
Eval(CAR(*currentCell),
|
|
||||||
currentEnv);
|
|
||||||
|
|
||||||
if (TYPE(CAR(*currentCell)) ==
|
|
||||||
errorObject)
|
|
||||||
{
|
|
||||||
noErrors = 0;
|
|
||||||
object err = copyObject(
|
|
||||||
CAR(*currentCell));
|
|
||||||
deleteObject(input);
|
|
||||||
CPYERR(ERR(err));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentCell = &CDR(*currentCell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noErrors)
|
|
||||||
{
|
|
||||||
result = apply(CAR(input), CDR(input),
|
|
||||||
currentEnv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE(CAR(input)) == procedureObject &&
|
|
||||||
PROC_SPECIAL(CAR(input)) &&
|
|
||||||
PROC_TYPE(CAR(input)) == compoundProc)
|
|
||||||
{
|
|
||||||
result = Eval(result, currentEnv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = copyObject(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteObject(input);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bindArgs(object parameters, object args, env newEnv)
|
int bindArgs(object parameters, object args, env newEnv)
|
||||||
/* на почетку извршавања функције, везује прослеђене параметре, за симболе у
|
/* на почетку извршавања функције, везује прослеђене параметре, за симболе у
|
||||||
* дефиницији функције, везивање се врши у новонасталом окружењу, уколико је
|
* дефиницији функције, везивање се врши у новонасталом окружењу, уколико је
|
||||||
|
@ -142,12 +63,106 @@ int bindArgs(object parameters, object args, env newEnv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object apply(object procedure, object parameters, env currentEnv)
|
object Eval(object input, env currentEnv)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
|
int tailExpression = 0;
|
||||||
|
|
||||||
|
eval:
|
||||||
|
if (TYPE(input) == symbolObject)
|
||||||
|
{
|
||||||
|
result = referVariable(SYM(input), currentEnv);
|
||||||
|
}
|
||||||
|
else if (TYPE(input) == consObject)
|
||||||
|
{
|
||||||
|
if (!properList(input))
|
||||||
|
{
|
||||||
|
deleteObject(input);
|
||||||
|
SIGERR(improperListError);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int regularEvalOrder = 1;
|
||||||
|
CAR(input) = Eval(CAR(input), currentEnv);
|
||||||
|
if (TYPE(CAR(input)) == errorObject)
|
||||||
|
{
|
||||||
|
result = copyObject(CAR(input));
|
||||||
|
deleteObject(input);
|
||||||
|
CPYERR(ERR(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE(CAR(input)) == procedureObject &&
|
||||||
|
PROC_SPECIAL(CAR(input)))
|
||||||
|
{
|
||||||
|
regularEvalOrder = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
object *currentCell = &CDR(input);
|
||||||
|
int noErrors = 1;
|
||||||
|
if (regularEvalOrder)
|
||||||
|
{
|
||||||
|
while (TYPE(*currentCell) != nilObject)
|
||||||
|
{
|
||||||
|
CAR(*currentCell) =
|
||||||
|
Eval(CAR(*currentCell),
|
||||||
|
currentEnv);
|
||||||
|
|
||||||
|
if (TYPE(CAR(*currentCell)) ==
|
||||||
|
errorObject)
|
||||||
|
{
|
||||||
|
noErrors = 0;
|
||||||
|
object err = copyObject(
|
||||||
|
CAR(*currentCell));
|
||||||
|
deleteObject(input);
|
||||||
|
CPYERR(ERR(err));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentCell = &CDR(*currentCell);
|
||||||
|
}
|
||||||
|
if (noErrors)
|
||||||
|
{
|
||||||
|
goto apply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto apply;
|
||||||
|
if (TYPE(CAR(input)) == procedureObject &&
|
||||||
|
PROC_SPECIAL(CAR(input)) &&
|
||||||
|
PROC_TYPE(CAR(input)) == compoundProc)
|
||||||
|
{
|
||||||
|
result = Eval(result, currentEnv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = copyObject(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tailExpression)
|
||||||
|
{
|
||||||
|
removeEnvironment(currentEnv);
|
||||||
|
}
|
||||||
|
deleteObject(input);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
object procedure, parameters;
|
||||||
|
apply:
|
||||||
|
procedure = copyObject(CAR(input));
|
||||||
|
parameters = copyObject(CDR(input));
|
||||||
|
deleteObject(input);
|
||||||
|
if (tailExpression && PROC_TYPE(procedure) != builtinProc)
|
||||||
|
{
|
||||||
|
removeEnvironment(currentEnv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (TYPE(procedure) != procedureObject)
|
if (TYPE(procedure) != procedureObject)
|
||||||
{
|
{
|
||||||
|
deleteObject(procedure);
|
||||||
|
deleteObject(parameters);
|
||||||
SIGERR(notApplicableError);
|
SIGERR(notApplicableError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +170,7 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
object(*f)() = PROC_BUILTIN(procedure);
|
object(*f)() = PROC_BUILTIN(procedure);
|
||||||
if (f == defineInt || f == lambdaInt || f == ifInt ||
|
if (f == defineInt || f == lambdaInt || f == ifInt ||
|
||||||
f == applyInt)
|
f == applyInt || f == defineMacroInt)
|
||||||
{
|
{
|
||||||
result = f(parameters, currentEnv);
|
result = f(parameters, currentEnv);
|
||||||
}
|
}
|
||||||
|
@ -164,12 +179,21 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
result = f(parameters);
|
result = f(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tailExpression)
|
||||||
|
{
|
||||||
|
removeEnvironment(currentEnv);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteObject(procedure);
|
||||||
|
deleteObject(parameters);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++currentRecursionDepth > maxRecursionDepth)
|
if (++currentRecursionDepth > maxRecursionDepth)
|
||||||
{
|
{
|
||||||
--currentRecursionDepth;
|
--currentRecursionDepth;
|
||||||
|
deleteObject(procedure);
|
||||||
|
deleteObject(parameters);
|
||||||
SIGERR(maxRecursionDepthError);
|
SIGERR(maxRecursionDepthError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +205,8 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
deleteObject(args);
|
deleteObject(args);
|
||||||
removeEnvironment(procEnv);
|
removeEnvironment(procEnv);
|
||||||
|
deleteObject(procedure);
|
||||||
|
deleteObject(parameters);
|
||||||
SIGERR(argumentNumberError);
|
SIGERR(argumentNumberError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,11 +226,12 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
//pruneExpr(¤tExpr); ова функција ће бити коришћена за
|
//pruneExpr(¤tExpr); ова функција ће бити коришћена за
|
||||||
// упроштавање израза, тако да постану репно-елиминалбилни, када буде
|
// упроштавање израза, тако да постану репно-елиминалбилни, када буде
|
||||||
// написана ЛОЛ :)
|
// написана ЛОЛ :)
|
||||||
currentExpr = Eval(currentExpr, procEnv);
|
|
||||||
result = copyObject(currentExpr);
|
|
||||||
|
|
||||||
removeEnvironment(procEnv);
|
deleteObject(procedure);
|
||||||
|
deleteObject(parameters);
|
||||||
--currentRecursionDepth;
|
--currentRecursionDepth;
|
||||||
|
input = currentExpr;
|
||||||
return result;
|
currentEnv = procEnv;
|
||||||
|
tailExpression = 1;
|
||||||
|
goto eval;
|
||||||
}
|
}
|
||||||
|
|
21
internals.c
21
internals.c
|
@ -763,6 +763,8 @@ object eqvQInt(object parameters)
|
||||||
|
|
||||||
object applyInt(object parameters, env currentEnv)
|
object applyInt(object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
|
object expression;
|
||||||
|
|
||||||
if (listLength(parameters) != 2)
|
if (listLength(parameters) != 2)
|
||||||
{
|
{
|
||||||
SIGERR(argumentNumberError);
|
SIGERR(argumentNumberError);
|
||||||
|
@ -772,7 +774,24 @@ object applyInt(object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
SIGERR(typeError);
|
SIGERR(typeError);
|
||||||
}
|
}
|
||||||
return apply(CAR(parameters), CAR(CDR(parameters)), currentEnv);
|
/* ово извршавање "примени" функције се врши тако што се "наводи" сваки
|
||||||
|
* појединачни члан листе параметара, и потом ствара комплетан израз
|
||||||
|
* који се евалуира, што укључује и примену функције, ово се чини јер
|
||||||
|
* по тренутном дизајну интерпретера засебна "примени" функција као
|
||||||
|
* таква не постоји */
|
||||||
|
TYPE(expression) = consObject;
|
||||||
|
CONS(expression) = malloc(sizeof(cons));
|
||||||
|
CAR(expression) = copyObject(CAR(parameters));
|
||||||
|
CDR(expression) = copyObject(CAR(CDR(parameters)));
|
||||||
|
|
||||||
|
object *current = &expression;
|
||||||
|
while (TYPE(*current) != nilObject)
|
||||||
|
{
|
||||||
|
CAR(*current) = quoteExpression(CAR(*current));
|
||||||
|
current = &CDR(*current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Eval(expression, currentEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
object displayInt(object parameters)
|
object displayInt(object parameters)
|
||||||
|
|
17
util.c
17
util.c
|
@ -274,6 +274,23 @@ object copyObject(object input)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object quoteExpression(object input)
|
||||||
|
{
|
||||||
|
object result;
|
||||||
|
|
||||||
|
TYPE(result) = consObject;
|
||||||
|
CONS(result) = malloc(sizeof(cons));
|
||||||
|
TYPE(CAR(result)) = symbolObject;
|
||||||
|
SYM(CAR(result)) = malloc(sizeof(char) * (strlen("навод") + 1));
|
||||||
|
strcpy(SYM(CAR(result)), "навод");
|
||||||
|
TYPE(CDR(result)) = consObject;
|
||||||
|
CONS(CDR(result)) = malloc(sizeof(cons));
|
||||||
|
CAR(CDR(result)) = input;
|
||||||
|
TYPE(CDR(CDR(result))) = nilObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
object longlongToNumber(long long int input)
|
object longlongToNumber(long long int input)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
|
|
1
util.h
1
util.h
|
@ -193,6 +193,7 @@ int improperListLength(object list);
|
||||||
* као члан */
|
* као члан */
|
||||||
void deleteObject(object input);
|
void deleteObject(object input);
|
||||||
object copyObject(object input);
|
object copyObject(object input);
|
||||||
|
object quoteExpression(object input);
|
||||||
|
|
||||||
object longlongToNumber(long long int input);
|
object longlongToNumber(long long int input);
|
||||||
object shortenFractionNum(object a);
|
object shortenFractionNum(object a);
|
||||||
|
|
Loading…
Reference in a new issue