some scaffolding for adding functions
This commit is contained in:
parent
0bfdb1b962
commit
9009175bc9
74
src/mumble.c
74
src/mumble.c
|
@ -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);
|
free(v->builtin_func_name);
|
||||||
v->builtin_func_name = NULL;
|
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user