diff --git a/src/env.c b/src/env.c index d96c325..906d84c 100644 --- a/src/env.c +++ b/src/env.c @@ -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; +} \ No newline at end of file diff --git a/src/env.h b/src/env.h index 78da27b..f745740 100644 --- a/src/env.h +++ b/src/env.h @@ -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); diff --git a/src/pebblisp.c b/src/pebblisp.c index 3fe7f60..dc2d3ae 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -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 * diff --git a/src/pebblisp.h b/src/pebblisp.h index e77191b..a2627c8 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -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);