diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java index 626821a38aa55082fb3aaa99c9751aa448a45d17..5483988770fdc65ac8914b97e0e5e77558197827 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java @@ -35,6 +35,7 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.UnlistNodeGen.RecursiveLengthNodeGen; +import com.oracle.truffle.r.nodes.builtin.base.UnlistNodeGen.UnlistLengthNodeGen; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.unary.PrecedenceNode; import com.oracle.truffle.r.nodes.unary.PrecedenceNodeGen; @@ -75,12 +76,37 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { } @Child private PrecedenceNode precedenceNode = PrecedenceNodeGen.create(); - @Child private RLengthNode lengthNode; + @Child private UnlistLength lengthNode; @Child private RecursiveLength recursiveLengthNode; @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Child private Node hasSizeNode; @Child private ForeignArray2R foreignArray2RNode; + @ImportStatic({Message.class, RRuntime.class, ForeignArray2R.class}) + @TypeSystemReference(RTypes.class) + protected abstract static class UnlistLength extends Node { + + public abstract int execute(Object vector); + + @Child private RLengthNode lengthNode; + + @Specialization + protected int getLength(@SuppressWarnings("unused") RLanguage l) { + // language object do not get expanded - as such their length for the purpose of unlist + // is 1 + return 1; + } + + @Fallback + protected int getLength(Object operand) { + if (lengthNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + lengthNode = insert(RLengthNode.create()); + } + return lengthNode.executeInteger(operand); + } + } + @ImportStatic({Message.class, RRuntime.class, ForeignArray2R.class}) @TypeSystemReference(RTypes.class) protected abstract static class RecursiveLength extends Node { @@ -216,13 +242,13 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { private int getLength(Object operand) { initLengthNode(); - return lengthNode.executeInteger(operand); + return lengthNode.execute(operand); } private void initLengthNode() { if (lengthNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - lengthNode = insert(RLengthNode.create()); + lengthNode = insert(UnlistLengthNodeGen.create()); } } 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 6a2e9b1cacd26120349a7a35de73b55368f7effe..a0f28d0b14a8db2066bc0e085d95feb94ed9d28e 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 @@ -72358,6 +72358,12 @@ a.b a a.b a2 a3 "1" "2" "3" +##com.oracle.truffle.r.test.builtins.TestBuiltin_unlist.testUnlist# +#{ unlist(list(quote(for(i in seq(1)) print(i))), recursive=F) } +[[1]] +for (i in seq(1)) print(i) + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_unlist.testUnlist# #{ x <- list("a", c("b", "c"), list("d", list("e"))) ; unlist(x) } [1] "a" "b" "c" "d" "e" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unlist.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unlist.java index 7beb5839d2c2f90561a96c652fe6e333d68da693..ea57dc309ce7add318414dc3c97e44faaea48977 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unlist.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unlist.java @@ -338,6 +338,8 @@ public class TestBuiltin_unlist extends TestBase { assertEval("{ x <- list(1,list(2,3),4) ; z <- list(x,x) ; u <- list(z,z) ; u[[c(2,2,3)]] <- 6 ; unlist(u) }"); assertEval("{ x<-quote(f(1,2)); y<-function(z) 42; l<-list(x, y, NULL); y<-unlist(l); c(length(y), typeof(y)) }"); + + assertEval("{ unlist(list(quote(for(i in seq(1)) print(i))), recursive=F) }"); } @Test