Cleanup and a couple (micro) optimizations.

This commit is contained in:
Sage Vaillancourt 2022-03-28 23:51:05 -04:00
parent 66a07e395c
commit af7a2e6265
8 changed files with 27 additions and 102 deletions

View File

@ -56,11 +56,9 @@ Object fetchFromEnvironment(const char* name, struct Environment* env)
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)
{
int paramCount = listLength(params);
if (outer) {
outer->refs += 1;
}

View File

@ -25,7 +25,7 @@ void setGlobal(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);
void addToEnv(struct Environment* env, const char* name, Object obj);

View File

@ -50,10 +50,6 @@ int listLength(const Object* listObj)
*/
Object* itemAt(const Object* listObj, int n)
{
if (!listObj || !isListy(*listObj)) {
return NULL;
}
FOR_POINTER_IN_LIST(listObj) {
if (n-- == 0) {
return POINTER;
@ -80,46 +76,6 @@ Object* tail(const Object* listObj)
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 getAllocations()
@ -153,19 +109,18 @@ void allocObject(Object** spot, const Object src)
* Does nothing if `dest` is NULL or not a list type
* @param dest The list to append to
* @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)) {
return;
}
if (isEmpty(dest)) {
if (dest->list == NULL) {
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
@ -199,9 +154,6 @@ static const char* errorText[] = {"MISMATCHED_PARENS",
*/
int stringList(char* dest, const Object* obj)
{
if (!dest || !isListy(*obj)) {
return 0;
}
const char* initial = dest;
dest += sprintf(dest, "(");
@ -503,11 +455,6 @@ void printAndClean(Object* target)
*/
void deleteList(Object* dest)
{
if (!isListy(*dest)) {
printf("Tried to delete something other than a list\n");
return;
}
Object* march = dest->list;
while (march != NULL) {
Object* prevMarch = march;

View File

@ -144,7 +144,7 @@ int isEmpty(const Object* obj);
Object* tail(const Object* listObj);
void nf_addToList(Object* dest, Object src);
Object* nf_addToList(Object* dest, Object src);
void deleteList(Object* dest);

View File

@ -103,12 +103,12 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
Object lambda = eval(argForms, env);
const Object* inputList = argForms->forward;
Object outputList = listObject();
if (lambda.type != TYPE_LAMBDA) {
return errorObject(BAD_TYPE);
}
Object outputList = listObject();
if (inputList) {
FOR_POINTER_IN_LIST(inputList) {
// Create a new list for each element,
@ -116,7 +116,7 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
Object tempInput = cloneObject(*POINTER);
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
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 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 newEnv =
envForLambda(&lambda->lambda->params, remaining, env);
envForLambda(&lambda->lambda->params, remaining, evalLength - 1, env);
Object ret = eval(&lambda->lambda->body, &newEnv);
deleteEnv(&newEnv);
cleanObject(lambda);
@ -278,15 +278,16 @@ Object evalList(const Object* obj, struct Environment* env)
return listEvalFunc(obj, &first_eval, evalLength - 1, env);
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
Object list = listObject();
int i = 0;
nf_addToList(&list, first_eval);
Object* t = nf_addToList(&list, first_eval);
FOR_POINTER_IN_LIST(obj) {
if (i != 0) {
nf_addToList(&list, eval(POINTER, env));
allocObject(&t->forward, eval(POINTER, env));
t = t->forward;
}
i++;
}
@ -319,15 +320,6 @@ Object eval(const Object* obj, struct Environment* env)
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 structo = params[0];
@ -510,19 +502,6 @@ Object parseEval(const char* input, struct Environment* env)
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 parens = 0;
Object obj = numberObject(0);

View File

@ -54,7 +54,7 @@ void copySlice(char* dest, struct Slice* src);
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);
Object simpleFuncEval(Object func, Object arg1, Object arg2, struct Environment* env);

View File

@ -3,10 +3,11 @@
#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;
if ((typeLength - 1) > length ) {
if ((typeLength - 1) > length) {
return errorObject(NOT_ENOUGH_ARGUMENTS);
}
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 first_eval = eval(&cloned, env);
Object testee = cloneObject(*POINTER);
Object e = listEvalLambda(&first_eval, &testee, env);
Object e = listEvalLambda(&first_eval, &testee, 2, env);
if (e.number) {
nf_addToList(&filtered, testee); // May need to re-clone testee?
}
@ -299,7 +300,7 @@ int areEqual(const Object* obj1, const Object* obj2);
int listEquality(const Object* list1, const Object* list2)
{
Object* element1, *element2;
Object* element1, * element2;
for (element1 = (list1)->list, element2 = (list2)->list;
element1 != ((void*) 0) && element2 != ((void*) 0);
element1 = element1->forward, element2 = element2->forward) {

View File

@ -86,7 +86,7 @@ answer_to_connection(void* cls, struct MHD_Connection* connection,
//res.structObject->fields[0] = queryParams;
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);
page = result.string;
break;