Skip to content

Commit f50999f

Browse files
tomasstupkasteve-s
authored andcommitted
implement rapply for expressions
(cherry picked from commit 4c8101caac45c6403b822815073d4bf671ec0cc2)
1 parent 6609c0d commit f50999f

File tree

3 files changed

+126
-15
lines changed

3 files changed

+126
-15
lines changed

com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rapply.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
5858
import com.oracle.truffle.r.runtime.context.RContext;
5959
import com.oracle.truffle.r.runtime.data.RDataFactory;
60+
import com.oracle.truffle.r.runtime.data.RExpression;
6061
import com.oracle.truffle.r.runtime.data.RFunction;
6162
import com.oracle.truffle.r.runtime.data.RList;
6263
import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector;
@@ -78,22 +79,32 @@ public abstract class Rapply extends RBuiltinNode.Arg5 {
7879

7980
static {
8081
Casts casts = new Casts(Rapply.class);
81-
casts.arg("object").mustBe(RAbstractListVector.class, Message.GENERIC, "'object' must be a list or expression");
82+
casts.arg("object").mustBe(RAbstractListBaseVector.class, Message.GENERIC, "'object' must be a list or expression");
8283
casts.arg("f").mustBe(RFunction.class);
8384
casts.arg("classes").mapNull(constant("ANY")).mapMissing(constant("ANY")).mustBe(stringValue()).asStringVector().findFirst().mustNotBeNA();
8485
casts.arg("deflt").allowNull().mapMissing(nullConstant()).mustBe(anyValue());
8586
casts.arg("how").mapNull(constant("unlist")).mapMissing(constant("unlist")).mustBe(stringValue()).asStringVector().findFirst().mustNotBeNA();
8687
}
8788

8889
@Specialization(guards = "!isReplace(how)")
89-
protected Object rapplyReplace(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how, @Cached("create()") UnaryCopyAttributesNode attri) {
90-
90+
protected Object rapplyReplace(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how,
91+
@Cached("create()") UnaryCopyAttributesNode attri) {
9192
return attri.execute(RDataFactory.createList((Object[]) rapply.execute(frame, object, f, classes, deflt, how)), object);
9293
}
9394

9495
@Specialization(guards = "isReplace(how)")
9596
protected Object rapply(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how) {
97+
return rapply.execute(frame, object, f, classes, deflt, how);
98+
}
99+
100+
@Specialization(guards = "!isReplace(how)")
101+
protected Object rapplyReplace(VirtualFrame frame, RExpression object, RFunction f, String classes, Object deflt, String how,
102+
@Cached("create()") UnaryCopyAttributesNode attri) {
103+
return attri.execute(RDataFactory.createList((Object[]) rapply.execute(frame, object, f, classes, deflt, how)), object);
104+
}
96105

106+
@Specialization(guards = "isReplace(how)")
107+
protected Object rapply(VirtualFrame frame, RExpression object, RFunction f, String classes, Object deflt, String how) {
97108
return rapply.execute(frame, object, f, classes, deflt, how);
98109
}
99110

@@ -148,7 +159,7 @@ public abstract static class RapplyInternalNode extends RBaseNode implements Int
148159
protected static final String VECTOR_NAME = "object";
149160
protected static final String INDEX_NAME = "i";
150161

151-
public abstract Object execute(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how);
162+
public abstract Object execute(VirtualFrame frame, RAbstractListBaseVector object, RFunction f, String classes, Object deflt, String how);
152163

153164
protected static FrameSlot createIndexSlot(Frame frame) {
154165
return FrameSlotChangeMonitor.findOrAddFrameSlot(frame.getFrameDescriptor(), INDEX_NAME, FrameSlotKind.Int);
@@ -159,7 +170,7 @@ protected static FrameSlot createVectorSlot(Frame frame) {
159170
}
160171

161172
@Specialization(guards = "isReplace(how)")
162-
protected RAbstractListBaseVector cachedLapplyReplace(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how,
173+
protected RAbstractListBaseVector cachedRapplyReplace(VirtualFrame frame, RAbstractListBaseVector object, RFunction f, String classes, Object deflt, String how,
163174
@Cached("createIndexSlot(frame)") FrameSlot indexSlot,
164175
@Cached("createVectorSlot(frame)") FrameSlot vectorSlot,
165176
@Cached("create()") RLengthNode lengthNode,
@@ -201,7 +212,7 @@ private RapplyInternalNode getRapply() {
201212
}
202213

203214
@Specialization(guards = "!isReplace(how)")
204-
protected Object[] cachedLapply(VirtualFrame frame, RAbstractListVector object, RFunction f, String classes, Object deflt, String how,
215+
protected Object[] cachedRapply(VirtualFrame frame, RAbstractListBaseVector object, RFunction f, String classes, Object deflt, String how,
205216
@Cached("createIndexSlot(frame)") FrameSlot indexSlot,
206217
@Cached("createVectorSlot(frame)") FrameSlot vectorSlot,
207218
@Cached("create()") RLengthNode lengthNode,

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ Class "OptionalFunction", by class "standardGeneric", distance 4
447447
Class "PossibleMethod", by class "standardGeneric", distance 4
448448
Class "optionalMethod", by class "standardGeneric", distance 5
449449

450-
##com.oracle.truffle.r.test.S4.TestS4.testConversions#Ignored.NewRVersionMigration#
450+
##com.oracle.truffle.r.test.S4.TestS4.testConversions#
451451
#{ asS4(7:42) }
452452
[1] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
453453
[26] 32 33 34 35 36 37 38 39 40 41 42
@@ -539,7 +539,7 @@ Use showMethods("gen") for currently available ones.
539539
[1] 42
540540
[1] 42
541541

542-
##com.oracle.truffle.r.test.S4.TestS4.testMethods#Ignored.NewRVersionMigration#Output.IgnoreWarningMessage#
542+
##com.oracle.truffle.r.test.S4.TestS4.testMethods#Output.IgnoreWarningMessage#
543543
#{ setClass("foo"); setMethod("diag<-", "foo", function(x, value) 42); removeMethod("diag<-", "foo"); removeGeneric("diag<-"); removeClass("foo") }
544544
Creating a generic function for ‘diag<-’ from package ‘base’ in the global environment
545545
[1] TRUE
@@ -560,7 +560,7 @@ Note: method with signature ‘A2#A1’ chosen for function ‘foo’,
560560
#{ setClass('A1', representation(a='numeric')); setMethod('length', 'A1', function(x) x@a); obj <- new('A1'); obj@a <- 10; length(obj) }
561561
[1] 10
562562

563-
##com.oracle.truffle.r.test.S4.TestS4.testMethods#Ignored.NewRVersionMigration#
563+
##com.oracle.truffle.r.test.S4.TestS4.testMethods#
564564
#{ setClass('A2', representation(a = 'numeric')); setMethod('rep', 'A2', function(x, a, b, c) { c(x@a, a, b, c) }); setMethod('ifelse', c(yes = 'A2'), function(test, yes, no) print(test)) }
565565
Creating a generic function for ‘ifelse’ from package ‘base’ in the global environment
566566

@@ -31879,19 +31879,19 @@ logical(0)
3187931879
# file.exists('com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/data/tree1/filedoesnotexist')
3188031880
[1] FALSE
3188131881

31882-
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#
31882+
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#Ignored.ImplementationError#
3188331883
# file.exists('com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/data/tree1/filedoesnotexist/..')
3188431884
[1] FALSE
3188531885

3188631886
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#
3188731887
# file.exists('com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/data/tree1/filedoesnotexist/../aa')
3188831888
[1] FALSE
3188931889

31890-
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#
31890+
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#Ignored.ImplementationError#
3189131891
# file.exists('com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/data/tree1/filedoesnotexist/../aa/..')
3189231892
[1] FALSE
3189331893

31894-
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#
31894+
##com.oracle.truffle.r.test.builtins.TestBuiltin_fileexists.testFileDoesNotExist#Ignored.ImplementationError#
3189531895
# file.exists('com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/data/tree1/filedoesnotexist/../dummy.txt')
3189631896
[1] FALSE
3189731897

@@ -57337,10 +57337,91 @@ numeric(0)
5733757337
#argv <- list(structure(c('Tukey', 'Venables', 'Tierney', 'Ripley', 'Ripley', 'McNeil', 'R Core'), class = 'AsIs'), 7L, 'min'); .Internal(rank(argv[[1]], argv[[2]], argv[[3]]))
5733857338
[1] 6 7 5 3 3 1 2
5733957339

57340-
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#Ignored.Unimplemented#
57340+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
5734157341
#{rapply(expression('a+b'), function(x) { x })}
5734257342
[1] "a+b"
5734357343

57344+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57345+
#{rapply(expression('a+b'), function(x)x)}
57346+
[1] "a+b"
57347+
57348+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57349+
#{rapply(expression(a=1, 2, b=3), function(x)x)}
57350+
a b
57351+
1 2 3
57352+
57353+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57354+
#{rapply(expression(a=1, 2, b=list(1,2,3)), function(x)x)}
57355+
$a
57356+
[1] 1
57357+
57358+
[[2]]
57359+
[1] 2
57360+
57361+
$b
57362+
list(1, 2, 3)
57363+
57364+
57365+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57366+
#{rapply(expression(a=1, 2, b=list(1,2,3), c=expression('a+b')), function(x)x)}
57367+
$a
57368+
[1] 1
57369+
57370+
[[2]]
57371+
[1] 2
57372+
57373+
$b
57374+
list(1, 2, 3)
57375+
57376+
$c
57377+
expression("a+b")
57378+
57379+
57380+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57381+
#{rapply(expression(a=1, 2, b=list(1,2,3), list(1,2,3), c=expression('a+b')), function(x)x)}
57382+
$a
57383+
[1] 1
57384+
57385+
[[2]]
57386+
[1] 2
57387+
57388+
$b
57389+
list(1, 2, 3)
57390+
57391+
[[4]]
57392+
list(1, 2, 3)
57393+
57394+
$c
57395+
expression("a+b")
57396+
57397+
57398+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57399+
#{rapply(expression(a=1, 2, b=list(1,2,3), list(1,2,3), c=expression('a+b'), expression('a+b')), function(x)x)}
57400+
$a
57401+
[1] 1
57402+
57403+
[[2]]
57404+
[1] 2
57405+
57406+
$b
57407+
list(1, 2, 3)
57408+
57409+
[[4]]
57410+
list(1, 2, 3)
57411+
57412+
$c
57413+
expression("a+b")
57414+
57415+
[[6]]
57416+
expression("a+b")
57417+
57418+
57419+
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyExpression#
57420+
#{rapply(expression(list(1,2,3)), function(x)x)}
57421+
[[1]]
57422+
list(1, 2, 3)
57423+
57424+
5734457425
##com.oracle.truffle.r.test.builtins.TestBuiltin_rapply.testLapplyList#
5734557426
#l2 = list(a = 1:10, b = 11:20,c=c('d','a','t','a')); rapply(l2, mean, how = "list", classes = "integer")
5734657427
$a
@@ -74337,6 +74418,19 @@ integer(0)
7433774418
[41] 26163.27 26367.35 26571.43 26775.51 26979.59 27183.67 27387.76 27591.84
7433874419
[49] 27795.92 28000.00
7433974420

74421+
##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#
74422+
#seq_along()
74423+
Error in seq_along() : 0 arguments passed to 'seq_along' which requires 1
74424+
74425+
##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#
74426+
#{ assign('length.myclass', function(...) 42, envir=.__S3MethodsTable__.); x <- 1; class(x) <- 'myclass'; res <- seq_along(x); rm('length.myclass', envir=.__S3MethodsTable__.); res }
74427+
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
74428+
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
74429+
74430+
##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#
74431+
#{ length <- function(x) 42; seq_along(c(1,2,3)) }
74432+
[1] 1 2 3
74433+
7434074434
##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#
7434174435
#{ x <- c(1,2,3); class(x) <- 'myclass'; length.myclass <- function(w) '48'; seq_along(x) }
7434274436
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rapply.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ public void testLapplyList() {
6161

6262
@Test
6363
public void testLapplyExpression() {
64-
assertEval(Ignored.Unimplemented, "{rapply(expression('a+b'), function(x) { x })}");
65-
// TODO more tests
64+
assertEval("{rapply(expression('a+b'), function(x) { x })}");
65+
assertEval("{rapply(expression('a+b'), function(x)x)}");
66+
assertEval("{rapply(expression(list(1,2,3)), function(x)x)}");
67+
assertEval("{rapply(expression(a=1, 2, b=3), function(x)x)}");
68+
assertEval("{rapply(expression(a=1, 2, b=list(1,2,3)), function(x)x)}");
69+
assertEval("{rapply(expression(a=1, 2, b=list(1,2,3), c=expression('a+b')), function(x)x)}");
70+
assertEval("{rapply(expression(a=1, 2, b=list(1,2,3), list(1,2,3), c=expression('a+b')), function(x)x)}");
71+
assertEval("{rapply(expression(a=1, 2, b=list(1,2,3), list(1,2,3), c=expression('a+b'), expression('a+b')), function(x)x)}");
6672
}
6773
}

0 commit comments

Comments
 (0)