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