diff --git a/README.md b/README.md index aa8ef68..161052a 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,12 @@ mumble> / a b c mumble> VERBOSITY=0 mumble> VERBOSITY=1 mumble> VERBOSITY=2 +mumble> def { {plus} {(@ {x y} {+ x y})} } +( ) +mumble> plus +( @ { x y } { + x y } ) +mumble> eval {plus 1 2} +3.000000 ``` diff --git a/mumble b/mumble index 0313917..d50aabb 100755 Binary files a/mumble and b/mumble differ diff --git a/src/mumble.c b/src/mumble.c index cc40b17..29e90f5 100644 --- a/src/mumble.c +++ b/src/mumble.c @@ -226,17 +226,17 @@ void delete_lispval(lispval* v) if (VERBOSE) printfln("Freeing user-defined func"); if (v->env != NULL) { - destroy_lispenv(v->env); + // destroy_lispenv(v->env); free(v->env); v->env = NULL; } if (v->variables != NULL) { - delete_lispval(v->variables); + // delete_lispval(v->variables); free(v->variables); v->variables = NULL; } if (v->manipulation != NULL) { - delete_lispval(v->manipulation); + // delete_lispval(v->manipulation); free(v->manipulation); v->manipulation = NULL; } @@ -334,6 +334,8 @@ lispval* get_from_lispenv(char* sym, lispenv* env) if (env->parent != NULL) { return get_from_lispenv(sym, env->parent); } else { + if (VERBOSE) + printfln("Unbound symbol %s", sym); return lispval_err("Error: unbound symbol"); } // and this explains shadowing! @@ -460,6 +462,14 @@ lispval* read_lispval(mpc_ast_t* t) } // Print +void print_env(lispenv* env) +{ + printfln("Environment: "); + for (int i = 0; i < env->count; i++) { + printfln("Value for symbol %s: ", env->syms[i]); + print_lispval_tree(env->vals[i], 2); + } +} void print_lispval_tree(lispval* v, int indent_level) { char* indent = malloc(sizeof(char) * (indent_level + 1)); @@ -729,7 +739,7 @@ lispval* builtin_def(lispval* v, lispenv* env) LISPVAL_ASSERT(source->type == LISPVAL_QEXPR, "Error: Argument passed to def is not a q-expr, i.e., a bracketed list."); LISPVAL_ASSERT(source->count == 2, "Error: Argument passed to def should be a q expr with two q expressions as children: def { { a b } { 1 2 } } "); LISPVAL_ASSERT(source->cell[0]->type == LISPVAL_QEXPR, "Error: Argument passed to def should be a q expr with two q expressions as children: def { { a b } { 1 2 } } "); - LISPVAL_ASSERT(source->cell[1]->type == LISPVAL_QEXPR, "Error: Argument passed to def should be a q expr with two q expressions as children: def { { a b } { 1 2 } } "); + LISPVAL_ASSERT(source->cell[1]->type == LISPVAL_QEXPR || source->cell[1]->type == LISPVAL_SEXPR, "Error: Argument passed to def should be a q expr with two q expressions as children: def { { a b } { 1 2 } } "); LISPVAL_ASSERT(source->cell[0]->count == source->cell[1]->count, "Error: In function \"def\" both subarguments should have the same length"); lispval* symbols = source->cell[0]; @@ -930,7 +940,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"); + printfln("Checking if first element is a function"); if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_BUILTIN_FUNC)) { if (VERBOSE) @@ -943,8 +953,10 @@ lispval* evaluate_lispval(lispval* l, lispenv* env) // Ok, do this properly now. if (VERBOSE) printfln("Constructing function and operands"); + lispval* f = clone_lispval(l->cell[0]); lispval* operands = lispval_sexpr(); + for (int i = 1; i < l->count; i++) { lispval_append_child(operands, l->cell[i]); } @@ -966,22 +978,37 @@ lispval* evaluate_lispval(lispval* l, lispenv* env) } if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_USER_FUNC)) { - // Do something with user-defined functions here + if (VERBOSE) + printfln("Evaluating user-defined function"); + lispval* f = clone_lispval(l->cell[0]); + f->env->parent = env; - // check whether function takes as many arguments as given LISPVAL_ASSERT(f->variables->count == (l->count - 1), "Error: Incorrect number of variables given to user-defined function"); + if (VERBOSE) + printfln("Number of variables match"); - for (int i = 1; i < l->count; i++) { - // lispval_append_child(operands, l->cell[i]); - insert_in_current_lispenv( - f->variables->cell[i]->sym, l->cell[i], f->env); + if (VERBOSE) { + printfln("Function vars:"); + print_lispval_tree(f->variables, 2); + printfln("Function manipulation:"); + print_lispval_tree(f->manipulation, 2); } - lispval* answer = evaluate_lispval(f->manipulation, f->env); - destroy_lispenv(f->env); - return answer; - // return lispval_err("Error: User-defined functions not yet implemented"); + for (int i = 0; i < f->variables->count; i++) { + insert_in_current_lispenv(f->variables->cell[i]->sym, l->cell[i + 1], f->env); + } + if (VERBOSE) { + printfln("User defined function environment: "); + print_env(f->env); + } + lispval* temp = clone_lispval(f->manipulation); + temp->type = LISPVAL_SEXPR; + lispval* answer = evaluate_lispval(temp, f->env); + // lispval* answer = builtin_eval(f->manipulation, f->env); + // destroy_lispenv(f->env); + return answer; + return lispval_err("Error: User-defined functions not yet implemented"); } return l; @@ -1099,7 +1126,7 @@ int main(int argc, char** argv) } delete_lispval(answer); if (VERBOSE > 1) - printfln("variable \"answer\" after deletion: %p", answer); + printfln("variable \"answer\" after deletion: %p ", answer); // delete_lispval(answer); // do this twice, just to see. //if(VERBOSE) printfln("Deleting this lispval:"); // if(VERBOSE) print_lispval_tree(l,2);