From ea2d4234a4168083bab25525dce8c3f6f347b258 Mon Sep 17 00:00:00 2001 From: Michael Haupt <michael.haupt@oracle.com> Date: Thu, 19 Jun 2014 09:44:50 +0200 Subject: [PATCH] allow more fancy function lookups --- .../truffle/r/nodes/RTruffleVisitor.java | 2 +- .../com/oracle/truffle/r/parser/ast/Call.java | 4 +-- .../truffle/r/parser/ast/FunctionCall.java | 5 ++++ .../truffle/r/test/ExpectedTestOutput.test | 24 +++++++++++++++ .../oracle/truffle/r/test/all/AllTests.java | 30 +++++++++++++++++++ .../r/test/simple/TestSimpleFunctions.java | 10 +++++++ 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java index da33cc8deb..7738056fb0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java @@ -135,7 +135,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { } return RCallNode.createCall(callSource, ReadVariableNode.create(callName, RRuntime.TYPE_FUNCTION, false), aCallArgNode); } else { - RNode lhs = call.getFunctionCall().accept(this); + RNode lhs = call.getLhsNode().accept(this); return RCallNode.createCall(callSource, lhs, aCallArgNode); } } diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/Call.java b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/Call.java index 0193a2db89..ad2c364bf2 100644 --- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/Call.java +++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/Call.java @@ -49,9 +49,9 @@ public abstract class Call extends ASTNode { return create(src, Symbol.getSymbol(c.getValues()[0]), args); } else if (call instanceof FunctionCall) { return new FunctionCall(src, (FunctionCall) call, args); + } else { + return new FunctionCall(src, call, args); } - assert false; - return null; } public static ASTNode create(SourceSection src, Symbol funName, List<ArgNode> args) { diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/FunctionCall.java b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/FunctionCall.java index b6e3310447..4db3a7d1cf 100644 --- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/FunctionCall.java +++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ast/FunctionCall.java @@ -57,6 +57,11 @@ public class FunctionCall extends Call { return (FunctionCall) lhs; } + public ASTNode getLhsNode() { + assert lhs instanceof ASTNode; + return (ASTNode) lhs; + } + public boolean isSuper() { return isSuper; } 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 253ed91af8..a6a2a75f34 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 @@ -11684,6 +11684,30 @@ Hello world #{ g <- function(...) { c(...,...) } ; g(3) } [1] 3 3 +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[1]](1) } +[1] 2 + +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[2]](1) } +[1] 3 + +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(1)(1) } +[1] 2 + +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(2)(1) } +[1] 3 + +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 1 ; (if (v==1) f else g)(1) } +[1] 2 + +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testInvokeIndirectly +#{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 2 ; (if (v==1) f else g)(1) } +[1] 3 + ##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testMatching #{ f <- function(a) { a } ; f(1,2) } Error in f(1, 2) : unused argument (2) 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 145764bdc4..c9b925c241 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 @@ -14623,6 +14623,36 @@ public class AllTests extends TestBase { assertEvalError("{ f <- function(a,b,c,d) { a + b } ; f(1,x=1,2,3,4) }"); } + @Test + public void TestSimpleFunctions_testInvokeIndirectly_249a400b35f2f0c3cc210c2719eadf10() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(1)(1) }"); + } + + @Test + public void TestSimpleFunctions_testInvokeIndirectly_eba1980fa779ba82a6d33dd930b37480() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(2)(1) }"); + } + + @Test + public void TestSimpleFunctions_testInvokeIndirectly_c69f1367fbb3330e6e446038532361d0() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 1 ; (if (v==1) f else g)(1) }"); + } + + @Test + public void TestSimpleFunctions_testInvokeIndirectly_0426e7a36eb62ebaece970a5f8adb8c3() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 2 ; (if (v==1) f else g)(1) }"); + } + + @Test + public void TestSimpleFunctions_testInvokeIndirectly_6b4d9a5443d0ef4f0adb1985be5be697() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[1]](1) }"); + } + + @Test + public void TestSimpleFunctions_testInvokeIndirectly_70237bb41c7522a4a2a4a4bab29d79a6() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[2]](1) }"); + } + @Test public void TestSimpleFunctions_testMatching_c272d90b4e2480f9f6fc9b6bfcc79e74() { assertEval("{ x<-function(foo,bar){foo*bar} ; x(f=10,2) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java index e1f9f349af..9ba10fff31 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java @@ -228,4 +228,14 @@ public class TestSimpleFunctions extends TestBase { assertEvalError("{ f <- function(...) { ..1 + ..2 } ; f(1,,3) }"); } + @Test + public void testInvokeIndirectly() { + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(1)(1) }"); + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; h <- function(v) if (v==1) f else g ; h(2)(1) }"); + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 1 ; (if (v==1) f else g)(1) }"); + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; v <- 2 ; (if (v==1) f else g)(1) }"); + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[1]](1) }"); + assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[2]](1) }"); + } + } -- GitLab