From 9af0b10768144a1d7afb66b37a8fa9becbdf8f9c Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Wed, 11 Feb 2015 09:37:59 -0800
Subject: [PATCH] implement '[[' access for environments

---
 .../r/nodes/access/array/ArrayPositionCast.java   | 11 +++++++++++
 .../nodes/access/array/read/AccessArrayNode.java  | 15 +++++++++++++++
 .../r/nodes/unary/CastToContainerNode.java        |  5 +++++
 .../src/com/oracle/truffle/r/runtime/RError.java  |  2 ++
 4 files changed, 33 insertions(+)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java
index 07fcb565e5..de2e5bbf21 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java
@@ -36,6 +36,7 @@ import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.env.*;
 import com.oracle.truffle.r.runtime.ops.na.*;
 
 abstract class ArrayPositionsCastBase extends RNode {
@@ -142,6 +143,11 @@ public abstract class ArrayPositionCast extends ArrayPositionsCastBase {
         return operand;
     }
 
+    @Specialization
+    protected Object doEnvOp(REnvironment vector, Object operand) {
+        return operand;
+    }
+
     @Specialization
     protected Object doMissingVector(VirtualFrame frame, RAbstractContainer container, RMissing operand) {
         int[] dimensions = getDimensions(container);
@@ -376,6 +382,11 @@ public abstract class ArrayPositionCast extends ArrayPositionsCastBase {
             return operand;
         }
 
+        @Specialization
+        protected Object doEnvOp(REnvironment vector, Object operand, Object exact) {
+            return operand;
+        }
+
         @Specialization
         protected int doFactor(RNull vector, RFactor operand, Object exact) {
             return 0;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
index 7803a01e6e..f5ade96a1d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
@@ -1689,6 +1689,21 @@ public abstract class AccessArrayNode extends RNode {
         return pairlist.getDataAtAsObject(position - 1);
     }
 
+    @SuppressWarnings("unused")
+    @Specialization
+    protected Object access(REnvironment env, Object exact, int recLevel, Object position, RAbstractLogicalVector dropDim) {
+        if (isSubset) {
+            error.enter();
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.OBJECT_NOT_SUBSETTABLE, "environment");
+        }
+        if (!(position instanceof String || ((position instanceof RStringVector) && ((RStringVector) position).getLength() == 1))) {
+            error.enter();
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.WRONG_ARGS_SUBSET_ENV);
+        }
+        Object obj = env.get(RRuntime.asString(position));
+        return obj == null ? RNull.instance : obj;
+    }
+
     protected boolean outOfBounds(RList vector, @SuppressWarnings("unused") Object exact, @SuppressWarnings("unused") int recLevel, int position) {
         return position > vector.getLength();
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
index 98d1cc102a..4a1e804d4e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
@@ -76,6 +76,11 @@ public abstract class CastToContainerNode extends CastNode {
         return pairlist;
     }
 
+    @Specialization
+    protected REnvironment cast(REnvironment env) {
+        return env;
+    }
+
     @Override
     public RNode substitute(REnvironment env) {
         return CastToContainerNodeGen.create(getOperand(), false, false, false);
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 c8071a3966..c948e477e2 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
@@ -382,6 +382,7 @@ public final class RError extends RuntimeException {
         TYPE_EXPECTED("%s argument expected"),
         CANNOT_CHANGE_DIRECTORY("cannot change working directory"),
         FIRST_ARG_MUST_BE_STRING("first argument must be a character string"),
+        ARG_MUST_BE_CHARACTER_VECTOR_LENGTH_ONE("argument must be a character vector of length 1"),
         ZERO_LENGTH_VARIABLE("attempt to use zero-length variable name"),
         ARGUMENT_NOT_INTERPRETABLE_LOGICAL("argument is not interpretable as logical"),
         OPERATIONS_NUMERIC_LOGICAL_COMPLEX("operations are possible only for numeric, logical or complex types"),
@@ -430,6 +431,7 @@ public final class RError extends RuntimeException {
         IS_OF_WRONG_LENGTH("'%s' is of wrong length %d (!= %d)"),
         IS_OF_WRONG_ARITY("'%d' argument passed to '%s' which requires '%d'"),
         OBJECT_NOT_SUBSETTABLE("object of type '%s' is not subsettable"),
+        WRONG_ARGS_SUBSET_ENV("wrong arguments for subsetting an environment"),
         DIMS_DONT_MATCH_LENGTH("dims [product %d] do not match the length of object [%d]"),
         DIMNAMES_DONT_MATCH_DIMS("length of 'dimnames' [%d] must match that of 'dims' [%d]"),
         DIMNAMES_DONT_MATCH_EXTENT("length of 'dimnames' [%d] not equal to array extent"),
-- 
GitLab