Skip to content
Snippets Groups Projects
Commit 3fe17cdc authored by Adam Welc's avatar Adam Welc
Browse files

Merge pull request #253 in G/fastr from...

Merge pull request #253 in G/fastr from ~ADAM.WELC_ORACLE.COM/fastr:feature/builtins_sprint to master

* commit '0d32f917':
  Rewritten parameter casts for duplicated and anyDuplicated builtins.
  Simplified parameter cast to use freshly added abstract vector check.
  Added test for abstract vector to cast builder.
parents 94cac98a 0d32f917
Branches
No related tags found
No related merge requests found
......@@ -49,7 +49,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
......@@ -85,7 +84,7 @@ public abstract class Array extends RBuiltinNode {
@Override
protected void createCasts(CastBuilder casts) {
Function<Object, Object> argType = this::argType;
casts.arg("data").mustBe(instanceOf(RAbstractListVector.class).or(numericValue()).or(stringValue()).or(complexValue().or(rawValue())),
casts.arg("data").mustBe(abstractVectorValue(),
RError.SHOW_CALLER, RError.Message.MUST_BE_VECTOR_BUT_WAS, "data",
argType);
casts.arg("dim").asIntegerVector().mustBe(notEmpty(), RError.SHOW_CALLER, RError.Message.CANNOT_BE_LENGTH, "dims", 0);
......
......@@ -11,26 +11,30 @@
package com.oracle.truffle.r.nodes.builtin.base;
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.binary.CastTypeNode;
import com.oracle.truffle.r.nodes.binary.CastTypeNodeGen;
import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.nodes.unary.TypeofNode;
import com.oracle.truffle.r.nodes.unary.TypeofNodeGen;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.RType;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RLogicalVector;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RTypedValue;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
import com.oracle.truffle.r.runtime.nodes.DuplicationHelper;
public class DuplicatedFunctions {
......@@ -39,8 +43,24 @@ public class DuplicatedFunctions {
@Child protected CastTypeNode castTypeNode;
@Child protected TypeofNode typeof;
protected boolean isIncomparable(byte incomparables) {
return incomparables == RRuntime.LOGICAL_TRUE;
private final ConditionProfile incomparable = ConditionProfile.createBinaryProfile();
protected void casts(CastBuilder casts) {
casts.arg("x").mustBe(nullValue().or(abstractVectorValue()), RError.SHOW_CALLER, RError.Message.GENERIC,
"duplicated() applies only to vectors").asVector();
casts.arg("fromLast").asLogicalVector().findFirst();
}
protected boolean isIncomparable(RAbstractVector incomparables) {
if (incomparable.profile(incomparables.getLength() == 1 && incomparables instanceof RLogicalVector && ((RAbstractLogicalVector) incomparables).getDataAt(0) == RRuntime.LOGICAL_FALSE)) {
return false;
} else {
return true;
}
}
protected boolean notAbstractVector(Object o) {
return !(o instanceof RAbstractVector);
}
protected boolean empty(RAbstractContainer x) {
......@@ -61,45 +81,45 @@ public class DuplicatedFunctions {
@Override
protected void createCasts(CastBuilder casts) {
casts.toLogical(2).toInteger(3);
casts(casts);
// currently not supported and not tested, but NA is a correct value (the same for empty
// vectors) whereas 0 is not (throws an error)
casts.arg("nmax").asIntegerVector().findFirst(RRuntime.INT_NA);
}
@TruffleBoundary
protected static RLogicalVector analyzeAndCreateResult(RAbstractContainer x, RAbstractContainer incomparables, byte fromLast) {
protected static RLogicalVector analyzeAndCreateResult(RAbstractVector x, RAbstractVector incomparables, byte fromLast) {
DuplicationHelper ds = DuplicationHelper.analyze(x, incomparables, false, RRuntime.fromLogical(fromLast));
return RDataFactory.createLogicalVector(ds.getDupVec(), RDataFactory.COMPLETE_VECTOR);
}
@SuppressWarnings("unused")
@Specialization
protected RLogicalVector duplicated(RNull x, Object incomparables, byte fromLast, int nmax) {
return RDataFactory.createEmptyLogicalVector();
}
@Specialization(guards = {"!isIncomparable(incomparables)", "!empty(x)"})
protected RLogicalVector duplicatedFalseIncomparables(RAbstractVector x, @SuppressWarnings("unused") byte incomparables, byte fromLast, @SuppressWarnings("unused") int nmax) {
protected RLogicalVector duplicatedFalseIncomparables(RAbstractVector x, @SuppressWarnings("unused") RAbstractVector incomparables, byte fromLast, @SuppressWarnings("unused") int nmax) {
return analyzeAndCreateResult(x, null, fromLast);
}
@Specialization(guards = {"isIncomparable(incomparables)", "!empty(x)"})
protected RLogicalVector duplicatedTrueIncomparables(RAbstractVector x, byte incomparables, byte fromLast, @SuppressWarnings("unused") int nmax) {
protected RLogicalVector duplicatedTrueIncomparables(RAbstractVector x, RAbstractVector incomparables, byte fromLast, @SuppressWarnings("unused") int nmax) {
initChildren();
RType xType = typeof.execute(x);
RAbstractVector vector = (RAbstractVector) (castTypeNode.execute(incomparables, xType));
return analyzeAndCreateResult(x, vector, fromLast);
}
@Specialization(guards = {"!empty(x)"})
protected RLogicalVector duplicated(RAbstractContainer x, RAbstractContainer incomparables, byte fromLast, @SuppressWarnings("unused") int nmax) {
@SuppressWarnings("unused")
@Specialization(guards = {"notAbstractVector(incomparables)", "!empty(x)"})
protected RLogicalVector duplicatedTrueIncomparables(RAbstractVector x, Object incomparables, byte fromLast, int nmax) {
initChildren();
RType xType = typeof.execute(x);
return analyzeAndCreateResult(x, (RAbstractContainer) (castTypeNode.execute(incomparables, xType)), fromLast);
// TODO: this is not quite correct, as passing expression generated some obscure error
// message, but is it worth fixing
throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_COERCE, ((RTypedValue) incomparables).getRType().getName(), xType.getName());
}
@SuppressWarnings("unused")
@Specialization(guards = "empty(x)")
protected RLogicalVector duplicatedEmpty(RAbstractContainer x, RAbstractContainer incomparables, byte fromLast, int nmax) {
return RDataFactory.createLogicalVector(0);
protected RLogicalVector duplicatedEmpty(RAbstractVector x, Object incomparables, byte fromLast, int nmax) {
return RDataFactory.createEmptyLogicalVector();
}
}
......@@ -108,40 +128,36 @@ public class DuplicatedFunctions {
@Override
protected void createCasts(CastBuilder casts) {
casts.toLogical(2);
casts(casts);
}
@SuppressWarnings("unused")
@Specialization(guards = {"!isIncomparable(incomparables)", "!empty(x)"})
protected int anyDuplicatedFalseIncomparables(RAbstractVector x, byte incomparables, byte fromLast) {
protected int anyDuplicatedFalseIncomparables(RAbstractVector x, RAbstractVector incomparables, byte fromLast) {
return DuplicationHelper.analyze(x, null, true, RRuntime.fromLogical(fromLast)).getIndex();
}
@Specialization(guards = {"isIncomparable(incomparables)", "!empty(x)"})
protected int anyDuplicatedTrueIncomparables(RAbstractVector x, byte incomparables, byte fromLast) {
protected int anyDuplicatedTrueIncomparables(RAbstractVector x, RAbstractVector incomparables, byte fromLast) {
initChildren();
RType xType = typeof.execute(x);
RAbstractVector vector = (RAbstractVector) (castTypeNode.execute(incomparables, xType));
return DuplicationHelper.analyze(x, vector, true, RRuntime.fromLogical(fromLast)).getIndex();
return DuplicationHelper.analyze(x, (RAbstractVector) (castTypeNode.execute(incomparables, xType)), true, RRuntime.fromLogical(fromLast)).getIndex();
}
@Specialization(guards = {"!empty(x)"})
protected int anyDuplicated(RAbstractContainer x, RAbstractContainer incomparables, byte fromLast) {
@Specialization(guards = {"notAbstractVector(incomparables)", "!empty(x)"})
protected int anyDuplicatedTrueIncomparables(RAbstractVector x, Object incomparables, @SuppressWarnings("unused") byte fromLast) {
initChildren();
RType xType = typeof.execute(x);
return DuplicationHelper.analyze(x, (RAbstractContainer) (castTypeNode.execute(incomparables, xType)), true, RRuntime.fromLogical(fromLast)).getIndex();
// TODO: this is not quite correct, as passing expression generated some obscure error
// message, but is it worth fixing
throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_COERCE, ((RTypedValue) incomparables).getRType().getName(), xType.getName());
}
@SuppressWarnings("unused")
@Specialization(guards = "empty(x)")
protected int anyDuplicatedEmpty(RAbstractContainer x, RAbstractContainer incomparables, byte fromLast) {
protected int anyDuplicatedEmpty(RAbstractVector x, Object incomparables, byte fromLast) {
return 0;
}
@SuppressWarnings("unused")
@Specialization
protected int anyDuplicatedNull(RNull x, RAbstractContainer incomparables, byte fromLast) {
return 0;
}
}
}
......@@ -64,6 +64,7 @@ import com.oracle.truffle.r.runtime.data.RRaw;
import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
......@@ -995,6 +996,10 @@ public final class CastBuilder {
return integerValue().or(doubleValue()).or(logicalValue());
}
public static ArgumentTypeFilter<Object, Object> abstractVectorValue() {
return numericValue().or(stringValue()).or(complexValue()).or(rawValue()).or(instanceOf(RAbstractListVector.class));
}
public static TypePredicateArgumentFilter<Object, String> scalarStringValue() {
return predefFilters().scalarStringValue();
}
......
......@@ -18164,6 +18164,11 @@ logical(0)
#{ duplicated(c(1,2,1)) }
[1] FALSE FALSE TRUE
 
##com.oracle.truffle.r.test.builtins.TestBuiltin_duplicated.testDuplicated
#{ duplicated(c(1,2,1), incomparables=function() 42) }
Error in duplicated.default(c(1, 2, 1), incomparables = function() 42) :
cannot coerce type 'closure' to vector of type 'double'
##com.oracle.truffle.r.test.builtins.TestBuiltin_duplicated.testDuplicated
#{ duplicated(c(1,2,3,2), incomparables = c(2+6i)) }
[1] FALSE FALSE FALSE FALSE
......@@ -18210,6 +18215,14 @@ In duplicated.default(c(1L, 2L, 1L, 1L, 3L, 2L), incomparables = "cat") :
#{ duplicated(list(76.5, 5L, 5L, 76.5, 5, 5), incomparables = c(5L, 76.5)) }
[1] FALSE FALSE TRUE FALSE FALSE FALSE
 
##com.oracle.truffle.r.test.builtins.TestBuiltin_duplicated.testDuplicated
#{ x<-function() 42; duplicated(x) }
Error in duplicated.default(x) : duplicated() applies only to vectors
##com.oracle.truffle.r.test.builtins.TestBuiltin_duplicated.testDuplicated
#{ x<-quote(f(7, 42)); duplicated(x) }
Error in duplicated.default(x) : duplicated() applies only to vectors
##com.oracle.truffle.r.test.builtins.TestBuiltin_duplicated.testDuplicated
#{duplicated(c("abc"))}
[1] FALSE
......@@ -130,5 +130,10 @@ public class TestBuiltin_duplicated extends TestBase {
assertEval(Output.IgnoreWarningContext, "{ duplicated(c(1,2,3,2), incomparables = c(2+6i)) }");
assertEval("{ duplicated(NULL, 0); }");
assertEval("{ x<-quote(f(7, 42)); duplicated(x) }");
assertEval("{ x<-function() 42; duplicated(x) }");
assertEval(Output.IgnoreErrorMessage, "{ duplicated(c(1,2,1), incomparables=function() 42) }");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment