Омогућена делимична елиминација репних позива, измењена "примени" функција
This commit is contained in:
parent
b136002d40
commit
a765bf886f
4
Makefile
4
Makefile
|
@ -9,8 +9,8 @@ LIBPREFIX = $(PREFIX)/lib
|
|||
|
||||
# флегови за C компајлер и линкер
|
||||
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 = -std=c99 -pedantic -Wall -Wextra -O3 -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 -Wno-maybe-uninitialized -O3 -fexec-charset=UTF-8 -finput-charset=UTF-8 -fwide-exec-charset=UTF-32LE
|
||||
LDFLAGS = -lm -lc
|
||||
|
||||
CC = cc
|
||||
|
|
199
eval.c
199
eval.c
|
@ -11,85 +11,6 @@ int maxRecursionDepth = 10000;
|
|||
|
||||
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)
|
||||
/* на почетку извршавања функције, везује прослеђене параметре, за симболе у
|
||||
* дефиницији функције, везивање се врши у новонасталом окружењу, уколико је
|
||||
|
@ -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;
|
||||
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)
|
||||
{
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
SIGERR(notApplicableError);
|
||||
}
|
||||
|
||||
|
@ -155,7 +170,7 @@ object apply(object procedure, object parameters, env currentEnv)
|
|||
{
|
||||
object(*f)() = PROC_BUILTIN(procedure);
|
||||
if (f == defineInt || f == lambdaInt || f == ifInt ||
|
||||
f == applyInt)
|
||||
f == applyInt || f == defineMacroInt)
|
||||
{
|
||||
result = f(parameters, currentEnv);
|
||||
}
|
||||
|
@ -164,12 +179,21 @@ object apply(object procedure, object parameters, env currentEnv)
|
|||
result = f(parameters);
|
||||
}
|
||||
|
||||
if (tailExpression)
|
||||
{
|
||||
removeEnvironment(currentEnv);
|
||||
}
|
||||
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (++currentRecursionDepth > maxRecursionDepth)
|
||||
{
|
||||
--currentRecursionDepth;
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
SIGERR(maxRecursionDepthError);
|
||||
}
|
||||
|
||||
|
@ -181,6 +205,8 @@ object apply(object procedure, object parameters, env currentEnv)
|
|||
{
|
||||
deleteObject(args);
|
||||
removeEnvironment(procEnv);
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
SIGERR(argumentNumberError);
|
||||
}
|
||||
|
||||
|
@ -200,11 +226,12 @@ object apply(object procedure, object parameters, env currentEnv)
|
|||
//pruneExpr(¤tExpr); ова функција ће бити коришћена за
|
||||
// упроштавање израза, тако да постану репно-елиминалбилни, када буде
|
||||
// написана ЛОЛ :)
|
||||
currentExpr = Eval(currentExpr, procEnv);
|
||||
result = copyObject(currentExpr);
|
||||
|
||||
removeEnvironment(procEnv);
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
--currentRecursionDepth;
|
||||
|
||||
return result;
|
||||
input = currentExpr;
|
||||
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 expression;
|
||||
|
||||
if (listLength(parameters) != 2)
|
||||
{
|
||||
SIGERR(argumentNumberError);
|
||||
|
@ -772,7 +774,24 @@ object applyInt(object parameters, env currentEnv)
|
|||
{
|
||||
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)
|
||||
|
|
17
util.c
17
util.c
|
@ -274,6 +274,23 @@ object copyObject(object input)
|
|||
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 result;
|
||||
|
|
Loading…
Reference in a new issue