diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index fcfc475523f28c9fc75c8c8235a82d79b4f1a594..4cbfd06eec2158522d899cf2380d7c8792dfa3c0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -70,13 +70,18 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RExpression; +import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; +import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -112,7 +117,15 @@ public abstract class Combine extends RBuiltinNode.Arg2 { public abstract Object executeCombine(Object value, Object recursive); protected boolean isSimpleArguments(RArgsValuesAndNames args) { - return !signatureHasNames(args.getSignature()) && args.getLength() == 1 && !(args.getArgument(0) instanceof RAbstractVector) && !RRuntime.isForeignObject(args.getArgument(0)); + return !signatureHasNames(args.getSignature()) && + args.getLength() == 1 && + !(args.getArgument(0) instanceof RAbstractVector) && + !(args.getArgument(0) instanceof REnvironment) && + !(args.getArgument(0) instanceof RFunction) && + !(args.getArgument(0) instanceof RLanguage) && + !(args.getArgument(0) instanceof RSymbol) && + !(args.getArgument(0) instanceof RS4Object) && + !RRuntime.isForeignObject(args.getArgument(0)); } @Specialization(guards = {"isSimpleArguments(args)", "!recursive"}) 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 8ad6b28bbead4b239ae670cd2e29eabd6202b81f..13ee304a4dd986aa243cc5fd205000730482dfc4 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 @@ -11567,6 +11567,59 @@ NULL Warning message: In body(argv[[1]]) : argument is not a function +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(as.expression(1)) +expression(1) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(as.expression(1), as.expression(1)) +expression(1, 1) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(as.symbol(1)) +[[1]] +`1` + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(as.symbol(1), as.symbol(1)) +[[1]] +`1` + +[[2]] +`1` + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(environment()) +[[1]] +<environment: R_GlobalEnv> + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(environment(), environment()) +[[1]] +<environment: R_GlobalEnv> + +[[2]] +<environment: R_GlobalEnv> + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(x~a) +[[1]] +x ~ a + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#c(x~a, x~b) +[[1]] +x ~ a + +[[2]] +x ~ b + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# #typeof(c(substitute(graphics::par), list(as.symbol('a')))) [1] "list" @@ -12179,6 +12232,16 @@ x y #{ f <- function() { }; length(c(f, 2)) == 2 } [1] TRUE +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#{ f <- function(){}; l <- c(f); print(is.list(l)); identical(l[[1]], f) } +[1] TRUE +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#{ f <- function(){}; l <- c(f, f); print(is.list(l)); identical(l[[1]], f) } +[1] TRUE +[1] TRUE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# #{ f <- function(x,y) { c(x,y) } ; f(1,1) ; f(1, TRUE) ; f(NULL, NULL) } NULL @@ -12198,6 +12261,30 @@ Slot "d": [1] 42 +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#{ setClass('foo', representation(bar = 'ANY')); c(new('foo', bar=1)) } +[[1]] +An object of class "foo" +Slot "bar": +[1] 1 + + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# +#{ setClass('foo', representation(bar = 'ANY')); c(new('foo', bar=1), new('foo', bar=1)) } +[[1]] +An object of class "foo" +Slot "bar": +[1] 1 + + +[[2]] +An object of class "foo" +Slot "bar": +[1] 1 + + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_c.testCombine# #{ typeof(c(as.symbol("foo"), 42)) } [1] "list" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java index 7dd4697df4814f8358a53ecbcb52206a1756bd5a..974a0d5f7ba803258b3236f09f5c6ecdfc3a8532 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_c.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -541,6 +541,19 @@ public class TestBuiltin_c extends TestBase { assertEval("{ x<-c(a=42); y<-c(b=7); z<-c(x,y); w<-names(z); w[[1]]<-\"c\"; z }"); assertEval("typeof(c(substitute(graphics::par), list(as.symbol('a'))))"); + + assertEval("c(x~a)"); + assertEval("c(x~a, x~b)"); + assertEval("{ f <- function(){}; l <- c(f); print(is.list(l)); identical(l[[1]], f) }"); + assertEval("{ f <- function(){}; l <- c(f, f); print(is.list(l)); identical(l[[1]], f) }"); + assertEval("c(environment())"); + assertEval("c(environment(), environment())"); + assertEval("c(as.expression(1))"); + assertEval("c(as.expression(1), as.expression(1))"); + assertEval("c(as.symbol(1))"); + assertEval("c(as.symbol(1), as.symbol(1))"); + assertEval("{ setClass('foo', representation(bar = 'ANY')); c(new('foo', bar=1)) }"); + assertEval("{ setClass('foo', representation(bar = 'ANY')); c(new('foo', bar=1), new('foo', bar=1)) }"); } @Test