SEXP RPIServiceImpl::dereference()

in src/RRefs.cpp [28:82]


SEXP RPIServiceImpl::dereference(RRef const& ref) {
  switch (ref.ref_case()) {
    case RRef::kPersistentIndex: {
      int i = ref.persistentindex();
      return persistentRefStorage.has(i) ? (SEXP)persistentRefStorage[i] : R_NilValue;
    }
    case RRef::kGlobalEnv:
      return R_GlobalEnv;
    case RRef::kCurrentEnv:
      return currentEnvironment();
    case RRef::kSysFrameIndex: {
      int index = ref.sysframeindex();
      auto const& stack = rDebugger.getSavedStack();
      if (index < 0 || index >= stack.size()) return R_NilValue;
      return stack[index].environment;
    }
    case RRef::kErrorStackSysFrameIndex: {
      int index = ref.errorstacksysframeindex();
      if (index < 0 || index >= lastErrorStack.size()) return R_NilValue;
      return lastErrorStack[index].environment;
    }
    case RRef::kMember: {
      ShieldSEXP env = dereference(ref.member().env());
      return env.getVar(ref.member().name());
    }
    case RRef::kParentEnv: {
      PrSEXP env = dereference(ref.parentenv().env());
      int count = ref.parentenv().index();
      for (int i = 0; i < count; ++i) {
        if (env.type() != ENVSXP || env == R_EmptyEnv) {
          return R_NilValue;
        }
        env = env.parentEnv();
      }
      return env;
    }
    case RRef::kExpression: {
      ShieldSEXP env = dereference(ref.expression().env());
      std::string code = ref.expression().code();
      return RI->eval(parseCode(code), named("envir", env));
    }
    case RRef::kListElement: {
      ShieldSEXP list = dereference(ref.listelement().list());
      long long index = ref.listelement().index();
      ShieldSEXP unclassed = Rf_inherits(list, "factor") ? (SEXP)list : RI->unclass(list);
      return RI->doubleSubscript(unclassed, index + 1);
    }
    case RRef::kAttributes: {
      ShieldSEXP x = dereference(ref.attributes());
      return RI->attributes(Rf_lang2(RI->quote, x));
    }
    default:
      return R_NilValue;
  }
}