From 4eeb67a2e39d3ee3124db3ec18215dacf1c9b8da Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Mon, 20 Mar 2017 12:32:52 +0100
Subject: [PATCH] Minor fixes of issues found when working on
 prophet/shiny/knitr packages

---
 .../oracle/truffle/r/nodes/builtin/base/AsCall.java |  4 ++++
 .../oracle/truffle/r/nodes/builtin/base/Call.java   | 11 +++++++++++
 .../oracle/truffle/r/nodes/builtin/base/Eval.java   |  5 +++++
 .../src/com/oracle/truffle/r/runtime/RType.java     |  3 ++-
 .../oracle/truffle/r/test/ExpectedTestOutput.test   | 13 +++++++++++++
 .../truffle/r/test/builtins/TestBuiltin_eval.java   |  8 +++++++-
 .../test/builtins/TestBuiltin_extract_replace.java  |  8 +++++++-
 documentation/dev/testing.md                        | 10 ++++++----
 8 files changed, 55 insertions(+), 7 deletions(-)

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 136f10c14c..c374db6cb7 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 ed84a24405..5f04839d3b 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 3367d84ad0..00e8d03e3f 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 9ee98c9d78..9487504ff9 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 5fc5fb2db8..6124052917 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
@@ -22281,6 +22281,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
@@ -22908,6 +22913,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 a87bc5a748..d1b9210eb8 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 f841282b01..3745256f04 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 0e6ed21eab..cb82ac7ec8 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. 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:
 
-- 
GitLab