Додат синтаксни елемент "'"

This commit is contained in:
kappa 2019-01-20 14:12:47 +01:00
parent f978180190
commit a0f6fa8e3f
5 changed files with 66 additions and 8 deletions

3
eval.c
View file

@ -41,7 +41,8 @@ object eval(object input)
int noErrors = 1; int noErrors = 1;
while (TYPE(*currentCell) != nilObject) while (TYPE(*currentCell) != nilObject)
{ {
if (strcmp(SYM(CAR(input)), "навод") != 0) if (TYPE(CAR(input)) != symbolObject ||
strcmp(SYM(CAR(input)), "навод") != 0)
{ {
CAR(*currentCell) = CAR(*currentCell) =
eval(CAR(*currentCell)); eval(CAR(*currentCell));

View file

@ -122,9 +122,9 @@ object divide(object parameters)
} }
else 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 else
{ {

View file

@ -9,7 +9,8 @@ char *errors[] =
"Непознати симбол", "Непознати симбол",
"Објекат није примењив", "Објекат није примењив",
"Дељење нулом", "Дељење нулом",
"Функцији није прослеђен правилан број аргумената" "Функцији није прослеђен правилан број аргумената",
"Синтаксна грешка"
}; };
void printValue(object input); void printValue(object input);

61
read.c
View file

@ -13,6 +13,7 @@ typedef enum
undefinedToken, undefinedToken,
numberToken, numberToken,
symbolToken, symbolToken,
quoteToken,
lParenthesisToken, lParenthesisToken,
rParenthesisToken rParenthesisToken
} tokenType; } tokenType;
@ -86,7 +87,7 @@ int completeExpression(token **tokenQueue)
} }
else else
{ {
if (indentLevel == 0) if (indentLevel == 0 && current->type != quoteToken)
{ {
result = 1; result = 1;
} }
@ -141,7 +142,7 @@ token *lex1Token(char *input, int *i)
regcomp(&regSpace, "^[[:space:]]*", REG_EXTENDED); regcomp(&regSpace, "^[[:space:]]*", REG_EXTENDED);
regcomp(&regNumber, "^[-+]?[[:digit:]]+", REG_EXTENDED); regcomp(&regNumber, "^[-+]?[[:digit:]]+", REG_EXTENDED);
regcomp(&regSymbol, "^[-+/*_\\\\=<>!&[:alnum:]]+", REG_EXTENDED); regcomp(&regSymbol, "^[-+/*_\\\\=<>!&?[:alnum:]]+", REG_EXTENDED);
regcomp(&regQuote, "^'", REG_EXTENDED); regcomp(&regQuote, "^'", REG_EXTENDED);
regcomp(&regLParenthesis, "^\\(", REG_EXTENDED); regcomp(&regLParenthesis, "^\\(", REG_EXTENDED);
regcomp(&regRParenthesis, "^\\)", REG_EXTENDED); regcomp(&regRParenthesis, "^\\)", REG_EXTENDED);
@ -172,6 +173,10 @@ token *lex1Token(char *input, int *i)
result->type = symbolToken; result->type = symbolToken;
} }
} }
else if (!regexec(&regQuote, input + *i, nmatches, a, 0))
{
result->type = quoteToken;
}
else if (!regexec(&regLParenthesis, input + *i, nmatches, a, 0)) else if (!regexec(&regLParenthesis, input + *i, nmatches, a, 0))
{ {
result->type = lParenthesisToken; result->type = lParenthesisToken;
@ -259,6 +264,33 @@ object parseExpression(token **inputList)
strcpy(SYM(result), input.lexeme); strcpy(SYM(result), input.lexeme);
return result; 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) else if (input.type == lParenthesisToken)
{ {
object *listCurrent = &result; object *listCurrent = &result;
@ -279,7 +311,30 @@ object parseExpression(token **inputList)
input = **inputList; input = **inputList;
free(*inputList); free(*inputList);
*inputList = input.next; *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; return result;
} }

3
util.h
View file

@ -25,7 +25,8 @@ typedef enum
unrecognizedSymbolError, unrecognizedSymbolError,
notApplicableError, notApplicableError,
divisionByZeroError, divisionByZeroError,
argumentNumberError argumentNumberError,
syntaxError
} error; } error;
typedef struct object object; typedef struct object object;