Омогућено ефективно дефинисање функција
This commit is contained in:
parent
f832904490
commit
a257cd21cd
6
Makefile
6
Makefile
|
@ -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
4
eval.c
|
@ -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
1
init.c
|
@ -25,4 +25,5 @@ void init()
|
||||||
addSymbolInternal("дефиниши", &define);
|
addSymbolInternal("дефиниши", &define);
|
||||||
addSymbolInternal("тачно->нетачно", &exactToInexact);
|
addSymbolInternal("тачно->нетачно", &exactToInexact);
|
||||||
addSymbolInternal("нетачно->тачно", &inexactToExact);
|
addSymbolInternal("нетачно->тачно", &inexactToExact);
|
||||||
|
addSymbolInternal("ламбда", &lambda);
|
||||||
}
|
}
|
||||||
|
|
90
internals.c
90
internals.c
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
5
print.c
5
print.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
17
symtable.c
17
symtable.c
|
@ -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
26
util.c
|
@ -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));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue