From 4dc9a4e888a73f12bdbeae080fe9fb97392ecdd6 Mon Sep 17 00:00:00 2001 From: kappa Date: Mon, 18 Feb 2019 23:20:44 +0100 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D1=9A=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=20=D0=B7=D0=B0=20=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D0=BE=D0=B2=D0=B0=D1=9A=D0=B5=20=D0=B3=D1=80=D0=B5?= =?UTF-8?q?=D1=88=D0=BA=D0=B0=D0=BC=D0=B0,=20=D0=B4=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=D1=82=D0=B0=20"=D0=B1=D0=B0=D1=86=D0=B8"=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D1=98=D0=B0=20=D0=B8=20"=D1=83=D1=81=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2"=20=D1=81=D0=BF=D0=B5=D1=86=D0=B8=D1=98=D0=B0?= =?UTF-8?q?=D0=BB=D0=BD=D0=B0=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 ++-- cirilisp.c | 7 +++++++ eval.c | 4 ++-- internals.c | 29 ++++++++++++++++++++++++----- internals.h | 1 + print.c | 19 +------------------ read.c | 12 ++++++++---- util.c | 26 +++++++++++++++++++++++++- util.h | 14 +++++++++++++- инит.ћ | 36 ++++++++++++++++++++++++++++++++---- 10 files changed, 115 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index bdde11a..6cfe63a 100644 --- a/Makefile +++ b/Makefile @@ -20,14 +20,14 @@ L_SRC = инит.ћ INC = util.h read.h eval.h print.h internals.h OBJ = $(C_SRC:.c=.o) -all: cirilisp +all: cirilisp $(L_SRC) .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< $(OBJ): $(INC) $(L_SRC) -cirilisp: $(OBJ) $(L_SRC) +cirilisp: $(OBJ) $(CC) -o $@ $(OBJ) $(LDFLAGS) clean: diff --git a/cirilisp.c b/cirilisp.c index dd183a4..30666d7 100644 --- a/cirilisp.c +++ b/cirilisp.c @@ -17,7 +17,13 @@ int load(char *pathname) } object exp; while (TYPE(exp = eval(read("", stream), globalEnv)) != EOFObject) + { + if (TYPE(exp) == errorObject) + { + print(exp); + } deleteObject(exp); + } eofStatus = 0; fclose(stream); return 1; @@ -67,6 +73,7 @@ void init() addSymbolInternal("прикажи", &displayInt, 0); addSymbolInternal("штампај", &printInt, 0); addSymbolInternal("почни", &beginInt, 0); + addSymbolInternal("баци", &throwInt, 0); addSymbolInternal("направи-ниску", &makeStrInt, 0); addSymbolInternal("дужина-ниске", &strLengthInt, 0); diff --git a/eval.c b/eval.c index 07932f4..e713882 100644 --- a/eval.c +++ b/eval.c @@ -34,7 +34,7 @@ object eval(object input, env currentEnv) { result = copyObject(CAR(input)); deleteObject(input); - SIGERR(ERR(result)); + CPYERR(ERR(result)); } if (TYPE(CAR(input)) == procedureObject && @@ -60,7 +60,7 @@ object eval(object input, env currentEnv) object err = copyObject( CAR(*currentCell)); deleteObject(input); - SIGERR(ERR(err)); + CPYERR(ERR(err)); break; } currentCell = &CDR(*currentCell); diff --git a/internals.c b/internals.c index da9423a..27c21f1 100644 --- a/internals.c +++ b/internals.c @@ -290,7 +290,7 @@ object defineInt(object parameters, env currentEnv) currentEnv); if (TYPE(value) == errorObject) { - SIGERR(ERR(value)); + CPYERR(ERR(value)); } addSymbolVariable(SYM(result), value, currentEnv); } @@ -423,7 +423,7 @@ object ifInt(object parameters, env currentEnv) predicate = eval(copyObject(CAR(parameters)), currentEnv); if (TYPE(predicate) == errorObject) { - SIGERR(ERR(predicate)); + CPYERR(ERR(predicate)); } if (TYPE(predicate) == boolObject && BOOL(predicate) == 0) @@ -438,14 +438,14 @@ object ifInt(object parameters, env currentEnv) if (TYPE(result) == errorObject) { - SIGERR(ERR(result)); + CPYERR(ERR(result)); } break; case 3: predicate = eval(copyObject(CAR(parameters)), currentEnv); if (TYPE(predicate) == errorObject) { - SIGERR(ERR(predicate)); + CPYERR(ERR(predicate)); } if (TYPE(predicate) == boolObject && BOOL(predicate) == 0) @@ -461,7 +461,7 @@ object ifInt(object parameters, env currentEnv) if (TYPE(result) == errorObject) { - SIGERR(ERR(result)); + CPYERR(ERR(result)); } break; default: @@ -758,6 +758,25 @@ object beginInt(object parameters) return last; } +object throwInt(object parameters) +{ + if (listLength(parameters) != 1) + { + SIGERR(argumentNumberError); + } + if (TYPE(CAR(parameters)) != stringObject) + { + SIGERR(typeError); + } + + object result; + TYPE(result) = errorObject; + ERR(result) = malloc((strlen(STR(CAR(parameters))) + 1) * + sizeof(char)); + strcpy(ERR(result), STR(CAR(parameters))); + return result; +} + object makeStrInt(object parameters) { object result; diff --git a/internals.h b/internals.h index 83c245a..79d3af3 100644 --- a/internals.h +++ b/internals.h @@ -33,5 +33,6 @@ object applyInt(object parameters, env currentEnv); object displayInt(object parameters); object printInt(object parameters); object beginInt(object parameters); +object throwInt(object parameters); object makeStrInt(object parameters); object strLengthInt(object parameters); diff --git a/print.c b/print.c index 5733bee..8831738 100644 --- a/print.c +++ b/print.c @@ -2,30 +2,13 @@ #include "util.h" -char *errors[] = -{ - "Конс објекат мора бити правилна листа да би могао бити евалуиран", - "Неправилан конс \".\" оператер", - "Неправилан тип аргумента прослеђен функцији", - "Непознати симбол", - "Објекат није примењив", - "Дељење нулом", - "Функцији није прослеђен правилан број аргумената", - "Пређена је максимална дубина рекурзије", - "Невалидан карактер", - "Невалидна тараба-секвенца", - "Неочекивани крај фајла", - "Неочекивана заграда", - "Недовољно меморије доступно" -}; - void printValue(object input); int print(object input) { if (TYPE(input) == errorObject) { - fprintf(stderr, "\nГРЕШКА: %s\n\n", errors[ERR(input)]); + fprintf(stderr, "\nГРЕШКА: %s\n\n", ERR(input)); } else if (TYPE(input) == EOFObject) { diff --git a/read.c b/read.c index d71eeaa..4299f1d 100644 --- a/read.c +++ b/read.c @@ -353,7 +353,8 @@ object macroFunction(wchar_t m, FILE *stream) { object currentObject = read("", stream); if (TYPE(currentObject) == errorObject && - ERR(currentObject) == unmatchedParenError) + !strcmp(ERR(currentObject), + commonErrs[unmatchedParenError])) { TYPE(*listCurrent) = nilObject; break; @@ -392,7 +393,7 @@ object macroFunction(wchar_t m, FILE *stream) { object error = copyObject(CAR(*listCurrent)); deleteObject(result); - SIGERR(ERR(error)); + CPYERR(ERR(error)); } int properDotComb = 1, dotPlace = -1, length; @@ -443,7 +444,7 @@ object macroFunction(wchar_t m, FILE *stream) expression = read("", stream); if (TYPE(expression) == errorObject) { - SIGERR(ERR(expression)); + CPYERR(ERR(expression)); } else if (TYPE(expression) == EOFObject) { @@ -481,7 +482,10 @@ object macroFunction(wchar_t m, FILE *stream) if (c == L'\\') { c = scanwc(stream); - buffer[i++] = escapedWChar(c); + if (c != L'\n') + { + buffer[i++] = escapedWChar(c); + } } else { diff --git a/util.c b/util.c index c7f56e3..d4b0e98 100644 --- a/util.c +++ b/util.c @@ -5,6 +5,23 @@ #include "util.h" +char *commonErrs[] = +{ + "Конс објекат мора бити правилна листа да би могао бити евалуиран", + "Неправилан конс \".\" оператер", + "Неправилан тип аргумента прослеђен функцији", + "Непознати симбол", + "Објекат није примењив", + "Дељење нулом", + "Функцији није прослеђен правилан број аргумената", + "Пређена је максимална дубина рекурзије", + "Невалидан карактер", + "Невалидна тараба-секвенца", + "Неочекивани крај фајла", + "Неочекивана заграда", + "Недовољно меморије доступно" +}; + entry **findEntry(entry **current, char *symbol) { int cond; @@ -170,6 +187,11 @@ void deleteObject(object input) free(STR(input)); STR(input) = NULL; } + else if (TYPE(input) == errorObject && ERR(input) != NULL) + { + free(ERR(input)); + ERR(input) = NULL; + } else if (TYPE(input) == procedureObject && PROC_TYPE(input) == compoundProc) { @@ -237,7 +259,9 @@ object copyObject(object input) CHR(result) = CHR(input); break; case errorObject: - ERR(result) = ERR(input); + ERR(result) = + malloc(sizeof(char) * (strlen(ERR(input)) + 1)); + strcpy(ERR(result), ERR(input)); break; default: break; diff --git a/util.h b/util.h index 6454095..b1ff737 100644 --- a/util.h +++ b/util.h @@ -14,6 +14,16 @@ #define ERR(x) ((x).value.err) #define SIGERR(error) \ +{\ + object __result;\ + TYPE(__result) = errorObject;\ + ERR(__result) = malloc((strlen(commonErrs[error]) + 1) *\ + sizeof(char));\ + strcpy(ERR(__result), commonErrs[error]);\ + return __result;\ +} + +#define CPYERR(error) \ {\ object __result;\ TYPE(__result) = errorObject;\ @@ -67,6 +77,8 @@ typedef enum outOfMemoryError } error; +extern char *commonErrs[]; + typedef enum { fractionNum, @@ -107,7 +119,7 @@ struct object dataType type; union { - error err; + char *err; char *symbol; char *string; wchar_t character; diff --git a/инит.ћ b/инит.ћ index 9c941f2..2c22d5d 100644 --- a/инит.ћ +++ b/инит.ћ @@ -2,16 +2,33 @@ (опиши (садр џ) (сар (сдр џ))) (опиши (сдар џ) (сдр (сар џ))) (опиши (сддр џ) (сдр (сдр џ))) +(опиши (сааар џ) (сар (сар (сар џ)))) +(опиши (саадр џ) (сар (сар (сдр џ)))) +(опиши (садар џ) (сар (сдр (сар џ)))) +(опиши (саддр џ) (сар (сдр (сдр џ)))) +(опиши (сдаар џ) (сдр (сар (сар џ)))) +(опиши (сдадр џ) (сдр (сар (сдр џ)))) +(опиши (сддар џ) (сдр (сдр (сар џ)))) +(опиши (сдддр џ) (сдр (сдр (сдр џ)))) + +(опиши нил ()) (опиши (није предикат) (ако предикат #л #и)) -(опиши нил ()) - (опиши истинито #и) (опиши лажно #л) (опиши (листа . арг) арг) +(опиши (дужина листа) + (опиши (дужина-пом листа акумулатор) + (ако (нил? листа) + акумулатор + (дужина-пом (сдр листа) (+ акумулатор 1)))) + (ако (није (листа? листа)) + (баци "Неправилан тип аргумента прослеђен функцији") + (дужина-пом листа 0))) + (опиши-складњу (и . предикати) (ако (нил? предикати) #и (ако (нил? (сдр предикати)) @@ -28,5 +45,16 @@ (примени или (сдр предикати)) (сар предикати))))) -#|(опиши-складњу (услов . клаузе) - (|# +(опиши-складњу (услов . клаузе) + (ако (= (дужина клаузе) 0) + (баци "Конс позван са празном листом клауза") + (ако (није (и (конс? (сар клаузе)) (листа? (сар клаузе)))) + (баци "Неправилна конс клауза") + (листа 'ако (саар клаузе) + (ако (нил? (сдар клаузе)) + (саар клаузе) + (листа 'примени 'почни + (листа 'навод (сдар клаузе)))) + (ако (нил? (сдр клаузе)) + () + (примени услов (сдр клаузе)))))))