Expr* EvalPair(Env* env, Expr* expr, Expr* cont){ expr = expr->u.list; // expr=expr->next; if(strcmp(expr->u.symbol, "+") == 0){ return EvalPlus(env, expr, cont); }else if(strcmp(expr->u.symbol, "-") == 0){ return EvalMinus(env, expr, cont); }else if(strcmp(expr->u.symbol, "*") == 0){ return EvalMul(env, expr, cont); }else if(strcmp(expr->u.symbol, "define") == 0){ return EvalDefine(env, expr, cont); }else if(strcmp(expr->u.symbol, "if") == 0){ return EvalIf(env, expr, cont); }else if(strcmp(expr->u.symbol, "lambda") == 0){ return EvalLambda(env, expr, cont); }else if(strcmp(expr->u.symbol, "halt") == 0){ // return expr; // return Halt expression. return Eval(env, GetSecond(expr), cont); }else if(strcmp(expr->u.symbol, "car") == 0){ return EvalCar(env, expr, cont); }else if(strcmp(expr->u.symbol, "cdr") == 0){ return EvalCdr(env, expr, cont); }else if(strcmp(expr->u.symbol, "null?") == 0){ return EvalNullp(env, expr, cont); }else if(strcmp(expr->u.symbol, "pair?") == 0){ return EvalPairp(env, expr, cont); }else if(strcmp(expr->u.symbol, "list")== 0){ // puts("to EvalList"); Expr* ret = EvalList(env, expr, cont); // puts("from EvalList"); return ret; }else if(strcmp(expr->u.symbol, "let") == 0){ puts("go let"); return EvalLet(env, expr, cont); }else if(strcmp(expr->u.symbol, "cons") == 0){ return EvalCons(env ,expr, cont); }else if(strcmp(expr->u.symbol, "append") == 0){ return EvalAppend(env, expr, cont); }else if(strcmp(expr->u.symbol, ">") == 0){ return EvalGT(env, expr, cont); }else{ // puts("Eval Function"); char* funcname = expr->u.symbol; // printf("funcname is %s\n", funcname); Expr* ret = EvalFunction(env, expr, cont); return ret; // printf("funcname %s end\n", funcname); } }
Term * InternalApply(List arguments, ContextBindings * contextBindings) { Term * function = Iterate(&arguments), * error = NULL; if (NULL == function) return InvalidArgumentCount(); function = EvalRecursive(function, contextBindings); switch(function->tag) { case terFunction: if (!EvalArguments(&arguments, contextBindings, &error)) return error; return function->function(arguments); case terLazyFunction: return function->lazy.function(arguments, contextBindings); case terLambda: if (!EvalArguments(&arguments, contextBindings, &error)) return error; return EvalLambda(function->lambda, arguments); default: return InvalidArgumentType(); } }