diff --git a/Makefile b/Makefile index 1c207e8..44fc035 100644 --- a/Makefile +++ b/Makefile @@ -5,26 +5,28 @@ VERSION = 0,8 # локација за инсталацију PREFIX = /usr/local +LIBPREFIX = $(PREFIX)/lib # флегови за 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 -SRC = cirilisp.c read.c eval.c print.c util.c internals.c init.c -OBJ = $(SRC:.c=.o) +C_SRC = cirilisp.c read.c eval.c print.c util.c internals.c +TCH_SRC = инит.ћ +OBJ = $(C_SRC:.c=.o) all: cirilisp .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -$(OBJ): util.h read.h eval.h print.h internals.h init.h +$(OBJ): util.h read.h eval.h print.h internals.h $(TCH_SRC) -cirilisp: $(OBJ) +cirilisp: $(OBJ) $(TCH_SRC) $(CC) -o $@ $(OBJ) $(LDFLAGS) clean: @@ -32,21 +34,24 @@ clean: dist: clean mkdir -p cirilisp-$(VERSION) - cp -r Makefile util.h read.h eval.h print.h $(SRC) cirilisp-$(VERSION) + cp -r Makefile util.h read.h eval.h print.h $(C_SRC) cirilisp-$(VERSION) tar -cf cirilisp-$(VERSION).tar cirilisp-$(VERSION) gzip cirilisp-$(VERSION).tar rm -rf cirilisp-$(VERSION) install: all mkdir -p $(DESTDIR)$(PREFIX)/bin + mkdir -p $(DESTDIR)$(LIBPREFIX)/cirilisp cp -f cirilisp $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/cirilisp + cp -f $(TCH_SRC) $(DESTDIR)$(LIBPREFIX)/cirilisp # mkdir -p $(DESTDIR)$(MANPREFIX)/man1 # sed "s/VERSION/$(VERSION)/g" < cirilisp.1 > $(DESTDIR)$(MANPREFIX)/man1/dwm.1 # chmod 644 $(DESTDIR)$(MANPREFIX)/man1/cirilisp.1 uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/cirilisp + rm -rf $(DESTDIR)$(LIBPREFIX)/cirilisp # rm -f $(DESTDIR)$(MANPREFIX)/man1/cirilisp.1 .PHONY: all clean dist install uninstall diff --git a/cirilisp.c b/cirilisp.c index 0198aab..190b623 100644 --- a/cirilisp.c +++ b/cirilisp.c @@ -1,15 +1,65 @@ +#include #include +#include -#include "init.h" +#include "internals.h" #include "read.h" #include "eval.h" #include "print.h" +extern int eofStatus; +int load(char *pathname) +{ + FILE *stream; + if ((stream = fopen(pathname, "r")) == NULL) + { + return 0; + } + while (TYPE(eval(read("", stream), globalEnv)) != EOFObject) + ; + eofStatus = 0; + fclose(stream); + return 1; +} + +void init() +{ + if (setlocale(LC_ALL, "sr_RS.utf8") == NULL) + { + fprintf(stderr, "lokal programa se nije mogao podesiti na\ +\"sr_RS.utf8\", proverite da li ste ga osposobili na vasem sistemu\n"); + exit(0); + } +/* Омогућава библиотекама коришћеним у интерпретеру да протумаче српску + * ћирилицу */ + + globalEnv = createEnvironment(NULL); + addSymbolInternal("+", &addInt, 0); + addSymbolInternal("-", &subtractInt, 0); + addSymbolInternal("*", &multiplyInt, 0); + addSymbolInternal("/", ÷Int, 0); + addSymbolInternal("навод", "eInt, 1); + addSymbolInternal("дефиниши", &defineInt, 1); + addSymbolInternal("тачно->нетачно", &exactToInexactInt, 0); + addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0); + addSymbolInternal("ламбда", &lambdaInt, 1); + addSymbolInternal("<", &lessInt, 0); + addSymbolInternal(">", &greaterInt, 0); + addSymbolInternal("ако", &ifInt, 1); + + if (!load("/usr/local/lib/cirilisp/инит.ћ")) + { + fprintf(stderr, "Није пронађена стандардна ЋИРЛИСП библиотека\ +\nПрограм се није могао правилно покренути\n"); + exit(0); + } +} + int main(int argc, char **argv) { init(); - while (print(eval(read("ШКЉ> "), globalEnv))); - printf("\nДостигнут крај стрима.\nЗбогом и дођите нам опет!\n"); + while (print(eval(read("ШКЉ> ", stdin), globalEnv))); + printf("\nДостигнут крај улазног тока.\nЗбогом и дођите нам опет!\n"); return 0; } diff --git a/init.c b/init.c deleted file mode 100644 index 2c335e0..0000000 --- a/init.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -#include "internals.h" - -void init() -{ - if (setlocale(LC_ALL, "sr_RS.utf8") == NULL) - { - fprintf(stderr, "lokal se nije mogao podesiti na\ -\"sr_RS.utf8\", proverite da li ste ga osposobili na vasem sistemu\n"); - exit(0); - } -/* Омогућава библиотекама коришћеним у интерпретеру да протумаче српску - * ћирилицу */ - - globalEnv = createEnvironment(NULL); - addSymbolInternal("+", &addInt, 0); - addSymbolInternal("-", &subtractInt, 0); - addSymbolInternal("*", &multiplyInt, 0); - addSymbolInternal("/", ÷Int, 0); - addSymbolInternal("навод", "eInt, 1); - addSymbolInternal("дефиниши", &defineInt, 1); - addSymbolInternal("тачно->нетачно", &exactToInexactInt, 0); - addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0); - addSymbolInternal("ламбда", &lambdaInt, 1); - addSymbolInternal("<", &lessInt, 0); - addSymbolInternal(">", &greaterInt, 0); - addSymbolInternal("ако", &ifInt, 1); -} diff --git a/init.h b/init.h deleted file mode 100644 index c6d8ff4..0000000 --- a/init.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void init(void); diff --git a/read.c b/read.c index 47670dc..a372023 100644 --- a/read.c +++ b/read.c @@ -17,16 +17,16 @@ int isEscape(wchar_t c); wint_t scanwc(FILE *stream); wint_t unscanwc(wint_t c, FILE *stream); object getToken(); -object macroFunction(wchar_t m); +object macroFunction(wchar_t m, FILE *stream); -object read(char *prompt) +object read(char *prompt, FILE *stream) { printf("%s", prompt); wint_t c; object result; - while (iswspace(c = scanwc(stdin))) + while (iswspace(c = scanwc(stream))) ; if (c == WEOF) { @@ -34,12 +34,12 @@ object read(char *prompt) } else if (isMacroC(c)) { - result = macroFunction(c); + result = macroFunction(c, stream); } else if (isEscape(c) || isConstituent(c)) { - unscanwc(c, stdin); - result = getToken(); + unscanwc(c, stream); + result = getToken(stream); } else { @@ -48,7 +48,7 @@ object read(char *prompt) if (TYPE(result) == unspecifiedObject) { - return read(""); + return read("", stream); /* уколико улаз функције није прави објекат (на пример уколико је учитан * коментар) покушавамо прочитати опет */ } @@ -146,17 +146,17 @@ int lengthDigitArray(char *s) return i; } -object getToken() +object getToken(FILE *stream) { object result; wchar_t *buffer = getBuffer(); wint_t c; int i = 0; - c = scanwc(stdin); + c = scanwc(stream); buffer[0] = towlower(c); if (isEscape(c)) { - while ((c = scanwc(stdin)) != WEOF && !isEscape(c)) + while ((c = scanwc(stream)) != WEOF && !isEscape(c)) { if (i + 2 >= bufferSize) { @@ -174,7 +174,7 @@ object getToken() } else { - while (isConstituent(c = scanwc(stdin))) + while (isConstituent(c = scanwc(stream))) { if (i + 1 >= bufferSize) { @@ -182,7 +182,7 @@ object getToken() } buffer[++i] = towlower(c); } - unscanwc(c, stdin); + unscanwc(c, stream); buffer[++i] = L'\0'; } @@ -248,7 +248,7 @@ wchar_t escapedWChar(wchar_t c) } } -object dispatchedChar(wint_t c) +object dispatchedChar(wint_t c, FILE *stream) { object result; @@ -260,7 +260,7 @@ object dispatchedChar(wint_t c) wchar_t *buffer = getBuffer(); int i = 0, n; - c = scanwc(stdin); + c = scanwc(stream); if (c == WEOF) { SIGERR(unexpectedEOFError); @@ -271,8 +271,8 @@ object dispatchedChar(wint_t c) } else { - unscanwc(c, stdin); - while ((c = scanwc(stdin)) != WEOF && !iswspace(c)) + unscanwc(c, stream); + while ((c = scanwc(stream)) != WEOF && !iswspace(c)) { if (i + 1 >= bufferSize) { @@ -317,8 +317,8 @@ object dispatchedChar(wint_t c) case L'|': for (;;) { - if (((c = scanwc(stdin)) == L'|' && - (c = scanwc(stdin)) == L'#') || c == WEOF) + if (((c = scanwc(stream)) == L'|' && + (c = scanwc(stream)) == L'#') || c == WEOF) { break; } @@ -335,7 +335,7 @@ object dispatchedChar(wint_t c) return result; } -object macroFunction(wchar_t m) +object macroFunction(wchar_t m, FILE *stream) { object result; object *listCurrent; @@ -349,7 +349,7 @@ object macroFunction(wchar_t m) listCurrent = &result; for (;;) { - object currentObject = read(""); + object currentObject = read("", stream); if (TYPE(currentObject) == errorObject && ERR(currentObject) == unmatchedParenError) { @@ -438,7 +438,7 @@ object macroFunction(wchar_t m) break; case L'\'': case L'`': - expression = read(""); + expression = read("", stream); if (TYPE(expression) == errorObject) { SIGERR(ERR(expression)); @@ -463,14 +463,14 @@ object macroFunction(wchar_t m) break; case L';': TYPE(result) = unspecifiedObject; - while ((c = scanwc(stdin)) != L'\n' && c != WEOF) + while ((c = scanwc(stream)) != L'\n' && c != WEOF) ; break; case L'"': buffer = getBuffer(); int i = 0; - while ((c = scanwc(stdin)) != L'"' && c != WEOF) + while ((c = scanwc(stream)) != L'"' && c != WEOF) { if (i + 2 >= bufferSize) { @@ -478,7 +478,7 @@ object macroFunction(wchar_t m) } if (c == L'\\') { - c = scanwc(stdin); + c = scanwc(stream); buffer[i++] = escapedWChar(c); } else @@ -499,7 +499,7 @@ object macroFunction(wchar_t m) STR(result) = s; break; case L'#': - result = dispatchedChar(scanwc(stdin)); + result = dispatchedChar(scanwc(stream), stream); break; } diff --git a/read.h b/read.h index ccff389..36f7aa5 100644 --- a/read.h +++ b/read.h @@ -2,4 +2,4 @@ #include "util.h" -object read(char *prompt); +object read(char *prompt, FILE *stream); diff --git a/инит.ћ b/инит.ћ new file mode 100644 index 0000000..2a42a53 --- /dev/null +++ b/инит.ћ @@ -0,0 +1 @@ +(дефиниши (= а б) (ако (> а б) #л (ако (< а б) #л #и)))