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

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 - компајлер за ћирилични дијалекат лиспа # cirilisp - компајлер за ћирилични дијалекат лиспа
# ћирилисп верзија # ћирилисп верзија
VERSION = 0.5 VERSION = 0.7
# локација за инсталацију # локација за инсталацију
PREFIX = /usr/local PREFIX = /usr/local
# флегови за C компајлер и линкер # флегови за C компајлер и линкер
CPPFLAGS = -D_POSIX_C_SOURCE=200809L CPPFLAGS = -D_POSIX_C_SOURCE=200809L
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

4
eval.c
View file

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

1
init.c
View file

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

View file

@ -2,7 +2,7 @@
#include "util.h" #include "util.h"
#include "eval.h" #include "eval.h"
int allNumbers(object list) int allNums(object list)
{ {
object *currentCell = &list; object *currentCell = &list;
while (TYPE(*currentCell) != nilObject) while (TYPE(*currentCell) != nilObject)
@ -16,12 +16,26 @@ int allNumbers(object list)
return 1; 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 add(object parameters)
{ {
object result; object result;
TYPE(result) = numberObject; TYPE(result) = numberObject;
if (!allNumbers(parameters)) if (!allNums(parameters))
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
ERR(result) = typeError; ERR(result) = typeError;
@ -47,7 +61,7 @@ object subtract(object parameters)
object result; object result;
TYPE(result) = numberObject; TYPE(result) = numberObject;
if (!allNumbers(parameters)) if (!allNums(parameters))
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
ERR(result) = typeError; ERR(result) = typeError;
@ -75,7 +89,7 @@ object multiply(object parameters)
object result; object result;
TYPE(result) = numberObject; TYPE(result) = numberObject;
if (!allNumbers(parameters)) if (!allNums(parameters))
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
ERR(result) = typeError; ERR(result) = typeError;
@ -101,7 +115,7 @@ object divide(object parameters)
object result; object result;
TYPE(result) = numberObject; TYPE(result) = numberObject;
if (!allNumbers(parameters)) if (!allNums(parameters))
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
ERR(result) = typeError; ERR(result) = typeError;
@ -192,19 +206,79 @@ object quote(object parameters)
return result; 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 define(object parameters)
{ {
object result; object result;
if (listLength(parameters) != 2) if (listLength(parameters) == 0)
{ {
TYPE(result) = errorObject; TYPE(result) = errorObject;
ERR(result) = argumentNumberError; ERR(result) = argumentNumberError;
} }
else if (TYPE(CAR(parameters)) == symbolObject) else if (TYPE(CAR(parameters)) == symbolObject)
{ {
result = copyObject(CAR(parameters)); if (listLength(parameters) == 2)
addSymbolVariable(SYM(result), {
result = copyObject(CAR(parameters));
addSymbolVariable(SYM(result),
eval(copyObject(CAR(CDR(parameters))))); 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 else
{ {

View file

@ -9,3 +9,4 @@ object exactToInexact(object parameters);
object inexactToExact(object parameters); object inexactToExact(object parameters);
object quote(object parameters); object quote(object parameters);
object define(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 ? 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) else if (TYPE(input) == symbolObject)
{ {

View file

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

26
util.c
View file

@ -5,14 +5,15 @@
#include "util.h" #include "util.h"
#define SPECIALFORMSNUM 2 #define SPECIALFORMSNUM 3
int isSpecialForm(char *symbol) int isSpecialForm(char *symbol)
{ {
int result = 0; int result = 0;
char *specialForms[] = char *specialForms[] =
{ {
"навод", "навод",
"дефиниши" "дефиниши",
"ламбда"
}; };
for (int i = 0; i < SPECIALFORMSNUM; ++i) for (int i = 0; i < SPECIALFORMSNUM; ++i)
@ -98,6 +99,22 @@ object copyObject(object input)
CAR(result) = copyObject(CAR(input)); CAR(result) = copyObject(CAR(input));
CDR(result) = copyObject(CDR(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; return result;
} }
@ -300,3 +317,8 @@ object inverseNum(object a)
return result; 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 minusNum(object a);
object timesNum(object a, object b); object timesNum(object a, object b);
object inverseNum(object a); object inverseNum(object a);
procedure *createProcedure();