diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java index a881407971880e04ca684dc1a66dd08129e1c4d9..ebf063b71dffefaff13aaf04a55a5eed6eb5f286 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java @@ -100,14 +100,14 @@ public class DynLoadFunctions { data[i] = dllInfo; } RList result = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)); - RVector.setClassAttr(result, RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS), null, null); + RVector.setVectorClassAttr(result, RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS), null, null); return result; } } private static RList createDLLInfoList(Object[] data) { RList dllInfo = RDataFactory.createList(data, RDataFactory.createStringVector(DLLInfo.NAMES, RDataFactory.COMPLETE_VECTOR)); - RVector.setClassAttr(dllInfo, RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS), null, null); + RVector.setVectorClassAttr(dllInfo, RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS), null, null); return dllInfo; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java index efa2d560ffd323ac0cb5ded1a4fdb5334c039087..9edbd53f30eb6535a8aad7e37eed72c8a606666b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java @@ -314,7 +314,7 @@ public class LaFunctions { RDoubleVector modulusVec = RDataFactory.createDoubleVectorFromScalar(modulus); modulusVec.setAttr("logarithm", useLogIn); RList result = RDataFactory.createList(new Object[]{modulusVec, sign}, NAMES_VECTOR); - RList.setClassAttr(result, DET_CLASS, null, null); + RList.setVectorClassAttr(result, DET_CLASS, null, null); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java index 4ffba92c5db28e803805d63af15646fb62857e07..fcc23b4d159c2eac5ce04b236226bdf2fad83153 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java @@ -79,10 +79,18 @@ public abstract class Structure extends RBuiltinNode { for (int i = 0; i < values.length; i++) { Object value = fixupValue(values[i]); String attrName = fixupAttrName(argNames[i + 1]); - if (value == RNull.instance) { - res.removeAttr(attrName); + if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { + if (value == RNull.instance) { + res = (RAbstractContainer) res.setClassAttr(null); + } else { + res = (RAbstractContainer) res.setClassAttr((RStringVector) value); + } } else { - res = (RAbstractContainer) res.setAttr(attrName, value); + if (value == RNull.instance) { + res.removeAttr(attrName); + } else { + res.setAttr(attrName, value); + } } } return res; 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 b00fa7944d4bfffbc4132821061510cf078301a9..78aa089824addcc4edd5c63a273d83dc567247cc 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 @@ -164,7 +164,7 @@ public abstract class TypeConvert extends RBuiltinNode { } RIntVector res = RDataFactory.createIntVector(data, complete); res.setLevels(RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); - return RVector.setClassAttr(res, RDataFactory.createStringVector("factor"), null, null); + return RVector.setVectorClassAttr(res, RDataFactory.createStringVector("factor"), null, null); } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java index eb31cd844a3b507e5dbdc44ca31776eb3da61af2..e5cf9deda213d3b50990031152b8629995aad884 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java @@ -35,7 +35,7 @@ public abstract class UnClass extends RBuiltinNode { if (resultVector.isShared()) { resultVector = resultVector.copy(); } - return RVector.setClassAttr(resultVector, null, null, null); + return RVector.setVectorClassAttr(resultVector, null, null, null); } return arg; } @@ -48,7 +48,7 @@ public abstract class UnClass extends RBuiltinNode { if (resultFrame.isShared()) { resultFrame = resultFrame.copy(); } - return RVector.setClassAttr(resultFrame.getVector(), null, arg, null); + return RVector.setVectorClassAttr(resultFrame.getVector(), null, arg, null); } @Specialization @@ -59,6 +59,6 @@ public abstract class UnClass extends RBuiltinNode { if (resultFrame.isShared()) { resultFrame = resultFrame.copy(); } - return RVector.setClassAttr(resultFrame.getVector(), null, null, arg); + return RVector.setVectorClassAttr(resultFrame.getVector(), null, null, arg); } } 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 9cc09ec1e4d84395cd5dea0798e1d1c1645ca325..5dc2897803a17a4a35e0067229a1fd98cc115e64 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 @@ -99,7 +99,7 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode { } else if (name.equals(RRuntime.DIMNAMES_ATTR_KEY)) { return updateDimNames(frame, resultVector, value); } else if (name.equals(RRuntime.CLASS_ATTR_KEY)) { - return RVector.setClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); + return RVector.setVectorClassAttr(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)) { @@ -114,11 +114,11 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode { @TruffleBoundary public static RAbstractContainer setClassAttrFromObject(RVector resultVector, RAbstractContainer container, Object value, SourceSection sourceSection) { if (value instanceof RStringVector) { - return RVector.setClassAttr(resultVector, (RStringVector) value, container.getElementClass() == RDataFrame.class ? container : null, + return RVector.setVectorClassAttr(resultVector, (RStringVector) value, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); } if (value instanceof String) { - return RVector.setClassAttr(resultVector, RDataFactory.createStringVector((String) value), container.getElementClass() == RDataFrame.class ? container : null, + return RVector.setVectorClassAttr(resultVector, RDataFactory.createStringVector((String) value), container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); } throw RError.error(sourceSection, RError.Message.SET_INVALID_CLASS_ATTR); 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 196a22df5bacf0f424000ad8a99e35d88d83016b..1026beea51f893fae726a59c2c250392da7d0f44 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 @@ -176,7 +176,7 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode { } } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { if (value == RNull.instance) { - res = RVector.setClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); + res = RVector.setVectorClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); } else { res = UpdateAttr.setClassAttrFromObject(resultVector, container, value, getEncapsulatingSourceSection()); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java index b3675f366db369c158ec27d7f1b2bf98afc7e8bc..37fa0e9d465ea96cd68cb0f540b5e68ec3131a63 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java @@ -61,7 +61,7 @@ public abstract class UpdateClass extends RBuiltinNode { protected Object setClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { controlVisibility(); RVector resultVector = arg.materializeNonSharedVector(); - return RVector.setClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); + return RVector.setVectorClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @Specialization @@ -102,7 +102,7 @@ public abstract class UpdateClass extends RBuiltinNode { throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_ARRAY_UPDATE_CLASS); } - return RVector.setClassAttr(resultVector, RDataFactory.createStringVector(className), arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg + return RVector.setVectorClassAttr(resultVector, RDataFactory.createStringVector(className), arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @@ -111,7 +111,7 @@ public abstract class UpdateClass extends RBuiltinNode { protected Object setClass(RAbstractContainer arg, RStringVector className) { controlVisibility(); RVector resultVector = arg.materializeNonSharedVector(); - return RVector.setClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); + return RVector.setVectorClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } public Object setClass(RFunction arg, @SuppressWarnings("unused") Object className) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java index c9d49853b917dadec1fc28443c79387dd7185d5e..bda5ebe634a64bbaaee2959a01c772c0840c4129 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java @@ -76,7 +76,7 @@ public abstract class UpdateOldClass extends RInvisibleBuiltinNode { protected Object setOldClass(RAbstractContainer arg, RStringVector className) { controlVisibility(); RVector resultVector = arg.materializeNonSharedVector(); - return RVector.setClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); + return RVector.setVectorClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @Specialization @@ -84,7 +84,7 @@ public abstract class UpdateOldClass extends RInvisibleBuiltinNode { protected Object setOldClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { controlVisibility(); RVector resultVector = arg.materializeNonSharedVector(); - return RVector.setClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); + return RVector.setVectorClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @TruffleBoundary diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java index 9203dd89db409b1e40366e494b344bdbc3074028..480169c013a924a88259accdc8287cd4048fb1a9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java @@ -64,7 +64,17 @@ public abstract class UpdateStorageMode extends RBuiltinNode { if (attrs != null) { RAttributable rresult = (RAttributable) result; for (RAttribute attr : attrs) { - rresult = rresult.setAttr(attr.getName(), attr.getValue()); + String attrName = attr.getName(); + Object v = attr.getValue(); + if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { + if (v == RNull.instance) { + rresult = rresult.setClassAttr(null); + } else { + rresult = rresult.setClassAttr((RStringVector) v); + } + } else { + rresult.setAttr(attrName, v); + } } } } 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 623bd07b9de50c87d9be1853181a41ebeb9407b3..42cc3f0d73727ff0f766e5231a30dc66ca76f5c1 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 @@ -189,7 +189,7 @@ public abstract class AccessArrayNode extends RNode { protected Object accessFactor(VirtualFrame frame, RFactor factor, int recLevel, Object position, RAbstractLogicalVector dropDim) { RIntVector res = (RIntVector) castVector(frame, accessRecursive(frame, factor.getVector(), position, recLevel, dropDim)); res.setLevels(factor.getVector().getAttr(RRuntime.LEVELS_ATTR_KEY)); - return RVector.setClassAttr(res, RDataFactory.createStringVector("factor"), null, null); + return RVector.setVectorClassAttr(res, RDataFactory.createStringVector("factor"), null, null); } @SuppressWarnings("unused") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java index 3b2e1647c639918a561c3c1d97aafa85331bdc0f..ca31defef717cb4c7268e3c49f94a3b39e86a222 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java @@ -88,6 +88,28 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { return specializeToUnaryOp().execute(frame, left); } + @Specialization + protected RLogicalVector doFactorOp(RFactor left, @SuppressWarnings("unused") RNull right) { + if (left.isOrdered()) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS, arithmetic.opName()); + + } else { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, arithmetic.opName()); + } + return RDataFactory.createNAVector(left.getLength() == 0 ? 1 : left.getLength()); + } + + @Specialization + protected RLogicalVector doFactorOp(@SuppressWarnings("unused") RNull left, RFactor right) { + if (right.isOrdered()) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS, arithmetic.opName()); + + } else { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, arithmetic.opName()); + } + return RDataFactory.createNAVector(right.getLength() == 0 ? 1 : right.getLength()); + } + @Specialization protected RDoubleVector doLeftNull(RNull left, RAbstractIntVector right) { return doRightNull(right, left); @@ -103,6 +125,12 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { return doRightNull(right, left); } + @SuppressWarnings("unused") + @Specialization(guards = "nonNumeric") + protected RComplexVector doLeftNull(RNull left, RAbstractVector right) { + throw RError.error(this.getSourceSection(), RError.Message.NON_NUMERIC_BINARY); + } + @Specialization protected RComplexVector doLeftNull(RNull left, RAbstractComplexVector right) { return doRightNull(right, left); @@ -132,31 +160,37 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { return RDataFactory.createEmptyComplexVector(); } + @SuppressWarnings("unused") + @Specialization(guards = "nonNumeric") + protected RComplexVector doRightNull(RAbstractVector left, RNull right) { + throw RError.error(this.getSourceSection(), RError.Message.NON_NUMERIC_BINARY); + } + @SuppressWarnings("unused") @Specialization protected RDoubleVector doRightNull(RNull left, RNull right) { return RDataFactory.createEmptyDoubleVector(); } - @Specialization - protected Object doLeftString(RAbstractStringVector left, Object right) { + @Specialization(guards = "!isFactorRight") + protected Object doLeftString(RAbstractStringVector left, RAbstractContainer right) { return doRightString(right, left); } @SuppressWarnings("unused") - @Specialization - protected Object doRightString(Object left, RAbstractStringVector right) { + @Specialization(guards = "!isFactorLeft") + protected Object doRightString(RAbstractContainer left, RAbstractStringVector right) { throw RError.error(this.getSourceSection(), RError.Message.NON_NUMERIC_BINARY); } - @Specialization - protected Object doLeftRaw(RAbstractRawVector left, Object right) { + @Specialization(guards = "!isFactorRight") + protected Object doLeftRaw(RAbstractRawVector left, RAbstractContainer right) { return doRightRaw(right, left); } @SuppressWarnings("unused") - @Specialization - protected Object doRightRaw(Object left, RAbstractRawVector right) { + @Specialization(guards = "!isFactorLeft") + protected Object doRightRaw(RAbstractContainer left, RAbstractRawVector right) { throw RError.error(this.getSourceSection(), RError.Message.NON_NUMERIC_BINARY); } @@ -490,6 +524,50 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { return performComplexVectorOpSameLength(left, right); } + // factors + + @Specialization + protected RLogicalVector doFactorOp(RFactor left, RAbstractContainer right) { + if (left.isOrdered()) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS, arithmetic.opName()); + + } else { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, arithmetic.opName()); + } + return RDataFactory.createNAVector(Math.max(left.getLength(), right.getLength())); + } + + @Specialization + protected RLogicalVector doFactorOp(RAbstractContainer left, RFactor right) { + if (right.isOrdered()) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS, arithmetic.opName()); + + } else { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, arithmetic.opName()); + } + return RDataFactory.createNAVector(Math.max(left.getLength(), right.getLength())); + } + + protected boolean nonNumeric(@SuppressWarnings("unused") RNull left, RAbstractContainer right) { + return right.getElementClass() == RString.class || right.getElementClass() == RRaw.class; + } + + protected boolean nonNumeric(RAbstractContainer left) { + return left.getElementClass() == RString.class || left.getElementClass() == RRaw.class; + } + + protected boolean isFactorLeft(RAbstractContainer left) { + return left.getElementClass() == RFactor.class; + } + + protected boolean isFactorRight(@SuppressWarnings("unused") RAbstractStringVector left, RAbstractContainer right) { + return right.getElementClass() == RFactor.class; + } + + protected boolean isFactorRight(@SuppressWarnings("unused") RAbstractRawVector left, RAbstractContainer right) { + return right.getElementClass() == RFactor.class; + } + // implementation private void copyAttributes(RVector ret, RAbstractVector left, RAbstractVector right) { 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 d1a4c5b129a9ca0b5bab5b66048f2aee13705b18..40bec6926fa771ed92988b51ca2b2782a1a1ffd0 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 @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.binary; +import java.util.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; @@ -293,12 +295,39 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { // null @Specialization - protected RLogicalVector doNull(RNull left, Object right) { + protected RLogicalVector doNull(RNull left, RNull right) { return RDataFactory.createLogicalVector(0); } - @Specialization - protected RLogicalVector doNull(Object left, RNull right) { + @Specialization(guards = "!isFactor") + protected RLogicalVector doNull(RNull left, RAbstractContainer right) { + return RDataFactory.createLogicalVector(0); + } + + @Specialization(guards = "!isFactor") + protected RLogicalVector doNull(RAbstractContainer left, RNull right) { + return RDataFactory.createLogicalVector(0); + } + + @Specialization(guards = "!meaningfulOp") + protected RLogicalVector doFactorOpError(RFactor left, RNull right) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + return RDataFactory.createNAVector(left.getLength() == 0 ? 1 : left.getLength()); + } + + @Specialization(guards = "!meaningfulOp") + protected RLogicalVector doFactorOpError(RNull left, RFactor right) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + return RDataFactory.createNAVector(right.getLength() == 0 ? 1 : right.getLength()); + } + + @Specialization(guards = "meaningfulOp") + protected RLogicalVector doFactorOp(RFactor left, RNull right) { + return RDataFactory.createLogicalVector(0); + } + + @Specialization(guards = "meaningfulOp") + protected RLogicalVector doFactorOp(RNull left, RFactor right) { return RDataFactory.createLogicalVector(0); } @@ -703,16 +732,6 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { // factor and scalar - @Specialization(guards = "!meaningfulOp") - protected RLogicalVector doFactorOp(RFactor left, Object right) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); - } - - @Specialization(guards = "!meaningfulOp") - protected RLogicalVector doFactorOp(Object left, RFactor right) { - throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); - } - @Specialization(guards = "meaningfulOp") protected RLogicalVector doFactorOp(RFactor left, int right) { return performStringVectorOp(RClosures.createFactorToStringVector(left, leftNACheck), RRuntime.intToString(right, false), false); @@ -1251,6 +1270,18 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { return performStringVectorOpSameLength(RClosures.createRawToStringVector(left, leftNACheck), RClosures.createFactorToStringVector(right, rightNACheck)); } + @Specialization(guards = "!meaningfulOp") + protected RLogicalVector doFactorOp(RFactor left, RAbstractContainer right) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + return RDataFactory.createNAVector(Math.max(left.getLength(), right.getLength())); + } + + @Specialization(guards = "!meaningfulOp") + protected RLogicalVector doFactorOp(RAbstractContainer left, RFactor right) { + RError.warning(getEncapsulatingSourceSection(), RError.Message.NOT_MEANINGFUL_FOR_FACTORS, logic.opName()); + return RDataFactory.createNAVector(Math.max(left.getLength(), right.getLength())); + } + // complex vector and vectors @Specialization(guards = "!areSameLength") @@ -1338,10 +1369,42 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { // guards + public boolean isFactor(RAbstractContainer left, RNull right) { + return left.getElementClass() == RFactor.class; + } + + public boolean isFactor(RNull left, RAbstractContainer right) { + return right.getElementClass() == RFactor.class; + } + + public boolean isFactor(RFactor left, RAbstractContainer right) { + return right.getElementClass() == RFactor.class; + } + + public boolean isFactor(RAbstractContainer left, RFactor right) { + return left.getElementClass() == RFactor.class; + } + public boolean meaningfulOp(RFactor left, RFactor right) { return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || (left.isOrdered() && right.isOrdered()); } + public boolean meaningfulOp(RFactor left, RNull right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || left.isOrdered(); + } + + public boolean meaningfulOp(RNull left, RFactor right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || right.isOrdered(); + } + + public boolean meaningfulOp(RFactor left, RAbstractContainer right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || left.isOrdered(); + } + + public boolean meaningfulOp(RAbstractContainer left, RFactor right) { + return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || right.isOrdered(); + } + public boolean meaningfulOp(RFactor left, Object right) { return logic instanceof BinaryCompare.Equal || logic instanceof BinaryCompare.NotEqual || left.isOrdered(); } 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 c5ad5fba8bd9cd6ff01f9fa949957950c2136c28..6e4f3226d39803fb3761b6179238b3d33db7c912 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 @@ -557,7 +557,8 @@ public final class RError extends RuntimeException { DEFAULT_METHOD_NOT_IMPLEMENTED_FOR_TYPE("default method not implemented for type '%s'"), 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"); + NOT_MEANINGFUL_FOR_FACTORS("%s not meaningful for factors"), + NOT_MEANINGFUL_FOR_ORDERED_FACTORS("'%s' is not meaningful for ordered factors"); public final String message; private final boolean hasArgs; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 30a6913553da083103bab1a31ae34fb27073b5a3..e2f49ac88dcbb020b042f773dd469427bde058a0 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -362,7 +362,7 @@ public class RSerialize { } else if (tag.equals(RRuntime.ROWNAMES_ATTR_KEY)) { vec.setRowNames(car); } else if (tag.equals(RRuntime.CLASS_ATTR_KEY)) { - result = RVector.setClassAttr(vec, (RStringVector) car, null, null); + result = RVector.setVectorClassAttr(vec, (RStringVector) car, null, null); } else { vec.setAttr(tag, car); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java index 3c51b93d1bdb1b184c2ed7f8a582bd5c9f25ada1..4b795f9d393c001b004791d4978f971340937459 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.env.*; /** @@ -48,13 +49,12 @@ public interface RAttributable { * Set the attribute {@code name} to {@code value}, overwriting any existing value. This is * generic; a class may need to override this to handle certain attributes specially. */ - default RAttributable setAttr(String name, Object value) { + default void setAttr(String name, Object value) { RAttributes attributes = getAttributes(); if (attributes == null) { attributes = initAttributes(); } attributes.put(name, value); - return this; } /** @@ -67,4 +67,10 @@ public interface RAttributable { attributes.remove(name); } } + + default RAttributable setClassAttr(RStringVector classAttr) { + setAttr(RRuntime.CLASS_ATTR_KEY, classAttr); + return this; + } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 1d19b5ae62deca786f9453d6ee25f403671f57a7..8c8f02ad26173dd8b5ff47c9e03392259e47dafc 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.runtime.data; +import java.util.*; + import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.RPromise.Closure; @@ -176,6 +178,12 @@ public final class RDataFactory { return traceDataCreated(new RLogicalVector(data, complete, dims, names)); } + public static RLogicalVector createNAVector(int length) { + byte[] data = new byte[length]; + Arrays.fill(data, RRuntime.LOGICAL_NA); + return createLogicalVector(data, INCOMPLETE_VECTOR); + } + public static RIntSequence createAscendingRange(int start, int end) { assert start <= end; return traceDataCreated(new RIntSequence(start, 1, end - start + 1)); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java index 3937de107a4e864f4215721134aa08ab12d1f853..41d6acbfbe38c1d2413e27f4028c8e0964754098 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java @@ -142,4 +142,9 @@ public final class RDataFrame implements RShareable, RAbstractContainer { return vector.getElementIndexByNameInexact(name); } + @Override + public RAbstractContainer setClassAttr(RStringVector classAttr) { + return RVector.setVectorClassAttr(vector, classAttr, this, null); + } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java index 600a7da4eef815eb085e2042803f08b597b23677..95330a9bb1f29368496be5893f746564e9f94bec 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java @@ -153,4 +153,9 @@ public final class RFactor implements RShareable, RAbstractContainer { vector.setLevels(newLevels); } + @Override + public RAbstractContainer setClassAttr(RStringVector classAttr) { + return RVector.setVectorClassAttr(vector, classAttr, null, this); + } + } 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 2b3a6961a4c433cc51504cf0b79f2757fa692df2..50e8e7f91f8bbd6391aafc4ffa6a4c805809ccc2 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 @@ -163,11 +163,10 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } @TruffleBoundary - public final RAbstractContainer setAttr(String name, Object value) { + public final void setAttr(String name, Object value) { if (attributes == null) { initAttributes(); } - RAbstractContainer res = this; if (name.equals(RRuntime.NAMES_ATTR_KEY)) { setNames(value); } else if (name.equals(RRuntime.DIM_ATTR_KEY)) { @@ -181,11 +180,10 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } else if (name.equals(RRuntime.ROWNAMES_ATTR_KEY)) { setRowNames(value); } else if (name.equals(RRuntime.CLASS_ATTR_KEY)) { - res = setClassAttr(this, (RStringVector) value, null, null); + throw Utils.nyi("The \"class\" attribute should be set using a separate method"); } else { attributes.put(name, value); } - return res; } public final Object getAttr(String name) { @@ -206,7 +204,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } else if (name.equals(RRuntime.ROWNAMES_ATTR_KEY)) { setRowNames(null); } else if (name.equals(RRuntime.CLASS_ATTR_KEY)) { - setClassAttr(this, (RStringVector) null, null, null); + throw Utils.nyi("The \"class\" attribute should be reset using a separate method"); } else { attributes.remove(name); } @@ -398,13 +396,22 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } } - public static RAbstractContainer setClassAttr(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame, RAbstractContainer enclosingFactor) { + @Override + public RAbstractContainer setClassAttr(RStringVector classAttr) { + return setClassAttrInternal(this, classAttr, null, null, true); + } + + public static RAbstractContainer setVectorClassAttr(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame, RAbstractContainer enclosingFactor) { + return setClassAttrInternal(vector, classAttr, enclosingDataFrame, enclosingFactor, false); + } + + private static RAbstractContainer setClassAttrInternal(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame, RAbstractContainer enclosingFactor, boolean convertToInt) { if (vector.attributes == null && classAttr != null && classAttr.getLength() != 0) { vector.initAttributes(); } if (vector.attributes != null && (classAttr == null || classAttr.getLength() == 0)) { vector.removeAttributeMapping(RRuntime.CLASS_ATTR_KEY); - // class attribute removed - no longer a data frame (even if it was before) + // class attribute removed - no longer a data frame or factor (even if it was before) return vector; } else if (classAttr != null && classAttr.getLength() != 0) { boolean ordered = false; @@ -425,17 +432,30 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV return RDataFactory.createDataFrame(vector); } } else if (RType.Factor.getName().equals(attr)) { - if (vector.getElementClass() != RInt.class) { - // TODO: add source section - throw RError.error(null, RError.Message.ADDING_INVALID_CLASS, "factor"); - } vector.putAttribute(RRuntime.CLASS_ATTR_KEY, classAttr); if (enclosingFactor != null) { // was a factor and still is a factor return enclosingFactor; } else { + RIntVector resVector; + if (vector.getElementClass() != RInt.class) { + if (vector.getElementClass() == RDouble.class && convertToInt) { + RAbstractDoubleVector sourceVector = (RAbstractDoubleVector) vector; + int[] data = new int[sourceVector.getLength()]; + for (int j = 0; j < data.length; j++) { + data[j] = RRuntime.double2int(sourceVector.getDataAt(j)); + } + resVector = RDataFactory.createIntVector(data, sourceVector.isComplete()); + resVector.copyAttributesFrom(sourceVector); + } else { + // TODO: add source section + throw RError.error(null, RError.Message.ADDING_INVALID_CLASS, "factor"); + } + } else { + resVector = (RIntVector) vector; + } // it's a factor now - return RDataFactory.createFactor((RIntVector) vector, ordered); + return RDataFactory.createFactor(resVector, ordered); } } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java index 1f7a32abe1f2513ef3e05c616dc5e8c7d9425a7e..bc37448c2807ca0676a435d9682e58efc4baffbd 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java @@ -136,6 +136,8 @@ public abstract class BinaryArithmetic extends Operation { return supportsIntResult; } + public abstract String opName(); + public abstract int op(int left, int right); public abstract double op(double left, double right); @@ -178,6 +180,11 @@ public abstract class BinaryArithmetic extends Operation { super(true, true, true); } + @Override + public String opName() { + return "+"; + } + @Override public int op(int left, int right) { try { @@ -227,6 +234,11 @@ public abstract class BinaryArithmetic extends Operation { super(false, false, true); } + @Override + public String opName() { + return "-"; + } + @Override public int op(int left, int right) { try { @@ -275,6 +287,11 @@ public abstract class BinaryArithmetic extends Operation { super(true, true, true); } + @Override + public String opName() { + return "*"; + } + @Override public int op(int left, int right) { try { @@ -398,6 +415,11 @@ public abstract class BinaryArithmetic extends Operation { super(false, false, false); } + @Override + public String opName() { + return "/"; + } + @Override public final int op(int left, int right) { throw RInternalError.shouldNotReachHere(); @@ -470,6 +492,11 @@ public abstract class BinaryArithmetic extends Operation { super(false, false, true); } + @Override + public String opName() { + return "%/%"; + } + @Override public int op(int left, int right) { if (right != 0) { @@ -510,6 +537,11 @@ public abstract class BinaryArithmetic extends Operation { super(false, false, true); } + @Override + public String opName() { + return "%%"; + } + @Override public int op(int left, int right) { // LICENSE: transcribed code from GNU R, which is licensed under GPL @@ -552,6 +584,11 @@ public abstract class BinaryArithmetic extends Operation { super(false, false, false); } + @Override + public String opName() { + return "^"; + } + @Override public int op(int left, int right) { throw RInternalError.shouldNotReachHere(); @@ -951,6 +988,11 @@ public abstract class BinaryArithmetic extends Operation { super(true, true, true); } + @Override + public String opName() { + throw Utils.nyi(); + } + @Override public int op(int left, int right) { return Math.max(left, right); @@ -980,6 +1022,11 @@ public abstract class BinaryArithmetic extends Operation { super(true, true, true); } + @Override + public String opName() { + throw Utils.nyi(); + } + @Override public int op(int left, int right) { return Math.min(left, right); 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 558be5cd61f64004d60fc7c4133659a96a3c103f..b5bd69a3358855ede2050fbc927e0d09c3cd2b57 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 @@ -8328,12 +8328,24 @@ Error in class(x) <- "factor" : Error in class(x) <- "factor" : adding class "factor" to an invalid object +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-c(1L, 2L, 1L); class(x)<-c("factor", "ordered"); levels(x)<-c("a", "b"); 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<-c(1L, 2L, 1L); class(x)<-c("factor", "ordered"); levels(x)<-c("a", "b"); 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<-c(1L, 2L, 1L); class(x)<-c("ordered", "factor"); levels(x)<-c("a", "b"); x + "a" } +[1] NA NA NA +Warning message: +In Ops.ordered(x, "a") : '+' is not meaningful for ordered factors + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor #{ x<-c(1L, 2L, 1L); class(x)<-c("ordered", "factor"); levels(x)<-c("a", "b"); x > "a" } [1] FALSE TRUE FALSE @@ -8354,6 +8366,18 @@ NULL #{ x<-factor(c("a", "b", "a")); is.atomic(x) } [1] TRUE +##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")); x == "a" } [1] TRUE FALSE TRUE @@ -8413,6 +8437,12 @@ Levels: a b #{ x<-factor(c("a", "b", "a"), ordered=TRUE); is.atomic(x) } [1] TRUE +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a"), ordered=TRUE); x + "a" } +[1] NA NA NA +Warning message: +In Ops.ordered(x, "a") : '+' is not meaningful for ordered factors + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor #{ x<-factor(c("a", "b", "a"), ordered=TRUE); x > "a" } [1] FALSE TRUE FALSE @@ -8448,6 +8478,45 @@ In y[1] <- x : Levels: a b c +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(1,2,1), .Label=c("a", "b"), class = c('factor'), .Names=c("111","112","113")); y<-structure(c(1,2,1), .Label=c("a", "b"), class = c('factor'), .Names=c("111","112","113")); x+y } +[1] NA NA NA +Warning message: +In Ops.factor(x, y) : + not meaningful for factors + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(1,2,1), .Label=c("a", "b"), class = c('factor'), .Names=c("111","112","113")); y<-structure(c(1,2,1), .Label=c("a", "b"), class = c('factor'), .Names=c("111","112","113")); x==y } +[1] TRUE TRUE TRUE + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(1.1,2.2,1.1), .Label=c("a", "b"), class = c('factor')); attributes(x) } +$levels +[1] "a" "b" + +$class +[1] "factor" + + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(1.1,2.2,1.1), .Label=c("a", "b"), class = c('factor')); x } +[1] a b a +Levels: a b + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(1.2,2.2,1.1), .Label=c("a", "b"), class = c('factor')); x } +[1] a b a +Levels: a b + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(c(2.2,3.2,2.1), .Label=c("a", "b"), class = c('factor')); as.integer(x) } +[1] 2 3 2 + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-structure(factor(c("a","b","c")), class=NULL); x } +[1] 1 2 3 +attr(,"levels") +[1] "a" "b" "c" + ##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 fb90a257aa2c0a196b13915fd21227016427c9ad..8f01be576944eb9643b8fc995eddac77bfe819fc 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 @@ -8188,6 +8188,36 @@ public class AllTests extends TestBase { assertEval("{ as.logical(factor(integer())) }"); } + @Test + public void TestSimpleBuiltins_testFactor_efa5f97d32564f78732db53e6862362e() { + assertEval("{ x<-structure(c(1.1,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); attributes(x) }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_d5fd844e772c2e96c1266f8c4e181e7a() { + assertEval("{ x<-structure(c(1.1,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); x }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_69974a637dd01d933a0274513b334646() { + assertEval("{ x<-structure(c(1.2,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); x }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_1d6da35b510c64fda496cd4d92b0b8dd() { + assertEval("{ x<-structure(c(2.2,3.2,2.1), .Label=c(\"a\", \"b\"), class = c('factor')); as.integer(x) }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_c97bd5071d6a70f07678a33414644e52() { + assertEval("{ x<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); y<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); x==y }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_a87228cb9283d7ba484ab0b60059e1bf() { + assertEval("{ x<-structure(factor(c(\"a\",\"b\",\"c\")), class=NULL); x }"); + } + @Test public void TestSimpleBuiltins_testFactor_2ef7de52def309425a9b70965111f004() { assertEvalError("{ x<-c(1,2,3); class(x)<-\"factor\"; x }"); @@ -8203,29 +8233,54 @@ public class AllTests extends TestBase { assertEvalError("{ x<-c(1L,2L,3L); class(x)<-\"factor\"; x }"); } + @Test + public void TestSimpleBuiltins_testFactor_778d87ada7ac057126f8a27cfe882a81() { + assertEvalError("{ x<-factor(c(\"c\", \"b\", \"a\", \"c\")); y<-c(1); y[[1]]<-x; y }"); + } + @Test public void TestSimpleBuiltins_testFactor_8e866be378d6495f8d649996dcb5bb3c() { - assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > \"a\" }"); + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x > \"a\" }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_cab09968ee0783bc157730e05358ed0c() { + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x + \"a\" }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_61bfd366e4db68e9bda18fe2c3cc87f2() { + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x == c(\"a\", \"b\") }"); } @Test public void TestSimpleBuiltins_testFactor_7cd2b27121f6c77b417a436d60108819() { - assertEvalError("{ x<-factor(c(\"a\", \"b\", \"a\")); x > c(\"a\", \"b\") }"); + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x > c(\"a\", \"b\") }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_a34678ac5082e00e15dd97ecd53f0e12() { + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x + c(\"a\", \"b\") }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_7b9d1da1c475fe180c3d19653a62003e() { + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\"), ordered=TRUE); x + \"a\" }"); } @Test public void TestSimpleBuiltins_testFactor_e1f4890b0e585468d589f92e64e8fe43() { - assertEvalError("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x > \"a\" }"); + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x > \"a\" }"); } @Test - public void TestSimpleBuiltins_testFactor_778d87ada7ac057126f8a27cfe882a81() { - assertEvalError("{ x<-factor(c(\"c\", \"b\", \"a\", \"c\")); y<-c(1); y[[1]]<-x; y }"); + public void TestSimpleBuiltins_testFactor_442949c79222d476ad19ed8d25f6d67b() { + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"ordered\", \"factor\"); levels(x)<-c(\"a\", \"b\"); x + \"a\" }"); } @Test - public void TestSimpleBuiltins_testFactor_61bfd366e4db68e9bda18fe2c3cc87f2() { - assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x == c(\"a\", \"b\") }"); + public void TestSimpleBuiltins_testFactor_b998c6b80f80df4ef39a60ff889bc0e4() { + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x + \"a\" }"); } @Test @@ -8238,6 +8293,11 @@ public class AllTests extends TestBase { assertEvalWarning("{ x<-factor(c(\"c\", \"b\", \"a\", \"c\")); y<-c(1); y[1]<-x; y }"); } + @Test + public void TestSimpleBuiltins_testFactor_79abe62e1800fec0bdfb1ee89b43889b() { + assertEvalWarning("{ x<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); y<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); x+y }"); + } + @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 ac3cfff7ea8519702fb6b060f60527a0c48dd152..6de5fbfd62bc46f254fa9c5c7888d6f80aad9262 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 @@ -3902,15 +3902,20 @@ public class TestSimpleBuiltins extends TestBase { 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 > \"a\" }"); + assertEvalWarning("{ 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\") }"); + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x > c(\"a\", \"b\") }"); + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\")); x + c(\"a\", \"b\") }"); assertEval("{ x<-factor(c(\"a\", \"b\", \"a\", \"c\")); x == c(\"a\", \"b\") }"); assertEval("{ x<-factor(c(\"a\", \"b\", \"a\"), ordered=TRUE); x > \"a\" }"); + assertEvalWarning("{ x<-factor(c(\"a\", \"b\", \"a\"), ordered=TRUE); x + \"a\" }"); assertEval("{ x<-c(1L, 2L, 1L); class(x)<-c(\"ordered\", \"factor\"); levels(x)<-c(\"a\", \"b\"); x > \"a\" }"); - assertEvalError("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x > \"a\" }"); + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x > \"a\" }"); + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"ordered\", \"factor\"); levels(x)<-c(\"a\", \"b\"); x + \"a\" }"); + assertEvalWarning("{ x<-c(1L, 2L, 1L); class(x)<-c(\"factor\", \"ordered\"); levels(x)<-c(\"a\", \"b\"); x + \"a\" }"); 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 }"); @@ -3929,6 +3934,17 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{ as.logical(factor(c(\"a\", \"b\", \"a\"))) }"); assertEval("{ as.logical(factor(integer())) }"); + + assertEval("{ x<-structure(c(1.1,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); attributes(x) }"); + assertEval("{ x<-structure(c(1.1,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); x }"); + assertEval("{ x<-structure(c(1.2,2.2,1.1), .Label=c(\"a\", \"b\"), class = c('factor')); x }"); + assertEval("{ x<-structure(c(2.2,3.2,2.1), .Label=c(\"a\", \"b\"), class = c('factor')); as.integer(x) }"); + + assertEval("{ x<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); y<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); x==y }"); + assertEvalWarning("{ x<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); y<-structure(c(1,2,1), .Label=c(\"a\", \"b\"), class = c('factor'), .Names=c(\"111\",\"112\",\"113\")); x+y }"); + + assertEval("{ x<-structure(factor(c(\"a\",\"b\",\"c\")), class=NULL); x }"); + } @Test