From 0ceea53538d8d230f782d95b277e04334fdf6746 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Tue, 10 Oct 2017 16:42:39 +0200
Subject: [PATCH] some more work on formatting

---
 .../r/nodes/builtin/base/Expression.java      |  3 +-
 .../base/printer/DoubleVectorPrinter.java     | 95 ++++++++++---------
 .../com/oracle/truffle/r/test/S4/TestS4.java  |  4 +-
 .../r/test/builtins/TestBuiltin_La.java       |  8 +-
 .../r/test/builtins/TestBuiltin_asmatrix.java |  4 +-
 .../r/test/builtins/TestBuiltin_dqr.java      |  2 +-
 .../r/test/builtins/TestBuiltin_format.java   | 32 ++++---
 .../r/test/builtins/TestBuiltin_summary.java  |  5 +
 8 files changed, 87 insertions(+), 66 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
index 6e245e1ed7..231aa74701 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
@@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -49,7 +50,7 @@ public abstract class Expression extends RBuiltinNode.Arg1 {
     }
 
     @Specialization
-    @ExplodeLoop
+    @TruffleBoundary
     protected Object doExpression(RArgsValuesAndNames args) {
         Object[] argValues = args.getArguments();
         Object[] data = new Object[argValues.length];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java
index 1a1e8590b4..b86ea1637e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/DoubleVectorPrinter.java
@@ -383,11 +383,11 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
 
     private static final int DECIMAL_SHIFT = 350;
     private static final double[][] DECIMAL_VALUES = new double[700][10];
+    private static final double[] DECIMAL_WEIGHTS = new double[700];
     /**
      * This array contains the halves minus the unit of least precision, e.g. 0.499999...
      */
     private static final double[] HALVES_MINUS_ULP = new double[700];
-    private static final double[] DECIMAL_WEIGHTS = new double[700];
 
     static {
         for (int i = 0; i < DECIMAL_WEIGHTS.length; i++) {
@@ -395,9 +395,9 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
         }
         for (int i = 0; i < DECIMAL_VALUES.length; i++) {
             for (int i2 = 0; i2 < 10; i2++) {
-                DECIMAL_VALUES[i][i2] = Math.pow(10, i - DECIMAL_SHIFT) * i2;
+                DECIMAL_VALUES[i][i2] = i2 / Math.pow(10, DECIMAL_SHIFT - i);
             }
-            HALVES_MINUS_ULP[i] = Double.longBitsToDouble(Double.doubleToLongBits(DECIMAL_VALUES[i][5]) - 1);
+            HALVES_MINUS_ULP[i] = Math.nextDown(DECIMAL_VALUES[i][5]);
         }
     }
 
@@ -458,18 +458,8 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
                 for (int i = 0; i < blanks; i++) {
                     str.append(' ');
                 }
-
-                double pow10 = DECIMAL_WEIGHTS[-log10 + d + DECIMAL_SHIFT];
-                long mantissa = (long) (x * pow10);
                 // round towards next digit instead of truncating
-                double rounded;
-                if ((mantissa & 1L) == 0) {
-                    // even
-                    rounded = x + HALVES_MINUS_ULP[log10 - d - 1 + DECIMAL_SHIFT];
-                } else {
-                    rounded = x + DECIMAL_VALUES[log10 - d - 1 + DECIMAL_SHIFT][5];
-                }
-
+                double rounded = x + DECIMAL_VALUES[log10 - d - 1 + DECIMAL_SHIFT][5];
                 if (Double.isFinite(rounded)) {
                     x = rounded;
                     // the rounding might have modified the exponent
@@ -504,36 +494,55 @@ public final class DoubleVectorPrinter extends VectorPrinter<RAbstractDoubleVect
                 str.append((char) ('0' + (log10 / 10)));
                 str.append((char) ('0' + (log10 % 10)));
             } else { /* e == 0 */
-                double pow10 = DECIMAL_WEIGHTS[d + DECIMAL_SHIFT];
-                long mantissa = (long) (x * pow10);
-                // round towards next digit instead of truncating
-                if ((mantissa & 1L) == 0) {
-                    // even
-                    x += HALVES_MINUS_ULP[-d - 1 + DECIMAL_SHIFT];
-                } else {
-                    x += DECIMAL_VALUES[-d - 1 + DECIMAL_SHIFT][5];
-                }
-
-                int log10 = x == 0 ? 0 : Math.max((int) Math.log10(x), 0);
-                int blanks = w // target width
-                                - (negated ? 1 : 0) // "-"
-                                - (log10 + 1) // digits before "."
-                                - (d > 0 ? 1 : 0) // "."
-                                - d; // digits after "."
+                boolean finalRun = ((int) x) == x; // within int range is always exact
+                double startingX = x;
+                double halfOfLastDigit = DECIMAL_VALUES[-d - 1 + DECIMAL_SHIFT][5];
+                while (true) {
+                    if (!finalRun) {
+                        double pow10 = x * DECIMAL_WEIGHTS[d + DECIMAL_SHIFT];
+                        double mantissa = Math.floor(pow10);
+                        double rest = pow10 - mantissa;
+
+                        if (rest < 0.49 || rest > 0.99) {
+                            // get the value away from the boundaries
+                            x += halfOfLastDigit;
+                            finalRun = true;
+                        }
+                    }
+                    int log10 = x == 0 ? 0 : Math.max((int) Math.log10(x), 0);
+                    int blanks = w // target width
+                                    - (negated ? 1 : 0) // "-"
+                                    - (log10 + 1) // digits before "."
+                                    - (d > 0 ? 1 : 0) // "."
+                                    - d; // digits after "."
+
+                    for (int i = 0; i < blanks; i++) {
+                        str.append(' ');
+                    }
+                    if (negated) {
+                        str.append('-');
+                    }
+                    for (int i = log10; i >= 0; i--) {
+                        x = appendDigit(x, i, str);
+                    }
+                    if (d > 0) {
+                        str.append(cdec);
+                        for (int i = 1; i <= d; i++) {
+                            x = appendDigit(x, -i, str);
+                        }
+                    }
+                    if (finalRun) {
+                        break;
+                    }
 
-                for (int i = 0; i < blanks; i++) {
-                    str.append(' ');
-                }
-                if (negated) {
-                    str.append('-');
-                }
-                for (int i = log10; i >= 0; i--) {
-                    x = appendDigit(x, i, str);
-                }
-                if (d > 0) {
-                    str.append(cdec);
-                    for (int i = 1; i <= d; i++) {
-                        x = appendDigit(x, -i, str);
+                    boolean even = ((str.charAt(str.length() - 1) - '0') & 1) == 0;
+                    if (even ? x > halfOfLastDigit : x >= halfOfLastDigit) {
+                        // the leftover is large enough to increment from rounding, so re-run
+                        x = startingX + DECIMAL_VALUES[-d + DECIMAL_SHIFT][1];
+                        finalRun = true;
+                        str.setLength(0);
+                    } else {
+                        break;
                     }
                 }
             }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
index 0d85c13983..e054c71b60 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
@@ -51,8 +51,8 @@ public class TestS4 extends TestRBase {
         assertEval("{ x<-42; slot(x, \".Data\") }");
 
         // disabled because of side effects causing other tests to fail
-        assertEval(Ignored.ImplementationError, "{ setClass(\"foo\", contains=\"numeric\"); x<-new(\"foo\"); res<-x@.Data; removeClass(\"foo\"); res }");
-        assertEval(Ignored.ImplementationError, "{ setClass(\"foo\", contains=\"numeric\"); x<-new(\"foo\"); res<-slot(x, \".Data\"); removeClass(\"foo\"); res }");
+        assertEval(Ignored.SideEffects, "{ setClass(\"foo\", contains=\"numeric\"); x<-new(\"foo\"); res<-x@.Data; removeClass(\"foo\"); res }");
+        assertEval(Ignored.SideEffects, "{ setClass(\"foo\", contains=\"numeric\"); x<-new(\"foo\"); res<-slot(x, \".Data\"); removeClass(\"foo\"); res }");
 
         assertEval(Output.IgnoreErrorContext, "{ getClass(\"ClassUnionRepresentation\")@foo }");
         assertEval(Output.IgnoreErrorContext, "{ c(42)@foo }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_La.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_La.java
index bedd0f6b53..4c37f829ff 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_La.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_La.java
@@ -42,9 +42,7 @@ public class TestBuiltin_La extends TestBase {
 
     @Test
     public void testLa4() {
-        // FIXME RInternalError: not implemented: .Internal La_svd
-        assertEval(Ignored.Unimplemented,
-                        "argv <- list('S', structure(c(1, 0, 0, 0, 0, 1.4142135623731, 0, 0, 0, 0, 1.73205080756888, 0, 0, 0, 0, 2), .Dim = c(4L, 4L), Dimnames = list(character(0), character(0))), c(2, 1.73205080756888, 1.4142135623731, 1), structure(c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0), .Dim = c(4L, 4L)), structure(c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0), .Dim = c(4L, 4L))); .Internal(La_svd(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
+        assertEval("argv <- list('S', structure(c(1, 0, 0, 0, 0, 1.4142135623731, 0, 0, 0, 0, 1.73205080756888, 0, 0, 0, 0, 2), .Dim = c(4L, 4L), Dimnames = list(character(0), character(0))), c(2, 1.73205080756888, 1.4142135623731, 1), structure(c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0), .Dim = c(4L, 4L)), structure(c(0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0), .Dim = c(4L, 4L))); .Internal(La_svd(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
     }
 
     @Test
@@ -67,9 +65,7 @@ public class TestBuiltin_La extends TestBase {
 
     @Test
     public void testLa8() {
-        // FIXME RInternalError: not implemented: .Internal La_svd
-        assertEval(Ignored.Unimplemented,
-                        "argv <- list('N', structure(c(-4, 0, 0, 0, 0, 0, 0, -406.725, 41.7955066364795, 0, 0, 0, 0, 0, -1550.79375, 381.717151319926, 49.8228991342168, 0, 0, 0, 0, -1277.325, 224.617432123818, -31.1858918860748, -282.060212912726, 0, 0, 0, -1042.675, 125.261805546114, -29.9849484767744, 164.425554254677, -170.353263600129, 0, 0, -469.696, 26.3795103523805, 4.19691803785862, -3.18974110831568, 0.0462484557378925, 1.46320172717486, 0, -7818, 18.2758880432689, 1.77525956575195, -1.45298766739792, -0.449176219307484, -0.281900648530911, -0.669305080560524), .Dim = c(7L, 7L), .Dimnames = list(c('1947', '1948', '1949', '1950', '1951', '1952', '1953'), c('(Intercept)', 'GNP.deflator', 'GNP', 'Unemployed', 'Armed.Forces', 'Population', 'Year'))), c(8164.12940108939, 457.24498274114, 324.584423503013, 134.312174464868, 4.95553195929945, 1.41954832076337, 0.000342370904183799), structure(0, .Dim = c(1L, 1L)), structure(0, .Dim = c(1L, 1L))); .Internal(La_svd(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
+        assertEval("argv <- list('N', structure(c(-4, 0, 0, 0, 0, 0, 0, -406.725, 41.7955066364795, 0, 0, 0, 0, 0, -1550.79375, 381.717151319926, 49.8228991342168, 0, 0, 0, 0, -1277.325, 224.617432123818, -31.1858918860748, -282.060212912726, 0, 0, 0, -1042.675, 125.261805546114, -29.9849484767744, 164.425554254677, -170.353263600129, 0, 0, -469.696, 26.3795103523805, 4.19691803785862, -3.18974110831568, 0.0462484557378925, 1.46320172717486, 0, -7818, 18.2758880432689, 1.77525956575195, -1.45298766739792, -0.449176219307484, -0.281900648530911, -0.669305080560524), .Dim = c(7L, 7L), .Dimnames = list(c('1947', '1948', '1949', '1950', '1951', '1952', '1953'), c('(Intercept)', 'GNP.deflator', 'GNP', 'Unemployed', 'Armed.Forces', 'Population', 'Year'))), c(8164.12940108939, 457.24498274114, 324.584423503013, 134.312174464868, 4.95553195929945, 1.41954832076337, 0.000342370904183799), structure(0, .Dim = c(1L, 1L)), structure(0, .Dim = c(1L, 1L))); .Internal(La_svd(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asmatrix.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asmatrix.java
index c309948ee3..c5201e71ff 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asmatrix.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asmatrix.java
@@ -60,8 +60,8 @@ public class TestBuiltin_asmatrix extends TestBase {
         assertEval("{ matrix(c(1+1i,2+2i,3+3i,4+4i),2) }");
         assertEval("{ matrix(nrow=2,ncol=2) }");
         assertEval("{ matrix(1:4,2,2) }");
-        assertEval(Ignored.ReferenceError, "{ matrix(1i,10,10) }");
-        assertEval(Ignored.ReferenceError, "{ matrix(c(1i,NA),10,10) }");
+        assertEval("{ matrix(1i,10,10) }");
+        assertEval("{ matrix(c(1i,NA),10,10) }");
         assertEval("{ matrix(c(10+10i,5+5i,6+6i,20-20i),2) }");
         assertEval("{ matrix(c(1i,100i),10,10) }");
         assertEval("{ matrix(1:6, nrow=3,byrow=TRUE)}");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dqr.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dqr.java
index 20fbc5bba7..6d8d3d0603 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dqr.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dqr.java
@@ -36,7 +36,7 @@ public class TestBuiltin_dqr extends TestBase {
 
     @Test
     public void testdqrcf() {
-        assertEval(Ignored.OutputFormatting, ".Fortran(.F_dqrcf, 1, 1L, 1L, 1, 1, 1L, 1, 1L)");
+        assertEval(".Fortran(.F_dqrcf, 1, 1L, 1L, 1, 1, 1L, 1, 1L)");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
index 8032615203..a05621fb9d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
@@ -287,17 +287,27 @@ public class TestBuiltin_format extends TestBase {
         assertEval("x <- c(1.0,2.0);names(x) <- c(\"x\",\"y\");argv <- list(x, FALSE, NULL, 0L, NULL, 0L, FALSE, FALSE, \".\");names(.Internal(format(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]])))");
     }
 
+    @Test
     public void testFormat() {
-        assertEval("{ format(7) }");
-        assertEval("{ format(7.42) }");
-        assertEval("{ format(c(7,42)) }");
-        assertEval("{ format(c(7.42,42.7)) }");
-        assertEval("{ format(c(7.42,42.7,NA)) }");
-        assertEval("{ .Internal(format(.GlobalEnv,FALSE,NA,0,0,3,TRUE,NA,'.')) }");
-        assertEval("{ format(1.1, scientific=TRUE) }");
-        assertEval("{ format(1.1, scientific=FALSE) }");
-        assertEval("{ format(1.1, scientific=c(TRUE, FALSE)) }");
-        assertEval("{ format(1.1, scientific=-10) }");
-        assertEval("{ format(1.1, scientific=c(-10, 1)) }");
+        assertEval("format(7)");
+        assertEval("format(7.42)");
+        assertEval("format(c(7,42))");
+        assertEval("format(c(7.42,42.7))");
+        assertEval("format(c(7.42,42.7,NA))");
+        assertEval(".Internal(format(.GlobalEnv,FALSE,NA,0,0,3,TRUE,NA,'.'))");
+        assertEval("format(1.1, scientific=TRUE)");
+        assertEval("format(1.1, scientific=FALSE)");
+        assertEval("format(1.1, scientific=c(TRUE, FALSE))");
+        assertEval("format(1.1, scientific=-10)");
+        assertEval("format(1.1, scientific=c(-10, 1))");
+        assertEval("format(c(9.99951, 13.1), digits=4)");
+        assertEval("format(1.60085, digits=5)");
+        assertEval("format(1.6000085, digits=7)");
+        assertEval("format(1.6001095, digits=7)");
+        assertEval(Ignored.OutputFormatting, "format(1.6011095, digits=7)");
+        assertEval("format(4.125e-04, digits=3)");
+        assertEval("format(4.135e-04, digits=3)");
+        assertEval("format(9.999999999995, digits=13); format(9.999999999995, digits=11)");
+        assertEval("format(9.999999995, digits=10)");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_summary.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_summary.java
index bdd46202cf..4005ecd53c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_summary.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_summary.java
@@ -37,4 +37,9 @@ public class TestBuiltin_summary extends TestBase {
         assertEval("argv <- structure(list(object = structure(list(Sepal.Length = c(5.1,     4.9, 4.7, 4.6, 5, 5.4, 4.6, 5, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3,     5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1, 4.6, 5.1, 4.8, 5,     5, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5, 5.5, 4.9, 4.4,     5.1, 5, 4.5, 4.4, 5, 5.1, 4.8, 5.1, 4.6, 5.3, 5, 7, 6.4,     6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2, 5, 5.9, 6, 6.1, 5.6,     6.7, 5.6, 5.8, 6.2, 5.6, 5.9, 6.1, 6.3, 6.1, 6.4, 6.6, 6.8,     6.7, 6, 5.7, 5.5, 5.5, 5.8, 6, 5.4, 6, 6.7, 6.3, 5.6, 5.5,     5.5, 6.1, 5.8, 5, 5.6, 5.7, 5.7, 6.2, 5.1, 5.7, 6.3, 5.8,     7.1, 6.3, 6.5, 7.6, 4.9, 7.3, 6.7, 7.2, 6.5, 6.4, 6.8, 5.7,     5.8, 6.4, 6.5, 7.7, 7.7, 6, 6.9, 5.6, 7.7, 6.3, 6.7, 7.2,     6.2, 6.1, 6.4, 7.2, 7.4, 7.9, 6.4, 6.3, 6.1, 7.7, 6.3, 6.4,     6, 6.9, 6.7, 6.9, 5.8, 6.8, 6.7, 6.7, 6.3, 6.5, 6.2, 5.9),     Sepal.Width = c(3.5, 3, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9,         3.1, 3.7, 3.4, 3, 3, 4, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4,         3.7, 3.6, 3.3, 3.4, 3, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4,         4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3, 3.4, 3.5, 2.3, 3.2,         3.5, 3.8, 3, 3.8, 3.2, 3.7, 3.3, 3.2, 3.2, 3.1, 2.3,         2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2, 3, 2.2, 2.9, 2.9, 3.1,         3, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3, 2.8, 3,         2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3, 3.4, 3.1, 2.3, 3, 2.5,         2.6, 3, 2.6, 2.3, 2.7, 3, 2.9, 2.9, 2.5, 2.8, 3.3, 2.7,         3, 2.9, 3, 3, 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3, 2.5, 2.8,         3.2, 3, 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2,         2.8, 3, 2.8, 3, 2.8, 3.8, 2.8, 2.8, 2.6, 3, 3.4, 3.1,         3, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3, 2.5, 3, 3.4, 3),     Petal.Length = c(1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5,         1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7,         1.5, 1.7, 1.5, 1, 1.7, 1.9, 1.6, 1.6, 1.5, 1.4, 1.6,         1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3, 1.5, 1.3,         1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5,         4.9, 4, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4, 4.7,         3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4, 4.9, 4.7, 4.3,         4.4, 4.8, 5, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5,         4.7, 4.4, 4.1, 4, 4.4, 4.6, 4, 3.3, 4.2, 4.2, 4.2, 4.3,         3, 4.1, 6, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1,         5.1, 5.3, 5.5, 5, 5.1, 5.3, 5.5, 6.7, 6.9, 5, 5.7, 4.9,         6.7, 4.9, 5.7, 6, 4.8, 4.9, 5.6, 5.8, 6.1, 6.4, 5.6,         5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 5.9,         5.7, 5.2, 5, 5.2, 5.4, 5.1), Petal.Width = c(0.2, 0.2,         0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1,         0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5,         0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2,         0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3,         0.2, 0.2, 0.2, 0.2, 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6,         1, 1.3, 1.4, 1, 1.5, 1, 1.4, 1.3, 1.4, 1.5, 1, 1.5, 1.1,         1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1, 1.1,         1, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4,         1.2, 1, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 2.5, 1.9, 2.1,         1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2, 1.9, 2.1, 2, 2.4,         2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2, 2, 1.8, 2.1, 1.8, 1.8,         1.8, 2.1, 1.6, 1.9, 2, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8,         1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2, 2.3,         1.8), Species = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,         1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,         1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,         1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,         1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,         2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,         2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,         2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L,         3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,         3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,         3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,         3L, 3L, 3L), .Label = c('setosa', 'versicolor', 'virginica'),         class = 'factor')), .Names = c('Sepal.Length', 'Sepal.Width',     'Petal.Length', 'Petal.Width', 'Species'), row.names = c(NA,     -150L), class = 'data.frame')), .Names = 'object');" +
                         "do.call('summary', argv)");
     }
+
+    @Test
+    public void testSummary() {
+        assertEval("summary(c(1.601,1.616))");
+    }
 }
-- 
GitLab