some scaffolding for adding functions

This commit is contained in:
NunoSempere 2023-05-06 23:28:04 -04:00
parent 0bfdb1b962
commit 9009175bc9
2 changed files with 65 additions and 13 deletions

BIN
mumble

Binary file not shown.

View File

@ -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)
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("<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