Cleanup and a couple (micro) optimizations.
This commit is contained in:
parent
66a07e395c
commit
af7a2e6265
|
@ -56,11 +56,9 @@ Object fetchFromEnvironment(const char* name, struct Environment* env)
|
||||||
return errorWithContext(DID_NOT_FIND_SYMBOL, name);
|
return errorWithContext(DID_NOT_FIND_SYMBOL, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Environment envForLambda(const Object* params, const Object* arg_forms,
|
struct Environment envForLambda(const Object* params, const Object* arg_forms, int paramCount,
|
||||||
struct Environment* outer)
|
struct Environment* outer)
|
||||||
{
|
{
|
||||||
int paramCount = listLength(params);
|
|
||||||
|
|
||||||
if (outer) {
|
if (outer) {
|
||||||
outer->refs += 1;
|
outer->refs += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ void setGlobal(struct Environment* env);
|
||||||
|
|
||||||
Object fetchFromEnvironment(const char* name, struct Environment* env);
|
Object fetchFromEnvironment(const char* name, struct Environment* env);
|
||||||
|
|
||||||
struct Environment envForLambda(const Object* params, const Object* arg_forms,
|
struct Environment envForLambda(const Object* params, const Object* arg_forms, int paramCount,
|
||||||
struct Environment* outer);
|
struct Environment* outer);
|
||||||
|
|
||||||
void addToEnv(struct Environment* env, const char* name, Object obj);
|
void addToEnv(struct Environment* env, const char* name, Object obj);
|
||||||
|
|
67
src/object.c
67
src/object.c
|
@ -50,10 +50,6 @@ int listLength(const Object* listObj)
|
||||||
*/
|
*/
|
||||||
Object* itemAt(const Object* listObj, int n)
|
Object* itemAt(const Object* listObj, int n)
|
||||||
{
|
{
|
||||||
if (!listObj || !isListy(*listObj)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_POINTER_IN_LIST(listObj) {
|
FOR_POINTER_IN_LIST(listObj) {
|
||||||
if (n-- == 0) {
|
if (n-- == 0) {
|
||||||
return POINTER;
|
return POINTER;
|
||||||
|
@ -80,46 +76,6 @@ Object* tail(const Object* listObj)
|
||||||
return tail;
|
return tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a given object is empty.
|
|
||||||
*
|
|
||||||
* BOOL, NUMBER, and ERROR types return true only when 0
|
|
||||||
* LIST, LAMBDA, and FUNC types return true only when NULL
|
|
||||||
* SYMBOL returns true only when it begins with a nullchar
|
|
||||||
* @param obj A pointer to the object to check
|
|
||||||
* @return True only if the non-null Object is empty/non-zero
|
|
||||||
*/
|
|
||||||
inline int isEmpty(const Object* obj)
|
|
||||||
{
|
|
||||||
if (obj == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (obj->type) {
|
|
||||||
case TYPE_NUMBER:
|
|
||||||
case TYPE_BOOL:
|
|
||||||
return obj->number == 0;
|
|
||||||
case TYPE_LIST:
|
|
||||||
case TYPE_SLIST:
|
|
||||||
return obj->list == NULL;
|
|
||||||
case TYPE_LAMBDA:
|
|
||||||
return obj->lambda == NULL;
|
|
||||||
case TYPE_STRUCT:
|
|
||||||
return obj->structObject == NULL;
|
|
||||||
case TYPE_SYMBOL:
|
|
||||||
case TYPE_STRING:
|
|
||||||
return obj->string == NULL || obj->string[0] == '\0';
|
|
||||||
case TYPE_FUNC:
|
|
||||||
return obj->func == NULL;
|
|
||||||
case TYPE_OTHER:
|
|
||||||
return obj->other == NULL;
|
|
||||||
case TYPE_ERROR:
|
|
||||||
return getErrorCode(*obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int allocations = 0;
|
int allocations = 0;
|
||||||
|
|
||||||
int getAllocations()
|
int getAllocations()
|
||||||
|
@ -153,19 +109,18 @@ void allocObject(Object** spot, const Object src)
|
||||||
* Does nothing if `dest` is NULL or not a list type
|
* Does nothing if `dest` is NULL or not a list type
|
||||||
* @param dest The list to append to
|
* @param dest The list to append to
|
||||||
* @param src The Object to copy into the list
|
* @param src The Object to copy into the list
|
||||||
|
* @returns A pointer to the tail of the destination list
|
||||||
*/
|
*/
|
||||||
void nf_addToList(Object* dest, const Object src)
|
Object* nf_addToList(Object* dest, const Object src)
|
||||||
{
|
{
|
||||||
if (!dest || !isListy(*dest)) {
|
if (dest->list == NULL) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty(dest)) {
|
|
||||||
allocObject(&dest->list, src);
|
allocObject(&dest->list, src);
|
||||||
return;
|
return dest->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocObject(&tail(dest)->forward, src);
|
Object* listTail = tail(dest);
|
||||||
|
allocObject(&listTail->forward, src);
|
||||||
|
return listTail->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SIMPLE_ERRORS
|
#ifndef SIMPLE_ERRORS
|
||||||
|
@ -199,9 +154,6 @@ static const char* errorText[] = {"MISMATCHED_PARENS",
|
||||||
*/
|
*/
|
||||||
int stringList(char* dest, const Object* obj)
|
int stringList(char* dest, const Object* obj)
|
||||||
{
|
{
|
||||||
if (!dest || !isListy(*obj)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const char* initial = dest;
|
const char* initial = dest;
|
||||||
|
|
||||||
dest += sprintf(dest, "(");
|
dest += sprintf(dest, "(");
|
||||||
|
@ -503,11 +455,6 @@ void printAndClean(Object* target)
|
||||||
*/
|
*/
|
||||||
void deleteList(Object* dest)
|
void deleteList(Object* dest)
|
||||||
{
|
{
|
||||||
if (!isListy(*dest)) {
|
|
||||||
printf("Tried to delete something other than a list\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object* march = dest->list;
|
Object* march = dest->list;
|
||||||
while (march != NULL) {
|
while (march != NULL) {
|
||||||
Object* prevMarch = march;
|
Object* prevMarch = march;
|
||||||
|
|
|
@ -144,7 +144,7 @@ int isEmpty(const Object* obj);
|
||||||
|
|
||||||
Object* tail(const Object* listObj);
|
Object* tail(const Object* listObj);
|
||||||
|
|
||||||
void nf_addToList(Object* dest, Object src);
|
Object* nf_addToList(Object* dest, Object src);
|
||||||
|
|
||||||
void deleteList(Object* dest);
|
void deleteList(Object* dest);
|
||||||
|
|
||||||
|
|
|
@ -103,12 +103,12 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
|
||||||
|
|
||||||
Object lambda = eval(argForms, env);
|
Object lambda = eval(argForms, env);
|
||||||
const Object* inputList = argForms->forward;
|
const Object* inputList = argForms->forward;
|
||||||
Object outputList = listObject();
|
|
||||||
|
|
||||||
if (lambda.type != TYPE_LAMBDA) {
|
if (lambda.type != TYPE_LAMBDA) {
|
||||||
return errorObject(BAD_TYPE);
|
return errorObject(BAD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object outputList = listObject();
|
||||||
if (inputList) {
|
if (inputList) {
|
||||||
FOR_POINTER_IN_LIST(inputList) {
|
FOR_POINTER_IN_LIST(inputList) {
|
||||||
// Create a new list for each element,
|
// Create a new list for each element,
|
||||||
|
@ -116,7 +116,7 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
|
||||||
Object tempInput = cloneObject(*POINTER);
|
Object tempInput = cloneObject(*POINTER);
|
||||||
|
|
||||||
Object* params = &lambda.lambda->params;
|
Object* params = &lambda.lambda->params;
|
||||||
struct Environment newEnv = envForLambda(params, &tempInput, env);
|
struct Environment newEnv = envForLambda(params, &tempInput, listLength(params), env);
|
||||||
|
|
||||||
// Add the lambda evaluation to the list
|
// Add the lambda evaluation to the list
|
||||||
Object lambda_output = eval(&lambda.lambda->body, &newEnv);
|
Object lambda_output = eval(&lambda.lambda->body, &newEnv);
|
||||||
|
@ -208,11 +208,11 @@ Object simpleFuncEval(const Object func, Object arg1, Object arg2, struct Enviro
|
||||||
* @param remaining The first element after `lambda`
|
* @param remaining The first element after `lambda`
|
||||||
* @param env The environment to evaluate in
|
* @param env The environment to evaluate in
|
||||||
*/
|
*/
|
||||||
Object listEvalLambda(Object* lambda, const Object* remaining,
|
Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength,
|
||||||
struct Environment* env)
|
struct Environment* env)
|
||||||
{
|
{
|
||||||
struct Environment newEnv =
|
struct Environment newEnv =
|
||||||
envForLambda(&lambda->lambda->params, remaining, env);
|
envForLambda(&lambda->lambda->params, remaining, evalLength - 1, env);
|
||||||
Object ret = eval(&lambda->lambda->body, &newEnv);
|
Object ret = eval(&lambda->lambda->body, &newEnv);
|
||||||
deleteEnv(&newEnv);
|
deleteEnv(&newEnv);
|
||||||
cleanObject(lambda);
|
cleanObject(lambda);
|
||||||
|
@ -278,15 +278,16 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
return listEvalFunc(obj, &first_eval, evalLength - 1, env);
|
return listEvalFunc(obj, &first_eval, evalLength - 1, env);
|
||||||
|
|
||||||
case TYPE_LAMBDA:
|
case TYPE_LAMBDA:
|
||||||
return listEvalLambda(&first_eval, first_form->forward, env);
|
return listEvalLambda(&first_eval, first_form->forward, evalLength, env);
|
||||||
|
|
||||||
default: { // Return list with each element evaluated
|
default: { // Return list with each element evaluated
|
||||||
Object list = listObject();
|
Object list = listObject();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
nf_addToList(&list, first_eval);
|
Object* t = nf_addToList(&list, first_eval);
|
||||||
FOR_POINTER_IN_LIST(obj) {
|
FOR_POINTER_IN_LIST(obj) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
nf_addToList(&list, eval(POINTER, env));
|
allocObject(&t->forward, eval(POINTER, env));
|
||||||
|
t = t->forward;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -319,15 +320,6 @@ Object eval(const Object* obj, struct Environment* env)
|
||||||
return errorObject(BAD_TYPE);
|
return errorObject(BAD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copySlice(char* dest, struct Slice* src)
|
|
||||||
{
|
|
||||||
if (!dest || !src) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
strncpy(dest, src->text, src->length);
|
|
||||||
dest[(int) src->length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
Object possessive(Object* params, int length, struct Environment* env)
|
Object possessive(Object* params, int length, struct Environment* env)
|
||||||
{
|
{
|
||||||
Object structo = params[0];
|
Object structo = params[0];
|
||||||
|
@ -510,19 +502,6 @@ Object parseEval(const char* input, struct Environment* env)
|
||||||
return symFromSlice(" ", 1);
|
return symFromSlice(" ", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
struct Slice *debug = tokens;
|
|
||||||
printd("start slice\n");
|
|
||||||
if (debug) {
|
|
||||||
while (debug->text) {
|
|
||||||
char tok[100];
|
|
||||||
copySlice(tok, debug);
|
|
||||||
printd("slice: '%s'\n", tok);
|
|
||||||
debug++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int parens = 0;
|
int parens = 0;
|
||||||
Object obj = numberObject(0);
|
Object obj = numberObject(0);
|
||||||
|
|
|
@ -54,7 +54,7 @@ void copySlice(char* dest, struct Slice* src);
|
||||||
|
|
||||||
Object evalLambdaArgs(const Object* arg_forms, struct Environment* env);
|
Object evalLambdaArgs(const Object* arg_forms, struct Environment* env);
|
||||||
|
|
||||||
Object listEvalLambda(Object* lambda, const Object* remaining,
|
Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength,
|
||||||
struct Environment* env);
|
struct Environment* env);
|
||||||
|
|
||||||
Object simpleFuncEval(Object func, Object arg1, Object arg2, struct Environment* env);
|
Object simpleFuncEval(Object func, Object arg1, Object arg2, struct Environment* env);
|
||||||
|
|
13
src/plfunc.c
13
src/plfunc.c
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
#include "plfunc.h"
|
#include "plfunc.h"
|
||||||
|
|
||||||
Object typeCheck(const char* funcName, Object* params, int length, int (*typeChecks[])(Object), int typeLength, int* failed)
|
Object typeCheck(const char* funcName, Object* params, int length,
|
||||||
|
int (* typeChecks[])(Object), int typeLength, int* failed)
|
||||||
{
|
{
|
||||||
*failed = 1;
|
*failed = 1;
|
||||||
if ((typeLength - 1) > length ) {
|
if ((typeLength - 1) > length) {
|
||||||
return errorObject(NOT_ENOUGH_ARGUMENTS);
|
return errorObject(NOT_ENOUGH_ARGUMENTS);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < typeLength - 1; i++) {
|
for (int i = 0; i < typeLength - 1; i++) {
|
||||||
|
@ -76,7 +77,7 @@ Object filter(Object* params, int length, struct Environment* env)
|
||||||
Object cloned = cloneObject(condition);
|
Object cloned = cloneObject(condition);
|
||||||
Object first_eval = eval(&cloned, env);
|
Object first_eval = eval(&cloned, env);
|
||||||
Object testee = cloneObject(*POINTER);
|
Object testee = cloneObject(*POINTER);
|
||||||
Object e = listEvalLambda(&first_eval, &testee, env);
|
Object e = listEvalLambda(&first_eval, &testee, 2, env);
|
||||||
if (e.number) {
|
if (e.number) {
|
||||||
nf_addToList(&filtered, testee); // May need to re-clone testee?
|
nf_addToList(&filtered, testee); // May need to re-clone testee?
|
||||||
}
|
}
|
||||||
|
@ -299,10 +300,10 @@ int areEqual(const Object* obj1, const Object* obj2);
|
||||||
|
|
||||||
int listEquality(const Object* list1, const Object* list2)
|
int listEquality(const Object* list1, const Object* list2)
|
||||||
{
|
{
|
||||||
Object* element1, *element2;
|
Object* element1, * element2;
|
||||||
for (element1 = (list1)->list, element2 = (list2)->list;
|
for (element1 = (list1)->list, element2 = (list2)->list;
|
||||||
element1 != ((void*) 0) && element2 != ((void*) 0);
|
element1 != ((void*) 0) && element2 != ((void*) 0);
|
||||||
element1 = element1->forward, element2 = element2->forward) {
|
element1 = element1->forward, element2 = element2->forward) {
|
||||||
if (!areEqual(element1, element2)) {
|
if (!areEqual(element1, element2)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ answer_to_connection(void* cls, struct MHD_Connection* connection,
|
||||||
//res.structObject->fields[0] = queryParams;
|
//res.structObject->fields[0] = queryParams;
|
||||||
Object route = cloneObject(routes[i].routeAction);
|
Object route = cloneObject(routes[i].routeAction);
|
||||||
|
|
||||||
Object result = listEvalLambda(&route, &res, routes[i].env);
|
Object result = listEvalLambda(&route, &res, 2, routes[i].env);
|
||||||
cleanObject(&res);
|
cleanObject(&res);
|
||||||
page = result.string;
|
page = result.string;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue