// 调用函数 MLval* MLval_call(MLenv* e, MLval* f, MLval* a) { // 内建函数直接调用 if (f->builtin) { return f->builtin(e, a); } // 记录参数数量 int given = a->count; int total = f->formals->count;
// 当有参数还需要处理时 while (a->count) { // 参数传递过多 if (f->formals->count == 0) { MLval_del(a); return MLval_err("Function passed too many arguments. " "Got %i, Expected %i.", given, total); } // 取出形参的第一个符号 MLval* sym = MLval_pop(f->formals, 0); // '&'特殊处理 if (strcmp(sym->sym, "&") == 0) { // 确保'&'后跟有其他符号 if (f->formals->count != 1) { MLval_del(a); return MLval_err("Function format invalid. " "Symbol '&' not followed by single symbol."); } // 下一个参数绑定到剩余的形参 MLval* nsym = MLval_pop(f->formals, 0); MLenv_put(f->env, nsym, builtin_list(e, a)); MLval_del(sym); MLval_del(nsym); break; } // 取出列表的下一个参数 MLval* val = MLval_pop(a, 0); // 绑定一份拷贝到函数的环境中 MLenv_put(f->env, sym, val); MLval_del(sym); MLval_del(val); } // 删除已经被绑定的参数列表 MLval_del(a);
// 如果形参列表中含有'&',将其绑定到空列表 if (f->formals->count > 0 && strcmp(f->formals->cell[0]->sym, "&") == 0) { // 检查并确保'&'没有背无效传递 if (f->formals->count != 2) { return MLval_err("Function format invalid. " "Symbol '&' not followed by single symbol."); } // 取出并删除'&'符号 MLval_del(MLval_pop(f->formals, 0)); // 取出下一个符号并绑定到空列表 MLval* sym = MLval_pop(f->formals, 0); MLval* val = MLval_qexpr(); // 绑定到环境中 MLenv_put(f->env, sym, val); MLval_del(sym); MLval_del(val); } // 如果所有的参数都被绑定,则开始计算 if (f->formals->count == 0) { // 将父环境设置为计算环境 f->env->par = e; // 计算并返回 return builtin_eval(f->env, MLval_add(MLval_sexpr(), MLval_copy(f->body))); } else { // 否则返回函数的拷贝 return MLval_copy(f); } }