if(!next.hasTag()) {
throw new EvalException("closure formal has no tag! op = " + op);
}
Symbol symbol = next.getTag();
SEXP val = rho.findVariable(symbol);
if(val == Symbol.UNBOUND_VALUE) {
throw new EvalException("could not find symbol \"%s\" in the environment of the generic function", symbol.getPrintName());
}
// SET_FRAME(newrho, CONS(val, FRAME(newrho)));
// SET_TAG(FRAME(newrho), symbol);
newrho.setVariable(symbol, val);
// if (missing) {
// SET_MISSING(FRAME(newrho), missing);
// if (TYPEOF(val) == PROMSXP && PRENV(val) == rho) {
// SEXP deflt;
// SET_PRENV(val, newrho);
// /* find the symbol in the method, copy its expression
// * to the promise */
// for(deflt = CAR(op); deflt != R_NilValue; deflt = CDR(deflt)) {
// if(TAG(deflt) == symbol)
// break;
// }
// if(deflt == R_NilValue)
// error(_("symbol \"%s\" not in environment of method"),
// CHAR(PRINTNAME(symbol)));
// SET_PRCODE(val, CAR(deflt));
// }
// }
}
/* copy the bindings of the spacial dispatch variables in the top
frame of the generic call to the new frame */
newrho.setVariable(DOT_DEFINED, rho.getVariable(DOT_DEFINED));
newrho.setVariable(DOT_METHOD, rho.getVariable(DOT_METHOD));
newrho.setVariable(DOT_TARGET, rho.getVariable(DOT_TARGET));
/* copy the bindings for .Generic and .Methods. We know (I think)
that they are in the second frame, so we could use that. */
newrho.setVariable(Symbols.GENERIC, newrho.getVariable(".Generic"));
newrho.setVariable(DOT_METHODS, newrho.getVariable(DOT_METHODS));
/* Find the calling context. Should be R_GlobalContext unless
profiling has inserted a CTXT_BUILTIN frame. */
Context cptr = context;
// cptr = R_GlobalContext;
// if (cptr->callflag & CTXT_BUILTIN)
// cptr = cptr->nextcontext;
/* The calling environment should either be the environment of the
generic, rho, or the environment of the caller of the generic,
the current sysparent. */
Environment callerenv = cptr.getCallingEnvironment(); /* or rho? */
/* get the rest of the stuff we need from the current context,
execute the method, and return the result */
FunctionCall call = cptr.getCall();
PairList arglist = cptr.getArguments();
SEXP val = R_execClosure(context, call, op, arglist, callerenv, newrho);
return val;
}