Small optimizations and cleanup.
This commit is contained in:
parent
158c21f441
commit
9a454e6a30
90
src/env.c
90
src/env.c
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue