diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index ec84baa9ed60d1161117164700bfa7e8d2c38e46..fe2eb079f49965a9bee08d91dbbc37b11f1d4a35 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -282,6 +282,7 @@ public final class REngine implements RContext.Engine { ConsoleHandler ch = singleton.context.getConsoleHandler(); ch.println("Unsupported specialization in node " + use.getNode().getClass().getSimpleName() + " - supplied values: " + Arrays.asList(use.getSuppliedValues()).stream().map(v -> v.getClass().getSimpleName()).collect(Collectors.toList())); + use.printStackTrace(); return null; } catch (RecognitionException | RuntimeException e) { singleton.context.getConsoleHandler().println("Exception while parsing: " + e); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TypeConvert.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TypeConvert.java index 15e3fe0797bf2c52fba612ea87c133bb35702d9c..03ef8a58d23cd2fabfa762bd1268775a9ead3f8a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TypeConvert.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TypeConvert.java @@ -165,7 +165,7 @@ public abstract class TypeConvert extends RBuiltinNode { RIntVector res = RDataFactory.createIntVector(data, complete); res.setAttr("levels", RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); res.setAttr("class", RDataFactory.createStringVector("factor")); - return res; + return RDataFactory.createFactor(res); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/CoerceVector.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/CoerceVector.java index b0185087e870bf218343d9f90616e9b536aed93c..eec8bfc66da0e9e94c01b80404bb1c5bad7d1e68 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/CoerceVector.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/CoerceVector.java @@ -42,6 +42,15 @@ public abstract class CoerceVector extends RNode { @Child private CastIntegerNode castInteger; @Child private CastStringNode castString; @Child private CastListNode castList; + @Child private CoerceVector coerceRecursive; + + private Object coerceRecursive(VirtualFrame frame, Object value, Object vector, Object operand) { + if (coerceRecursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + coerceRecursive = insert(CoerceVectorFactory.create(null, null, null)); + } + return coerceRecursive.executeEvaluated(frame, value, vector, operand); + } private Object castComplex(VirtualFrame frame, Object vector) { if (castComplex == null) { @@ -309,6 +318,13 @@ public abstract class CoerceVector extends RNode { return (RList) castList(frame, vector); } + // factor value + + @Specialization + protected Object coerce(VirtualFrame frame, RFactor value, RAbstractVector vector, Object operand) { + return coerceRecursive(frame, value.getVector(), vector, operand); + } + // function vector value @Specialization @@ -338,7 +354,7 @@ public abstract class CoerceVector extends RNode { return vector; } - protected boolean isVectorList(RAbstractVector value, RAbstractVector vector) { + protected boolean isVectorList(RAbstractContainer value, RAbstractVector vector) { return vector.getElementClass() == Object.class; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java index 6c714e11d7dd08946f3773235c584862beabdd21..6a1cfd0c93db3532420a91ca67ee01e3931542c6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java @@ -177,6 +177,11 @@ public abstract class UpdateArrayHelperNode extends RNode { return CastToContainerNodeFactory.create(child, false, false, false, true); } + @Specialization + protected Object update(VirtualFrame frame, Object v, RFactor value, int recLevel, Object positions, Object vector) { + return updateRecursive(frame, v, value.getVector(), vector, positions, recLevel); + } + @Specialization(guards = "emptyValue") protected RAbstractVector update(Object v, RAbstractVector value, int recLevel, Object[] positions, RAbstractVector vector) { if (isSubset) { 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 5b03886ca5b28b2c524d194c7b2934a84730775c..85cd6acc908fe39553b4105b6070163be01fd21f 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 @@ -72,6 +72,11 @@ public abstract class CastToContainerNode extends CastNode { return dataFrame; } + @Specialization + protected RFactor cast(RFactor factor) { + return factor; + } + @Specialization protected RExpression cast(RExpression expression) { return expression; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java index f0f6f4c2f4befc95e4d786827b84271f314824ae..90888984d5d6bc049318c00ad738a8686a73f25e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java @@ -3907,6 +3907,9 @@ public class TestSimpleBuiltins extends TestBase { assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x == c(\"a\", \"b\") }"); assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > c(\"a\", \"b\") }"); assertEval("{ x<-factor(c(\"a\", \"b\", \"a\", \"c\")); x == c(\"a\", \"b\") }"); + + assertEvalWarning("{ x<-factor(c(\"c\", \"b\", \"a\", \"c\")); y<-list(1); y[1]<-x; y }"); + assertEvalWarning("{ x<-factor(c(\"c\", \"b\", \"a\", \"c\")); y<-c(1); y[1]<-x; y }"); } @Test