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 = {
.outer = outer,
.strings = NULL,
.objects = NULL,
.structCount = 0,
.structCapacity = 0,
.size = paramCount,
@ -62,7 +60,12 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
};
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);
@ -81,29 +84,22 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
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)
{
// 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;
int is_local = 1;
while (temp_env) {
for (i = 0; i < temp_env->size; i++) {
// Add *new* item to env only if we're in the local scope
for (int i = 0; i < temp_env->size; i++) {
if (temp_env->strings[i] == NULL) {
if (is_local) {
temp_env->strings[i] =
calloc(sizeof(char), strlen(name) + 1);
strcpy(temp_env->strings[i], name);
temp_env->objects[i] = cloneObject(obj);
// Add *new* item to env only if we're in the original scope
if (temp_env == env) {
addToEnvAt(i, env, name, obj);
return;
}
break;
@ -115,7 +111,6 @@ void addToEnv(struct Environment* env, const char* name, const Object obj)
}
}
temp_env = temp_env->outer;
is_local = 0;
}
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] = malloc(strlen(name) + 1);
strcpy(env->strings[old_size], name);
env->objects[old_size] = cloneObject(obj);
addToEnvAt(old_size, env, name, obj);
}
void printEnv(struct Environment* env)
@ -155,11 +148,12 @@ void printEnv(struct Environment* env)
void addFunc(const char* name,
Object (* func)(Object*, int, struct Environment*),
struct Environment* env)
struct Environment* env,
int i)
{
Object o = newObject(TYPE_FUNC);
o.func = func;
addToEnv(env, name, o);
addToEnvAt(i, env, name, o);
}
void deleteEnv(struct Environment* e)
@ -180,9 +174,7 @@ void deleteEnv(struct Environment* e)
i++;
}
free(e->strings);
e->strings = NULL;
free(e->objects);
e->objects = NULL;
}
for (int i = 0; i < e->structCount; i++) {
@ -201,18 +193,6 @@ struct symFunc {
Object (* func)(Object*, int, struct Environment*);
};
struct Environment* globalEnv;
struct Environment* global()
{
return globalEnv;
}
void setGlobal(struct Environment* env)
{
globalEnv = env;
}
struct helpText {
const char* symbol;
const char* help;
@ -225,6 +205,8 @@ struct helpText helpTexts[100];
#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))
/// For any instances (e.g. segfault recovery) where defaultEnv() may be called
/// multiple times.
int helpInitialized = 0;
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()
{
char** strings = calloc(sizeof(char*), MAX_ENV_ELM);
Object* objects = malloc(sizeof(Object) * MAX_ENV_ELM);
char size = MAX_ENV_ELM;
struct Environment e = {
.outer = NULL,
.strings = strings,
.objects = objects,
.size = size,
.strings = calloc(sizeof(char*), MAX_ENV_ELM),
.objects = malloc(sizeof(Object) * MAX_ENV_ELM),
.size = MAX_ENV_ELM,
.structCount = 0,
.structCapacity = 8,
.structDefs = malloc(sizeof(struct StructDef) * 8),
@ -435,8 +413,8 @@ struct Environment defaultEnv()
#endif
};
for (unsigned i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) {
addFunc(symFuncs[i].sym, symFuncs[i].func, &e);
for (int i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) {
addFunc(symFuncs[i].sym, symFuncs[i].func, &e, i);
}
helpInitialized = 1;
@ -452,3 +430,15 @@ int getStructIndex(struct Environment* env, const char* name)
}
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,
Object (* func)(Object*, int, struct Environment*),
struct Environment* env);
struct Environment* env,
int i);
void deleteEnv(struct Environment* e);

View File

@ -170,42 +170,6 @@ Object evalBuiltIns(const Object* first, const Object* rest,
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
*
@ -221,7 +185,12 @@ Object listEvalFunc(const Object* list, const Object* function,
const int length, struct Environment* env)
{
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);
for (int i = 0; i < length; i++) {
@ -230,6 +199,18 @@ Object listEvalFunc(const Object* list, const Object* function,
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
*

View File

@ -49,8 +49,6 @@ Object parseEval(const char* input, 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);
Object evalLambdaArgs(const Object* arg_forms, struct Environment* env);