예제 #1
0
 public Context beginFunction(
     Environment rho, FunctionCall call, Closure closure, PairList arguments) {
   Context context = new Context();
   context.type = Type.FUNCTION;
   context.parent = this;
   context.evaluationDepth = evaluationDepth + 1;
   context.closure = closure;
   context.environment = Environment.createChildEnvironment(closure.getEnclosingEnvironment());
   context.session = session;
   context.arguments = arguments;
   context.call = call;
   context.callingEnvironment = rho;
   return context;
 }
예제 #2
0
  public static SEXP R_execMethod(Context context, Closure op, Environment rho) {

    /* create a new environment frame enclosed by the lexical
    environment of the method */
    Environment newrho = Environment.createChildEnvironment(op.getEnclosingEnvironment());

    /* copy the bindings for the formal environment from the top frame
    of the internal environment of the generic call to the new
    frame.  need to make sure missingness information is preserved
    and the environments for any default expression promises are
    set to the new environment.  should move this to envir.c where
    it can be done more efficiently. */
    for (PairList.Node next : op.getFormals().nodes()) {
      // R_varloc_t loc;
      // int missing;
      // TODO(alex): redo missingness handling
      //      loc = R_findVarLocInFrame(rho,symbol);
      //      if(loc == NULL)
      //       throw new EvalException("could not find symbol \"%s\" in environment of the generic
      // function"),
      //            CHAR(PRINTNAME(symbol)));
      //      missing = R_GetVarLocMISSING(loc);
      //      val = R_GetVarLocValue(loc);

      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;
  }