Омогућено ефективно дефинисање функција

This commit is contained in:
kappa 2019-01-29 00:07:33 +01:00
parent f832904490
commit a257cd21cd
9 changed files with 126 additions and 26 deletions

View file

@ -1,15 +1,15 @@
# cirilisp - компајлер за ћирилични дијалекат лиспа
# ћирилисп верзија
VERSION = 0.5
VERSION = 0.7
# локација за инсталацију
PREFIX = /usr/local
# флегови за C компајлер и линкер
CPPFLAGS = -D_POSIX_C_SOURCE=200809L
CFLAGS = -g -std=c99 -pedantic -Wall -O0
# CFLAGS = -std=c99 -pedantic -Wall -O1
# CFLAGS = -g -std=c99 -pedantic -Wall -O0
CFLAGS = -std=c99 -pedantic -Wall -O1
LDFLAGS = -lm -lc
CC = cc

4
eval.c
View file

@ -3,6 +3,7 @@
#include <string.h>
#include "util.h"
#include "internals.h"
#include "symtable.h"
object apply(object function, object parameters);
@ -79,10 +80,11 @@ object apply(object procedure, object parameters)
return result;
}
object(*f)() = PROC_BUILTIN(procedure);
if (PROC_TYPE(procedure) == builtinProc)
{
object(*f)() = PROC_BUILTIN(procedure);
result = f(parameters);
return result;
}

1
init.c
View file

@ -25,4 +25,5 @@ void init()
addSymbolInternal("дефиниши", &define);
addSymbolInternal("тачно->нетачно", &exactToInexact);
addSymbolInternal("нетачно->тачно", &inexactToExact);
addSymbolInternal("ламбда", &lambda);
}

View file

@ -2,7 +2,7 @@
#include "util.h"
#include "eval.h"
int allNumbers(object list)
int allNums(object list)
{
object *currentCell = &list;
while (TYPE(*currentCell) != nilObject)
@ -16,12 +16,26 @@ int allNumbers(object list)
return 1;
}
int allSyms(object list)
{
object *currentCell = &list;
while (TYPE(*currentCell) != nilObject)
{
if (TYPE(CAR(*currentCell)) != symbolObject)
{
return 0;
}
currentCell = &CDR(*currentCell);
}
return 1;
}
object add(object parameters)
{
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
if (!allNums(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
@ -47,7 +61,7 @@ object subtract(object parameters)
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
if (!allNums(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
@ -75,7 +89,7 @@ object multiply(object parameters)
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
if (!allNums(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
@ -101,7 +115,7 @@ object divide(object parameters)
object result;
TYPE(result) = numberObject;
if (!allNumbers(parameters))
if (!allNums(parameters))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
@ -192,21 +206,81 @@ object quote(object parameters)
return result;
}
object lambda(object parameters)
{
object result;
if (listLength(parameters) < 2)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (!(TYPE(CAR(parameters)) == consObject &&
allSyms(CAR(parameters))))
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
else
{
TYPE(result) = procedureObject;
PROC(result) = createProcedure();
PROC_TYPE(result) = compoundProc;
PROC_COMP_ARGS(result) = copyObject(CAR(parameters));
PROC_COMP_BODY(result) = copyObject(CDR(parameters));
}
return result;
}
object define(object parameters)
{
object result;
if (listLength(parameters) != 2)
if (listLength(parameters) == 0)
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
else if (TYPE(CAR(parameters)) == symbolObject)
{
if (listLength(parameters) == 2)
{
result = copyObject(CAR(parameters));
addSymbolVariable(SYM(result),
eval(copyObject(CAR(CDR(parameters)))));
}
else
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
}
else if (TYPE(CAR(parameters)) == consObject)
{
if (listLength(parameters) >= 2)
{
if (allSyms(CAR(parameters)))
{
result = copyObject(CAR(CAR(parameters)));
object args = copyObject(CDR(CAR(parameters)));
deleteObject(CAR(parameters));
CAR(parameters) = copyObject(args);
deleteObject(args);
object proc = lambda(parameters);
addSymbolVariable(SYM(result), proc);
}
else
{
TYPE(result) = errorObject;
ERR(result) = typeError;
}
}
else
{
TYPE(result) = errorObject;
ERR(result) = argumentNumberError;
}
}
else
{
TYPE(result) = errorObject;
ERR(result) = typeError;

View file

@ -9,3 +9,4 @@ object exactToInexact(object parameters);
object inexactToExact(object parameters);
object quote(object parameters);
object define(object parameters);
object lambda(object parameters);

View file

@ -54,6 +54,11 @@ void printValue(object input)
{
printf("<процедура:%s>", PROC_TYPE(input) == builtinProc ?
"уграђена" : "сложена");
if (PROC_TYPE(input) == compoundProc)
{
printValue(PROC_COMP_ARGS(input));
printValue(PROC_COMP_BODY(input));
}
}
else if (TYPE(input) == symbolObject)
{

View file

@ -79,20 +79,13 @@ int createTable()
}
void removeTableAux(entry **table)
{
if ((*table) != NULL)
{
free((*table)->name);
deleteObject((*table)->value);
if ((*table)->left != NULL)
{
removeTableAux(&(*table)->left);
free((*table)->left);
(*table)->left = NULL;
}
if ((*table)->right != NULL)
{
removeTableAux(&(*table)->right);
free((*table)->right);
(*table)->right = NULL;
}
}
@ -123,7 +116,7 @@ void addSymbolInternal(char *symbol, object (*function)())
}
TYPE((*e)->value) = procedureObject;
PROC((*e)->value) = malloc(sizeof(procedure));
PROC((*e)->value) = createProcedure();
PROC_TYPE((*e)->value) = builtinProc;
PROC_BUILTIN((*e)->value) = function;
(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1));
@ -189,7 +182,7 @@ object referVariableAux(int index, char *symbol)
}
else
{
result = (*e)->value;
result = copyObject((*e)->value);
}
return result;

26
util.c
View file

@ -5,14 +5,15 @@
#include "util.h"
#define SPECIALFORMSNUM 2
#define SPECIALFORMSNUM 3
int isSpecialForm(char *symbol)
{
int result = 0;
char *specialForms[] =
{
"навод",
"дефиниши"
"дефиниши",
"ламбда"
};
for (int i = 0; i < SPECIALFORMSNUM; ++i)
@ -98,6 +99,22 @@ object copyObject(object input)
CAR(result) = copyObject(CAR(input));
CDR(result) = copyObject(CDR(input));
}
else if (TYPE(input) == procedureObject)
{
PROC(result) = malloc(sizeof(procedure));
PROC_TYPE(result) = PROC_TYPE(input);
if (PROC_TYPE(result) == builtinProc)
{
PROC_BUILTIN(result) = PROC_BUILTIN(input);
}
else
{
PROC_COMP_ARGS(result) =
copyObject(PROC_COMP_ARGS(input));
PROC_COMP_BODY(result) =
copyObject(PROC_COMP_BODY(input));
}
}
return result;
}
@ -300,3 +317,8 @@ object inverseNum(object a)
return result;
}
procedure *createProcedure()
{
return malloc(sizeof(procedure));
}

2
util.h
View file

@ -121,3 +121,5 @@ object plusNum(object a, object b);
object minusNum(object a);
object timesNum(object a, object b);
object inverseNum(object a);
procedure *createProcedure();