Омогућена потпуна репна елиминација, "почни" је сада специјална форма, понашање је непромењено

This commit is contained in:
kappa 2019-09-21 10:53:37 +02:00
parent a876c02003
commit 43dcc68547
3 changed files with 97 additions and 61 deletions

View file

@ -93,7 +93,7 @@ void init()
addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0); addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0);
addSymbolInternal("опиши", &defineInt, 1); addSymbolInternal("опиши", &defineInt, 1);
addSymbolInternal("опиши-складњу", &defineMacroInt, 1); addSymbolInternal("опиши-складњу", &defineMacroInt, 1);
addSymbolInternal("почни", &beginInt, 0); addSymbolInternal("почни", &beginInt, 1);
addSymbolInternal("ниска?", &stringQInt, 0); addSymbolInternal("ниска?", &stringQInt, 0);
addSymbolInternal("сар", &carInt, 0); addSymbolInternal("сар", &carInt, 0);
addSymbolInternal("разломак?", &fractionQInt, 0); addSymbolInternal("разломак?", &fractionQInt, 0);

61
eval.c
View file

@ -81,8 +81,7 @@ eval:
deleteObject(input); deleteObject(input);
SIGERR(improperListError); SIGERR(improperListError);
} }
else
{
int regularEvalOrder = 1; int regularEvalOrder = 1;
CAR(input) = Eval(CAR(input), currentEnv); CAR(input) = Eval(CAR(input), currentEnv);
if (TYPE(CAR(input)) == errorObject) if (TYPE(CAR(input)) == errorObject)
@ -105,15 +104,13 @@ eval:
while (TYPE(*currentCell) != nilObject) while (TYPE(*currentCell) != nilObject)
{ {
CAR(*currentCell) = CAR(*currentCell) =
Eval(CAR(*currentCell), Eval(CAR(*currentCell), currentEnv);
currentEnv);
if (TYPE(CAR(*currentCell)) == if (TYPE(CAR(*currentCell)) == errorObject)
errorObject)
{ {
noErrors = 0; noErrors = 0;
object err = copyObject( object err =
CAR(*currentCell)); copyObject(CAR(*currentCell));
deleteObject(input); deleteObject(input);
CPYERR(ERR(err)); CPYERR(ERR(err));
break; break;
@ -134,8 +131,6 @@ eval:
macroEvalPending = 1; macroEvalPending = 1;
} }
goto apply; goto apply;
// big problem pendejo
}
} }
} }
else else
@ -155,7 +150,8 @@ apply:
procedure = copyObject(CAR(input)); procedure = copyObject(CAR(input));
parameters = copyObject(CDR(input)); parameters = copyObject(CDR(input));
deleteObject(input); deleteObject(input);
if (tailExpression && PROC_TYPE(procedure) != builtinProc && !macroEvalPending) if (tailExpression && PROC_TYPE(procedure) != builtinProc &&
!macroEvalPending)
{ {
removeEnvironment(currentEnv); removeEnvironment(currentEnv);
} }
@ -171,8 +167,35 @@ apply:
if (PROC_TYPE(procedure) == builtinProc) if (PROC_TYPE(procedure) == builtinProc)
{ {
object(*f)() = PROC_BUILTIN(procedure); 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 = &parameters;
while (TYPE(CDR(*current)) != nilObject)
{
current = &CDR(*current);
}
CAR(*current) = quoteExpression(CAR(*current));
}
}
if (f == defineInt || f == lambdaInt || f == ifInt || if (f == defineInt || f == lambdaInt || f == ifInt ||
f == applyInt || f == defineMacroInt) f == applyInt || f == defineMacroInt || f == beginInt)
{ {
result = f(parameters, currentEnv); result = f(parameters, currentEnv);
} }
@ -181,13 +204,18 @@ apply:
result = f(parameters); result = f(parameters);
} }
if (tailExpression) deleteObject(procedure);
deleteObject(parameters);
if (f == beginInt || f == ifInt)
{
input = result;
goto eval;
}
else if (tailExpression)
{ {
removeEnvironment(currentEnv); removeEnvironment(currentEnv);
} }
deleteObject(procedure);
deleteObject(parameters);
return result; return result;
} }
@ -225,9 +253,6 @@ apply:
} }
/* репни позив */ /* репни позив */
currentExpr = copyObject(CAR(*currentExprPointer)); currentExpr = copyObject(CAR(*currentExprPointer));
//pruneExpr(&currentExpr); ова функција ће бити коришћена за
// упроштавање израза, тако да постану репно-елиминалбилни, када буде
// написана ЛОЛ :)
deleteObject(procedure); deleteObject(procedure);
deleteObject(parameters); deleteObject(parameters);

View file

@ -837,7 +837,7 @@ object readInt(object parameters)
return Read("", stdin); return Read("", stdin);
} }
object beginInt(object parameters) object beginInt(object parameters, env currentEnv)
{ {
object last; object last;
if (listLength(parameters) == 0) if (listLength(parameters) == 0)
@ -847,11 +847,22 @@ object beginInt(object parameters)
else else
{ {
object *current = &parameters; object *current = &parameters;
object currentResult;
while (TYPE(CDR(*current)) != nilObject) while (TYPE(CDR(*current)) != nilObject)
{ {
currentResult = Eval(copyObject(CAR(*current)), currentEnv);
if (TYPE(currentResult) == errorObject)
{
CPYERR(ERR(currentResult));
}
current = &CDR(*current); current = &CDR(*current);
} }
last = copyObject(CAR(*current)); last = Eval(copyObject(CAR(*current)), currentEnv);
if (TYPE(last) == errorObject)
{
CPYERR(ERR(last));
}
} }
return last; return last;
} }