diff --git a/Makefile b/Makefile index 0f99652..1c207e8 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ PREFIX = /usr/local # флегови за C компајлер и линкер CPPFLAGS = -D_POSIX_C_SOURCE=200200L -# CFLAGS = -g -std=c99 -pedantic -Wall -O0 -CFLAGS = -std=c99 -pedantic -Wall -O3 +CFLAGS = -g -std=c99 -pedantic -Wall -O0 +# CFLAGS = -std=c99 -pedantic -Wall -O3 LDFLAGS = -lm -lc CC = cc diff --git a/cirilisp.c b/cirilisp.c index 4c28a89..0198aab 100644 --- a/cirilisp.c +++ b/cirilisp.c @@ -1,3 +1,5 @@ +#include + #include "init.h" #include "read.h" #include "eval.h" @@ -6,8 +8,8 @@ int main(int argc, char **argv) { init(); - for (;;) - { - print(eval(read("ШКЉ> "), globalEnv)); - } + while (print(eval(read("ШКЉ> "), globalEnv))); + printf("\nДостигнут крај стрима.\nЗбогом и дођите нам опет!\n"); + + return 0; } diff --git a/print.c b/print.c index ef85ad9..803e8cc 100644 --- a/print.c +++ b/print.c @@ -20,18 +20,23 @@ char *errors[] = void printValue(object input); -void print(object input) +int print(object input) { if (TYPE(input) == errorObject) { fprintf(stderr, "\nГРЕШКА: %s\n\n", errors[ERR(input)]); } + else if (TYPE(input) == EOFObject) + { + return 0; + } else if (TYPE(input) != unspecifiedObject) { printf("\n"); printValue(input); printf("\n\n"); } + return 1; } void printValue(object input) diff --git a/print.h b/print.h index 417c608..f6ce465 100644 --- a/print.h +++ b/print.h @@ -1,3 +1,3 @@ #pragma once -void print(object input); +int print(object input); diff --git a/read.c b/read.c index 1e415c9..47670dc 100644 --- a/read.c +++ b/read.c @@ -14,8 +14,8 @@ int isConstituent(wchar_t c); int isMacroC(wchar_t c); int isEscape(wchar_t c); -wchar_t scanwc(FILE *stream); -#define unscanwc(c,stream) ungetwc(c,stream); +wint_t scanwc(FILE *stream); +wint_t unscanwc(wint_t c, FILE *stream); object getToken(); object macroFunction(wchar_t m); @@ -28,7 +28,11 @@ object read(char *prompt) while (iswspace(c = scanwc(stdin))) ; - if (isMacroC(c)) + if (c == WEOF) + { + TYPE(result) = EOFObject; + } + else if (isMacroC(c)) { result = macroFunction(c); } @@ -103,21 +107,37 @@ wchar_t *increaseBuffer() return realloc(globalBuffer, bufferSize); } -wchar_t scanwc(FILE *stream) +int eofStatus = 0; +wint_t scanwc(FILE *stream) { - wint_t c; - - if ((c = fgetwc(stream)) == WEOF) + if (eofStatus) { - printf("\nКрај улазног стрима.\nВоЗдра и дођите нам опет!\n"); - exit(0); + return WEOF; } else { + wint_t c = getwc(stream); + if (c == WEOF) + { + eofStatus = 1; + } return c; } } +wint_t unscanwc(wint_t c, FILE *stream) +{ + if (c == WEOF) + { + eofStatus = 1; + return WEOF; + } + else + { + return ungetwc(c, stream); + } +} + int lengthDigitArray(char *s) { int i; @@ -136,7 +156,7 @@ object getToken() buffer[0] = towlower(c); if (isEscape(c)) { - while (!isEscape(c = scanwc(stdin))) + while ((c = scanwc(stdin)) != WEOF && !isEscape(c)) { if (i + 2 >= bufferSize) { @@ -147,6 +167,10 @@ object getToken() buffer[++i] = c; buffer[++i] = L'\0'; + if (c == WEOF) + { + SIGERR(unexpectedEOFError); + } } else { @@ -224,7 +248,7 @@ wchar_t escapedWChar(wchar_t c) } } -object dispatchedChar(wchar_t c) +object dispatchedChar(wint_t c) { object result; @@ -237,6 +261,10 @@ object dispatchedChar(wchar_t c) int i = 0, n; c = scanwc(stdin); + if (c == WEOF) + { + SIGERR(unexpectedEOFError); + } if (!isConstituent(c)) { CHR(result) = c; @@ -244,7 +272,7 @@ object dispatchedChar(wchar_t c) else { unscanwc(c, stdin); - while (!iswspace(c = scanwc(stdin))) + while ((c = scanwc(stdin)) != WEOF && !iswspace(c)) { if (i + 1 >= bufferSize) { @@ -289,14 +317,16 @@ object dispatchedChar(wchar_t c) case L'|': for (;;) { - if ((c = scanwc(stdin)) == L'|' && - (c = scanwc(stdin)) == L'#') + if (((c = scanwc(stdin)) == L'|' && + (c = scanwc(stdin)) == L'#') || c == WEOF) { break; } } TYPE(result) = unspecifiedObject; break; + case WEOF: + SIGERR(unexpectedEOFError); default: SIGERR(invalidHashSequenceError); break; @@ -311,6 +341,7 @@ object macroFunction(wchar_t m) object *listCurrent; object expression; wchar_t *buffer; + wint_t c; switch (m) { @@ -325,6 +356,13 @@ object macroFunction(wchar_t m) TYPE(*listCurrent) = nilObject; break; } + else if (TYPE(currentObject) == EOFObject) + { + TYPE(*listCurrent) = nilObject; + deleteObject(result); + SIGERR(unexpectedEOFError); + break; + } else { TYPE(*listCurrent) = consObject; @@ -403,7 +441,11 @@ object macroFunction(wchar_t m) expression = read(""); if (TYPE(expression) == errorObject) { - return expression; + SIGERR(ERR(expression)); + } + else if (TYPE(expression) == EOFObject) + { + SIGERR(unexpectedEOFError); } TYPE(result) = consObject; @@ -421,15 +463,14 @@ object macroFunction(wchar_t m) break; case L';': TYPE(result) = unspecifiedObject; - while (scanwc(stdin) != L'\n') + while ((c = scanwc(stdin)) != L'\n' && c != WEOF) ; break; case L'"': buffer = getBuffer(); - wchar_t c; int i = 0; - while ((c = scanwc(stdin)) != L'"') + while ((c = scanwc(stdin)) != L'"' && c != WEOF) { if (i + 2 >= bufferSize) { @@ -445,6 +486,10 @@ object macroFunction(wchar_t m) buffer[i++] = c; } } + if (c == WEOF) + { + SIGERR(unexpectedEOFError); + } buffer[i] = L'\0'; int n = wcstombs(NULL, buffer, 0) + 1; diff --git a/util.h b/util.h index 0031efc..38f478d 100644 --- a/util.h +++ b/util.h @@ -46,7 +46,8 @@ typedef enum boolObject, stringObject, charObject, - errorObject + errorObject, + EOFObject } dataType; typedef enum