Имплементиране командно-линијске опције, додате функције за препознавање типова бројева
This commit is contained in:
parent
4dc9a4e888
commit
d24fa3945d
5
Makefile
5
Makefile
|
@ -8,7 +8,8 @@ PREFIX = /usr/local
|
|||
LIBPREFIX = $(PREFIX)/lib
|
||||
|
||||
# флегови за C компајлер и линкер
|
||||
CPPFLAGS = -D_POSIX_C_SOURCE=200200L -DDESTDIR=\"$(DESTDIR)\"
|
||||
CPPFLAGS = -D_POSIX_C_SOURCE=200200L -DDESTDIR=\"$(DESTDIR)\" \
|
||||
-DVERSION=\"$(VERSION)\"
|
||||
CFLAGS = -g -std=c99 -pedantic -Wall -O0
|
||||
# CFLAGS = -std=c99 -pedantic -Wall -O3
|
||||
LDFLAGS = -lm -lc
|
||||
|
@ -25,7 +26,7 @@ all: cirilisp $(L_SRC)
|
|||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<
|
||||
|
||||
$(OBJ): $(INC) $(L_SRC)
|
||||
$(OBJ): $(INC)
|
||||
|
||||
cirilisp: $(OBJ)
|
||||
$(CC) -o $@ $(OBJ) $(LDFLAGS)
|
||||
|
|
66
cirilisp.c
66
cirilisp.c
|
@ -1,4 +1,5 @@
|
|||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -16,14 +17,17 @@ int load(char *pathname)
|
|||
return 0;
|
||||
}
|
||||
object exp;
|
||||
while (TYPE(exp = eval(read("", stream), globalEnv)) != EOFObject)
|
||||
while (TYPE(exp = Eval(Read("", stream), globalEnv)) != EOFObject)
|
||||
{
|
||||
if (TYPE(exp) == errorObject)
|
||||
{
|
||||
print(exp);
|
||||
Print(exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteObject(exp);
|
||||
}
|
||||
}
|
||||
eofStatus = 0;
|
||||
fclose(stream);
|
||||
return 1;
|
||||
|
@ -45,6 +49,8 @@ void init()
|
|||
addSymbolInternal("-", &subtractInt, 0);
|
||||
addSymbolInternal("*", &multiplyInt, 0);
|
||||
addSymbolInternal("/", ÷Int, 0);
|
||||
addSymbolInternal("бројилац", &numeratorInt, 0);
|
||||
addSymbolInternal("именилац", &denominatorInt, 0);
|
||||
addSymbolInternal("навод", "eInt, 1);
|
||||
addSymbolInternal("опиши", &defineInt, 1);
|
||||
addSymbolInternal("опиши-складњу", &defineMacroInt, 1);
|
||||
|
@ -58,6 +64,8 @@ void init()
|
|||
addSymbolInternal("нил?", &nilQInt, 0);
|
||||
addSymbolInternal("конс?", &consQInt, 0);
|
||||
addSymbolInternal("број?", &numberQInt, 0);
|
||||
addSymbolInternal("разломак?", &fractionQInt, 0);
|
||||
addSymbolInternal("реалан?", &realQInt, 0);
|
||||
addSymbolInternal("симбол?", &symbolQInt, 0);
|
||||
addSymbolInternal("процедура?", &procedureQInt, 0);
|
||||
addSymbolInternal("булски?", &boolQInt, 0);
|
||||
|
@ -81,14 +89,64 @@ void init()
|
|||
{
|
||||
fprintf(stderr, "Није пронађена стандардна ЋИРЛИСП библиотека\
|
||||
\nПрограм се није могао правилно покренути\n");
|
||||
exit(0);
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
const char *help =
|
||||
"\
|
||||
Команда: cirilisp [-q|-v|-h] [<име фајла>]*\n\
|
||||
Опције:\n\
|
||||
-q Не започињи ЧПШП (\"Читај, процени, штампај\" петљу) након\n\
|
||||
евалуирања командних аргумената\n\
|
||||
-h Одштампај овај кратки помоћник и затвори програм\n\
|
||||
-v Одштампај верзију програма и затвори програм\n\
|
||||
";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
init();
|
||||
while (print(eval(read("ШКЉ> ", stdin), globalEnv)))
|
||||
|
||||
int quitFlag = 0, opt;
|
||||
while ((opt = getopt(argc, argv, "qvh")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'q':
|
||||
quitFlag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
printf("Верзија: " VERSION "\n");
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
printf(help);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Непозната командна опција");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
while (argv[optind] != NULL)
|
||||
{
|
||||
if (!load(argv[optind]))
|
||||
{
|
||||
fprintf(stderr, "Није било могуће отворити фајл %s.\n\
|
||||
Проверите да ли дати фајл заиста постоји\n", argv[optind]);
|
||||
exit(2);
|
||||
}
|
||||
++optind;
|
||||
}
|
||||
|
||||
if (quitFlag)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("Добродошли у ЋИРИЛИСП ЧПШП окружење, верзија: " VERSION "\n");
|
||||
while (Print(Eval(Read("ШКЉ> ", stdin), globalEnv)))
|
||||
;
|
||||
printf("\nДостигнут крај улазног тока.\nЗбогом и дођите нам опет!\n");
|
||||
|
||||
|
|
10
eval.c
10
eval.c
|
@ -11,7 +11,7 @@ int maxRecursionDepth = 10000;
|
|||
|
||||
object apply(object function, object parameters, env currentEnv);
|
||||
|
||||
object eval(object input, env currentEnv)
|
||||
object Eval(object input, env currentEnv)
|
||||
{
|
||||
object result;
|
||||
|
||||
|
@ -29,7 +29,7 @@ object eval(object input, env currentEnv)
|
|||
else
|
||||
{
|
||||
int regularEvalOrder = 1;
|
||||
CAR(input) = eval(CAR(input), currentEnv);
|
||||
CAR(input) = Eval(CAR(input), currentEnv);
|
||||
if (TYPE(CAR(input)) == errorObject)
|
||||
{
|
||||
result = copyObject(CAR(input));
|
||||
|
@ -50,7 +50,7 @@ object eval(object input, env currentEnv)
|
|||
while (TYPE(*currentCell) != nilObject)
|
||||
{
|
||||
CAR(*currentCell) =
|
||||
eval(CAR(*currentCell),
|
||||
Eval(CAR(*currentCell),
|
||||
currentEnv);
|
||||
|
||||
if (TYPE(CAR(*currentCell)) ==
|
||||
|
@ -77,7 +77,7 @@ object eval(object input, env currentEnv)
|
|||
PROC_SPECIAL(CAR(input)) &&
|
||||
PROC_TYPE(CAR(input)) == compoundProc)
|
||||
{
|
||||
result = eval(result, currentEnv);
|
||||
result = Eval(result, currentEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ object apply(object procedure, object parameters, env currentEnv)
|
|||
object *currentSubProc = &body;
|
||||
while (TYPE(*currentSubProc) != nilObject)
|
||||
{
|
||||
CAR(*currentSubProc) = eval(CAR(*currentSubProc), procEnv);
|
||||
CAR(*currentSubProc) = Eval(CAR(*currentSubProc), procEnv);
|
||||
if (TYPE(CDR(*currentSubProc)) == nilObject)
|
||||
{
|
||||
result = copyObject(CAR(*currentSubProc));
|
||||
|
|
2
eval.h
2
eval.h
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
object eval(object input, env currentEnv);
|
||||
object Eval(object input, env currentEnv);
|
||||
object apply(object function, object parameters, env currentEnv);
|
||||
|
|
65
internals.c
65
internals.c
|
@ -198,6 +198,36 @@ object inexactToExactInt(object parameters)
|
|||
return result;
|
||||
}
|
||||
|
||||
object fractionPart(object parameters, int part)
|
||||
{
|
||||
if (listLength(parameters) != 1)
|
||||
{
|
||||
SIGERR(argumentNumberError);
|
||||
}
|
||||
if (TYPE(CAR(parameters)) != numberObject ||
|
||||
NUM_TYPE(CAR(parameters)) != fractionNum)
|
||||
{
|
||||
SIGERR(typeError);
|
||||
}
|
||||
object result;
|
||||
TYPE(result) = numberObject;
|
||||
NUM_TYPE(result) = fractionNum;
|
||||
NUM_DENOM(result) = 1;
|
||||
NUM_NUMER(result) = !part ? NUM_NUMER(CAR(parameters)) :
|
||||
NUM_DENOM(CAR(parameters));
|
||||
return result;
|
||||
}
|
||||
|
||||
object numeratorInt(object parameters)
|
||||
{
|
||||
return fractionPart(parameters, 0);
|
||||
}
|
||||
|
||||
object denominatorInt(object parameters)
|
||||
{
|
||||
return fractionPart(parameters, 1);
|
||||
}
|
||||
|
||||
object quoteInt(object parameters)
|
||||
{
|
||||
object result;
|
||||
|
@ -286,7 +316,7 @@ object defineInt(object parameters, env currentEnv)
|
|||
if (listLength(parameters) == 2)
|
||||
{
|
||||
result = copyObject(CAR(parameters));
|
||||
value = eval(copyObject(CAR(CDR(parameters))),
|
||||
value = Eval(copyObject(CAR(CDR(parameters))),
|
||||
currentEnv);
|
||||
if (TYPE(value) == errorObject)
|
||||
{
|
||||
|
@ -420,7 +450,7 @@ object ifInt(object parameters, env currentEnv)
|
|||
switch (listLength(parameters))
|
||||
{
|
||||
case 2:
|
||||
predicate = eval(copyObject(CAR(parameters)), currentEnv);
|
||||
predicate = Eval(copyObject(CAR(parameters)), currentEnv);
|
||||
if (TYPE(predicate) == errorObject)
|
||||
{
|
||||
CPYERR(ERR(predicate));
|
||||
|
@ -432,7 +462,7 @@ object ifInt(object parameters, env currentEnv)
|
|||
}
|
||||
else
|
||||
{
|
||||
result = eval(copyObject(CAR(CDR(parameters))),
|
||||
result = Eval(copyObject(CAR(CDR(parameters))),
|
||||
currentEnv);
|
||||
}
|
||||
|
||||
|
@ -442,7 +472,7 @@ object ifInt(object parameters, env currentEnv)
|
|||
}
|
||||
break;
|
||||
case 3:
|
||||
predicate = eval(copyObject(CAR(parameters)), currentEnv);
|
||||
predicate = Eval(copyObject(CAR(parameters)), currentEnv);
|
||||
if (TYPE(predicate) == errorObject)
|
||||
{
|
||||
CPYERR(ERR(predicate));
|
||||
|
@ -450,12 +480,12 @@ object ifInt(object parameters, env currentEnv)
|
|||
|
||||
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
||||
{
|
||||
result = eval(copyObject(CAR(CDR(CDR(parameters)))),
|
||||
result = Eval(copyObject(CAR(CDR(CDR(parameters)))),
|
||||
currentEnv);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = eval(copyObject(CAR(CDR(parameters))),
|
||||
result = Eval(copyObject(CAR(CDR(parameters))),
|
||||
currentEnv);
|
||||
}
|
||||
|
||||
|
@ -498,6 +528,29 @@ object numberQInt(object parameters)
|
|||
return checkType(parameters, numberObject);
|
||||
}
|
||||
|
||||
object checkNumType(object parameters, numType type)
|
||||
{
|
||||
if (listLength(parameters) != 1)
|
||||
{
|
||||
SIGERR(argumentNumberError);
|
||||
}
|
||||
object result;
|
||||
TYPE(result) = boolObject;
|
||||
BOOL(result) = TYPE(CAR(parameters)) == numberObject &&
|
||||
(NUM_TYPE(CAR(parameters)) == type ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
object fractionQInt(object parameters)
|
||||
{
|
||||
return checkNumType(parameters, fractionNum);
|
||||
}
|
||||
|
||||
object realQInt(object parameters)
|
||||
{
|
||||
return checkNumType(parameters, realNum);
|
||||
}
|
||||
|
||||
object symbolQInt(object parameters)
|
||||
{
|
||||
return checkType(parameters, symbolObject);
|
||||
|
|
|
@ -7,6 +7,8 @@ object multiplyInt(object parameters);
|
|||
object divideInt(object parameters);
|
||||
object exactToInexactInt(object parameters);
|
||||
object inexactToExactInt(object parameters);
|
||||
object numeratorInt(object parameters);
|
||||
object denominatorInt(object parameters);
|
||||
object quoteInt(object parameters);
|
||||
object lambdaInt(object parameters, env currentEnv);
|
||||
object defineInt(object parameters, env currentEnv);
|
||||
|
@ -18,6 +20,8 @@ object ifInt(object parameters, env currentEnv);
|
|||
object nilQInt(object parameters);
|
||||
object consQInt(object parameters);
|
||||
object numberQInt(object parameters);
|
||||
object fractionQInt(object parameters);
|
||||
object realQInt(object parameters);
|
||||
object symbolQInt(object parameters);
|
||||
object procedureQInt(object parameters);
|
||||
object boolQInt(object parameters);
|
||||
|
|
2
print.c
2
print.c
|
@ -4,7 +4,7 @@
|
|||
|
||||
void printValue(object input);
|
||||
|
||||
int print(object input)
|
||||
int Print(object input)
|
||||
{
|
||||
if (TYPE(input) == errorObject)
|
||||
{
|
||||
|
|
2
print.h
2
print.h
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
int print(object input);
|
||||
int Print(object input);
|
||||
void printValue(object input);
|
||||
|
|
18
read.c
18
read.c
|
@ -19,7 +19,7 @@ wint_t unscanwc(wint_t c, FILE *stream);
|
|||
object getToken();
|
||||
object macroFunction(wchar_t m, FILE *stream);
|
||||
|
||||
object read(char *prompt, FILE *stream)
|
||||
object Read(char *prompt, FILE *stream)
|
||||
{
|
||||
printf("%s", prompt);
|
||||
|
||||
|
@ -48,7 +48,7 @@ object read(char *prompt, FILE *stream)
|
|||
|
||||
if (TYPE(result) == unspecifiedObject)
|
||||
{
|
||||
return read("", stream);
|
||||
return Read("", stream);
|
||||
/* уколико улаз функције није прави објекат (на пример уколико је учитан
|
||||
* коментар) покушавамо прочитати опет */
|
||||
}
|
||||
|
@ -327,6 +327,16 @@ object dispatchedChar(wint_t c, FILE *stream)
|
|||
}
|
||||
TYPE(result) = unspecifiedObject;
|
||||
break;
|
||||
case L'!':
|
||||
for (;;)
|
||||
{
|
||||
if ((c = scanwc(stream)) == L'\n' || c == WEOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
TYPE(result) = unspecifiedObject;
|
||||
break;
|
||||
case WEOF:
|
||||
SIGERR(unexpectedEOFError);
|
||||
default:
|
||||
|
@ -351,7 +361,7 @@ object macroFunction(wchar_t m, FILE *stream)
|
|||
listCurrent = &result;
|
||||
for (;;)
|
||||
{
|
||||
object currentObject = read("", stream);
|
||||
object currentObject = Read("", stream);
|
||||
if (TYPE(currentObject) == errorObject &&
|
||||
!strcmp(ERR(currentObject),
|
||||
commonErrs[unmatchedParenError]))
|
||||
|
@ -441,7 +451,7 @@ object macroFunction(wchar_t m, FILE *stream)
|
|||
break;
|
||||
case L'\'':
|
||||
case L'`':
|
||||
expression = read("", stream);
|
||||
expression = Read("", stream);
|
||||
if (TYPE(expression) == errorObject)
|
||||
{
|
||||
CPYERR(ERR(expression));
|
||||
|
|
2
read.h
2
read.h
|
@ -2,4 +2,4 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
object read(char *prompt, FILE *stream);
|
||||
object Read(char *prompt, FILE *stream);
|
||||
|
|
Loading…
Reference in a new issue