diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java index 69d3d49b10821db3909ce52d7e07a13a352c5264..9cc09ec1e4d84395cd5dea0798e1d1c1645ca325 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java @@ -102,6 +102,8 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode { return RVector.setClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); } else if (name.equals(RRuntime.ROWNAMES_ATTR_KEY)) { resultVector.setRowNames(null); + } else if (name.equals(RRuntime.LEVELS_ATTR_KEY)) { + resultVector.setLevels(null); } else if (resultVector.getAttributes() != null) { resultVector.getAttributes().remove(name); } @@ -140,6 +142,8 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode { return setClassAttrFromObject(resultVector, container, value, getEncapsulatingSourceSection()); } else if (name.equals(RRuntime.ROWNAMES_ATTR_KEY)) { resultVector.setRowNames(castVector(frame, value)); + } else if (name.equals(RRuntime.LEVELS_ATTR_KEY)) { + resultVector.setLevels(castVector(frame, value)); } else { // generic attribute resultVector.setAttr(name, value); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java index 2dac8d6ef4276fed1818457c4e39bf0d1a6321e7..e057dd8e85058fa8143487c7c56b1901aef861b5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java @@ -179,11 +179,9 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode { UpdateAttr.setClassAttrFromObject(resultVector, container, value, getEncapsulatingSourceSection()); } } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) { - if (value == RNull.instance) { - resultVector.setRowNames(null); - } else { - resultVector.setRowNames(castVector(virtualFrame, value)); - } + resultVector.setRowNames(castVector(virtualFrame, value)); + } else if (attrName.equals(RRuntime.LEVELS_ATTR_KEY)) { + resultVector.setLevels(castVector(virtualFrame, value)); } else { if (value == RNull.instance) { resultVector.removeAttr(attrName); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index b39f7f345d3a1a6ac8eb05fbca3d8800073cea24..47e1c683d5fb66e1d58d4dc5f5020d9bef174a66 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java @@ -11,8 +11,11 @@ package com.oracle.truffle.r.nodes.builtin.base; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode; +import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RBuiltinKind; import com.oracle.truffle.r.runtime.data.*; @@ -24,6 +27,16 @@ import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; // 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateLevels extends RInvisibleBuiltinNode { + @Child private CastToVectorNode castVector; + + private RAbstractVector castVector(VirtualFrame frame, Object value) { + if (castVector == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castVector = insert(CastToVectorNodeFactory.create(null, false, false, false, false)); + } + return (RAbstractVector) castVector.executeObject(frame, value); + } + @Specialization @TruffleBoundary protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels) { @@ -34,11 +47,10 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode { } @Specialization - @TruffleBoundary - protected RAbstractVector updateLevels(RAbstractVector vector, Object levels) { + protected RAbstractVector updateLevels(VirtualFrame frame, RAbstractVector vector, Object levels) { controlVisibility(); RVector v = vector.materialize(); - v.setLevels(levels); + v.setLevels(castVector(frame, levels)); return v; } @@ -52,9 +64,9 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode { @Specialization @TruffleBoundary - protected RFactor updateLevels(RFactor factor, Object levels) { + protected RFactor updateLevels(VirtualFrame frame, RFactor factor, Object levels) { controlVisibility(); - factor.getVector().setLevels(levels); + factor.getVector().setLevels(castVector(frame, levels)); return factor; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java index 261a69b958f4e6f901aa0b54e1cc0bc0194b5bac..8f09abde45a867940c74e2b3971ac9a1328dbc5e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RNode.java @@ -158,6 +158,10 @@ public abstract class RNode extends Node { return RTypesGen.RTYPES.expectRDataFrame(execute(frame)); } + public RFactor executeRFactor(VirtualFrame frame) throws UnexpectedResultException { + return RTypesGen.RTYPES.expectRFactor(execute(frame)); + } + public RSymbol executeRSymbol(VirtualFrame frame) throws UnexpectedResultException { return RTypesGen.RTYPES.expectRSymbol(execute(frame)); } @@ -190,7 +194,7 @@ public abstract class RNode extends Node { return RTypesGen.RTYPES.expectRType(execute(frame)); } - public static boolean areSameLength(RAbstractVector a, RAbstractVector b) { + public static boolean areSameLength(RAbstractContainer a, RAbstractContainer b) { return a.getLength() == b.getLength(); } } 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 35d65aaf9e88ea41afe39e5cd0d9b0d8fb455df9..a6b85084e2b0933f0ebfad322aa1ce9c45c349c4 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 @@ -60,6 +60,8 @@ public abstract class ConstantNode extends RNode implements VisibilityController return new ConstantVectorNode((RAbstractVector) value); } else if (value instanceof RDataFrame) { return new ConstantDataFrameNode((RDataFrame) value); + } else if (value instanceof RFactor) { + return new ConstantFactorNode((RFactor) value); } else if (value instanceof RRaw) { return new ConstantRawNode((RRaw) value); } else if (value instanceof RFunction) { @@ -304,6 +306,27 @@ public abstract class ConstantNode extends RNode implements VisibilityController } } + private static final class ConstantFactorNode extends ConstantNode { + + private final RFactor factor; + + public ConstantFactorNode(RFactor factor) { + this.factor = factor; + } + + @Override + public RFactor executeRFactor(VirtualFrame frame) { + controlVisibility(); + return factor; + } + + @Override + public Object execute(VirtualFrame frame) { + controlVisibility(); + return factor; + } + } + private static final class ConstantRawNode extends ConstantNode { private final RRaw data; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index b80217f68c4c03d3253c78571d06e6d9d8bb2f5d..d8c732f9d642aef5e1f54539446aa27a8299a6a0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -701,6 +701,78 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_CONFORMABLE_ARRAYS); } + // factor and scalar + + @Specialization(guards = "!isEq") + protected RLogicalVector doFactorOp(RFactor left, Object right) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + } + + @Specialization(guards = "!isEq") + protected RLogicalVector doFactorOp(Object left, RFactor right) { + throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, int right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.intToString(right, false), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(int left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), RRuntime.intToString(left, false), true); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, double right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.doubleToString(right), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(double left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), RRuntime.doubleToString(left), true); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, byte right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.logicalToString(right), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(byte left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), RRuntime.logicalToString(left), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, String right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), right, false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(String left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), left, true); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, RComplex right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.complexToString(right), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RComplex left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), RRuntime.complexToString(left), true); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RFactor left, RRaw right) { + return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.rawToString(right), false); + } + + @Specialization(guards = "isEq") + protected RLogicalVector doFactorOp(RRaw left, RFactor right) { + return performStringVectorOp(RClosures.createFactorToStringVector(right, leftNACheck), RRuntime.rawToString(left), true); + } + protected static boolean differentDimensions(RAbstractVector left, RAbstractVector right) { if (!left.hasDimensions() || !right.hasDimensions()) { return false; @@ -791,6 +863,26 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(left, RClosures.createIntToStringVector(right, rightNACheck)); } + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doIntVectorDifferentLength(RAbstractIntVector left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createIntToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doIntVectorSameLength(RAbstractIntVector left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createIntToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doIntVectorDifferentLength(RFactor left, RAbstractIntVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createIntToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doIntVectorSameLength(RFactor left, RAbstractIntVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createIntToStringVector(right, rightNACheck)); + } + @Specialization(guards = "!areSameLength") protected RLogicalVector doIntVectorDifferentLength(RAbstractIntVector left, RComplexVector right) { return performComplexVectorOpDifferentLength(RClosures.createIntToComplexVector(left, leftNACheck), right); @@ -883,6 +975,26 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(left, RClosures.createDoubleToStringVector(right, rightNACheck)); } + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doDoubleVectorDifferentLength(RAbstractDoubleVector left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createDoubleToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doDoubleVectorSameLength(RAbstractDoubleVector left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createDoubleToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doDoubleVectorDifferentLength(RFactor left, RAbstractDoubleVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createDoubleToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doDoubleVectorSameLength(RFactor left, RAbstractDoubleVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createDoubleToStringVector(right, rightNACheck)); + } + @Specialization(guards = "!areSameLength") protected RLogicalVector doDoubleVectorDifferentLength(RAbstractDoubleVector left, RComplexVector right) { return performComplexVectorOpDifferentLength(RClosures.createDoubleToComplexVector(left, leftNACheck), right); @@ -955,6 +1067,26 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(left, RClosures.createLogicalToStringVector(right, rightNACheck)); } + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doLogicalVectorDifferentLength(RAbstractLogicalVector left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createLogicalToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doLogicalVectorSameLength(RAbstractLogicalVector left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createLogicalToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, leftNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doLogicalVectorDifferentLength(RFactor left, RAbstractLogicalVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createLogicalToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doLogicalVectorSameLength(RFactor left, RAbstractLogicalVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, leftNACheck), RClosures.createLogicalToStringVector(right, rightNACheck)); + } + @Specialization(guards = "!areSameLength") protected RLogicalVector doLogicalVectorDifferentLength(RAbstractLogicalVector left, RComplexVector right) { return performComplexVectorOpDifferentLength(RClosures.createLogicalToComplexVector(left, leftNACheck), right); @@ -1007,6 +1139,26 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(left, right); } + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RStringVector left, RFactor right) { + return performStringVectorOpDifferentLength(left, RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RStringVector left, RFactor right) { + return performStringVectorOpSameLength(left, RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RFactor left, RStringVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, rightNACheck), right); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RFactor left, RStringVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, rightNACheck), right); + } + @Specialization(guards = "!areSameLength") protected RLogicalVector doStringVectorDifferentLength(RStringVector left, RAbstractComplexVector right) { return performStringVectorOpDifferentLength(left, RClosures.createComplexToStringVector(right, rightNACheck)); @@ -1047,6 +1199,58 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(RClosures.createRawToStringVector(left, leftNACheck), right); } + // factor and vectors + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RFactor left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RFactor left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RFactor left, RAbstractComplexVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createComplexToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RFactor left, RAbstractComplexVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createComplexToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RAbstractComplexVector left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createComplexToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RAbstractComplexVector left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createComplexToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLength(RFactor left, RRawVector right) { + return performStringVectorOpDifferentLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createRawToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLength(RFactor left, RRawVector right) { + return performStringVectorOpSameLength(RClosures.createFactorToStringVector(left, rightNACheck), RClosures.createRawToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"!areSameLength", "isEq"}) + protected RLogicalVector doStringVectorDifferentLengthRRawVector(RRawVector left, RFactor right) { + return performStringVectorOpDifferentLength(RClosures.createRawToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + + @Specialization(guards = {"areSameLength", "isEq"}) + protected RLogicalVector doStringVectorSameLengthRRawVector(RRawVector left, RFactor right) { + return performStringVectorOpSameLength(RClosures.createRawToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); + } + // complex vector and vectors @Specialization(guards = "!areSameLength") @@ -1134,6 +1338,18 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { // guards + public boolean isEq(RFactor left, RFactor right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual; + } + + public boolean isEq(RFactor left, Object right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual; + } + + public boolean isEq(Object left, RFactor right) { + return !(logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual); + } + private boolean isVectorizedLogicalOp() { return !(logic instanceof BinaryLogic.And || logic instanceof BinaryLogic.Or); } 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 2e7305b88d64ee05f7369d610f0a48c5685742ef..17570328329ca7fca247dd8577f97e853c7036a6 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 @@ -553,7 +553,9 @@ public final class RError extends RuntimeException { FIRST_ELEMENT_USED("first element used of '%s' argument"), MUST_BE_COERCIBLE_INTEGER("argument must be coercible to non-negative integer"), DEFAULT_METHOD_NOT_IMPLEMENTED_FOR_TYPE("default method not implemented for type '%s'"), - ADDING_INVALID_CLASS("adding class \"%s\" to an invalid object"); + ADDING_INVALID_CLASS("adding class \"%s\" to an invalid object"), + IS_NA_TO_NON_VECTOR("is.na() applied to non-(list or vector) of type '%s'"), + NOT_MEANINGFUL_FOR_FACTORS("%s not meaningful for factors"); public final String message; private final boolean hasArgs; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index 6579249bf68bad3afb2bea4b37d09f7ba368ad27..f4a3e81da5c94fa07805b1fa1f5d3920c82baa19 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java @@ -214,6 +214,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } } + @TruffleBoundary public final void setLevels(Object newLevels) { if (attributes != null && newLevels == null) { // whether it's one dimensional array or not, assigning null always removes the "Levels" diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java index 2dfd14c197005f9bad72fd05df1c43567eb8d944..32b7d1c26275edecf13b3f7f6db3ce9af049c68e 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java @@ -23,6 +23,7 @@ package com.oracle.truffle.r.runtime.data.closures; import com.oracle.truffle.r.runtime.ops.na.NACheck; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; public class RClosures { @@ -101,4 +102,10 @@ public class RClosures { return new RComplexToStringVectorClosure(vector, check); } + // Factor to + + public static RAbstractStringVector createFactorToStringVector(RFactor factor, NACheck check) { + return new RFactorToStringVectorClosure(factor, check); + } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java index 22fc5f2164def5f8c60bafabda94c0163c0039da..0a614dc224f5f5cafc84402517093fa10a96b075 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java @@ -100,7 +100,7 @@ public abstract class BinaryCompare extends BooleanOperation { super(commutative, false); } - private static final class NotEqual extends BinaryCompare { + public static final class NotEqual extends BinaryCompare { public NotEqual() { super(true); @@ -144,7 +144,7 @@ public abstract class BinaryCompare extends BooleanOperation { } } - private static final class Equal extends BinaryCompare { + public static final class Equal extends BinaryCompare { public Equal() { super(true); 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 4c1ccfdf8c12d6f6bf890a50e93c33bec3edaa71..01212e5a0ae5b8a82a1f0dd113410a7cc972307f 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 @@ -8332,6 +8332,35 @@ NULL #{ x<-factor(c("a", "b", "a")); attr(x, "levels")<-character(); as.character(x) } [1] NA NA NA +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a")); x == "a" } +[1] TRUE FALSE TRUE + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a")); x == c("a", "b") } +[1] TRUE TRUE TRUE +Warning messages: +1: In is.na(e1) | is.na(e2) : + longer object length is not a multiple of shorter object length +2: In `==.default`(x, c("a", "b")) : + longer object length is not a multiple of shorter object length + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a")); x > "a" } +[1] NA NA NA +Warning message: +In Ops.factor(x, "a") : > not meaningful for factors + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a")); x > c("a", "b") } +[1] NA NA NA +Warning message: +In Ops.factor(x, c("a", "b")) : > not meaningful for factors + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a", "c")); x == c("a", "b") } +[1] TRUE TRUE TRUE FALSE + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor #{data = c(1,2,2,3,1,2,3,3,1,2,3,3,1);fdata<-factor(data);levels(fdata) = c('I','II','III');print(fdata);} [1] I II II III I II III III I II III III I diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java index d0877e00e11531382d33c697fb23ffc48ada1ce3..654d31fc5c2e6e6b619836ea9b036fdeec436be5 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java @@ -8113,6 +8113,16 @@ public class AllTests extends TestBase { assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); attr(x, \"levels\")<-character(); as.character(x) }"); } + @Test + public void TestSimpleBuiltins_testFactor_696be2cb6d37235d8e5aa08b6de78b44() { + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); x == \"a\" }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_6b857dc0c28485c71e998f91ad719e79() { + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\", \"c\")); x == c(\"a\", \"b\") }"); + } + @Test public void TestSimpleBuiltins_testFactor_2ef7de52def309425a9b70965111f004() { assertEvalError("{ x<-c(1,2,3); class(x)<-\"factor\"; x }"); @@ -8128,6 +8138,21 @@ public class AllTests extends TestBase { assertEvalError("{ x<-c(1L,2L,3L); class(x)<-\"factor\"; x }"); } + @Test + public void TestSimpleBuiltins_testFactor_8e866be378d6495f8d649996dcb5bb3c() { + assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > \"a\" }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_7cd2b27121f6c77b417a436d60108819() { + assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > c(\"a\", \"b\") }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_61bfd366e4db68e9bda18fe2c3cc87f2() { + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x == c(\"a\", \"b\") }"); + } + @Test public void TestSimpleBuiltins_testFileListing_9646bfd3fb553824f1f54cc5d04b8219() { assertEval("{ list.files(\"test/r/simple/data/tree1\") }"); 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 5dd75c552a11ce6c653d2c4f29b6e33b42e8b4ba..2a70539c45a9eed50f090eb6bfa79bcc9fe47222 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 @@ -3894,6 +3894,13 @@ public class TestSimpleBuiltins extends TestBase { assertEvalError("{ x<-c(1,2,3); class(x)<-\"factor\"; x }"); assertEvalError("{ x<-c(\"1\",\"2\",\"3\"); class(x)<-\"factor\"; x }"); assertEvalError("{ x<-c(1L,2L,3L); class(x)<-\"factor\"; x }"); + + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); x == \"a\" }"); + assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > \"a\" }"); + + 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\") }"); } @Test