diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridContext.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridContext.java index eafd17babdc2a831f150bc99a7c5d9da5541b293..928e050945ce7f070f6cade8a4b713191b3abeb8 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridContext.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridContext.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.library.fastrGrid.GridState.GridDeviceState; +import com.oracle.truffle.r.library.fastrGrid.device.FileGridDevice; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice.DeviceCloseException; import com.oracle.truffle.r.library.fastrGrid.device.SVGDevice; @@ -59,7 +60,7 @@ public final class GridContext { private int currentDeviceIdx = 0; private GridContext() { - devices.add(new DeviceAndState(null)); + devices.add(new DeviceAndState(null, null)); } public static GridContext getContext() { @@ -86,10 +87,15 @@ public final class GridContext { } public void setCurrentDevice(String name, GridDevice currentDevice) { + assert !(currentDevice instanceof FileGridDevice) : "FileGridDevice must have filenamePattern"; + setCurrentDevice(name, currentDevice, null); + } + + public void setCurrentDevice(String name, GridDevice currentDevice, String filenamePattern) { RGridGraphicsAdapter.addDevice(name); RGridGraphicsAdapter.setCurrentDevice(name); currentDeviceIdx = this.devices.size(); - this.devices.add(new DeviceAndState(currentDevice)); + this.devices.add(new DeviceAndState(currentDevice, filenamePattern)); assert devices.size() == RGridGraphicsAdapter.getDevicesCount(); } @@ -158,9 +164,9 @@ public final class GridContext { final GridDevice device; final GridDeviceState state; - DeviceAndState(GridDevice device) { + DeviceAndState(GridDevice device, String filenamePattern) { this.device = device; - this.state = new GridDeviceState(); + this.state = new GridDeviceState(filenamePattern); } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java index dac9a5976c3af8ea97a4b86fb38229cd2d6d69fd..5579a9051982fdcfa38d77d60f9ddb4a1c316fd8 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java @@ -15,6 +15,7 @@ import java.util.function.Supplier; import com.oracle.truffle.r.library.fastrGrid.device.GridColor; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.library.fastrGrid.grDevices.FileDevUtils; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -163,6 +164,10 @@ public final class GridState { return devState.scale; } + public String getNextPageFilename() { + return FileDevUtils.formatFilename(devState.filenamePattern, devState.pageIndex++); + } + public static final class GridPalette { public final GridColor[] colors; public final String[] colorNames; @@ -194,5 +199,11 @@ public final class GridState { private boolean isDisplayListOn = true; private RList displayList; private int displayListIndex = 0; + private int pageIndex = 2; + private String filenamePattern; + + GridDeviceState(String filenamePattern) { + this.filenamePattern = filenamePattern; + } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LNewPage.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LNewPage.java index 1b234eda3a3fc0e7ff305cf18785e6ec77813c36..27edec3641e8a9af72635d4db573cb0f2cc77b8f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LNewPage.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LNewPage.java @@ -14,8 +14,11 @@ package com.oracle.truffle.r.library.fastrGrid; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.library.fastrGrid.device.FileGridDevice; import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice.DeviceCloseException; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RNull; @@ -40,8 +43,17 @@ final class LNewPage extends RExternalBuiltinNode { } @TruffleBoundary - private static void openNewPage(GridDevice device) { - device.openNewPage(); + private void openNewPage(GridDevice device) { + if (device instanceof FileGridDevice) { + String path = GridContext.getContext().getGridState().getNextPageFilename(); + try { + ((FileGridDevice) device).openNewPage(path); + } catch (DeviceCloseException e) { + throw error(Message.GENERIC, "Cannot save the image. Details: " + e.getMessage()); + } + } else { + device.openNewPage(); + } } @Override diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/FileGridDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/FileGridDevice.java new file mode 100644 index 0000000000000000000000000000000000000000..753f4d5bfccc7d75c9e064bb0934666ba12f2af1 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/FileGridDevice.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.fastrGrid.device; + +/** + * Should be implemented by devices that save their output into a file. Such devices should only + * accept complete filenames, i.e. without '%d' placeholder, and the handling of the placeholder is + * left up to the calling code. + */ +public interface FileGridDevice extends GridDevice { + /** + * Each call to {@link #openNewPage()} should save the current image (into the current path) and + * start drawing a new image into the given path, i.e. the given path becomes a new current + * path. + * + * @param filename tha path where to save the next image, will not contain '%d' symbol as its + * processing should be handled by the caller. + * @throws DeviceCloseException + */ + void openNewPage(String filename) throws DeviceCloseException; +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java index 4a54283cd69ab66bf1d91d0542307e02ccae43ed..17f1667bcdae8776d5e7b9656b01aef8ce7aa277 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java @@ -39,10 +39,10 @@ import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext.GridLineJoin import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.Utils; -public class SVGDevice implements GridDevice { +public class SVGDevice implements GridDevice, FileGridDevice { private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.000"); private final StringBuilder data = new StringBuilder(1024); - private final String filename; + private String filename; private final double width; private final double height; @@ -73,14 +73,16 @@ public class SVGDevice implements GridDevice { height); } + @Override + public void openNewPage(String newFilename) throws DeviceCloseException { + saveFile(); + filename = newFilename; + openNewPage(); + } + @Override public void close() throws DeviceCloseException { - closeSVGDocument(); - try { - Files.write(Paths.get(filename), Collections.singleton(data.toString()), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new DeviceCloseException(e); - } + saveFile(); } @Override @@ -181,7 +183,19 @@ public class SVGDevice implements GridDevice { data.append("' ").append(attributes).append(" />"); } + private void saveFile() throws DeviceCloseException { + closeSVGDocument(); + try { + Files.write(Paths.get(filename), Collections.singleton(data.toString()), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new DeviceCloseException(e); + } + } + private void closeSVGDocument() { + if (data.length() == 0) { + return; + } if (cachedCtx != null) { // see #appendStyle append("</g>"); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/BufferedImageDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/BufferedImageDevice.java index 577784461859f69a3c600497f361c1f5b141dd17..1f95c9cfd18a2c5a0865f09be84016bacbfdf1aa 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/BufferedImageDevice.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/awt/BufferedImageDevice.java @@ -32,10 +32,12 @@ import java.io.IOException; import javax.imageio.ImageIO; -public final class BufferedImageDevice extends Graphics2DDevice { +import com.oracle.truffle.r.library.fastrGrid.device.FileGridDevice; + +public final class BufferedImageDevice extends Graphics2DDevice implements FileGridDevice { private final BufferedImage image; - private final String filename; private final String fileType; + private String filename; private BufferedImageDevice(String filename, String fileType, BufferedImage image, Graphics2D graphics, int width, int height) { super(graphics, width, height, true); @@ -56,8 +58,19 @@ public final class BufferedImageDevice extends Graphics2DDevice { return new BufferedImageDevice(filename, fileType, image, graphics, width, height); } + @Override + public void openNewPage(String newFilename) throws DeviceCloseException { + saveImage(); + filename = newFilename; + openNewPage(); + } + @Override public void close() throws DeviceCloseException { + saveImage(); + } + + private void saveImage() throws DeviceCloseException { try { ImageIO.write(image, fileType, new File(filename)); } catch (IOException e) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevCairo.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevCairo.java index 45bfaf37007c0f4c9f9e2c355f3b0a0086f66496..5001af1fd813ade89275b4a5ba1e9156310d3cf5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevCairo.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/DevCairo.java @@ -48,7 +48,7 @@ public class DevCairo extends RExternalBuiltinNode { throw error(Message.INVALID_ARG_TYPE); } - GridContext.getContext().setCurrentDevice("svg", new SVGDevice(filename, witdh / 72., height / 72.)); + GridContext.getContext().setCurrentDevice("svg", new SVGDevice(FileDevUtils.formatInitialFilename(filename), witdh / 72., height / 72.), filename); return RNull.instance; } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/FileDevUtils.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/FileDevUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..1b3d1de5038f9fd1d407bb87c7c31690b6001b86 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/FileDevUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.fastrGrid.grDevices; + +import com.oracle.truffle.api.CompilerAsserts; + +public class FileDevUtils { + public static String formatInitialFilename(String filename) { + return formatFilename(filename, 1); + } + + public static String formatFilename(String filename, int pageIndex) { + CompilerAsserts.neverPartOfCompilation(); + assert filename != null; + assert pageIndex >= 1; + return String.format(filename, pageIndex); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/InitWindowedDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/InitWindowedDevice.java index 49d65f69802d492b841b9a78143d565b18b3e758..de15f10dccd2b944a99a7bf02480d989c5ac3b61 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/InitWindowedDevice.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/InitWindowedDevice.java @@ -100,8 +100,8 @@ public final class InitWindowedDevice extends RExternalBuiltinNode { String formatName = name.substring(0, name.indexOf("::")); String filename = name.substring(name.lastIndexOf(':') + 1); try { - BufferedImageDevice device = BufferedImageDevice.open(filename, formatName, width, height); - GridContext.getContext().setCurrentDevice(formatName.toUpperCase(), device); + BufferedImageDevice device = BufferedImageDevice.open(FileDevUtils.formatInitialFilename(filename), formatName, width, height); + GridContext.getContext().setCurrentDevice(formatName.toUpperCase(), device, filename); } catch (NotSupportedImageFormatException e) { throw error(Message.GENERIC, String.format("Format '%s' is not supported.", formatName)); } 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 1c72cbcbc50a20eb60f4a9ae68dbba8f4c175312..5ad02cca608837419ec6fc089a807a26b7d0fc2e 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 @@ -75,6 +75,8 @@ public abstract class AsCall extends RBuiltinNode.Arg1 { return CallUtil.makeCallSourceUnavailable((Integer) x.getDataAt(0), avn); } else if (x.getDataAt(0) instanceof Double) { return CallUtil.makeCallSourceUnavailable((Double) x.getDataAt(0), avn); + } else if (x.getDataAt(0) instanceof RLanguage) { + return (RLanguage) x.getDataAt(0); } else { throw RInternalError.unimplemented(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index 4900debc6e7727015a5a17970fcee10d1d3caab1..e9748c82908fd0936ef94148042354a528f0b0cc 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -212,10 +212,11 @@ public abstract class Combine extends RBuiltinNode.Arg2 { @ExplodeLoop private int prepareElements(Object[] args, CastNode cast, int precedence, Object[] elements) { int size = 0; + boolean exprListPrecedence = precedence == EXPRESSION_PRECEDENCE || precedence == LIST_PRECEDENCE; for (int i = 0; i < elements.length; i++) { CombineInputCast inputCast = getCast(i); Object value = args[i]; - Object element = (precedence == EXPRESSION_PRECEDENCE && value instanceof RLanguage) ? value : cast.doCast(inputCast.cast(value)); + Object element = (exprListPrecedence && value instanceof RLanguage) ? value : cast.doCast(inputCast.cast(value)); element = inputCast.valueProfile.profile(element); elements[i] = element; size += getElementSize(element); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index f4d636e57a42f4340d51a196310c18a5b377efdf..f731b65357b7496f462c01b3b3ae585accbc0a4b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -17,10 +17,10 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalNA; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -39,6 +39,7 @@ import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.PathMatcher; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; @@ -1134,22 +1135,52 @@ public class FileFunctions { if (pathPattern.length() == 0 || RRuntime.isNA(pathPattern)) { continue; } - if (containsGlobChar(pathPattern) >= 0) { - throw RError.nyi(this, "wildcards"); + int firstGlobCharIdx = containsGlobChar(pathPattern); + if (firstGlobCharIdx >= 0) { + result = removeGlob(pathPattern, recursive, firstGlobCharIdx, result); + } else { + result = removeFile(FileSystems.getDefault().getPath(pathPattern), recursive, result); } - Path path = fileSystem.getPath(pathPattern); - if (Files.isDirectory(path)) { - if (!recursive) { - continue; - } else { - result = recursiveDelete(path); + } + return result; + } + + private int removeGlob(String pathPattern, boolean recursive, int firstGlobCharIdx, int result) { + // we take as much as we can from the pathPatter as the search root + int lastSeparator = pathPattern.substring(0, firstGlobCharIdx).lastIndexOf(File.separatorChar); + String searchRoot = pathPattern.substring(0, lastSeparator); + try { + int[] tmpResult = new int[]{result}; + PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pathPattern); + Files.walkFileTree(Paths.get(searchRoot), new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (matcher.matches(file)) { + tmpResult[0] = removeFile(file, recursive, tmpResult[0]); + return recursive ? FileVisitResult.SKIP_SUBTREE : FileVisitResult.CONTINUE; + } + return FileVisitResult.CONTINUE; } + }); + return tmpResult[0]; + } catch (IOException e) { + return 0; + } + } + + private int removeFile(Path path, boolean recursive, int resultIn) { + int result = resultIn; + if (Files.isDirectory(path)) { + if (!recursive) { + return result; + } else { + result = recursiveDelete(path); } - try { - Files.deleteIfExists(path); - } catch (IOException ex) { - result = 0; - } + } + try { + Files.deleteIfExists(path); + } catch (IOException ex) { + result = 0; } return result; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java index 52c861931e2d24a3b67b5c957da3e29cda2bd900..750e1a362d18251948670ec79494fdac7d9c95bf 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java @@ -194,7 +194,7 @@ public abstract class PrecedenceNode extends RBaseNode { @Specialization protected int doExpression(RLanguage val, boolean recursive) { - return EXPRESSION_PRECEDENCE; + return LIST_PRECEDENCE; } @Specialization 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 9817201bb64a4a7b2d2f74ae1c901a92e51dd744..ac34216e446012ba1f06857ec4b2c129855479e1 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 @@ -5747,6 +5747,10 @@ character(0) a b 1 2 +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascall.testAsCall# +#typeof(as.call(list(substitute(graphics::par)))) +[1] "language" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_ascall.testAsCall# #{ as.call(42) } Error in as.call(42) : invalid argument list @@ -10315,6 +10319,10 @@ NULL #argv <- list(structure(numeric(0), .Dim = c(0L, 0L))); .Internal(body(argv[[1]])) NULL +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#typeof(c(substitute(graphics::par), list(as.symbol('a')))) +[1] "list" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# #{ c( 100, 1:3, 200 ) } [1] 100 1 2 3 200 @@ -12852,6 +12860,15 @@ structure(integer(0), .Dim = 0:1, .Dimnames = list(NULL, NULL)) structure(integer(0), .Dim = c(0L, 3L), .Dimnames = list(NULL, NULL)) +##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testRetType#Ignored.ImplementationError# +#dput(cbind(substitute(graphics::par), list(as.symbol('a')))) +structure(list(`::`, graphics, par, a, a, a), .Dim = c(3L, 2L +)) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testRetType# +#typeof(cbind(substitute(graphics::par), list(as.symbol('a')))) +[1] "list" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testcbind1# #argv <- list(748L, c(5.08759633523238, 4.0943445622221, 5.66642668811243, 3.43398720448515), c(1L, 1L, 1L, 1L), 1L, c(FALSE, TRUE, TRUE, TRUE), c(0, 1, 0, 1), c(0, 1, 1, 1), c(0, 1, 0, 1), c(FALSE, FALSE, TRUE, FALSE), c(FALSE, FALSE, FALSE, TRUE));do.call('cbind', argv) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] @@ -67568,6 +67585,10 @@ quote(x + 1) Error in substitute(quote(x + 1), setClass("a")) : invalid environment specified +##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute# +#typeof(substitute(set)) +[1] "symbol" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute# #{ delayedAssign("expr", a * b) ; substitute(expr) } expr diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascall.java index 1649f2aae78282d9b7d635e7ca98f41e5d11fd5d..5715ff9d612ed6730d6b6feeabf9dddfb7d58810 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascall.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascall.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. */ @@ -61,5 +61,7 @@ public class TestBuiltin_ascall extends TestBase { assertEval("{ f <- function(x) x ; l <- list(f, 42) ; cl <- as.call(l); typeof(cl[[2]]) }"); assertEval("{ as.call(42) }"); + + assertEval("typeof(as.call(list(substitute(graphics::par))))"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java index 99bfa6460b0b1ecef9cc6496604026b2028ba8f1..7b4e8cf704f80dfe3d29adf4f62823fe98dfe16a 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java @@ -543,6 +543,8 @@ public class TestBuiltin_c extends TestBase { // names vector created by combine cannot be temporary assertEval("{ x<-c(a=42); y<-c(b=7); z<-c(x,y); w<-names(z); w[[1]]<-\"c\"; z }"); + + assertEval("typeof(c(substitute(graphics::par), list(as.symbol('a'))))"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cbind.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cbind.java index 82d71854d968bd8b5b0084273e5fe17026599329..4f598802c30f2be8ad7db72b85954c3181e5b4c3 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cbind.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cbind.java @@ -181,5 +181,8 @@ public class TestBuiltin_cbind extends TestBase { assertEval("dput(cbind(c(NULL, NULL), integer(0)))"); assertEval("dput(cbind(integer(0)))"); assertEval("dput(cbind(integer(0), NULL, NULL))"); + // FIXME FastR wrongly adds dimnames to the result + assertEval(Ignored.ImplementationError, "dput(cbind(substitute(graphics::par), list(as.symbol('a'))))"); + assertEval("typeof(cbind(substitute(graphics::par), list(as.symbol('a'))))"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java index ad2e9940d396e8865d77cb87da8e0c412f93eee5..f6ff5dcb0d200307287838f2a86794e251e8d86c 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java @@ -112,5 +112,7 @@ public class TestBuiltin_substitute extends TestBase { assertEval("substitute(quote(x+1), environment())"); assertEval("f<-function() {}; substitute(quote(x+1), f)"); assertEval("substitute(quote(x+1), setClass('a'))"); + + assertEval("typeof(substitute(set))"); } }