Омогућена потпуна репна елиминација, "почни" је сада специјална форма, понашање је непромењено
This commit is contained in:
parent
a876c02003
commit
43dcc68547
|
@ -93,7 +93,7 @@ void init()
|
|||
addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0);
|
||||
addSymbolInternal("опиши", &defineInt, 1);
|
||||
addSymbolInternal("опиши-складњу", &defineMacroInt, 1);
|
||||
addSymbolInternal("почни", &beginInt, 0);
|
||||
addSymbolInternal("почни", &beginInt, 1);
|
||||
addSymbolInternal("ниска?", &stringQInt, 0);
|
||||
addSymbolInternal("сар", &carInt, 0);
|
||||
addSymbolInternal("разломак?", &fractionQInt, 0);
|
||||
|
|
141
eval.c
141
eval.c
|
@ -81,61 +81,56 @@ eval:
|
|||
deleteObject(input);
|
||||
SIGERR(improperListError);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)))
|
||||
PROC_SPECIAL(CAR(input)) &&
|
||||
PROC_TYPE(CAR(input)) == compoundProc)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (TYPE(CAR(input)) == procedureObject &&
|
||||
PROC_SPECIAL(CAR(input)) &&
|
||||
PROC_TYPE(CAR(input)) == compoundProc)
|
||||
{
|
||||
macroEvalPending = 1;
|
||||
}
|
||||
goto apply;
|
||||
// big problem pendejo
|
||||
macroEvalPending = 1;
|
||||
}
|
||||
goto apply;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -155,7 +150,8 @@ apply:
|
|||
procedure = copyObject(CAR(input));
|
||||
parameters = copyObject(CDR(input));
|
||||
deleteObject(input);
|
||||
if (tailExpression && PROC_TYPE(procedure) != builtinProc && !macroEvalPending)
|
||||
if (tailExpression && PROC_TYPE(procedure) != builtinProc &&
|
||||
!macroEvalPending)
|
||||
{
|
||||
removeEnvironment(currentEnv);
|
||||
}
|
||||
|
@ -171,8 +167,35 @@ apply:
|
|||
if (PROC_TYPE(procedure) == builtinProc)
|
||||
{
|
||||
object(*f)() = PROC_BUILTIN(procedure);
|
||||
|
||||
if (f == ifInt)
|
||||
{
|
||||
if (listLength(parameters) >= 2)
|
||||
{
|
||||
CAR(CDR(parameters)) =
|
||||
quoteExpression(CAR(CDR(parameters)));
|
||||
}
|
||||
if (listLength(parameters) >= 3)
|
||||
{
|
||||
CAR(CDR(CDR(parameters))) =
|
||||
quoteExpression(CAR(CDR(CDR(parameters))));
|
||||
}
|
||||
}
|
||||
else if (f == beginInt)
|
||||
{
|
||||
if (listLength(parameters) >= 1)
|
||||
{
|
||||
object *current = ¶meters;
|
||||
while (TYPE(CDR(*current)) != nilObject)
|
||||
{
|
||||
current = &CDR(*current);
|
||||
}
|
||||
CAR(*current) = quoteExpression(CAR(*current));
|
||||
}
|
||||
}
|
||||
|
||||
if (f == defineInt || f == lambdaInt || f == ifInt ||
|
||||
f == applyInt || f == defineMacroInt)
|
||||
f == applyInt || f == defineMacroInt || f == beginInt)
|
||||
{
|
||||
result = f(parameters, currentEnv);
|
||||
}
|
||||
|
@ -181,13 +204,18 @@ apply:
|
|||
result = f(parameters);
|
||||
}
|
||||
|
||||
if (tailExpression)
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
if (f == beginInt || f == ifInt)
|
||||
{
|
||||
input = result;
|
||||
goto eval;
|
||||
}
|
||||
else if (tailExpression)
|
||||
{
|
||||
removeEnvironment(currentEnv);
|
||||
}
|
||||
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -225,9 +253,6 @@ apply:
|
|||
}
|
||||
/* репни позив */
|
||||
currentExpr = copyObject(CAR(*currentExprPointer));
|
||||
//pruneExpr(¤tExpr); ова функција ће бити коришћена за
|
||||
// упроштавање израза, тако да постану репно-елиминалбилни, када буде
|
||||
// написана ЛОЛ :)
|
||||
|
||||
deleteObject(procedure);
|
||||
deleteObject(parameters);
|
||||
|
|
15
internals.c
15
internals.c
|
@ -837,7 +837,7 @@ object readInt(object parameters)
|
|||
return Read("", stdin);
|
||||
}
|
||||
|
||||
object beginInt(object parameters)
|
||||
object beginInt(object parameters, env currentEnv)
|
||||
{
|
||||
object last;
|
||||
if (listLength(parameters) == 0)
|
||||
|
@ -847,11 +847,22 @@ object beginInt(object parameters)
|
|||
else
|
||||
{
|
||||
object *current = ¶meters;
|
||||
object currentResult;
|
||||
while (TYPE(CDR(*current)) != nilObject)
|
||||
{
|
||||
currentResult = Eval(copyObject(CAR(*current)), currentEnv);
|
||||
if (TYPE(currentResult) == errorObject)
|
||||
{
|
||||
CPYERR(ERR(currentResult));
|
||||
}
|
||||
|
||||
current = &CDR(*current);
|
||||
}
|
||||
last = copyObject(CAR(*current));
|
||||
last = Eval(copyObject(CAR(*current)), currentEnv);
|
||||
if (TYPE(last) == errorObject)
|
||||
{
|
||||
CPYERR(ERR(last));
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue