Имплементирана процедура за дефиницање променљивих

This commit is contained in:
kappa 2019-01-22 00:08:27 +01:00
parent da7568e644
commit 405739c217
9 changed files with 122 additions and 29 deletions

View file

@ -7,8 +7,8 @@ VERSION = 0.5
PREFIX = /usr/local PREFIX = /usr/local
# флегови за C компајлер и линкер # флегови за C компајлер и линкер
# CFLAGS = -g -std=c99 -pedantic -Wall -O0 CFLAGS = -g -std=c99 -pedantic -Wall -O0
CFLAGS = -std=c99 -pedantic -Wall -O1 # CFLAGS = -std=c99 -pedantic -Wall -O1
LDFLAGS = -lm -lc LDFLAGS = -lm -lc
CC = cc CC = cc

9
eval.c
View file

@ -19,9 +19,16 @@ object eval(object input)
else if (TYPE(input) == symbolObject) else if (TYPE(input) == symbolObject)
{ {
if (symbolExists(SYM(input))) if (symbolExists(SYM(input)))
{
if (typeOf(SYM(input)) == variableSymbol)
{
result = referVariable(SYM(input));
}
else
{ {
result = copyObject(input); result = copyObject(input);
} }
}
else else
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
@ -42,7 +49,7 @@ object eval(object input)
while (TYPE(*currentCell) != nilObject) while (TYPE(*currentCell) != nilObject)
{ {
if (TYPE(CAR(input)) != symbolObject || if (TYPE(CAR(input)) != symbolObject ||
strcmp(SYM(CAR(input)), "навод") != 0) !isSpecialForm(SYM(CAR(input))))
{ {
CAR(*currentCell) = CAR(*currentCell) =
eval(CAR(*currentCell)); eval(CAR(*currentCell));

1
init.c
View file

@ -21,6 +21,7 @@ void init()
addSymbolInternal("*", &multiply); addSymbolInternal("*", &multiply);
addSymbolInternal("/", &divide); addSymbolInternal("/", &divide);
addSymbolInternal("навод", &quote); addSymbolInternal("навод", &quote);
addSymbolInternal("дефиниши", &define);
addSymbolInternal("тачно->нетачно", &exactToInexact); addSymbolInternal("тачно->нетачно", &exactToInexact);
addSymbolInternal("нетачно->тачно", &inexactToExact); addSymbolInternal("нетачно->тачно", &inexactToExact);
} }

View file

@ -1,4 +1,6 @@
#include "symtable.h"
#include "util.h" #include "util.h"
#include "eval.h"
int allNumbers(object list) int allNumbers(object list)
{ {
@ -189,3 +191,21 @@ object quote(object parameters)
} }
return result; return result;
} }
object define(object parameters)
{
object result;
if (listLength(parameters) != 2)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (TYPE(CAR(parameters)) == symbolObject)
{
result = copyObject(CAR(parameters));
addSymbolVariable(SYM(result),
eval(copyObject(CAR(CDR(parameters)))));
}
return result;
}

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "util.h"
object add(object parameters); object add(object parameters);
object subtract(object parameters); object subtract(object parameters);
@ -7,3 +8,4 @@ object divide(object parameters);
object exactToInexact(object parameters); object exactToInexact(object parameters);
object inexactToExact(object parameters); object inexactToExact(object parameters);
object quote(object parameters); object quote(object parameters);
object define(object parameters);

View file

@ -5,12 +5,6 @@
#include "util.h" #include "util.h"
#include "symtable.h" #include "symtable.h"
typedef enum
{
internalSymbol,
objectSymbol
} symbolType;
typedef struct entry typedef struct entry
{ {
symbolType type; symbolType type;
@ -18,7 +12,7 @@ typedef struct entry
union union
{ {
object (*function)(); object (*function)();
object definition; object variable;
} value; } value;
struct entry *left; struct entry *left;
struct entry *right; struct entry *right;
@ -54,47 +48,67 @@ entry **findEntry(entry **current, char *symbol)
* одвојене ради читљивости */ * одвојене ради читљивости */
} }
void freeEntry(entry **current)
{
free((*current)->name);
if ((*current)->type == variableSymbol)
{
deleteObject((*current)->value.variable);
}
}
symbolType typeOf(char *symbol)
{
entry **e = findEntry(&root, symbol);
return (*e)->type;
}
int addSymbolInternal(char *symbol, object (*function)()) int addSymbolInternal(char *symbol, object (*function)())
{ {
int status = 1; int status = 1;
entry **e = findEntry(&root, symbol); entry **e = findEntry(&root, symbol);
if (*e == NULL) if (*e != NULL)
{
status = 0;
freeEntry(e);
}
else
{ {
*e = malloc(sizeof(entry)); *e = malloc(sizeof(entry));
}
(*e)->type = internalSymbol; (*e)->type = internalSymbol;
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); (*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
strcpy((*e)->name, symbol); strcpy((*e)->name, symbol);
(*e)->value.function = function; (*e)->value.function = function;
(*e)->left = (*e)->right = NULL; (*e)->left = (*e)->right = NULL;
}
else
{
status = 0;
}
return status; return status;
} }
int addSymbolDefinition(char *symbol, object definition) int addSymbolVariable(char *symbol, object variable)
{ {
int status = 1; int status = 1;
entry **e = findEntry(&root, symbol); entry **e = findEntry(&root, symbol);
if (*e == NULL) if (*e != NULL)
{ {
*e = malloc(sizeof(entry)); status = 0;
(*e)->type = objectSymbol; freeEntry(e);
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
strcpy((*e)->name, symbol);
(*e)->value.definition = copyObject(definition);
(*e)->left = (*e)->right = NULL;
} }
else else
{ {
status = 0; *e = malloc(sizeof(entry));
} }
(*e)->type = variableSymbol;
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
strcpy((*e)->name, symbol);
(*e)->value.variable = copyObject(variable);
(*e)->left = (*e)->right = NULL;
return status; return status;
} }
@ -128,3 +142,21 @@ object (*internalFunction(char *symbol)) (object)
return ((*e)->value.function); return ((*e)->value.function);
} }
} }
object referVariable(char *symbol)
{
object result;
entry **e = findEntry(&root, symbol);
if (*e == NULL || (*e)->type != variableSymbol)
{
TYPE(result) = errorObject;
ERR(result) = unrecognizedSymbolError;
}
else
{
result = (*e)->value.variable;
}
return result;
}

View file

@ -2,16 +2,25 @@
#include "util.h" #include "util.h"
typedef enum
{
internalSymbol,
variableSymbol
} symbolType;
int addSymbolInternal(char *symbol, object (*function)()); int addSymbolInternal(char *symbol, object (*function)());
int addSymbolDefinition(char *symbol, object definition); int addSymbolVariable(char *symbol, object variable);
/* служе за различите методе дефинисања нових симбола у језику /* служе за различите методе дефинисања нових симбола у језику
* враћају 1 уколико је нови симбол успешно додат, а 0 уколико није * враћају 1 уколико је нови симбол успешно додат, а 0 уколико није
* (постоји симбол са истим именом) */ * (постоји симбол са истим именом) */
int symbolExists(char *symbol); int symbolExists(char *symbol);
/* враћа 1 уколико симбол постоји и 0 у супротном */ /* враћа 1 уколико симбол постоји и 0 у супротном */
symbolType typeOf(char *symbol);
object (*internalFunction(char *symbol)) (object parameters); object (*internalFunction(char *symbol)) (object parameters);
/* враћа показивач на функцију уколико је симбол дефинисан као интерна /* враћа показивач на функцију уколико је симбол дефинисан као интерна
* функција, NULL уколико симбол није функција или уколико не постоји * функција, NULL уколико симбол није функција или уколико не постоји
* */ * */
object referVariable(char *symbol);
/* враћа вредност на коју се односи име симбола у табели */

21
util.c
View file

@ -5,6 +5,27 @@
#include "util.h" #include "util.h"
#define SPECIALFORMSNUM 2
int isSpecialForm(char *symbol)
{
int result = 0;
char *specialForms[] =
{
"навод",
"дефиниши"
};
for (int i = 0; i < SPECIALFORMSNUM; ++i)
{
if (!strcmp(symbol, specialForms[i]))
{
result = 1;
}
}
return result;
}
int properList(object list) int properList(object list)
{ {
object *current = &list; object *current = &list;

1
util.h
View file

@ -75,6 +75,7 @@ struct cons
object cdr; object cdr;
}; };
int isSpecialForm(char *symbol);
int properList(object list); int properList(object list);
int listLength(object list); int listLength(object list);
void deleteObject(object input); void deleteObject(object input);