Mercurial > hg > truffle
changeset 22284:33d49924a921
PolyglotEngine.Value.as(String.class) gives the language that produced the value a chance to do its conversion to appropriate textual representation.
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Wed, 07 Oct 2015 13:32:25 +0200 |
parents | bc0c838ba705 |
children | 58b0a3e41785 |
files | truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ToStringTest.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java |
diffstat | 6 files changed, 131 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Wed Oct 07 12:39:09 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java Wed Oct 07 13:32:25 2015 +0200 @@ -53,6 +53,7 @@ import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.vm.PolyglotEngine; +import java.util.Objects; public class ImplicitExplicitExportTest { private static Thread mainThread; @@ -275,6 +276,19 @@ public ExportImportLanguage1() { } + + @Override + protected String toString(Ctx ctx, Object value) { + if (value instanceof String) { + try { + int number = Integer.parseInt((String) value); + return number + ": Int"; + } catch (NumberFormatException ex) { + // go on + } + } + return Objects.toString(value); + } } @TruffleLanguage.Registration(mimeType = L2, name = "ImportExport2", version = "0") @@ -283,6 +297,19 @@ public ExportImportLanguage2() { } + + @Override + protected String toString(Ctx ctx, Object value) { + if (value instanceof String) { + try { + double number = Double.parseDouble((String) value); + return number + ": Double"; + } catch (NumberFormatException ex) { + // go on + } + } + return Objects.toString(value); + } } @TruffleLanguage.Registration(mimeType = L3, name = "ImportExport3", version = "0")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ToStringTest.java Wed Oct 07 13:32:25 2015 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.test.vm; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class ToStringTest { + @Test + public void valueToStringValueWith1() throws Exception { + PolyglotEngine engine = PolyglotEngine.buildNew().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language2.eval(Source.fromText("explicit.value=42", "define 42")); + PolyglotEngine.Value value = language1.eval(Source.fromText("return=value", "42.value")); + assertEquals("It's fourtytwo", "42", value.get()); + + String textual = value.as(String.class); + assertEquals("Nicely formated as by L1", "42: Int", textual); + } + + @Test + public void valueToStringValueWith2() throws Exception { + PolyglotEngine engine = PolyglotEngine.buildNew().build(); + PolyglotEngine.Language language1 = engine.getLanguages().get("application/x-test-import-export-1"); + PolyglotEngine.Language language2 = engine.getLanguages().get("application/x-test-import-export-2"); + language1.eval(Source.fromText("explicit.value=42", "define 42")); + PolyglotEngine.Value value = language2.eval(Source.fromText("return=value", "42.value")); + assertEquals("It's fourtytwo", "42", value.get()); + + String textual = value.as(String.class); + assertEquals("Nicely formated as by L2", "42.0: Double", textual); + } + +}
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Wed Oct 07 12:39:09 2015 +0200 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Wed Oct 07 13:32:25 2015 +0200 @@ -707,7 +707,10 @@ * Obtains Java view of the object represented by this symbol. The method basically * delegates to * {@link JavaInterop#asJavaObject(java.lang.Class, com.oracle.truffle.api.interop.TruffleObject)} - * just handles primitive types as well. + * . The method handles primitive types (like {@link Number}, etc.) by casting and returning + * them. When a {@link String}.<code>class</code> is requested, the method let's the + * language that produced the value to do the + * {@link TruffleLanguage#toString(java.lang.Object, java.lang.Object) necessary formating}. * * @param <T> the type of the view one wants to obtain * @param representation the class of the view interface (it has to be an interface) @@ -723,6 +726,10 @@ return representation.cast(eto.getDelegate()); } } + if (representation == String.class) { + final Class<? extends TruffleLanguage> clazz = language.getClass(); + return representation.cast(SPI.toString(language, findEnv(clazz), obj)); + } if (representation.isInstance(obj)) { return representation.cast(obj); } @@ -1043,5 +1050,10 @@ protected void dispose(TruffleLanguage<?> impl, TruffleLanguage.Env env) { super.dispose(impl, env); } + + @Override + protected String toString(TruffleLanguage language, TruffleLanguage.Env env, Object obj) { + return super.toString(language, env, obj); + } } // end of SPIAccessor }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Oct 07 12:39:09 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Oct 07 13:32:25 2015 +0200 @@ -56,6 +56,7 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; +import java.util.Objects; /** * An entry point for everyone who wants to implement a Truffle based language. By providing an @@ -271,6 +272,23 @@ protected abstract Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException; /** + * Generates language specific textual representation of a value. Each language may have special + * formating conventions - even primitive values may not follow the traditional Java formating + * rules. As such when + * {@link com.oracle.truffle.api.vm.PolyglotEngine.Value#as(java.lang.Class) + * value.as(String.class)} is requested, it consults the language that produced the value by + * calling this method. By default this method calls {@link Objects#toString(java.lang.Object)}. + * + * @param context the execution context for doing the conversion + * @param value the value to convert. Either primitive type or + * {@link com.oracle.truffle.api.interop.TruffleObject} + * @return textual representation of the value in this language + */ + protected String toString(C context, Object value) { + return Objects.toString(value); + } + + /** * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot} * that, when executed, computes the result of a textual expression in the language; used to * create an @@ -343,6 +361,11 @@ void dispose() { lang.disposeContext(ctx); } + + String toString(TruffleLanguage<?> language, Object obj) { + assert lang == language; + return lang.toString(ctx, obj); + } } /** @@ -526,6 +549,11 @@ assert impl == env.langCtx.lang; env.langCtx.dispose(); } + + @Override + protected String toString(TruffleLanguage<?> language, Env env, Object obj) { + return env.langCtx.toString(language, obj); + } } }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Oct 07 12:39:09 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Oct 07 13:32:25 2015 +0200 @@ -342,4 +342,8 @@ protected void dispose(TruffleLanguage<?> impl, Env env) { API.dispose(impl, env); } + + protected String toString(TruffleLanguage<?> language, Env env, Object obj) { + return API.toString(language, env, obj); + } }
--- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java Wed Oct 07 12:39:09 2015 +0200 +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java Wed Oct 07 13:32:25 2015 +0200 @@ -375,8 +375,8 @@ final PolyglotEngine.Value result = apply.invoke(null, fn); try { - String res = result.as(String.class); - fail("Cannot be converted to String: " + res); + Boolean res = result.as(Boolean.class); + fail("Cannot be converted to Boolean: " + res); } catch (ClassCastException ex) { // correct }