Permalink
Browse files

Changes to substitute and findVar:

In C, substitute( , R_NilValue) does no substs, just
getting PREXPRs, while substitute( , R_GlobalEnv) does
substitutions.

In R, no change:  substitute( , .GlobalEnv) is just like
R_NilValue above.  

git-svn-id: https://svn.r-project.org/R/branches/djm-findvar@37268 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information...
1 parent 8f64ecc commit 7b0cff40ca7b6b1b29cf3b7fcd295c697ce8d58c murdoch committed Feb 5, 2006
Showing with 44 additions and 18 deletions.
  1. +6 −0 NEWS
  2. +25 −18 src/main/coerce.c
  3. +13 −0 src/main/envir.c
View
6 NEWS
@@ -729,6 +729,12 @@ BUG FIXES
o rbind.data.frame() gave a corrupt data frame if one of the
named arguments was a zero-row data frame. (PR#8506)
+
+ o Checks for NULL in the rho argument of the C-level findVar
+ function have been added.
+
+ o The C-level substitute function was handling NULL in its rho
+ argument incorrectly.
o The code for pgamma() introduced in 2.1.0 failed for large
values of 'shape' where the previous code was perfectly
View
@@ -1965,7 +1965,10 @@ SEXP attribute_hidden do_docall(SEXP call, SEXP op, SEXP args, SEXP rho)
/* values as found in the environment. There is no inheritance so only */
/* the supplied environment is searched. If no environment is specified */
/* the environment in which substitute was called is used. If the */
-/* specified environment is R_NilValue then R_GlobalEnv is used. */
+/* specified environment is R_GlobalEnv it is converted to R_NilValue, for */
+/* historical reasons. */
+/* In substitute(), R_NilValue signals that no substitution should be done, only */
+/* extraction of promise expressions. */
/* Arguments to do_substitute should not be evaluated. */
SEXP substitute(SEXP lang, SEXP rho)
@@ -1975,20 +1978,22 @@ SEXP substitute(SEXP lang, SEXP rho)
case PROMSXP:
return substitute(PREXPR(lang), rho);
case SYMSXP:
- t = findVarInFrame3( rho, lang, TRUE);
- if (t != R_UnboundValue) {
- if (TYPEOF(t) == PROMSXP) {
- do {
- t = PREXPR(t);
- }
- while(TYPEOF(t) == PROMSXP);
- return t;
- }
- else if (TYPEOF(t) == DOTSXP) {
- error(_("... used in an incorrect context"));
- }
- if (rho != R_GlobalEnv)
- return t;
+ if (rho != R_NilValue) {
+ t = findVarInFrame3( rho, lang, TRUE);
+ if (t != R_UnboundValue) {
+ if (TYPEOF(t) == PROMSXP) {
+ do {
+ t = PREXPR(t);
+ }
+ while(TYPEOF(t) == PROMSXP);
+ return t;
+ }
+ else if (TYPEOF(t) == DOTSXP) {
+ error(_("... used in an incorrect context"));
+ }
+ if (rho != R_GlobalEnv)
+ return t;
+ }
}
return (lang);
case LANGSXP:
@@ -2008,6 +2013,8 @@ SEXP attribute_hidden substituteList(SEXP el, SEXP rho)
if (isNull(el))
return el;
if (CAR(el) == R_DotsSymbol) {
+ if (rho == R_NilValue)
+ return substituteList(CDR(el), rho);
h = findVarInFrame3(rho, CAR(el), TRUE);
if (h == R_NilValue)
return substituteList(CDR(el), rho);
@@ -2047,13 +2054,13 @@ SEXP attribute_hidden do_substitute(SEXP call, SEXP op, SEXP args, SEXP rho)
env = rho;
else
env = eval(CADR(args), rho);
- if (env == R_NilValue)
- env = R_GlobalEnv;
+ if (env == R_GlobalEnv) /* For historical reasons, don't substitute in R_GlobalEnv */
+ env = R_NilValue;
else if (TYPEOF(env) == VECSXP)
env = NewEnvironment(R_NilValue, VectorToPairList(env), R_BaseEnv);
else if (TYPEOF(env) == LISTSXP)
env = NewEnvironment(R_NilValue, duplicate(env), R_BaseEnv);
- if (TYPEOF(env) != ENVSXP)
+ else if (TYPEOF(env) != ENVSXP)
errorcall(call, _("invalid environment specified"));
PROTECT(env);
View
@@ -865,6 +865,11 @@ SEXP findVarInFrame3(SEXP rho, SEXP symbol, Rboolean doGet)
{
int hashcode;
SEXP frame, c;
+
+ if (TYPEOF(rho) == NILSXP) {
+ warning(_("use of NULL environment is deprecated"));
+ rho = R_BaseEnv;
+ }
if (rho == R_BaseNamespace || rho == R_BaseEnv)
return SYMBOL_BINDING_VALUE(symbol);
@@ -959,6 +964,14 @@ static SEXP findGlobalVar(SEXP symbol)
SEXP findVar(SEXP symbol, SEXP rho)
{
SEXP vl;
+
+ if (TYPEOF(rho) == NILSXP) {
+ warning(_("use of NULL environment is deprecated"));
+ rho = R_BaseEnv;
+ }
+
+ if (!isEnvironment(rho)) error(_("argument to %s is not an environment"), "findVar");
+
#ifdef USE_GLOBAL_CACHE
/* This first loop handles local frames, if there are any. It
will also handle all frames if rho is a global frame other than

0 comments on commit 7b0cff4

Please sign in to comment.