mumble

A Lisp written in C, following the *Build Your Own Lisp* book
Log | Files | Refs | README

commit 9009175bc9ec7f79db903798797fc6fd9ec39aa8
parent 0bfdb1b962de41da1c1dc1e20f2a04e6e0c2a29b
Author: NunoSempere <nuno.sempere@protonmail.com>
Date:   Sat,  6 May 2023 23:28:04 -0400

some scaffolding for adding functions

Diffstat:
Mmumble | 0
Msrc/mumble.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/mumble b/mumble Binary files differ. diff --git 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: + 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 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 func"); - if (v->builtin_func_name != NULL) - free(v->builtin_func_name); - v->builtin_func_name = NULL; + 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 func"); + 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("<function, name: %s, pointer: %p> ", v->builtin_func_name, v->builtin_func); break; + case LISPVAL_USER_FUNC: + printf("<user-defined function, pointer: %p> ", 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