diff --git a/mumble b/mumble index 013364e..438a268 100755 Binary files a/mumble and b/mumble differ diff --git a/src/mumble.c b/src/mumble.c index d879bc3..a168edf 100644 --- a/src/mumble.c +++ b/src/mumble.c @@ -44,7 +44,8 @@ enum { LISPVAL_NUM, LISPVAL_ERR, LISPVAL_SYM, - LISPVAL_FUNC, + LISPVAL_BUILTIN_FUNC, + LISPVAL_USER_FUNC, LISPVAL_SEXPR, LISPVAL_QEXPR, }; @@ -118,7 +119,7 @@ lispval* lispval_builtin_func(lispbuiltin func, char* builtin_func_name) if (VERBOSE) printfln("Allocating func name:%s, pointer: %p", builtin_func_name, func); lispval* v = malloc(sizeof(lispval)); - v->type = LISPVAL_FUNC; + v->type = LISPVAL_BUILTIN_FUNC; v->count = 0; v->builtin_func_name = malloc(strlen(builtin_func_name) + 1); strcpy(v->builtin_func_name, builtin_func_name); @@ -128,6 +129,18 @@ lispval* lispval_builtin_func(lispbuiltin func, char* builtin_func_name) return v; } +lispenv* new_lispenv(); +lispval* lispval_lambda_func(lispval* variables, lispval* manipulation){ + lispval* v = malloc(sizeof(lispval)); + v->type = LISPVAL_USER_FUNC; + v->builtin_func = NULL; + v->env = new_lispenv(); + v->variables = variables; + v->manipulation = manipulation; + // unclear how to garbage-collect this. Maybe add to a list and collect at the end? + return v; +} + lispval* lispval_sexpr(void) { if (VERBOSE) @@ -190,16 +203,41 @@ void delete_lispval(lispval* v) if (VERBOSE) printfln("Freed sym"); break; - case LISPVAL_FUNC: - if (VERBOSE) - printfln("Freeing func"); - if (v->builtin_func_name != NULL) - free(v->builtin_func_name); - v->builtin_func_name = NULL; + case LISPVAL_BUILTIN_FUNC: + if (v->builtin_func_name != NULL){ + if (VERBOSE){ + printfln("Freeing builtin func"); + } + free(v->builtin_func_name); + v->builtin_func_name = NULL; + } if (v != NULL) free(v); if (VERBOSE) - printfln("Freed func"); + printfln("Freed builtin func"); + // Don't do anything with v->func for now + // Though we could delete the pointer to the function later + // free(v->func); + break; + case LISPVAL_USER_FUNC: + if (VERBOSE) + printfln("Freeing user-defined func"); + if (v->env != NULL){ + free(v->env); + v->env = NULL; + } + if (v->variables != NULL){ + free(v->variables); + v->variables = NULL; + } + if (v->manipulation != NULL){ + free(v->manipulation); + v->manipulation = NULL; + } + if (v != NULL) + free(v); + if (VERBOSE) + printfln("Freed user-defined func"); // Don't do anything with v->func for now // Though we could delete the pointer to the function later // free(v->func); @@ -399,9 +437,12 @@ void print_lispval_tree(lispval* v, int indent_level) case LISPVAL_SYM: printfln("%sSymbol: %s", indent, v->sym); break; - case LISPVAL_FUNC: + case LISPVAL_BUILTIN_FUNC: printfln("%sFunction, name: %s, pointer: %p", indent, v->builtin_func_name, v->builtin_func); break; + case LISPVAL_USER_FUNC: + printfln("%sUser-defined function: %p", indent, v->env); // Identify it with its environment? + break; case LISPVAL_SEXPR: printfln("%sSExpr, with %d children:", indent, v->count); for (int i = 0; i < v->count; i++) { @@ -439,9 +480,12 @@ void print_lispval_parenthesis(lispval* v) case LISPVAL_SYM: printf("%s ", v->sym); break; - case LISPVAL_FUNC: + case LISPVAL_BUILTIN_FUNC: printf(" ", v->builtin_func_name, v->builtin_func); break; + case LISPVAL_USER_FUNC: + printf(" ", v->env); + break; case LISPVAL_SEXPR: printf("( "); for (int i = 0; i < v->count; i++) { @@ -497,9 +541,12 @@ lispval* clone_lispval(lispval* old) case LISPVAL_SYM: new = lispval_sym(old->sym); break; - case LISPVAL_FUNC: + case LISPVAL_BUILTIN_FUNC: new = lispval_builtin_func(old->builtin_func, old->builtin_func_name); break; + case LISPVAL_USER_FUNC: + new = lispval_lambda_func(old->variables, old->manipulation); + break; case LISPVAL_SEXPR: new = lispval_sexpr(); break; @@ -874,7 +921,7 @@ lispval* evaluate_lispval(lispval* l, lispenv* env) // Check if the first element is an operation. if (VERBOSE) printfln("Checking is first element is a function"); - if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_FUNC)) { + if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_BUILTIN_FUNC)){ if (VERBOSE) printfln("Passed check"); @@ -909,6 +956,11 @@ lispval* evaluate_lispval(lispval* l, lispenv* env) printfln("Cleaned up. Returning"); return answer; } + + if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_USER_FUNC)) { + // Do something with user-defined functions here + } + return l; } // Increase or decrease verbosity level manually