src/lib/env.c
sexp* r_env_as_list_compat(sexp* env, sexp* out) {
  sexp* nms = KEEP(r_env_names(env));
  sexp* types = KEEP(r_env_binding_types(env, nms));

  if (types == R_NilValue) {
    FREE(2);
    return out;
  }

  r_ssize n = r_length(nms);
  sexp* const * p_nms = r_chr_deref_const(nms);
  const int* p_types = r_int_deref_const(types);

  for (r_ssize i = 0; i < n; ++i) {
    enum r_env_binding_type type = p_types[i];
    if (type == R_ENV_BINDING_ACTIVE) {
      r_ssize fn_idx = r_chr_detect_index(nms, r_str_deref(p_nms[i]));
      if (fn_idx < 0) {
        r_abort("Internal error: Can't find active binding in list");
      }

      sexp* fn = r_list_get(out, fn_idx);
      sexp* value = r_eval(KEEP(r_call(fn)), r_empty_env);
      r_list_poke(out, fn_idx, value);
      FREE(1);
    }
  }

  FREE(2);
  return out;
}
// On R < 4.0, the active binding function is returned instead of
// its value. We invoke the active bindings here to get consistent
// behaviour in all supported R versions.
On R < 4.0, the active binding function is returned instead of
its value. We invoke the active bindings here to get consistent
behaviour in all supported R versions.
On R < 4 . 0 the active binding function is returned instead of its value . We invoke the active bindings here to get consistent behaviour in all supported R versions .
sexp* r_env_as_list_compat(sexp* env, sexp* out) {
  sexp* nms = KEEP(r_env_names(env));
  sexp* types = KEEP(r_env_binding_types(env, nms));
  if (types == R_NilValue) {
    FREE(2);
    return out;
  }
  r_ssize n = r_length(nms);
  sexp* const * p_nms = r_chr_deref_const(nms);
  const int* p_types = r_int_deref_const(types);
  for (r_ssize i = 0; i < n; ++i) {
    enum r_env_binding_type type = p_types[i];
    if (type == R_ENV_BINDING_ACTIVE) {
      r_ssize fn_idx = r_chr_detect_index(nms, r_str_deref(p_nms[i]));
      if (fn_idx < 0) {
        r_abort("Internal error: Can't find active binding in list");
      }
      sexp* fn = r_list_get(out, fn_idx);
      sexp* value = r_eval(KEEP(r_call(fn)), r_empty_env);
      r_list_poke(out, fn_idx, value);
      FREE(1);
    }
  }
  FREE(2);
  return out;
}
sexp * r_env_as_list_compat ( sexp * env , sexp * out ) { sexp * nms = KEEP ( r_env_names ( env ) ) ; sexp * types = KEEP ( r_env_binding_types ( env , nms ) ) ; if ( types == R_NilValue ) { FREE ( 2 ) ; return out ; } r_ssize n = r_length ( nms ) ; sexp * const * p_nms = r_chr_deref_const ( nms ) ; const int * p_types = r_int_deref_const ( types ) ; for ( r_ssize i = 0 ; i < n ; ++ i ) { enum r_env_binding_type type = p_types [ i ] ; if ( type == R_ENV_BINDING_ACTIVE ) { r_ssize fn_idx = r_chr_detect_index ( nms , r_str_deref ( p_nms [ i ] ) ) ; if ( fn_idx < 0 ) { r_abort ( " " ) ; } sexp * fn = r_list_get ( out , fn_idx ) ; sexp * value = r_eval ( KEEP ( r_call ( fn ) ) , r_empty_env ) ; r_list_poke ( out , fn_idx , value ) ; FREE ( 1 ) ; } } FREE ( 2 ) ; return out ; }
On R < 4.0, the active binding function is returned instead of
its value.
On R < 4 . 0 the active binding function is returned instead of its value .