From 59111b17dbfa7384ef13146bea7cd59934c2b30f Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Sat, 22 Aug 2015 15:27:30 -0700
Subject: [PATCH] deparse/indexing fixes for BlockNode

---
 .../r/engine/RRuntimeASTAccessImpl.java       | 25 +++++++++++++++++--
 .../truffle/r/nodes/control/BlockNode.java    |  8 +++++-
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
index f31b8311fa..373cfaaa2c 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
@@ -127,9 +127,17 @@ public class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
             return 3;
         } else if (node instanceof ReplacementNode) {
             return 3;
+        } else if (node instanceof BlockNode) {
+            /*
+             * We can't get this completely compatible with GnuR without knowing if the source had a
+             * "{" or not. However, semantically what really matters is that if the length is > 1,
+             * there *must* have been a "{", so we fabricate it.
+             */
+            int len = ((BlockNode) node).getSequence().length;
+            return len == 1 ? 1 : len + 1;
         } else {
             // TODO fill out
-            assert false : node;
+            throw RInternalError.unimplemented(node.toString());
         }
         return result;
     }
@@ -221,11 +229,24 @@ public class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
                 default:
                     assert false;
             }
+        } else if (node instanceof BlockNode) {
+            /* See related comments in getLength. */
+            RNode[] seq = ((BlockNode) node).getSequence();
+            if (seq.length > 1) {
+                switch (index) {
+                    case 0:
+                        return RDataFactory.createSymbol("{");
+                    default:
+                        return RASTUtils.createLanguageElement(seq[index - 1]);
+                }
+            } else {
+                return RASTUtils.createLanguageElement(seq[0]);
+            }
         } else if (node instanceof ReplacementNode) {
             return RNull.instance;
         } else {
             // TODO fill out
-            assert false;
+            throw RInternalError.unimplemented(node.toString());
         }
         return null;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java
index 91b24aef9c..91d70aa54a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/BlockNode.java
@@ -77,6 +77,9 @@ public class BlockNode extends SequenceNode implements RSyntaxNode, VisibilityCo
     @Override
     public void deparseImpl(RDeparse.State state) {
         state.startNodeDeparse(this);
+        if (sequence.length > 1) {
+            state.writeOpenCurlyNLIncIndent();
+        }
         for (int i = 0; i < sequence.length; i++) {
             state.mark();
             sequence[i].deparse(state);
@@ -86,6 +89,9 @@ public class BlockNode extends SequenceNode implements RSyntaxNode, VisibilityCo
                 state.mark(); // in case last
             }
         }
+        if (sequence.length > 1) {
+            state.decIndentWriteCloseCurly();
+        }
         state.endNodeDeparse(this);
     }
 
@@ -96,7 +102,7 @@ public class BlockNode extends SequenceNode implements RSyntaxNode, VisibilityCo
          * it is represented as a LANGSXP with symbol "{" and a NULL cdr, representing the empty
          * sequence. This is an unpleasant special case in FastR that we can only detect by
          * re-examining the original source.
-         *
+         * 
          * A sequence of length 1, i.e. a single statement, is represented as itself, e.g. a SYMSXP
          * for "x" or a LANGSXP for a function call. Otherwise, the representation is a LISTSXP
          * pairlist, where the car is the statement and the cdr is either NILSXP or a LISTSXP for
-- 
GitLab