Small optimizations and cleanup.

This commit is contained in:
Sage Vaillancourt 2022-03-27 00:03:34 -04:00
parent 158c21f441
commit 9a454e6a30
4 changed files with 60 additions and 90 deletions

View File

@ -53,8 +53,6 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
struct Environment env = { struct Environment env = {
.outer = outer, .outer = outer,
.strings = NULL,
.objects = NULL,
.structCount = 0, .structCount = 0,
.structCapacity = 0, .structCapacity = 0,
.size = paramCount, .size = paramCount,
@ -62,7 +60,12 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
}; };
if (paramCount == 0) { if (paramCount == 0) {
return outer ? *outer : env; if (outer) {
return *outer;
}
env.strings = NULL;
env.objects = NULL;
return env;
} }
env.strings = calloc(sizeof(char*), paramCount + 1); env.strings = calloc(sizeof(char*), paramCount + 1);
@ -81,29 +84,22 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
return env; return env;
} }
// TODO Maybe extend environment using a new outer, instead of realloc void addToEnvAt(int i, struct Environment* env, const char* name, const Object obj)
{
env->strings[i] = malloc(sizeof(char) * strlen(name) + 1);
strcpy(env->strings[i], name);
env->objects[i] = cloneObject(obj);
}
void addToEnv(struct Environment* env, const char* name, const Object obj) void addToEnv(struct Environment* env, const char* name, const Object obj)
{ {
// int sym_pos = findInEnv(&env, name);
// if(sym_pos != -1) {
// Object o = cloneObject(obj);
// cleanObject(&env->objects[sym_pos]);
// env->objects[sym_pos] = o;
// return;
// }
int i;
struct Environment* temp_env = env; struct Environment* temp_env = env;
int is_local = 1;
while (temp_env) { while (temp_env) {
for (i = 0; i < temp_env->size; i++) { for (int i = 0; i < temp_env->size; i++) {
// Add *new* item to env only if we're in the local scope
if (temp_env->strings[i] == NULL) { if (temp_env->strings[i] == NULL) {
if (is_local) { // Add *new* item to env only if we're in the original scope
temp_env->strings[i] = if (temp_env == env) {
calloc(sizeof(char), strlen(name) + 1); addToEnvAt(i, env, name, obj);
strcpy(temp_env->strings[i], name);
temp_env->objects[i] = cloneObject(obj);
return; return;
} }
break; break;
@ -115,7 +111,6 @@ void addToEnv(struct Environment* env, const char* name, const Object obj)
} }
} }
temp_env = temp_env->outer; temp_env = temp_env->outer;
is_local = 0;
} }
printd("Reallocating environment\n"); printd("Reallocating environment\n");
@ -129,9 +124,7 @@ void addToEnv(struct Environment* env, const char* name, const Object obj)
env->strings[old_size + j] = NULL; env->strings[old_size + j] = NULL;
} }
env->strings[old_size] = malloc(strlen(name) + 1); addToEnvAt(old_size, env, name, obj);
strcpy(env->strings[old_size], name);
env->objects[old_size] = cloneObject(obj);
} }
void printEnv(struct Environment* env) void printEnv(struct Environment* env)
@ -155,11 +148,12 @@ void printEnv(struct Environment* env)
void addFunc(const char* name, void addFunc(const char* name,
Object (* func)(Object*, int, struct Environment*), Object (* func)(Object*, int, struct Environment*),
struct Environment* env) struct Environment* env,
int i)
{ {
Object o = newObject(TYPE_FUNC); Object o = newObject(TYPE_FUNC);
o.func = func; o.func = func;
addToEnv(env, name, o); addToEnvAt(i, env, name, o);
} }
void deleteEnv(struct Environment* e) void deleteEnv(struct Environment* e)
@ -180,9 +174,7 @@ void deleteEnv(struct Environment* e)
i++; i++;
} }
free(e->strings); free(e->strings);
e->strings = NULL;
free(e->objects); free(e->objects);
e->objects = NULL;
} }
for (int i = 0; i < e->structCount; i++) { for (int i = 0; i < e->structCount; i++) {
@ -201,18 +193,6 @@ struct symFunc {
Object (* func)(Object*, int, struct Environment*); Object (* func)(Object*, int, struct Environment*);
}; };
struct Environment* globalEnv;
struct Environment* global()
{
return globalEnv;
}
void setGlobal(struct Environment* env)
{
globalEnv = env;
}
struct helpText { struct helpText {
const char* symbol; const char* symbol;
const char* help; const char* help;
@ -225,6 +205,8 @@ struct helpText helpTexts[100];
#define pfn(_func) buildFuncSym(_func ## Symbol, &(_func), _func ## Doc, NULL) #define pfn(_func) buildFuncSym(_func ## Symbol, &(_func), _func ## Doc, NULL)
#define pf(_name, _func) buildFuncSym(_name, &(_func), _func ## Doc, _func ## Tests, array_length(_func ## Tests)) #define pf(_name, _func) buildFuncSym(_name, &(_func), _func ## Doc, _func ## Tests, array_length(_func ## Tests))
/// For any instances (e.g. segfault recovery) where defaultEnv() may be called
/// multiple times.
int helpInitialized = 0; int helpInitialized = 0;
struct symFunc buildFuncSym(const char* symbol, Object (* func)(Object*, int, struct Environment*), const char* help, struct symFunc buildFuncSym(const char* symbol, Object (* func)(Object*, int, struct Environment*), const char* help,
@ -371,15 +353,11 @@ int runTests(int detailed)
struct Environment defaultEnv() struct Environment defaultEnv()
{ {
char** strings = calloc(sizeof(char*), MAX_ENV_ELM);
Object* objects = malloc(sizeof(Object) * MAX_ENV_ELM);
char size = MAX_ENV_ELM;
struct Environment e = { struct Environment e = {
.outer = NULL, .outer = NULL,
.strings = strings, .strings = calloc(sizeof(char*), MAX_ENV_ELM),
.objects = objects, .objects = malloc(sizeof(Object) * MAX_ENV_ELM),
.size = size, .size = MAX_ENV_ELM,
.structCount = 0, .structCount = 0,
.structCapacity = 8, .structCapacity = 8,
.structDefs = malloc(sizeof(struct StructDef) * 8), .structDefs = malloc(sizeof(struct StructDef) * 8),
@ -435,8 +413,8 @@ struct Environment defaultEnv()
#endif #endif
}; };
for (unsigned i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) { for (int i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) {
addFunc(symFuncs[i].sym, symFuncs[i].func, &e); addFunc(symFuncs[i].sym, symFuncs[i].func, &e, i);
} }
helpInitialized = 1; helpInitialized = 1;
@ -452,3 +430,15 @@ int getStructIndex(struct Environment* env, const char* name)
} }
return -1; return -1;
} }
struct Environment* globalEnv;
struct Environment* global()
{
return globalEnv;
}
void setGlobal(struct Environment* env)
{
globalEnv = env;
}

View File

@ -32,7 +32,8 @@ void printEnv(struct Environment* env);
void addFunc(const char* name, void addFunc(const char* name,
Object (* func)(Object*, int, struct Environment*), Object (* func)(Object*, int, struct Environment*),
struct Environment* env); struct Environment* env,
int i);
void deleteEnv(struct Environment* e); void deleteEnv(struct Environment* e);

View File

@ -170,42 +170,6 @@ Object evalBuiltIns(const Object* first, const Object* rest,
return *first; return *first;
} }
/**
* Bulk evaluator of Objects in a given list. Puts the results in a given array
*
* Note that `destArr` is a raw array, not an Object list, and that `start` is
* not itself a list, but the first element *in* a list to be evaluated. This
* allows more speed and flexibility in what should be evaluated.
*
* @param destArr The raw array to put the results into. Not an Object list!
* @param start The Object element to start with
* @param env The environment to use while evaluating
*/
void evalForms(Object* destArr, const Object* start, struct Environment* env)
{
int i = 0;
while (start) {
destArr[i] = eval(start, env);
start = start->forward;
i++;
}
}
Object listEvalFunc(const Object* list, const Object* function,
int length, struct Environment* env);
Object simpleFuncEval(const Object func, Object arg1, Object arg2, struct Environment* env)
{
Object funcList = startList(func);
nf_addToList(&funcList, arg1);
Object current = cloneObject(arg2);
nf_addToList(&funcList, current);
Object first_eval = eval(funcList.list, env);
arg1 = listEvalFunc(&funcList, &first_eval, 2, env);
cleanObject(&funcList);
return arg1;
}
/** /**
* Evaluates a list whose first element is a function, applying that function * Evaluates a list whose first element is a function, applying that function
* *
@ -221,7 +185,12 @@ Object listEvalFunc(const Object* list, const Object* function,
const int length, struct Environment* env) const int length, struct Environment* env)
{ {
Object rest[length]; Object rest[length];
evalForms(rest, list->list->forward, env);
const Object* start = list->list->forward;
for (int i = 0; i < length; i++) {
rest[i] = eval(start, env);
start = start->forward;
}
Object result = function->func(rest, length, env); Object result = function->func(rest, length, env);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -230,6 +199,18 @@ Object listEvalFunc(const Object* list, const Object* function,
return result; return result;
} }
Object simpleFuncEval(const Object func, Object arg1, Object arg2, struct Environment* env)
{
Object funcList = startList(func);
nf_addToList(&funcList, arg1);
Object current = cloneObject(arg2);
nf_addToList(&funcList, current);
Object first_eval = eval(funcList.list, env);
arg1 = listEvalFunc(&funcList, &first_eval, 2, env);
cleanObject(&funcList);
return arg1;
}
/** /**
* Evaluates a list whose first element is a lambda, applying that lambda * Evaluates a list whose first element is a lambda, applying that lambda
* *

View File

@ -49,8 +49,6 @@ Object parseEval(const char* input, struct Environment* env);
Object evalList(const Object* obj, struct Environment* env); Object evalList(const Object* obj, struct Environment* env);
void evalForms(Object* destList, const Object* src, struct Environment* env);
void copySlice(char* dest, struct Slice* src); 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);