mirror of
https://github.com/enso-org/enso.git
synced 2024-09-17 16:17:25 +03:00
Implement Interop Library for Unresolved Symbols (#952)
This commit is contained in:
parent
e9b676834b
commit
510d9e4a2d
@ -1,11 +1,20 @@
|
||||
package org.enso.interpreter.runtime.callable;
|
||||
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.interop.*;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.node.callable.MethodResolverNode;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
|
||||
/** Simple runtime value representing a yet-unresolved by-name symbol. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class UnresolvedSymbol implements TruffleObject {
|
||||
private final String name;
|
||||
private final ModuleScope scope;
|
||||
@ -17,7 +26,7 @@ public class UnresolvedSymbol implements TruffleObject {
|
||||
* @param scope the scope in which this symbol was created
|
||||
*/
|
||||
private UnresolvedSymbol(String name, ModuleScope scope) {
|
||||
this.name = name.intern();
|
||||
this.name = name;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@ -68,4 +77,31 @@ public class UnresolvedSymbol implements TruffleObject {
|
||||
public static UnresolvedSymbol build(String name, ModuleScope scope) {
|
||||
return new UnresolvedSymbol(name, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this object as executable through the interop library.
|
||||
*
|
||||
* @return always true
|
||||
*/
|
||||
@ExportMessage
|
||||
public boolean isExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Implements the logic of executing {@link UnresolvedSymbol} through the interop library. */
|
||||
@ExportMessage
|
||||
@ImportStatic(Constants.CacheSizes.class)
|
||||
public static class Execute {
|
||||
@Specialization
|
||||
static Object doDispatch(
|
||||
UnresolvedSymbol symbol,
|
||||
Object[] arguments,
|
||||
@Cached MethodResolverNode methodResolverNode,
|
||||
@CachedLibrary(limit = "BUILTIN_INTEROP_DISPATCH") InteropLibrary library)
|
||||
throws ArityException, UnsupportedTypeException, UnsupportedMessageException {
|
||||
if (arguments.length == 0) throw ArityException.create(1, 0);
|
||||
Function function = methodResolverNode.execute(symbol, arguments[0]);
|
||||
return library.execute(function, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package org.enso.interpreter.test.semantic
|
||||
|
||||
import org.enso.interpreter.test.{InterpreterTest, InterpreterContext}
|
||||
import org.enso.interpreter.test.{InterpreterContext, InterpreterTest}
|
||||
|
||||
class InteropTest extends InterpreterTest {
|
||||
override def subject: String = "Interop Library"
|
||||
|
||||
override def specify(
|
||||
implicit interpreterContext: InterpreterContext
|
||||
override def specify(implicit
|
||||
interpreterContext: InterpreterContext
|
||||
): Unit = {
|
||||
"support tail recursive functions" in {
|
||||
val code =
|
||||
@ -53,5 +53,26 @@ class InteropTest extends InterpreterTest {
|
||||
val fun = eval(code)
|
||||
fun.call(1, 2) shouldEqual 2
|
||||
}
|
||||
|
||||
"work with unresolved symbols" in {
|
||||
val code =
|
||||
"""
|
||||
|Number.add x = x + this
|
||||
|Text.add x = this + x
|
||||
|
|
||||
|main = add
|
||||
|""".stripMargin
|
||||
val symbol = eval(code)
|
||||
symbol.call(1, 2) shouldEqual 3
|
||||
symbol.call(3, 4) shouldEqual 7
|
||||
symbol.execute("Hello", " World") shouldEqual "Hello World"
|
||||
}
|
||||
|
||||
"work with unresolved symbols from builtin scope" in {
|
||||
val code = "main = to_text"
|
||||
val symbol = eval(code)
|
||||
symbol.call(1) shouldEqual "1"
|
||||
symbol.execute("Foo") shouldEqual "Foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user