From a0f6fa8e3f2fed37ecf12dff0ce97b197f70cd50 Mon Sep 17 00:00:00 2001 From: kappa Date: Sun, 20 Jan 2019 14:12:47 +0100 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B0=D1=82=20=D1=81=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=BA=D1=81=D0=BD=D0=B8=20=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=20"'"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eval.c | 3 ++- internals.c | 4 ++-- print.c | 3 ++- read.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--- util.h | 3 ++- 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/eval.c b/eval.c index 080fd48..861448d 100644 --- a/eval.c +++ b/eval.c @@ -41,7 +41,8 @@ object eval(object input) int noErrors = 1; while (TYPE(*currentCell) != nilObject) { - if (strcmp(SYM(CAR(input)), "навод") != 0) + if (TYPE(CAR(input)) != symbolObject || + strcmp(SYM(CAR(input)), "навод") != 0) { CAR(*currentCell) = eval(CAR(*currentCell)); diff --git a/internals.c b/internals.c index 4242420..db8b2f7 100644 --- a/internals.c +++ b/internals.c @@ -122,9 +122,9 @@ object divide(object parameters) } else { - if (NUM(add(CDR(parameters))) != 0) + if (NUM(multiply(CDR(parameters))) != 0) { - NUM(result) = NUM(CAR(parameters))/NUM(add(CDR(parameters))); + NUM(result) = NUM(CAR(parameters))/NUM(multiply(CDR(parameters))); } else { diff --git a/print.c b/print.c index 9a0fed3..11fada7 100644 --- a/print.c +++ b/print.c @@ -9,7 +9,8 @@ char *errors[] = "Непознати симбол", "Објекат није примењив", "Дељење нулом", - "Функцији није прослеђен правилан број аргумената" + "Функцији није прослеђен правилан број аргумената", + "Синтаксна грешка" }; void printValue(object input); diff --git a/read.c b/read.c index 7b4ba34..7f0192a 100644 --- a/read.c +++ b/read.c @@ -13,6 +13,7 @@ typedef enum undefinedToken, numberToken, symbolToken, + quoteToken, lParenthesisToken, rParenthesisToken } tokenType; @@ -86,7 +87,7 @@ int completeExpression(token **tokenQueue) } else { - if (indentLevel == 0) + if (indentLevel == 0 && current->type != quoteToken) { result = 1; } @@ -141,7 +142,7 @@ token *lex1Token(char *input, int *i) regcomp(®Space, "^[[:space:]]*", REG_EXTENDED); regcomp(®Number, "^[-+]?[[:digit:]]+", REG_EXTENDED); - regcomp(®Symbol, "^[-+/*_\\\\=<>!&[:alnum:]]+", REG_EXTENDED); + regcomp(®Symbol, "^[-+/*_\\\\=<>!&?[:alnum:]]+", REG_EXTENDED); regcomp(®Quote, "^'", REG_EXTENDED); regcomp(®LParenthesis, "^\\(", REG_EXTENDED); regcomp(®RParenthesis, "^\\)", REG_EXTENDED); @@ -172,6 +173,10 @@ token *lex1Token(char *input, int *i) result->type = symbolToken; } } + else if (!regexec(®Quote, input + *i, nmatches, a, 0)) + { + result->type = quoteToken; + } else if (!regexec(®LParenthesis, input + *i, nmatches, a, 0)) { result->type = lParenthesisToken; @@ -259,6 +264,33 @@ object parseExpression(token **inputList) strcpy(SYM(result), input.lexeme); return result; } + else if (input.type == quoteToken) + { + if ((*inputList)->type != rParenthesisToken) + { + TYPE(result) = consObject; + CONS(result) = malloc(sizeof(cons)); + TYPE(CAR(result)) = symbolObject; + SYM(CAR(result)) = malloc((strlen("навод") + 1) + * sizeof(char)); + strcpy(SYM(CAR(result)), "навод"); + + TYPE(CDR(result)) = consObject; + CONS(CDR(result)) = malloc(sizeof(cons)); + CAR(CDR(result)) = parseExpression(inputList); + + TYPE(CDR(CDR(result))) = nilObject; + } + else + { + TYPE(result) = errorObject; + ERR(result) = syntaxError; + } + +/* уколико "'" оператер директно претходи затвореној загради није могуће + * правилно га претворити у навод оператер стога се он изоставља из било којег + * израза */ + } else if (input.type == lParenthesisToken) { object *listCurrent = &result; @@ -279,7 +311,30 @@ object parseExpression(token **inputList) input = **inputList; free(*inputList); *inputList = input.next; - } + int noErrors = 1; + listCurrent = &result; + + while (TYPE(*listCurrent) != nilObject) + { + if (TYPE(CAR(*listCurrent)) == errorObject) + { + noErrors = 0; + } + listCurrent = &CDR(*listCurrent); + } + if (!noErrors) + { + deleteObject(result); + TYPE(result) = errorObject; + ERR(result) = syntaxError; + } + } + else if (input.type == rParenthesisToken) + { + TYPE(result) = errorObject; + ERR(result) = syntaxError; + } + free(input.lexeme); return result; } diff --git a/util.h b/util.h index 312c631..204e6b2 100644 --- a/util.h +++ b/util.h @@ -25,7 +25,8 @@ typedef enum unrecognizedSymbolError, notApplicableError, divisionByZeroError, - argumentNumberError + argumentNumberError, + syntaxError } error; typedef struct object object;