From b17d4f2c3876e0789953b52dd0fc264fc6b98447 Mon Sep 17 00:00:00 2001 From: Adam Welc <adam.welc@oracle.com> Date: Thu, 6 Nov 2014 11:55:57 +0100 Subject: [PATCH] Factors are now represented by a separate internal type. --- .../r/nodes/builtin/base/AsCharacter.java | 34 +++++ .../r/nodes/builtin/base/AsInteger.java | 7 + .../nodes/builtin/base/DynLoadFunctions.java | 4 +- .../r/nodes/builtin/base/Inherits.java | 6 +- .../r/nodes/builtin/base/LaFunctions.java | 2 +- .../r/nodes/builtin/base/Tabulate.java | 8 +- .../truffle/r/nodes/builtin/base/UnClass.java | 17 ++- .../r/nodes/builtin/base/UpdateAttr.java | 12 +- .../nodes/builtin/base/UpdateAttributes.java | 2 +- .../r/nodes/builtin/base/UpdateClass.java | 7 +- .../r/nodes/builtin/base/UpdateLevels.java | 19 ++- .../r/nodes/builtin/base/UpdateOldClass.java | 4 +- .../oracle/truffle/r/nodes/RProxyNode.java | 13 ++ .../com/oracle/truffle/r/nodes/RTypes.java | 4 +- .../nodes/access/array/ArrayPositionCast.java | 5 + .../r/nodes/function/WrapArgumentNode.java | 6 + .../r/nodes/unary/CastIntegerNode.java | 5 + .../truffle/r/nodes/unary/InheritsNode.java | 4 +- .../truffle/r/nodes/unary/PrecedenceNode.java | 5 + .../truffle/r/nodes/unary/TypeofNode.java | 10 ++ .../com/oracle/truffle/r/runtime/RError.java | 3 +- .../oracle/truffle/r/runtime/RRuntime.java | 1 + .../oracle/truffle/r/runtime/RSerialize.java | 2 +- .../truffle/r/runtime/data/RDataFactory.java | 4 + .../truffle/r/runtime/data/RDataFrame.java | 2 +- .../truffle/r/runtime/data/RFactor.java | 144 ++++++++++++++++++ .../truffle/r/runtime/data/RVector.java | 19 ++- .../truffle/r/test/ExpectedTestOutput.test | 38 +++++ .../oracle/truffle/r/test/all/AllTests.java | 45 ++++++ .../r/test/simple/TestSimpleBuiltins.java | 12 ++ 30 files changed, 410 insertions(+), 34 deletions(-) create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java index e8f4dc36a2..b841764a4e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java @@ -24,9 +24,12 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import java.util.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.Node.*; import com.oracle.truffle.r.nodes.function.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; @@ -40,6 +43,7 @@ public abstract class AsCharacter extends RBuiltinNode { @Child private CastStringNode castStringNode; @Child private DispatchedCallNode dcn; + @Child private CastToVectorNode castVector; private void initCast() { if (castStringNode == null) { @@ -48,6 +52,14 @@ public abstract class AsCharacter extends RBuiltinNode { } } + 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); + } + private String castString(VirtualFrame frame, int o) { initCast(); return (String) castStringNode.executeString(frame, o); @@ -141,6 +153,28 @@ public abstract class AsCharacter extends RBuiltinNode { } } + // TODO: this shold be handled by a generic function + @Specialization + protected Object doFactor(VirtualFrame frame, RFactor value) { + controlVisibility(); + Object attr = value.getVector().getAttr(RRuntime.LEVELS_ATTR_KEY); + if (attr == null) { + return RNull.instance; + } else { + RAbstractStringVector vec = (RAbstractStringVector) castVector(frame, attr); + String[] data = new String[value.getLength()]; + if (vec.getLength() == 0) { + Arrays.fill(data, RRuntime.STRING_NA); + return RDataFactory.createStringVector(data, RDataFactory.INCOMPLETE_VECTOR); + } else { + for (int i = 0; i < data.length; i++) { + data[i] = vec.getDataAt(value.getVector().getDataAt(i) - 1); + } + return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR); + } + } + } + protected boolean isObject(VirtualFrame frame, RAbstractVector vector) { return vector.isObject(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java index 8febf62b73..ff874767f2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java @@ -130,4 +130,11 @@ public abstract class AsInteger extends RBuiltinNode { controlVisibility(); return castIntVector(frame, vector); } + + @Specialization + protected RIntVector asInteger(RFactor factor) { + controlVisibility(); + return factor.getVector(); + } + } 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 dcd4e03591..a881407971 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); + RVector.setClassAttr(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); + RVector.setClassAttr(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/Inherits.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java index d5d2b80f68..254cdf49e3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java @@ -58,19 +58,19 @@ public abstract class Inherits extends RBuiltinNode { } @SuppressWarnings("unused") - public boolean whichFalse(RAbstractVector x, RAbstractStringVector what, byte which) { + public boolean whichFalse(RAbstractContainer x, RAbstractStringVector what, byte which) { return which != RRuntime.LOGICAL_TRUE; } @Specialization(guards = "whichFalse") - protected byte doInherits(VirtualFrame frame, RAbstractVector x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { + protected byte doInherits(VirtualFrame frame, RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { return initInheritsNode().execute(frame, x, what); } @TruffleBoundary // map operations lead to recursion resulting in compilation failure @Specialization(guards = "!whichFalse") - protected Object doesInherit(RAbstractVector x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { + protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) { Map<String, Integer> classToPos = InheritsNode.initClassToPos(x); int[] result = new int[what.getLength()]; for (int i = 0; i < what.getLength(); ++i) { 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 bbc832a386..efa2d560ff 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); + RList.setClassAttr(result, DET_CLASS, null, null); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java index 06a8471fff..8a03dfbcab 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java @@ -50,6 +50,12 @@ public abstract class Tabulate extends RBuiltinNode { return RDataFactory.createIntVector(ans, RDataFactory.COMPLETE_VECTOR); } + @Specialization(guards = {"isValidNBin"}) + @TruffleBoundary + public RIntVector tabulate(RFactor bin, int nBins) { + return tabulate(bin.getVector(), nBins); + } + @SuppressWarnings("unused") @Specialization public RIntVector tabulate(Object bin, int nBins) { @@ -57,7 +63,7 @@ public abstract class Tabulate extends RBuiltinNode { throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_INPUT); } - protected boolean isValidNBin(@SuppressWarnings("unused") RAbstractIntVector bin, int nBins) { + protected boolean isValidNBin(@SuppressWarnings("unused") RAbstractContainer bin, int nBins) { if (RRuntime.isNA(nBins) || nBins < 0) { throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARGUMENT, "nbin"); } 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 0af23a5b2e..eb31cd844a 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 @@ -15,8 +15,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.utilities.BranchProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.data.RDataFrame; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -36,7 +35,7 @@ public abstract class UnClass extends RBuiltinNode { if (resultVector.isShared()) { resultVector = resultVector.copy(); } - return RVector.setClassAttr(resultVector, null, null); + return RVector.setClassAttr(resultVector, null, null, null); } return arg; } @@ -49,7 +48,17 @@ public abstract class UnClass extends RBuiltinNode { if (resultFrame.isShared()) { resultFrame = resultFrame.copy(); } - return RVector.setClassAttr(resultFrame.getVector(), null, arg); + return RVector.setClassAttr(resultFrame.getVector(), null, arg, null); } + @Specialization + @TruffleBoundary + protected Object unClass(RFactor arg) { + controlVisibility(); + RFactor resultFrame = arg; + if (resultFrame.isShared()) { + resultFrame = resultFrame.copy(); + } + return RVector.setClassAttr(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 2fd0112738..69d3d49b10 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,23 +99,25 @@ 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() == RVector.class ? container : null); + 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 (resultVector.getAttributes() != null) { resultVector.getAttributes().remove(name); } // return frame if it's one, otherwise return the vector - return container.getElementClass() == RVector.class ? container : resultVector; + return container.getElementClass() == RDataFrame.class ? container : resultVector; } @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() == RVector.class ? container : null); + return RVector.setClassAttr(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() == RVector.class ? container : null); + return RVector.setClassAttr(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); } @@ -143,7 +145,7 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode { resultVector.setAttr(name, value); } // return frame if it's one, otherwise return the vector - return container.getElementClass() == RVector.class ? container : resultVector; + return container.getElementClass() == RDataFrame.class ? container : resultVector; } @Specialization(guards = "!nullValue") 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 467b7c5017..2dac8d6ef4 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 @@ -174,7 +174,7 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode { } } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { if (value == RNull.instance) { - RVector.setClassAttr(resultVector, null, container.getElementClass() == RVector.class ? container : null); + RVector.setClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null); } else { 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 c41ff936aa..b3675f366d 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() == RVector.class ? arg : null); + return RVector.setClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @Specialization @@ -102,7 +102,8 @@ 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() == RVector.class ? arg : null); + return RVector.setClassAttr(resultVector, RDataFactory.createStringVector(className), arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg + : null); } @Specialization @@ -110,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() == RVector.class ? arg : null); + return RVector.setClassAttr(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/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index 9a3c1b075e..b39f7f345d 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 @@ -15,8 +15,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RBuiltinKind; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import static com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -41,6 +40,22 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode { RVector v = vector.materialize(); v.setLevels(levels); return v; + } + + @Specialization + @TruffleBoundary + protected RFactor updateLevels(RFactor factor, @SuppressWarnings("unused") RNull levels) { + controlVisibility(); + factor.getVector().setLevels(null); + return factor; + } + @Specialization + @TruffleBoundary + protected RFactor updateLevels(RFactor factor, Object levels) { + controlVisibility(); + factor.getVector().setLevels(levels); + return factor; } + } 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 65dc054bb3..c9d49853b9 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() == RVector.class ? arg : null); + return RVector.setClassAttr(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() == RVector.class ? arg : null); + return RVector.setClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null); } @TruffleBoundary diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java index 5e3cdef138..335b598f5f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RProxyNode.java @@ -46,6 +46,10 @@ public abstract class RProxyNode extends RNode { return dataFrame; } + protected RFactor proxyFactor(RFactor factor) { + return factor; + } + @Specialization protected RNull wrap(RNull x) { return proxy(x); @@ -208,6 +212,15 @@ public abstract class RProxyNode extends RNode { return proxyDataFrame(x); } + @Specialization + protected RFactor wrap(RFactor x) { + return proxy(x); + } + + protected RFactor proxy(RFactor x) { + return proxyFactor(x); + } + @Specialization protected RMissing wrap(RMissing x) { return proxy(x); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTypes.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTypes.java index d0821bb765..06d4f6a547 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTypes.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTypes.java @@ -40,8 +40,8 @@ import com.oracle.truffle.r.runtime.env.*; @TypeSystem({boolean.class, byte.class, int.class, double.class, RRaw.class, RComplex.class, String.class, RIntSequence.class, RDoubleSequence.class, RIntVector.class, RDoubleVector.class, RRawVector.class, RComplexVector.class, RStringVector.class, RLogicalVector.class, RFunction.class, RNull.class, RMissing.class, REnvironment.class, RExpression.class, RConnection.class, MaterializedFrame.class, FrameSlot.class, RAbstractIntVector.class, RAbstractDoubleVector.class, RAbstractLogicalVector.class, RAbstractComplexVector.class, - RAbstractStringVector.class, RAbstractRawVector.class, RList.class, RAbstractVector.class, RDataFrame.class, RSymbol.class, RPromise.class, RLanguage.class, RPairList.class, - RFormula.class, RAbstractContainer.class, RArgsValuesAndNames.class, RType.class, Object[].class}) + RAbstractStringVector.class, RAbstractRawVector.class, RList.class, RAbstractVector.class, RDataFrame.class, RFactor.class, RSymbol.class, RPromise.class, RLanguage.class, + RPairList.class, RFormula.class, RAbstractContainer.class, RArgsValuesAndNames.class, RType.class, Object[].class}) public class RTypes { @TypeCheck 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 d2e24a2694..6904958bc3 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 @@ -266,6 +266,11 @@ public abstract class ArrayPositionCast extends ArrayPositionsCastBase { return castInteger.executeCast(frame, operand); } + @Specialization + protected Object doFactor(VirtualFrame frame, RAbstractContainer container, RFactor factor) { + return convertOperatorRecursive(frame, container, factor.getVector()); + } + @Specialization protected RList doList(RAbstractContainer container, RList operand) { return operand; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java index b66b6d8d0b..4ee1159015 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java @@ -70,6 +70,12 @@ public abstract class WrapArgumentNode extends RProxyNode { return dataFrame; } + @Override + protected RFactor proxyFactor(RFactor factor) { + proxyVector(factor.getVector()); + return factor; + } + public abstract RNode getOperand(); public static WrapArgumentNode create(RNode operand, boolean modeChange) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java index 1a903880cc..9986440352 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java @@ -412,6 +412,11 @@ public abstract class CastIntegerNode extends CastNode { return ret; } + @Specialization + protected RIntVector doFactor(RFactor factor) { + return factor.getVector(); + } + private RError cannotCoerceListError() { throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "integer"); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java index e1fc7ff143..15c0e4ee65 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java @@ -42,7 +42,7 @@ public abstract class InheritsNode extends BinaryNode { // map operations lead to recursion resulting in compilation failure @Specialization - protected Object doesInherit(RAbstractVector x, RAbstractStringVector what) { + protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what) { Map<String, Integer> classToPos = initClassToPos(x); for (int i = 0; i < what.getLength(); ++i) { if (classToPos.get(what.getDataAt(i)) != null) { @@ -53,7 +53,7 @@ public abstract class InheritsNode extends BinaryNode { } @TruffleBoundary - public static Map<String, Integer> initClassToPos(RAbstractVector x) { + public static Map<String, Integer> initClassToPos(RAbstractContainer x) { RStringVector klass = x.getClassHierarchy(); // Create a mapping for elements to their respective positions diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java index 4f1f70e368..42aa8f6b56 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java @@ -161,6 +161,11 @@ public abstract class PrecedenceNode extends UnaryNode { return EXPRESSION_PRECEDENCE; } + @Specialization + protected int doFactor(RFactor val, byte recursive) { + return INT_PRECEDENCE; + } + protected boolean isRecursive(RList val, byte recursive) { return recursive == RRuntime.LOGICAL_TRUE; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java index 3a58e82ef7..43c1b04356 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/TypeofNode.java @@ -162,6 +162,16 @@ public abstract class TypeofNode extends UnaryNode { return RType.Integer; } + @Specialization + protected RType typeof(RDataFrame frame) { + return RType.List; + } + + @Specialization + protected RType typeof(RFactor factor) { + return RType.Integer; + } + public static boolean isFunctionBuiltin(RFunction fun) { return fun.isBuiltin(); } 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 aee0e82ae3..2e7305b88d 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 @@ -552,7 +552,8 @@ public final class RError extends RuntimeException { UNEXPECTED("unexpected '%s' in \"%s\""), 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'"); + DEFAULT_METHOD_NOT_IMPLEMENTED_FOR_TYPE("default method not implemented for type '%s'"), + ADDING_INVALID_CLASS("adding class \"%s\" to an invalid object"); public final String message; private final boolean hasArgs; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java index b7e737ffc7..69f26f12cc 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java @@ -93,6 +93,7 @@ public class RRuntime { public static final String DIMNAMES_LIST_ELEMENT_NAME_PREFIX = "$dimnames"; public static final String CLASS_ATTR_KEY = "class"; + public static final String FACTOR_ATTR_KEY = "factor"; public static final String PREVIOUS_ATTR_KEY = "previous"; public static final String ROWNAMES_ATTR_KEY = "row.names"; 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 55062856a5..290652e0f5 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)) { - RVector.setClassAttr(vec, (RStringVector) car, null); + RVector.setClassAttr(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/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 085c73acad..c5ea07be92 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 @@ -300,6 +300,10 @@ public final class RDataFactory { return traceDataCreated(new RExpression(list)); } + public static RFactor createFactor(RIntVector vector) { + return traceDataCreated(new RFactor(vector)); + } + public static RVector createObjectVector(Object[] data, boolean completeVector) { if (data.length < 1) { return null; 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 234e6cd0b7..d008396f97 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 @@ -78,7 +78,7 @@ public final class RDataFrame implements RShareable, RAbstractContainer { @Override public Class<?> getElementClass() { - return RVector.class; + return RDataFrame.class; } @Override 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 new file mode 100644 index 0000000000..f58a701846 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.runtime.data; + +import com.oracle.truffle.r.runtime.data.model.*; + +public final class RFactor implements RShareable, RAbstractContainer { + + private RIntVector vector; + + public RFactor(RIntVector vector) { + this.vector = vector; + } + + public RIntVector getVector() { + return vector; + } + + @Override + public int getLength() { + return vector.getLength(); + } + + @Override + public void markNonTemporary() { + vector.markNonTemporary(); + } + + @Override + public boolean isTemporary() { + return vector.isTemporary(); + } + + @Override + public boolean isShared() { + return vector.isShared(); + } + + @Override + public RVector makeShared() { + return vector.makeShared(); + } + + @Override + public RFactor copy() { + return RDataFactory.createFactor((RIntVector) vector.copy()); + } + + @Override + public RAttributes getAttributes() { + return vector.getAttributes(); + } + + @Override + public int[] getDimensions() { + return vector.getDimensions(); + } + + @Override + public Class<?> getElementClass() { + return RFactor.class; + } + + @Override + public RVector materializeNonSharedVector() { + if (isShared()) { + vector = (RIntVector) vector.copy(); + vector.markNonTemporary(); + } + return vector; + } + + @Override + public Object getDataAtAsObject(int index) { + return vector.getDataAtAsObject(index); + } + + @Override + public Object getNames() { + return vector.getNames(); + } + + @Override + public RList getDimNames() { + return vector.getDimNames(); + } + + @Override + public Object getRowNames() { + return vector.getRowNames(); + } + + @Override + public RStringVector getClassHierarchy() { + return vector.getClassHierarchy(); + } + + @Override + public boolean isObject() { + return true; + } + + public RAttributes initAttributes() { + return vector.initAttributes(); + } + + @Override + public RShareable materializeToShareable() { + return this; + } + + public int getElementIndexByName(String name) { + return vector.getElementIndexByName(name); + } + + public int getElementIndexByNameInexact(String name) { + return vector.getElementIndexByNameInexact(name); + } + + public void setLevels(Object newLevels) { + vector.setLevels(newLevels); + } + +} 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 a1d351e9e2..6579249bf6 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 @@ -180,7 +180,7 @@ 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)) { - setClassAttr(this, (RStringVector) value, null); + setClassAttr(this, (RStringVector) value, null, null); } else { attributes.put(name, value); } @@ -204,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); + setClassAttr(this, (RStringVector) null, null, null); } else { attributes.remove(name); } @@ -399,7 +399,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV } } - public static RAbstractContainer setClassAttr(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame) { + public static RAbstractContainer setClassAttr(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame, RAbstractContainer enclosingFactor) { if (vector.attributes == null && classAttr != null && classAttr.getLength() != 0) { vector.initAttributes(); } @@ -418,6 +418,19 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV // it's a data frame now return RDataFactory.createDataFrame(vector); } + } else if (RType.Factor.getName().equals(classAttr.getDataAt(i))) { + 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 { + // it's a factor now + return RDataFactory.createFactor((RIntVector) vector); + } } } vector.putAttribute(RRuntime.CLASS_ATTR_KEY, classAttr); 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 bd88572dd4..6f9e43f335 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 @@ -8269,6 +8269,28 @@ x [1,] 10+0i -4+0i [2,] -2+0i 0+0i +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-c("1","2","3"); class(x)<-"factor"; x } +Error in class(x) <- "factor" : + adding class "factor" to an invalid object + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-c(1,2,3); class(x)<-"factor"; x } +Error in class(x) <- "factor" : + adding class "factor" to an invalid object + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-c(1L,2L,3L); class(x)<-"factor"; x } +Error in print.factor(1:3) : replacement has length zero + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ x<-factor(c("a", "b", "a")); attr(x, "levels")<-NULL; as.character(x) } +NULL + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testFactor +#{ 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 #{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 @@ -8510,6 +8532,14 @@ NULL #{ inherits(new.env(), "try-error") } [1] FALSE +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits +#{ x<-data.frame(c(1,2)); inherits(x, "data.frame") } +[1] TRUE + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits +#{ x<-factor("a", "b", "a"); inherits(x, "factor") } +[1] TRUE + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits #{x <- 10; inherits(x, "a") ;} [1] FALSE @@ -14224,6 +14254,14 @@ Error in typeof(...) : unused arguments (2, 3, 4) #{ typeof(typeof(NULL)) } [1] "character" +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testTypeOf +#{ x<-data.frame(c("a", "b", "a")); typeof(x) } +[1] "list" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testTypeOf +#{ x<-factor(c("a", "b", "a")); typeof(x) } +[1] "integer" + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testUnlist #{ names(unlist(list(a=list(b=list("1"))))) } [1] "a.b" 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 88e8c8372a..c50e14f06b 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 @@ -8053,6 +8053,31 @@ public class AllTests extends TestBase { assertEval("{ses <- c(\"low\", \"middle\", \"low\", \"low\", \"low\", \"low\", \"middle\", \"low\", \"middle\", \"middle\", \"middle\", \"middle\", \"middle\", \"high\", \"high\", \"low\", \"middle\", \"middle\", \"low\", \"high\"); ses.f.bad.order <- factor(ses); is.factor(ses.f.bad.order);levels(ses.f.bad.order);ses.f <- factor(ses, levels = c(\"low\", \"middle\", \"high\"));ses.order <- ordered(ses, levels = c(\"low\", \"middle\", \"high\"));print(ses.order); } "); } + @Test + public void TestSimpleBuiltins_testFactor_6287c53e3c5f805807ac27e404a05595() { + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); attr(x, \"levels\")<-NULL; as.character(x) }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_6057e63e95871f7ed5c00eb75931ac57() { + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); attr(x, \"levels\")<-character(); as.character(x) }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_2ef7de52def309425a9b70965111f004() { + assertEvalError("{ x<-c(1,2,3); class(x)<-\"factor\"; x }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_7a9b1db57fd6e717cb6a5a4289638383() { + assertEvalError("{ x<-c(\"1\",\"2\",\"3\"); class(x)<-\"factor\"; x }"); + } + + @Test + public void TestSimpleBuiltins_testFactor_78f60bd3f5d980d4b71b67fa44964e85() { + assertEvalError("{ x<-c(1L,2L,3L); class(x)<-\"factor\"; x }"); + } + @Test public void TestSimpleBuiltins_testFileListing_9646bfd3fb553824f1f54cc5d04b8219() { assertEval("{ list.files(\"test/r/simple/data/tree1\") }"); @@ -8418,6 +8443,16 @@ public class AllTests extends TestBase { assertEval("{ inherits(new.env(), \"try-error\") }"); } + @Test + public void TestSimpleBuiltins_testInherits_04a77c3cfe28848e28a68ba564162427() { + assertEval("{ x<-data.frame(c(1,2)); inherits(x, \"data.frame\") }"); + } + + @Test + public void TestSimpleBuiltins_testInherits_20d6545f67c653e20d3b612df41b64c2() { + assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }"); + } + @Test public void TestSimpleBuiltins_testInheritsIgnore_d0dc6389c924878311546ba61d753a22() { assertEval("{x <- 10;class(x) <- c(\"a\", \"b\");inherits(x, 2, c(TRUE)) ;}"); @@ -14918,6 +14953,16 @@ public class AllTests extends TestBase { assertEval("{ f <- function(...) typeof(...); f(1, 2, 3, 4)}"); } + @Test + public void TestSimpleBuiltins_testTypeOf_d63eb623f4c13b74dc9704bb857ca416() { + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); typeof(x) }"); + } + + @Test + public void TestSimpleBuiltins_testTypeOf_4b90c824616e773167165340b6cfea37() { + assertEval("{ x<-data.frame(c(\"a\", \"b\", \"a\")); typeof(x) }"); + } + @Test public void TestSimpleBuiltins_testTypeOfIgnore_847d333bfb40729281acd0b949d4c097() { assertEval("{ f <- function(...) typeof(...); f()}"); 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 1faa2e5c7c..0d91359ab0 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 @@ -1592,6 +1592,9 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{ f <- function(...) typeof(...); f(1, 2)}"); assertEval("{ f <- function(...) typeof(...); f(1, 2, 3)}"); assertEval("{ f <- function(...) typeof(...); f(1, 2, 3, 4)}"); + + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); typeof(x) }"); + assertEval("{ x<-data.frame(c(\"a\", \"b\", \"a\")); typeof(x) }"); } @Test @@ -3291,6 +3294,9 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{x <- 10;class(x) <- c(\"a\", \"b\");inherits(x, \"a\", c(TRUE)) ;}"); assertEval("{ inherits(NULL, \"try-error\") }"); assertEval("{ inherits(new.env(), \"try-error\") }"); + + assertEval("{ x<-data.frame(c(1,2)); inherits(x, \"data.frame\") }"); + assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }"); } @Test @@ -3871,6 +3877,12 @@ public class TestSimpleBuiltins extends TestBase { // Checkstyle: stop line length check assertEval("{ses <- c(\"low\", \"middle\", \"low\", \"low\", \"low\", \"low\", \"middle\", \"low\", \"middle\", \"middle\", \"middle\", \"middle\", \"middle\", \"high\", \"high\", \"low\", \"middle\", \"middle\", \"low\", \"high\"); ses.f.bad.order <- factor(ses); is.factor(ses.f.bad.order);levels(ses.f.bad.order);ses.f <- factor(ses, levels = c(\"low\", \"middle\", \"high\"));ses.order <- ordered(ses, levels = c(\"low\", \"middle\", \"high\"));print(ses.order); } "); // Checkstyle: resume line length check + + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); attr(x, \"levels\")<-NULL; as.character(x) }"); + assertEval("{ x<-factor(c(\"a\", \"b\", \"a\")); attr(x, \"levels\")<-character(); as.character(x) }"); + 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 }"); } @Test -- GitLab