From 1d46c1d6863e879fd3f66afbcfc23a25a0aad0ae Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Fri, 17 Apr 2015 14:04:02 -0700
Subject: [PATCH] fixes for AST manipulation on calls of form f()()

---
 .../com/oracle/truffle/r/nodes/RASTUtils.java |  37 +++++++++++-------
 .../truffle/r/nodes/access/ConstantNode.java  |   2 +-
 .../r/nodes/runtime/RASTHelperImpl.java       |   6 ++-
 .../com/oracle/truffle/r/runtime/RError.java  |   1 +
 ll.rds                                        | Bin 81 -> 0 bytes
 5 files changed, 30 insertions(+), 16 deletions(-)
 delete mode 100644 ll.rds

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
index 25c7d4903f..6a67896121 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
@@ -27,6 +27,7 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.r.nodes.access.*;
+import com.oracle.truffle.r.nodes.access.ConstantNode.ConstantFunctionNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode.ConstantMissingNode;
 import com.oracle.truffle.r.nodes.access.variables.*;
 import com.oracle.truffle.r.nodes.builtin.*;
@@ -171,17 +172,18 @@ public class RASTUtils {
         return expr instanceof RExpression || expr instanceof RLanguage;
     }
 
-    @TruffleBoundary
     /**
-     * Create an {@link RCallNode} where {@code fn} is either a:
+     * Create an {@link RCallNode}. Where {@code fn} is either a:
      * <ul>
-     * <li>{@link RFunction}\<li>
-     * <li>{@link ConstantFunctioNode}</li>
-     * <li>{@link ConstantStringNode}</li>
+     * <li>{@link RFunction}\
+     * <li>{@code ConstantFunctionNode}</li>
+     * <li>{@code ConstantStringNode}</li>
      * <li>{@link ReadVariableNode}</li>
+     * <li>{@link RCallNode}</li>
      * <li>GroupDispatchNode</li>
      * </ul>
      */
+    @TruffleBoundary
     public static RNode createCall(Object fna, CallArgumentsNode callArgsNode) {
         Object fn = fna;
         if (fn instanceof ConstantNode) {
@@ -197,8 +199,11 @@ public class RASTUtils {
         } else if (fn instanceof RFunction) {
             RFunction rfn = (RFunction) fn;
             return RCallNode.createCall(null, ConstantNode.create(rfn), callArgsNode, null);
+        } else if (fn instanceof RCallNode) {
+            return RCallNode.createCall(null, (RCallNode) fn, callArgsNode, null);
         } else {
-            return RCallNode.createCall(null, ((RCallNode) fn).getFunctionNode(), callArgsNode, null);
+            // some value that we cannot represent (from substitute)
+            throw RError.error(RError.Message.IMPOSSIBLE_SUBSTITUTE);
         }
     }
 
@@ -235,14 +240,14 @@ public class RASTUtils {
     private static final CallArgsNodeFinder callArgsNodeFinder = new CallArgsNodeFinder();
 
     /**
-     * Returns the name (as an {@link RSymbol} or the function associated with an {@link RCallNode}
+     * Returns the name (as an {@link RSymbol} of the function associated with an {@link RCallNode}
      * or {@link GroupDispatchNode}.
      *
      * @param escape Add escape characters to non-standard names
      */
     public static Object findFunctionName(Node node, boolean escape) {
-        RNode child = (RNode) unwrap(findFunctionNode(node));
-        if (child instanceof ConstantNode && ((ConstantNode) child).getValue() instanceof RFunction) {
+        RNode child = (RNode) unwrap(getFunctionNode(node));
+        if (child instanceof ConstantFunctionNode) {
             return ((ConstantNode) child).getValue();
         } else if (child instanceof ReadVariableNode) {
             String name = ((ReadVariableNode) child).getIdentifier();
@@ -260,9 +265,8 @@ public class RASTUtils {
         } else if (child instanceof RBuiltinNode) {
             RBuiltinNode builtinNode = (RBuiltinNode) child;
             return RDataFactory.createSymbol((builtinNode.getBuiltin().getRBuiltin().name()));
-        } else if (child instanceof RCallNode) {
-            return findFunctionName(child, escape);
         } else {
+            // TODO This should really fail in some way as (clearly) this is not a "name"
             // some more complicated expression, just deparse it
             RDeparse.State state = RDeparse.State.createPrintableState();
             child.deparse(state);
@@ -270,15 +274,20 @@ public class RASTUtils {
         }
     }
 
+    public static boolean isNamedFunctionNode(Node aCallNode) {
+        RNode n = (RNode) unwrap(getFunctionNode(aCallNode));
+        return (n instanceof ReadVariableNode || n instanceof GroupDispatchNode || n instanceof RBuiltinNode || n instanceof ConstantFunctionNode);
+
+    }
+
     private static String escapeName(String name) {
         return RDeparse.quotify(name, RDeparse.BACKTICK);
     }
 
     /**
-     * Returns the {@link ReadVariableNode} associated with a {@link RCallNode} or the
-     * {@link GroupDispatchNode} .
+     * Unifies {@link RCallNode} and {@link GroupDispatchNode} for accessing (likely) function name.
      */
-    public static RNode findFunctionNode(Node node) {
+    public static RNode getFunctionNode(Node node) {
         if (node instanceof RCallNode) {
             return ((RCallNode) node).getFunctionNode();
         } else if (node instanceof GroupDispatchNode) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java
index 301f795a15..ab19c1bd11 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ConstantNode.java
@@ -393,7 +393,7 @@ public abstract class ConstantNode extends RNode implements VisibilityController
         }
     }
 
-    private static final class ConstantFunctionNode extends ConstantNode {
+    public static final class ConstantFunctionNode extends ConstantNode {
 
         private final RFunction function;
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
index 461fe9190e..e2d9ab2f4f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
@@ -139,7 +139,11 @@ public class RASTHelperImpl implements RASTHelper {
         int index = indexArg;
         if (node instanceof RCallNode || node instanceof GroupDispatchNode) {
             if (index == 0) {
-                return RASTUtils.findFunctionName(node, true);
+                if (RASTUtils.isNamedFunctionNode(node)) {
+                    return RASTUtils.findFunctionName(node, true);
+                } else {
+                    return RDataFactory.createLanguage(RASTUtils.getFunctionNode(node));
+                }
             } else {
                 CallArgumentsNode args = RASTUtils.findCallArgumentsNode(node);
                 return RASTUtils.createLanguageElement(args, index - 1);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 8d3ed6d528..35f0938bc7 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -558,6 +558,7 @@ public final class RError extends RuntimeException {
         FILE_CANNOT_REMOVE("  cannot remove file '%s'"),
         FILE_CANNOT_RENAME("  cannot rename file '%s' to '%s'"),
         DIR_CANNOT_CREATE("cannot create dir '%s'"),
+        IMPOSSIBLE_SUBSTITUTE("substitute result cannot be represented"),
         PERFORMANCE("performance problem: %s");
 
         public final String message;
diff --git a/ll.rds b/ll.rds
deleted file mode 100644
index 86e986118defb43e488f17b96fbe791f0524cb55..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 81
zcmb2|=3oE==I#ec2?+^F327-Q2}x{*tp{t^*z6S2N;*;+7&+{PkEJrMOiW2ge86&P
iO=aiKl}8=g7$S^aCKw7H^I#JC&tSC9DmjyZfdK#w+8V6@

-- 
GitLab