Поправљени багови у "ако", промењен систем детектовања специјалних форми
This commit is contained in:
parent
b7f3124302
commit
e8705cec39
4
Makefile
4
Makefile
|
@ -8,8 +8,8 @@ PREFIX = /usr/local
|
||||||
|
|
||||||
# флегови за C компајлер и линкер
|
# флегови за C компајлер и линкер
|
||||||
CPPFLAGS = -D_POSIX_C_SOURCE=200200L
|
CPPFLAGS = -D_POSIX_C_SOURCE=200200L
|
||||||
CFLAGS = -g -std=c99 -pedantic -Wall -O0
|
# CFLAGS = -g -std=c99 -pedantic -Wall -O0
|
||||||
# CFLAGS = -std=c99 -pedantic -Wall -O3
|
CFLAGS = -std=c99 -pedantic -Wall -O3
|
||||||
LDFLAGS = -lm -lc
|
LDFLAGS = -lm -lc
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
|
|
36
eval.c
36
eval.c
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
|
#include "eval.h"
|
||||||
|
|
||||||
int currentRecursionDepth = 0;
|
int currentRecursionDepth = 0;
|
||||||
#define MAXRECURSIONDEPTH 1000
|
#define MAXRECURSIONDEPTH 1000
|
||||||
|
@ -22,22 +23,22 @@ object eval(object input, env currentEnv)
|
||||||
{
|
{
|
||||||
if (!properList(input))
|
if (!properList(input))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(improperListError);
|
||||||
ERR(result) = improperListError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int specialForm = 0;
|
int regularEvalOrder = 1;
|
||||||
if (TYPE(CAR(input)) == symbolObject &&
|
CAR(input) = eval(CAR(input), currentEnv);
|
||||||
isSpecialForm(SYM(CAR(input))))
|
if (TYPE(CAR(input)) == procedureObject &&
|
||||||
|
PROC_TYPE(CAR(input)) == builtinProc &&
|
||||||
|
PROC_SPECIAL(CAR(input)))
|
||||||
{
|
{
|
||||||
specialForm = 1;
|
regularEvalOrder = 0;
|
||||||
CAR(input) = eval(CAR(input), currentEnv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object *currentCell = &input;
|
object *currentCell = &CDR(input);
|
||||||
int noErrors = 1;
|
int noErrors = 1;
|
||||||
if (!specialForm)
|
if (regularEvalOrder)
|
||||||
{
|
{
|
||||||
while (TYPE(*currentCell) != nilObject)
|
while (TYPE(*currentCell) != nilObject)
|
||||||
{
|
{
|
||||||
|
@ -49,9 +50,10 @@ object eval(object input, env currentEnv)
|
||||||
errorObject)
|
errorObject)
|
||||||
{
|
{
|
||||||
noErrors = 0;
|
noErrors = 0;
|
||||||
TYPE(result) = errorObject;
|
object err = copyObject(
|
||||||
ERR(result) =
|
CAR(*currentCell));
|
||||||
ERR(CAR(*currentCell));
|
deleteObject(input);
|
||||||
|
SIGERR(ERR(err));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
currentCell = &CDR(*currentCell);
|
currentCell = &CDR(*currentCell);
|
||||||
|
@ -80,15 +82,13 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
|
|
||||||
if (TYPE(procedure) != procedureObject)
|
if (TYPE(procedure) != procedureObject)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(notApplicableError);
|
||||||
ERR(result) = notApplicableError;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PROC_TYPE(procedure) == builtinProc)
|
if (PROC_TYPE(procedure) == builtinProc)
|
||||||
{
|
{
|
||||||
object(*f)() = PROC_BUILTIN(procedure);
|
object(*f)() = PROC_BUILTIN(procedure);
|
||||||
if (f == define || f == lambda || f == ifStatement)
|
if (f == defineInt || f == lambdaInt || f == ifInt)
|
||||||
{
|
{
|
||||||
result = f(parameters, currentEnv);
|
result = f(parameters, currentEnv);
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,7 @@ object apply(object procedure, object parameters, env currentEnv)
|
||||||
env definitionEnv = PROC_COMP_ENV(procedure);
|
env definitionEnv = PROC_COMP_ENV(procedure);
|
||||||
if (listLength(parameters) != listLength(args))
|
if (listLength(parameters) != listLength(args))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
env procEnv = createEnvironment(definitionEnv);
|
env procEnv = createEnvironment(definitionEnv);
|
||||||
|
|
24
init.c
24
init.c
|
@ -16,16 +16,16 @@ void init()
|
||||||
* ћирилицу */
|
* ћирилицу */
|
||||||
|
|
||||||
globalEnv = createEnvironment(NULL);
|
globalEnv = createEnvironment(NULL);
|
||||||
addSymbolInternal("+", &add);
|
addSymbolInternal("+", &addInt, 0);
|
||||||
addSymbolInternal("-", &subtract);
|
addSymbolInternal("-", &subtractInt, 0);
|
||||||
addSymbolInternal("*", &multiply);
|
addSymbolInternal("*", &multiplyInt, 0);
|
||||||
addSymbolInternal("/", ÷);
|
addSymbolInternal("/", ÷Int, 0);
|
||||||
addSymbolInternal("навод", "e);
|
addSymbolInternal("навод", "eInt, 1);
|
||||||
addSymbolInternal("дефиниши", &define);
|
addSymbolInternal("дефиниши", &defineInt, 1);
|
||||||
addSymbolInternal("тачно->нетачно", &exactToInexact);
|
addSymbolInternal("тачно->нетачно", &exactToInexactInt, 0);
|
||||||
addSymbolInternal("нетачно->тачно", &inexactToExact);
|
addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0);
|
||||||
addSymbolInternal("ламбда", &lambda);
|
addSymbolInternal("ламбда", &lambdaInt, 1);
|
||||||
addSymbolInternal("<", &less);
|
addSymbolInternal("<", &lessInt, 0);
|
||||||
addSymbolInternal(">", &greater);
|
addSymbolInternal(">", &greaterInt, 0);
|
||||||
addSymbolInternal("ако", &ifStatement);
|
addSymbolInternal("ако", &ifInt, 1);
|
||||||
}
|
}
|
||||||
|
|
126
internals.c
126
internals.c
|
@ -33,15 +33,14 @@ int allSyms(object list)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
object add(object parameters)
|
object addInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
TYPE(result) = numberObject;
|
TYPE(result) = numberObject;
|
||||||
|
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 0)
|
else if (listLength(parameters) == 0)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +50,7 @@ object add(object parameters)
|
||||||
{
|
{
|
||||||
object first, rest;
|
object first, rest;
|
||||||
first = CAR(parameters);
|
first = CAR(parameters);
|
||||||
rest = add(CDR(parameters));
|
rest = addInt(CDR(parameters));
|
||||||
|
|
||||||
result = plusNum(first, rest);
|
result = plusNum(first, rest);
|
||||||
}
|
}
|
||||||
|
@ -59,20 +58,18 @@ object add(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object subtract(object parameters)
|
object subtractInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
TYPE(result) = numberObject;
|
TYPE(result) = numberObject;
|
||||||
|
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 0)
|
else if (listLength(parameters) == 0)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 1)
|
else if (listLength(parameters) == 1)
|
||||||
{
|
{
|
||||||
|
@ -81,21 +78,20 @@ object subtract(object parameters)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = plusNum(CAR(parameters),
|
result = plusNum(CAR(parameters),
|
||||||
minusNum(add(CDR(parameters))));
|
minusNum(addInt(CDR(parameters))));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object multiply(object parameters)
|
object multiplyInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
TYPE(result) = numberObject;
|
TYPE(result) = numberObject;
|
||||||
|
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 0)
|
else if (listLength(parameters) == 0)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +101,7 @@ object multiply(object parameters)
|
||||||
{
|
{
|
||||||
object first, rest;
|
object first, rest;
|
||||||
first = CAR(parameters);
|
first = CAR(parameters);
|
||||||
rest = multiply(CDR(parameters));
|
rest = multiplyInt(CDR(parameters));
|
||||||
|
|
||||||
result = timesNum(first,rest);
|
result = timesNum(first,rest);
|
||||||
}
|
}
|
||||||
|
@ -113,20 +109,18 @@ object multiply(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object divide(object parameters)
|
object divideInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
TYPE(result) = numberObject;
|
TYPE(result) = numberObject;
|
||||||
|
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 0)
|
else if (listLength(parameters) == 0)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (listLength(parameters) == 1)
|
else if (listLength(parameters) == 1)
|
||||||
{
|
{
|
||||||
|
@ -134,11 +128,11 @@ object divide(object parameters)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
object check = inverseNum(multiply(CDR(parameters)));
|
object check = inverseNum(multiplyInt(CDR(parameters)));
|
||||||
if (TYPE(check) != errorObject)
|
if (TYPE(check) != errorObject)
|
||||||
{
|
{
|
||||||
result = timesNum(CAR(parameters),
|
result = timesNum(CAR(parameters),
|
||||||
inverseNum(multiply(CDR(parameters))));
|
inverseNum(multiplyInt(CDR(parameters))));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -150,19 +144,17 @@ object divide(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object exactToInexact(object parameters)
|
object exactToInexactInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
|
|
||||||
if (listLength(parameters) != 1)
|
if (listLength(parameters) != 1)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (TYPE(CAR(parameters)) != numberObject)
|
else if (TYPE(CAR(parameters)) != numberObject)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -172,19 +164,17 @@ object exactToInexact(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object inexactToExact(object parameters)
|
object inexactToExactInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
|
|
||||||
if (listLength(parameters) != 1)
|
if (listLength(parameters) != 1)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (TYPE(CAR(parameters)) != numberObject)
|
else if (TYPE(CAR(parameters)) != numberObject)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -194,13 +184,12 @@ object inexactToExact(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object quote(object parameters)
|
object quoteInt(object parameters)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
if (listLength(parameters) != 1)
|
if (listLength(parameters) != 1)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -239,18 +228,16 @@ breakloop:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object lambda(object parameters, env currentEnv)
|
object lambdaInt(object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
if (listLength(parameters) < 2)
|
if (listLength(parameters) < 2)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (!validArgumentList(CAR(parameters)))
|
else if (!validArgumentList(CAR(parameters)))
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -265,28 +252,29 @@ object lambda(object parameters, env currentEnv)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object define(object parameters, env currentEnv)
|
object defineInt(object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
object result;
|
object result, value;
|
||||||
if (listLength(parameters) == 0)
|
if (listLength(parameters) == 0)
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
else if (TYPE(CAR(parameters)) == symbolObject)
|
else if (TYPE(CAR(parameters)) == symbolObject)
|
||||||
{
|
{
|
||||||
if (listLength(parameters) == 2)
|
if (listLength(parameters) == 2)
|
||||||
{
|
{
|
||||||
result = copyObject(CAR(parameters));
|
result = copyObject(CAR(parameters));
|
||||||
addSymbolVariable(SYM(result),
|
value = eval(copyObject(CAR(CDR(parameters))),
|
||||||
eval(copyObject(CAR(CDR(parameters))),
|
currentEnv);
|
||||||
currentEnv),
|
if (TYPE(value) == errorObject)
|
||||||
currentEnv);
|
{
|
||||||
|
SIGERR(ERR(value));
|
||||||
|
}
|
||||||
|
addSymbolVariable(SYM(result), value, currentEnv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (TYPE(CAR(parameters)) == consObject)
|
else if (TYPE(CAR(parameters)) == consObject)
|
||||||
|
@ -300,32 +288,30 @@ object define(object parameters, env currentEnv)
|
||||||
deleteObject(CAR(parameters));
|
deleteObject(CAR(parameters));
|
||||||
CAR(parameters) = copyObject(args);
|
CAR(parameters) = copyObject(args);
|
||||||
deleteObject(args);
|
deleteObject(args);
|
||||||
object proc = lambda(parameters, currentEnv);
|
object proc = lambdaInt(parameters,
|
||||||
|
currentEnv);
|
||||||
addSymbolVariable(SYM(result), proc,
|
addSymbolVariable(SYM(result), proc,
|
||||||
currentEnv);
|
currentEnv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(argumentNumberError);
|
||||||
ERR(result) = argumentNumberError;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TYPE(result) = errorObject;
|
SIGERR(typeError);
|
||||||
ERR(result) = typeError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object less(object parameters)
|
object lessInt(object parameters)
|
||||||
{
|
{
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
|
@ -355,7 +341,7 @@ object less(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object greater(object parameters)
|
object greaterInt(object parameters)
|
||||||
{
|
{
|
||||||
if (!allNums(parameters))
|
if (!allNums(parameters))
|
||||||
{
|
{
|
||||||
|
@ -385,13 +371,17 @@ object greater(object parameters)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
object ifStatement(object parameters, env currentEnv)
|
object ifInt(object parameters, env currentEnv)
|
||||||
{
|
{
|
||||||
object predicate, result;
|
object predicate, result;
|
||||||
switch (listLength(parameters))
|
switch (listLength(parameters))
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
predicate = eval(CAR(parameters), currentEnv);
|
predicate = eval(copyObject(CAR(parameters)), currentEnv);
|
||||||
|
if (TYPE(predicate) == errorObject)
|
||||||
|
{
|
||||||
|
SIGERR(ERR(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
||||||
{
|
{
|
||||||
|
@ -402,9 +392,18 @@ object ifStatement(object parameters, env currentEnv)
|
||||||
result = eval(copyObject(CAR(CDR(parameters))),
|
result = eval(copyObject(CAR(CDR(parameters))),
|
||||||
currentEnv);
|
currentEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TYPE(result) == errorObject)
|
||||||
|
{
|
||||||
|
SIGERR(ERR(result));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
predicate = eval(CAR(parameters), currentEnv);
|
predicate = eval(copyObject(CAR(parameters)), currentEnv);
|
||||||
|
if (TYPE(predicate) == errorObject)
|
||||||
|
{
|
||||||
|
SIGERR(ERR(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
||||||
{
|
{
|
||||||
|
@ -416,6 +415,11 @@ object ifStatement(object parameters, env currentEnv)
|
||||||
result = eval(copyObject(CAR(CDR(parameters))),
|
result = eval(copyObject(CAR(CDR(parameters))),
|
||||||
currentEnv);
|
currentEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TYPE(result) == errorObject)
|
||||||
|
{
|
||||||
|
SIGERR(ERR(result));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SIGERR(argumentNumberError);
|
SIGERR(argumentNumberError);
|
||||||
|
|
24
internals.h
24
internals.h
|
@ -1,15 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
object add(object parameters);
|
object addInt(object parameters);
|
||||||
object subtract(object parameters);
|
object subtractInt(object parameters);
|
||||||
object multiply(object parameters);
|
object multiplyInt(object parameters);
|
||||||
object divide(object parameters);
|
object divideInt(object parameters);
|
||||||
object exactToInexact(object parameters);
|
object exactToInexactInt(object parameters);
|
||||||
object inexactToExact(object parameters);
|
object inexactToExactInt(object parameters);
|
||||||
object quote(object parameters);
|
object quoteInt(object parameters);
|
||||||
object lambda(object parameters);
|
object lambdaInt(object parameters);
|
||||||
object define(object parameters);
|
object defineInt(object parameters);
|
||||||
object less(object parameters);
|
object lessInt(object parameters);
|
||||||
object greater(object parameters);
|
object greaterInt(object parameters);
|
||||||
object ifStatement(object parameters);
|
object ifInt(object parameters);
|
||||||
|
|
73
read.c
73
read.c
|
@ -126,83 +126,14 @@ int lengthDigitArray(char *s)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isFracNumToken(char *s)
|
|
||||||
{
|
|
||||||
int digitNum1 = lengthDigitArray(s);
|
|
||||||
|
|
||||||
if (digitNum1 == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1] == '\0')
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1] == '/')
|
|
||||||
{
|
|
||||||
int digitNum2 = lengthDigitArray(s + digitNum1 + 1);
|
|
||||||
|
|
||||||
if (digitNum2 == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1 + 1 + digitNum2] == '\0')
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int isRealNumToken(char *s)
|
|
||||||
{
|
|
||||||
int digitNum1 = lengthDigitArray(s);
|
|
||||||
|
|
||||||
if (digitNum1 == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1] == '\0')
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1] == ',')
|
|
||||||
{
|
|
||||||
int digitNum2 = lengthDigitArray(s + digitNum1 + 1);
|
|
||||||
|
|
||||||
if (digitNum2 == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (s[digitNum1 + 1 + digitNum2] == '\0')
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object getToken()
|
object getToken()
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
wchar_t *buffer = getBuffer();
|
wchar_t *buffer = getBuffer();
|
||||||
wint_t c;
|
wint_t c;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
buffer[0] = c = scanwc(stdin);
|
c = scanwc(stdin);
|
||||||
|
buffer[0] = towlower(c);
|
||||||
if (isEscape(c))
|
if (isEscape(c))
|
||||||
{
|
{
|
||||||
while (!isEscape(c = scanwc(stdin)))
|
while (!isEscape(c = scanwc(stdin)))
|
||||||
|
|
33
util.c
33
util.c
|
@ -62,7 +62,7 @@ void removeEnvironment(env input)
|
||||||
free(input);
|
free(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSymbolInternal(char *symbol, object (*function)())
|
void addSymbolInternal(char *symbol, object (*function)(), int isSpecialForm)
|
||||||
{
|
{
|
||||||
entry **e = findEntry(&globalEnv->table, symbol);
|
entry **e = findEntry(&globalEnv->table, symbol);
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ void addSymbolInternal(char *symbol, object (*function)())
|
||||||
PROC((*e)->value) = createProcedure();
|
PROC((*e)->value) = createProcedure();
|
||||||
PROC_TYPE((*e)->value) = builtinProc;
|
PROC_TYPE((*e)->value) = builtinProc;
|
||||||
PROC_BUILTIN((*e)->value) = function;
|
PROC_BUILTIN((*e)->value) = function;
|
||||||
|
PROC_SPECIAL((*e)->value) = isSpecialForm;
|
||||||
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
|
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
|
||||||
strcpy((*e)->name, symbol);
|
strcpy((*e)->name, symbol);
|
||||||
(*e)->left = (*e)->right = NULL;
|
(*e)->left = (*e)->right = NULL;
|
||||||
|
@ -123,29 +124,6 @@ object referVariable(char *symbol,env currentEnv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPECIALFORMSNUM 4
|
|
||||||
int isSpecialForm(char *symbol)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
char *specialForms[] =
|
|
||||||
{
|
|
||||||
"навод",
|
|
||||||
"дефиниши",
|
|
||||||
"ламбда",
|
|
||||||
"ако"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < SPECIALFORMSNUM; ++i)
|
|
||||||
{
|
|
||||||
if (!strcmp(symbol, specialForms[i]))
|
|
||||||
{
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int properList(object list)
|
int properList(object list)
|
||||||
{
|
{
|
||||||
object *current = &list;
|
object *current = &list;
|
||||||
|
@ -224,6 +202,7 @@ object copyObject(object input)
|
||||||
if (PROC_TYPE(result) == builtinProc)
|
if (PROC_TYPE(result) == builtinProc)
|
||||||
{
|
{
|
||||||
PROC_BUILTIN(result) = PROC_BUILTIN(input);
|
PROC_BUILTIN(result) = PROC_BUILTIN(input);
|
||||||
|
PROC_SPECIAL(result) = PROC_SPECIAL(input);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -340,8 +319,7 @@ object shortenFractionNum(object a)
|
||||||
if (NUM_DENOM(result) == 0)
|
if (NUM_DENOM(result) == 0)
|
||||||
{
|
{
|
||||||
deleteObject(result);
|
deleteObject(result);
|
||||||
TYPE(result) = errorObject;
|
SIGERR(divisionByZeroError);
|
||||||
ERR(result) = divisionByZeroError;
|
|
||||||
}
|
}
|
||||||
else if (NUM_NUMER(result) == 0)
|
else if (NUM_NUMER(result) == 0)
|
||||||
{
|
{
|
||||||
|
@ -442,8 +420,7 @@ object inverseNum(object a)
|
||||||
if (NUM_NUMER(result) == 0)
|
if (NUM_NUMER(result) == 0)
|
||||||
{
|
{
|
||||||
deleteObject(result);
|
deleteObject(result);
|
||||||
TYPE(result) = errorObject;
|
SIGERR(divisionByZeroError);
|
||||||
ERR(result) = divisionByZeroError;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
20
util.h
20
util.h
|
@ -15,15 +15,16 @@
|
||||||
|
|
||||||
#define SIGERR(error) \
|
#define SIGERR(error) \
|
||||||
{\
|
{\
|
||||||
object result;\
|
object __result;\
|
||||||
TYPE(result) = errorObject;\
|
TYPE(__result) = errorObject;\
|
||||||
ERR(result) = error;\
|
ERR(__result) = error;\
|
||||||
return result;\
|
return __result;\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROC(x) ((x).value.proc)
|
#define PROC(x) ((x).value.proc)
|
||||||
#define PROC_TYPE(x) ((x).value.proc->type)
|
#define PROC_TYPE(x) ((x).value.proc->type)
|
||||||
#define PROC_BUILTIN(x) ((x).value.proc->value.builtin)
|
#define PROC_BUILTIN(x) ((x).value.proc->value.builtin.pointer)
|
||||||
|
#define PROC_SPECIAL(x) ((x).value.proc->value.builtin.isSpecialForm)
|
||||||
#define PROC_COMP_ARGS(x) ((x).value.proc->value.compound.args)
|
#define PROC_COMP_ARGS(x) ((x).value.proc->value.compound.args)
|
||||||
#define PROC_COMP_BODY(x) ((x).value.proc->value.compound.body)
|
#define PROC_COMP_BODY(x) ((x).value.proc->value.compound.body)
|
||||||
#define PROC_COMP_ENV(x) ((x).value.proc->value.compound.environment)
|
#define PROC_COMP_ENV(x) ((x).value.proc->value.compound.environment)
|
||||||
|
@ -142,7 +143,11 @@ struct procedure
|
||||||
procType type;
|
procType type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
object (*builtin)(object);
|
struct
|
||||||
|
{
|
||||||
|
object (*pointer)(object);
|
||||||
|
int isSpecialForm;
|
||||||
|
} builtin;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
object args;
|
object args;
|
||||||
|
@ -158,7 +163,7 @@ env globalEnv;
|
||||||
env createEnvironment(env enclosing);
|
env createEnvironment(env enclosing);
|
||||||
void removeEnvironment(env input);
|
void removeEnvironment(env input);
|
||||||
|
|
||||||
void addSymbolInternal(char *symbol, object (*function)());
|
void addSymbolInternal(char *symbol, object (*function)(), int isSpecialForm);
|
||||||
void addSymbolVariable(char *symbol, object variable, env currentEnv);
|
void addSymbolVariable(char *symbol, object variable, env currentEnv);
|
||||||
/* функције помоћу којих се дефинишу нове променљиве: addSymbolVariable се
|
/* функције помоћу којих се дефинишу нове променљиве: addSymbolVariable се
|
||||||
* позива током корисничких дефиниција у програму, док се addSymbolInternal
|
* позива током корисничких дефиниција у програму, док се addSymbolInternal
|
||||||
|
@ -171,7 +176,6 @@ object referVariable(char *symbol, env currentEnv);
|
||||||
/* враћа вредност на коју се односи име симбола у табели */
|
/* враћа вредност на коју се односи име симбола у табели */
|
||||||
/******************************* */
|
/******************************* */
|
||||||
|
|
||||||
int isSpecialForm(char *symbol);
|
|
||||||
int properList(object list);
|
int properList(object list);
|
||||||
int listLength(object list);
|
int listLength(object list);
|
||||||
void deleteObject(object input);
|
void deleteObject(object input);
|
||||||
|
|
Loading…
Reference in a new issue