Mercurial > hg > truffle
changeset 22378:06bdf4a43126
Adding parse with argument names into the API and TCK
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Wed, 18 Nov 2015 11:53:28 +0100 |
parents | a765d165e7ec |
children | fdf6ad720cdc |
files | truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TckLanguage.java truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java |
diffstat | 3 files changed, 106 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Mon Nov 16 15:58:03 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Nov 18 11:53:28 2015 +0100 @@ -387,16 +387,20 @@ /** * Evaluates source of (potentially different) language. The {@link Source#getMimeType() * MIME type) is used to identify the {@link TruffleLanguage} to use to perform the - * {@link #parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...)} - * . + * {@link #parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...)}. + * The names of arguments are parameters for the resulting + * {#link CallTarget} that allow the <code>source</code> to reference + * the actual parameters passed to {@link CallTarget#call(java.lang.Object...)}. * * @param source the source to evaluate + * @param argumentNames the names of {@link CallTarget#call(java.lang.Object...)} + * arguments that can be referenced from the source * @return the call target representing the parsed result * @throws IOException if the parsing or evaluation fails for some reason */ - public CallTarget parse(Source source) throws IOException { + public CallTarget parse(Source source, String... argumentNames) throws IOException { TruffleLanguage<?> language = API.findLanguageImpl(vm, null, source.getMimeType()); - return language.parse(source, null); + return language.parse(source, null, argumentNames); } /**
--- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TckLanguage.java Mon Nov 16 15:58:03 2015 +0100 +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TckLanguage.java Wed Nov 18 11:53:28 2015 +0100 @@ -29,14 +29,18 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import java.io.IOException; -@TruffleLanguage.Registration(mimeType = "x-application/tck", name = "TCK", version = "1.0") +@TruffleLanguage.Registration(mimeType = "application/x-tck", name = "TCK", version = "1.0") public final class TckLanguage extends TruffleLanguage<Env> { public static final TckLanguage INSTANCE = new TckLanguage(); @@ -47,8 +51,18 @@ @Override protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - final double value = Double.parseDouble(code.getCode()); - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(value)); + final RootNode root; + final String txt = code.getCode(); + if (txt.startsWith("TCK42:")) { + int nextColon = txt.indexOf(":", 6); + String mimeType = txt.substring(6, nextColon); + Source toParse = Source.fromText(txt.substring(nextColon + 1), "").withMimeType(mimeType); + root = new MultiplyNode(toParse); + } else { + final double value = Double.parseDouble(txt); + root = RootNode.createConstantNode(value); + } + return Truffle.getRuntime().createCallTarget(root); } @Override @@ -85,4 +99,49 @@ protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { throw new IOException(); } + + private static final class MultiplyNode extends RootNode implements TruffleObject, ForeignAccess.Factory { + private final Source code; + + public MultiplyNode(Source toParse) { + super(TckLanguage.class, null, null); + this.code = toParse; + } + + @Override + public Object execute(VirtualFrame frame) { + Env env = TckLanguage.INSTANCE.findContext(TckLanguage.INSTANCE.createFindContextNode()); + if (frame.getArguments().length == 0) { + return this; + } + try { + CallTarget call = env.parse(code, (String)frame.getArguments()[1], (String)frame.getArguments()[2]); + return call.call(6, 7); + } catch (IOException ex) { + throw new AssertionError("Cannot parse " + code, ex); + } + } + + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(this); + } + + @Override + public boolean canHandle(TruffleObject obj) { + return obj instanceof MultiplyNode; + } + + @Override + public CallTarget accessMessage(Message tree) { + if (tree == Message.IS_EXECUTABLE) { + return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(Boolean.TRUE)); + } else if (Message.createExecute(2).equals(tree)) { + return Truffle.getRuntime().createCallTarget(this); + } else { + throw new IllegalArgumentException("" + tree); + } + } + + } }
--- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java Mon Nov 16 15:58:03 2015 +0100 +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java Wed Nov 18 11:53:28 2015 +0100 @@ -41,6 +41,13 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * A collection of tests that can certify language implementation to be compliant with most recent @@ -170,6 +177,19 @@ } /** + * Code snippet to multiplyCode two two variables. The test uses the snippet + * as a parameter to your language's {@link TruffleLanguage#parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...)} + * method. + * + * @param firstName name of the first variable to multiplyCode + * @param secondName name of the second variable to multiplyCode + * @return code snippet that multiplies the two variables in your language + */ + protected String multiplyCode(String firstName, String secondName) { + throw new UnsupportedOperationException("multiply(String,String) method not implemeted!"); + } + + /** * Name of a function that counts number of its invocations in current {@link PolyglotEngine} * context. Your function should somehow keep a counter to remember number of its invocations * and always increment it. The first invocation should return <code>1</code>, the second @@ -615,14 +635,27 @@ PolyglotEngine.Value function = vm().findGlobalSymbol(evaluateSource()); assertNotNull(evaluateSource() + " found", function); - Random r = new Random(); - double expect = Math.floor(r.nextDouble() * 100000.0) / 10.0; - Object parsed = function.invoke(null, "x-application/tck", "" + expect).get(); + double expect = Math.floor(RANDOM.nextDouble() * 100000.0) / 10.0; + Object parsed = function.invoke(null, "application/x-tck", "" + expect).get(); assertTrue("Expecting numeric result, was:" + expect, parsed instanceof Number); double value = ((Number)parsed).doubleValue(); assertEquals("Gets the double", expect, value, 0.01); } + @Test + public void multiplyTwoVariables() throws Exception { + final String firstVar = "var" + (char)('A' + RANDOM.nextInt(24)); + final String secondVar = "var" + (char)('0' + RANDOM.nextInt(10)); + String mulCode = multiplyCode(firstVar, secondVar); + Source source = Source.fromText("TCK42:" + mimeType() + ":" + mulCode, "evaluate " + firstVar + " * " + secondVar) + .withMimeType("application/x-tck"); + final PolyglotEngine.Value evalSource = vm().eval(source); + final PolyglotEngine.Value invokeMul = evalSource.invoke(null, firstVar, secondVar); + Object result = invokeMul.get(); + assertTrue("Expecting numeric result, was:" + result, result instanceof Number); + assertEquals("Right value", 42, ((Number)result).intValue()); + } + private PolyglotEngine.Value findGlobalSymbol(String name) throws Exception { PolyglotEngine.Value s = vm().findGlobalSymbol(name); assert s != null : "Symbol " + name + " is not found!";