diff --git a/cirilisp.c b/cirilisp.c index e10390e..66b8460 100644 --- a/cirilisp.c +++ b/cirilisp.c @@ -57,9 +57,11 @@ void init() addSymbolInternal("ниска?", &stringQInt, 0); addSymbolInternal("карактер?", &charQInt, 0); addSymbolInternal("листа?", &listQInt, 0); - addSymbolInternal("листа", &listInt, 0); addSymbolInternal("конс", &consInt, 0); + addSymbolInternal("сар", &carInt, 0); + addSymbolInternal("сдр", &cdrInt, 0); addSymbolInternal("јед?", &eqvQInt, 0); + addSymbolInternal("примени", &applyInt, 0); if (!load(DESTDIR"/usr/local/lib/cirilisp/инит.ћ")) { diff --git a/eval.c b/eval.c index 1c0aef5..09098ca 100644 --- a/eval.c +++ b/eval.c @@ -129,6 +129,8 @@ int bindArgs(object parameters, object args, env newEnv) currentArg = &CDR(*currentArg); currentParam = &CDR(*currentParam); } + addSymbolVariable(SYM(*currentArg), *currentParam, + newEnv); return 1; } } @@ -146,7 +148,8 @@ object apply(object procedure, object parameters, env currentEnv) if (PROC_TYPE(procedure) == builtinProc) { object(*f)() = PROC_BUILTIN(procedure); - if (f == defineInt || f == lambdaInt || f == ifInt) + if (f == defineInt || f == lambdaInt || f == ifInt || + f == applyInt) { result = f(parameters, currentEnv); } diff --git a/eval.h b/eval.h index 528dda7..a4ff6bb 100644 --- a/eval.h +++ b/eval.h @@ -1,3 +1,4 @@ #pragma once object eval(object input, env currentEnv); +object apply(object function, object parameters, env currentEnv); diff --git a/internals.c b/internals.c index 488adc2..ada9fff 100644 --- a/internals.c +++ b/internals.c @@ -497,13 +497,6 @@ object listQInt(object parameters) return result; } -object listInt(object parameters) -{ - object result; - result = copyObject(parameters); - return result; -} - object consInt(object parameters) { if (listLength(parameters) != 2) @@ -518,6 +511,32 @@ object consInt(object parameters) return result; } +object cellElement(object parameters, int part) +/* враћа car или cdr (сар или сдр) датог конс објекта у зависности од тога да + * ли је part 0 или нешто друго (1) */ +{ + if (listLength(parameters) != 1) + { + SIGERR(argumentNumberError); + } + if (TYPE(CAR(parameters)) != consObject) + { + SIGERR(typeError); + } + return !part ? copyObject(CAR(CAR(parameters))) : + copyObject(CDR(CAR(parameters))); +} + +object carInt(object parameters) +{ + return cellElement(parameters, 0); +} + +object cdrInt(object parameters) +{ + return cellElement(parameters, 1); +} + object eqvQInt(object parameters) { if (listLength(parameters) != 2) @@ -526,7 +545,7 @@ object eqvQInt(object parameters) } object result; TYPE(result) = boolObject; - BOOL(result) = 0; + BOOL(result) = 1; if (TYPE(CAR(parameters)) != TYPE(CAR(CDR(parameters)))) { BOOL(result) = 0; @@ -571,6 +590,9 @@ object eqvQInt(object parameters) BOOL(result) = CHR(CAR(parameters)) == CHR(CAR(CDR(parameters))); break; + case nilObject: + BOOL(result) = 1; + break; case consObject: case procedureObject: default: @@ -580,3 +602,17 @@ object eqvQInt(object parameters) } return result; } + +object applyInt(object parameters, env currentEnv) +{ + if (listLength(parameters) != 2) + { + SIGERR(argumentNumberError); + } + if (!properList(CAR(CDR(parameters))) || + TYPE(CAR(parameters)) != procedureObject) + { + SIGERR(typeError); + } + return apply(CAR(parameters), CAR(CDR(parameters)), currentEnv); +} diff --git a/internals.h b/internals.h index 1b6cc36..a421eef 100644 --- a/internals.h +++ b/internals.h @@ -8,12 +8,12 @@ object divideInt(object parameters); object exactToInexactInt(object parameters); object inexactToExactInt(object parameters); object quoteInt(object parameters); -object lambdaInt(object parameters); -object defineInt(object parameters); +object lambdaInt(object parameters, env currentEnv); +object defineInt(object parameters, env currentEnv); object lessInt(object parameters); object greaterInt(object parameters); object eqNumInt(object parameters); -object ifInt(object parameters); +object ifInt(object parameters, env currentEnv); object nilQInt(object parameters); object consQInt(object parameters); object numberQInt(object parameters); @@ -23,6 +23,8 @@ object boolQInt(object parameters); object stringQInt(object parameters); object charQInt(object parameters); object listQInt(object parameters); -object listInt(object parameters); object consInt(object parameters); +object carInt(object parameters); +object cdrInt(object parameters); object eqvQInt(object parameters); +object applyInt(object parameters, env currentEnv); diff --git a/инит.ћ b/инит.ћ index 258f917..3a501ff 100644 --- a/инит.ћ +++ b/инит.ћ @@ -1,2 +1,8 @@ -(дефиниши (не предикат) +(дефиниши (није предикат) (ако предикат #л #и)) + +(дефиниши нил ()) + +(дефиниши истинито #и) (дефиниши лажно #л) + +(дефиниши (листа . арг) арг)