diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java index 136f10c14cb0c2c9cbacc7516c6438097cdaeb93..c374db6cb7c1214b58bd5a9a42375a049fb5798c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java @@ -68,6 +68,10 @@ public abstract class AsCall extends RBuiltinNode { return Call.makeCallSourceUnavailable(((RAbstractStringVector) x.getDataAt(0)).getDataAt(0), avn); } else if (x.getDataAt(0) instanceof RFunction) { return Call.makeCallSourceUnavailable((RFunction) x.getDataAt(0), avn); + } else if (x.getDataAt(0) instanceof Integer) { + return Call.makeCallSourceUnavailable((Integer) x.getDataAt(0), avn); + } else if (x.getDataAt(0) instanceof Double) { + return Call.makeCallSourceUnavailable((Double) x.getDataAt(0), avn); } else { throw RInternalError.unimplemented(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java index ed84a24405e3deb35548b798fb1de41f4fb6f895..5f04839d3bd6a5603375337f7470e202b9bc4baf 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; @@ -105,6 +106,16 @@ public abstract class Call extends RBuiltinNode { return "function".equals(name) ? makeFunction(args) : makeCall0(ReadVariableNode.createFunctionLookup(RSyntaxNode.LAZY_DEPARSE, name), true, args); } + @TruffleBoundary + protected static RLanguage makeCallSourceUnavailable(int i, RArgsValuesAndNames args) { + return makeCall0(ConstantNode.create(i), true, args); + } + + @TruffleBoundary + protected static RLanguage makeCallSourceUnavailable(double d, RArgsValuesAndNames args) { + return makeCall0(ConstantNode.create(d), true, args); + } + @TruffleBoundary protected static RLanguage makeCallSourceUnavailable(RFunction function, RArgsValuesAndNames args) { return makeCall0(function, true, args); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java index 3367d84ad0838348813259ff5493955ce0d695d6..00e8d03e3f6c55b1f7ef38d6f59ce8c5cd047f0a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java @@ -45,6 +45,7 @@ import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen; import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.ReturnException; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RExpression; @@ -146,6 +147,8 @@ public abstract class Eval extends RBuiltinNode { REnvironment environment = envCast.execute(frame, envir, enclos); try { return RContext.getEngine().eval(expr, environment, rCaller); + } catch (ReturnException ret) { + return ret.getResult(); } finally { visibility.executeAfterCall(frame, rCaller); } @@ -157,6 +160,8 @@ public abstract class Eval extends RBuiltinNode { REnvironment environment = envCast.execute(frame, envir, enclos); try { return RContext.getEngine().eval(expr, environment, rCaller); + } catch (ReturnException ret) { + return ret.getResult(); } finally { visibility.executeAfterCall(frame, rCaller); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java index 9ee98c9d78bcde430d2e58bc088703ab50ada1bf..9487504ff90534eeb7005d30869202eda2ba20f2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2012, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2013, 2016, Oracle and/or its affiliates + * Copyright (c) 2013, 2017, Oracle and/or its affiliates * * All rights reserved. */ @@ -98,6 +98,7 @@ public enum RType { case Character: case Raw: case List: + case Expression: return true; default: return false; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 83b6bca2e5c7aa57fa66cfb50c50c58da9eb08a6..42f1b991f130b5271c02823746fac4d5a060ed03 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -22293,6 +22293,11 @@ x #{ ne <- new.env(); evalq(x <- 1, ne); ls(ne) } [1] "x" +##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testReturnInEvalExpr# +#f1 <- function(x) { eval(quote(if(x>2){return()}else 1)); 10 };f1(5);f1(0) +[1] 10 +[1] 10 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testWithEnvirAndEnclose# #a <- 1; lang <- quote(list(a)); eval(lang, NULL, NULL) Error in eval(expr, envir, enclos) : object 'a' not found @@ -22920,6 +22925,14 @@ Levels: A B C D E #tmp <- c(1,8,NA,3); pivot <- c(1,2,4,3); tmp[pivot] <- tmp; tmp [1] 1 8 3 NA +##com.oracle.truffle.r.test.builtins.TestBuiltin_extract_replace.replaceExpressionInLanguage#Ignored.OutputFormatting# +#e1 <- expression(x^2); l1 <- quote(y^2); l1[1] <- e1; l1 +(x^2)(y, 2) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_extract_replace.replaceExpressionInLanguage# +#e1 <- expression(x^2); l1 <- quote(y^2); l1[1] <- e1; l1[[1]]==e1[[1]] +[1] TRUE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_extract_replace.replaceInLanguagePreservesAttributes# #f <- quote(a+b); attr(f, 'mya') <- 42; f[[2]] <- quote(q); f q + b diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java index a87bc5a7482c9ab5cd1b0bae20b0a1edc405465a..d1b9210eb8a4806f224ceb5c0a09bc3912f25a14 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2016, Oracle and/or its affiliates + * Copyright (c) 2013, 2017, Oracle and/or its affiliates * * All rights reserved. */ @@ -60,4 +60,10 @@ public class TestBuiltin_eval extends TestBase { assertEval("a <- 1; lang <- quote(list(a)); eval(lang, new.env(), new.env())"); assertEval(Output.IgnoreErrorMessage, "y <- 2; x <- 2 ; eval(quote(x+y), c(-1, -2))"); } + + @Test + public void testReturnInEvalExpr() { + assertEval("f1 <- function(x) { eval(quote(if(x>2){return()}else 1)); 10 };f1(5);f1(0)"); + } + } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java index f841282b012391086fc26223296274ea5b1128be..3745256f0428282c4d0cd11142617b333cfdd409 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,4 +42,10 @@ public class TestBuiltin_extract_replace extends TestBase { public void replaceInLanguagePreservesAttributes() { assertEval("f <- quote(a+b); attr(f, 'mya') <- 42; f[[2]] <- quote(q); f"); } + + @Test + public void replaceExpressionInLanguage() { + assertEval("e1 <- expression(x^2); l1 <- quote(y^2); l1[1] <- e1; l1[[1]]==e1[[1]]"); + assertEval(Ignored.OutputFormatting, "e1 <- expression(x^2); l1 <- quote(y^2); l1[1] <- e1; l1"); + } } diff --git a/documentation/dev/testing.md b/documentation/dev/testing.md index d01e8d5dcdb38945f2cfbe5855cc809e4738533e..9d7e514bda36279d8287feec74a4611809412ee7 100644 --- a/documentation/dev/testing.md +++ b/documentation/dev/testing.md @@ -54,7 +54,7 @@ Package developers can provide tests in several ways. To enable the full set of ### Package Installation and Testing -Package installation and testing is partly handled by a R script `install.packages.R` in the `com.oracle.truffle.r.test.packages` project and partly by an `mx` script. There are two relevant `mx` commands, `installpkgs` and `pkgtest`. The former is simply a wrapper to `install.packages.R`, whereas `pkgtest` contains additional code to gather and compare test outputs. +Package installation and testing is partly handled by a R script `r/install.packages.R` in the `com.oracle.truffle.r.test.packages` project and partly by an `mx` script. There are two relevant `mx` commands, `installpkgs` and `pkgtest`. The former is simply a wrapper to `install.packages.R`, whereas `pkgtest` contains additional code to gather and compare test outputs. #### The install.packages.R script @@ -93,9 +93,11 @@ Key concepts are discussed below. ##### Package Blacklist -There are many packages that cannot be installed due to either missing functionality or fundamental limitations in FastR and this set is seeded from a a DCF file, `initial.package.blacklist`, in the `com.oracle.truffle.r.test.packages` project. `install.packages` operates in two modes, either creating a complete blacklist from an initial blacklist or reading a previously created blacklist file. In the latter case, if the blacklist file does not exist, it will be created. The complete blacklist file can specified in three ways: +There are many packages that cannot be installed due to either missing functionality or fundamental limitations in FastR and this set is seeded from a a DCF file, `initial.package.blacklist`, in the `com.oracle.truffle.r.test.packages` project. `install.packages` operates in two modes, either creating a complete blacklist from an initial blacklist or reading a previously created blacklist file. In the latter case, if the blacklist file does not exist, it will be created. The complete blacklist file can be specified in three ways: 1. using the command line argument `--blacklist-file`; if omitted defaults to the file `package.blacklist` +2. TODO +3. TODO ##### CRAN Mirror Packages are downloaded and installed from the repos given by the `repos` argument, a comma-separated list, that defaults to `CRAN`. CRAN packages are downloaded from a CRAN mirror. When the standard `utils::install_packages` function is run interactively, the user is prompted for a mirror. To avoid such interaction, `install.packages` has two ways for specifying a mirror. The default CRAN mirror is `http://cran.cnr.berkeley.edu/` but this can be changed either with the command line argument `--cran-mirror` or the environment variable `CRAN_MIRROR`. The `FASTR` repo is internal to the source base and contains FastR-specific test packages. The BioConductor repo can be added by setting `--repos BIOC`. It also implies `CRAN`. @@ -106,9 +108,9 @@ The directory in which to install the package can be specified either by setting ##### Specifying packages to Install If the `--pkg-filelist` argument is provided then the associated file should contain a list of packages to install, one per line. Otherwise if a package pattern argument is given, then all packages matching the (R) regular expression are candidates for installation, otherwise all available packages are candidates, computed by invoking the `available.packages()` function. The candidate set can be adjusted with additional options. The `--use-installed-pkgs` option will cause `install.packages` to analyze the package installation directory for existing successfully installed packages and remove those from the candidate set for installation. This option is implied by `--no-install`. Some convenience options implicitly set `--pkg-filelist`, namely: - --ok-only: sets it to the file `com.oracle.truffle.r.test.packages.ok.packages`. This file is a list of packages that are known to install. + --ok-only: sets it to the file `com.oracle.truffle.r.test.packages/ok.packages`. This file is a list of packages that are known to install. -N.B. The is file is updated only occasionally. Regressions, bug fixes, can render it inaccurate. +N.B. This file is updated only occasionally. Regressions, bug fixes, can render it inaccurate. Two options are designed to be used for a daily package testing run. These are based on the day of the year and install/test a rolling set of packages: