@Override public SEXP apply(Context context, Environment rho, FunctionCall call, PairList args) { PairList matchedArguments = ClosureDispatcher.matchArguments(formals, args); SEXP exprArgument = matchedArguments.findByTag(EXPR_ARGUMENT); SEXP envArgument = matchedArguments.findByTag(ENV_ARGUMENT); // Substitute handles ... in an idiosyncratic way: // Only the first argument is used, and there is no attempt to // match subsequent arguments against the 'env' argument. SEXP expr; if (exprArgument == Symbols.ELLIPSES) { SEXP ellipses = rho.getVariable(Symbols.ELLIPSES); if (ellipses == Null.INSTANCE) { expr = Null.INSTANCE; } else { PromisePairList.Node promisePairList = (PromisePairList.Node) ellipses; Promise promisedArg = (Promise) promisePairList.getValue(); expr = promisedArg.getExpression(); } } else { expr = exprArgument; } return substitute(expr, buildContext(context, rho, envArgument)); }
@Override public SEXP getVariable(Symbol name) { return rho.getVariable(name); }