Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement conversions (#180312665) #3227

Merged
merged 15 commits into from
Feb 6, 2022
Merged
6 changes: 6 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
- Updated the Scala compiler and dependencies
([#3214](https://github.com/enso-org/enso/pull/3214)).

## Interpreter/Runtime

- Added support for overloaded conversions. This allows the `from` method to be
implemented with several overloads.
([#3227](https://github.com/enso-org/enso/pull/3227))

## Enso 0.2.31 (2021-10-01)

## Interpreter/Runtime
Expand Down
6 changes: 6 additions & 0 deletions app/gui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
[3230]: https://github.com/enso-org/enso/pull/3230
[3240]: https://github.com/enso-org/enso/pull/3240

#### Enso Compiler

- [Added overloaded `from` conversions.][3227]

[3227]: https://github.com/enso-org/enso/pull/3227

# Enso 2.0.0-alpha.18 (2021-10-12)

<br/>![New Features](/docs/assets/tags/new_features.svg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Any.== that = if Meta.is_same_object this that then True else
Cons (Meta.Polyglot o_1) (Meta.Polyglot o_2) ->
langs_match = (this_meta.get_language == Meta.Java) && (that_meta.get_language == Meta.Java)
if langs_match.not then False else o_1.equals o_2
Cons (Meta.Unresolved_Symbol _) (Meta.Unresolved_Symbol _) ->
(this_meta.name == that_meta.name) && (this_meta.scope == that_meta.scope)
## Constructor comparison is covered by the identity equality.
Primitive objects should define their own equality.
Therefore, there are no more cases to handle in this method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ delta = 3

Arguments:
- m: The map to get the size of.
size: Map -> Integer
size : Map -> Integer
size m = case m of
Bin s _ _ _ _ -> s
_ -> 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ os = here.from_text System.os
## PRIVATE

Create an Os object from text.
from_text: Text -> Os
from_text : Text -> Os
from_text os =
if os == "linux" then Linux else
if os == "macos" then MacOS else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ simple_table_json =

## The headers for the columns in the JSON table `here.simple_table_json`.
simple_table_json_headers : Vector Text
simple_Table_json_headers = ["foo", "bar", "baz"]
simple_table_json_headers = ["foo", "bar", "baz"]

## Some simple GeoJSON.
geo_json : Enso_Json.Json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,9 @@ pad txt len =
Adds ANSI bold escape sequences to text if the feature is enabled.

Arguments:
- enabled: will insert ANSI sequences only if this flag is true and we are not on Windows.
- txt: The text to possibly bold.
ansi_bold_enabled : Text -> Text
ansi_bold : Boolean -> Text -> Text
ansi_bold enabled txt =
case Platform.os of
## Output formatting for Windows is not currently supported.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ specify label ~behavior pending=Nothing =
Arguments:
- verb: The property (see `Verbs`) being asserted
- argument: The argument to the verb.
Anu.should : (Verbs -> Any -> Any) -> Any -> Assertion
Any.should : (Verbs -> Any -> Any) -> Any -> Assertion
Any.should verb argument = verb Verbs this argument

## Fail a test with the given message.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ public class Constants {
/** Names for different language elements. */
public static class Names {
public static final String THIS_ARGUMENT = "this";
public static final String THAT_ARGUMENT = "that";
public static final String CURRENT_MODULE = "here";
public static final String FROM_MEMBER = "from";
}

/** Cache sizes for different AST nodes. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
*/
@NodeInfo(shortName = "App", description = "Executes function")
public class ApplicationNode extends ExpressionNode {

private @Children ExpressionNode[] argExpressions;

@Child private InvokeCallableNode invokeCallableNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package org.enso.interpreter.node.callable;

import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.enso.interpreter.Language;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.callable.dispatch.IndirectInvokeFunctionNode;
import org.enso.interpreter.node.callable.resolver.AnyResolverNode;
import org.enso.interpreter.node.callable.resolver.DataflowErrorResolverNode;
import org.enso.interpreter.node.callable.resolver.HostMethodCallNode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.runtime.Context;
import org.enso.interpreter.runtime.callable.UnresolvedConversion;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.library.dispatch.MethodDispatchLibrary;
import org.enso.interpreter.runtime.state.Stateful;

@GenerateUncached
@ReportPolymorphism
@ImportStatic({HostMethodCallNode.PolyglotCallType.class, HostMethodCallNode.class})
public abstract class IndirectInvokeConversionNode extends Node {

/** @return a new indirect method invocation node */
public static IndirectInvokeConversionNode build() {
return IndirectInvokeConversionNodeGen.create();
}

public abstract Stateful execute(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
Object that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail);

@Specialization(guards = "dispatch.canConvertFrom(that)")
Stateful doConvertFrom(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
Object that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail,
@CachedLibrary(limit = "10") MethodDispatchLibrary dispatch,
@CachedContext(Language.class) TruffleLanguage.ContextReference<Context> ctx,
@Cached ConditionProfile atomProfile,
@Cached ConditionProfile atomConstructorProfile,
@Cached IndirectInvokeFunctionNode indirectInvokeFunctionNode) {
try {
Function function =
dispatch.getConversionFunction(
that,
InvokeConversionNode.extractConstructor(
this, _this, ctx, atomConstructorProfile, atomProfile),
conversion);
return indirectInvokeFunctionNode.execute(
function,
frame,
state,
arguments,
schema,
defaultsExecutionMode,
argumentsExecutionMode,
isTail);
} catch (MethodDispatchLibrary.NoSuchConversionException e) {
throw new PanicException(
ctx.get().getBuiltins().error().makeNoSuchConversionError(_this, that, conversion), this);
}
}

@Specialization
Stateful doDataflowError(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
DataflowError that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail,
@CachedLibrary(limit = "10") MethodDispatchLibrary dispatch,
@CachedContext(Language.class) TruffleLanguage.ContextReference<Context> ctx,
@Cached BranchProfile profile,
@Cached ConditionProfile atomProfile,
@Cached ConditionProfile atomConstructorProfile,
@Cached IndirectInvokeFunctionNode indirectInvokeFunctionNode) {
try {
Function function =
dispatch.getConversionFunction(
that,
InvokeConversionNode.extractConstructor(
this, _this, ctx, atomConstructorProfile, atomProfile),
conversion);
return indirectInvokeFunctionNode.execute(
function,
frame,
state,
arguments,
schema,
defaultsExecutionMode,
argumentsExecutionMode,
isTail);
} catch (MethodDispatchLibrary.NoSuchConversionException e) {
profile.enter();
return new Stateful(state, that);
}
}

@Specialization
Stateful doPanicSentinel(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
PanicSentinel that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail) {
throw that;
}

@Specialization(guards = "interop.isString(that)")
Stateful doConvertText(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
Object that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail,
@CachedLibrary(limit = "10") MethodDispatchLibrary methods,
@CachedLibrary(limit = "1") MethodDispatchLibrary textDispatch,
@CachedLibrary(limit = "10") InteropLibrary interop,
@Cached ConditionProfile atomProfile,
@Cached ConditionProfile atomConstructorProfile,
@CachedContext(Language.class) TruffleLanguage.ContextReference<Context> ctx,
@Cached IndirectInvokeFunctionNode indirectInvokeFunctionNode) {
try {
String str = interop.asString(that);
Text txt = Text.create(str);
Function function =
textDispatch.getConversionFunction(
txt,
InvokeConversionNode.extractConstructor(
this, _this, ctx, atomConstructorProfile, atomProfile),
conversion);
arguments[0] = txt;
return indirectInvokeFunctionNode.execute(
function,
frame,
state,
arguments,
schema,
defaultsExecutionMode,
argumentsExecutionMode,
isTail);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException("Impossible, that is guaranteed to be a string.");
} catch (MethodDispatchLibrary.NoSuchConversionException e) {
throw new PanicException(
ctx.get().getBuiltins().error().makeNoSuchConversionError(_this, that, conversion), this);
}
}

@Specialization(
guards = {
"!methods.canConvertFrom(that)",
"!interop.isString(that)",
"!methods.hasSpecialConversion(that)"
})
Stateful doFallback(
MaterializedFrame frame,
Object state,
UnresolvedConversion conversion,
Object _this,
Object that,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail,
@CachedLibrary(limit = "10") MethodDispatchLibrary methods,
@CachedLibrary(limit = "10") InteropLibrary interop,
@CachedContext(Language.class) Context ctx) {
throw new PanicException(
ctx.getBuiltins().error().makeNoSuchConversionError(_this, that, conversion), this);
}
}
Loading