mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 11:52:59 +03:00
Providing onScope
This commit is contained in:
parent
b4aaa51676
commit
8ebabd5c83
@ -1,12 +1,15 @@
|
|||||||
package org.enso.interpreter.node.expression.builtin;
|
package org.enso.interpreter.node.expression.builtin;
|
||||||
|
|
||||||
import com.oracle.truffle.api.CompilerDirectives;
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.enso.interpreter.EnsoLanguage;
|
import org.enso.interpreter.EnsoLanguage;
|
||||||
import org.enso.interpreter.runtime.Module;
|
import org.enso.interpreter.runtime.Module;
|
||||||
|
import org.enso.interpreter.runtime.callable.Annotation;
|
||||||
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
|
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
|
||||||
import org.enso.interpreter.runtime.data.Type;
|
import org.enso.interpreter.runtime.data.Type;
|
||||||
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
|
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
|
||||||
@ -20,18 +23,20 @@ public abstract class Builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private AtomConstructor build(
|
private AtomConstructor build(
|
||||||
EnsoLanguage language, ModuleScope.Builder builder, ModuleScope scope, Type type) {
|
EnsoLanguage language, ModuleScope.Builder builder, Type type) {
|
||||||
var res = new AtomConstructor(name, builder.getModule(), type, true);
|
var res = new AtomConstructor(name, builder.getModule(), type, true);
|
||||||
res.initializeBuilder(language, builder);
|
var args = IntStream.range(0, params.size())
|
||||||
res.initializeFields(
|
|
||||||
language,
|
|
||||||
scope,
|
|
||||||
IntStream.range(0, params.size())
|
|
||||||
.mapToObj(
|
.mapToObj(
|
||||||
i ->
|
i ->
|
||||||
new ArgumentDefinition(
|
new ArgumentDefinition(
|
||||||
i, params.get(i), null, null, ArgumentDefinition.ExecutionMode.EXECUTE))
|
i, params.get(i), null, null, ArgumentDefinition.ExecutionMode.EXECUTE))
|
||||||
.toArray(ArgumentDefinition[]::new));
|
.toArray(ArgumentDefinition[]::new);
|
||||||
|
res.initializeBuilder(language, builder, new Annotation[0],args);
|
||||||
|
builder.onScope(scope -> {
|
||||||
|
res.initializeFields(
|
||||||
|
language,
|
||||||
|
scope);
|
||||||
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,14 +62,13 @@ public abstract class Builtin {
|
|||||||
EnsoLanguage language,
|
EnsoLanguage language,
|
||||||
Module module,
|
Module module,
|
||||||
ModuleScope.Builder builder,
|
ModuleScope.Builder builder,
|
||||||
ModuleScope scope,
|
|
||||||
Map<Class<? extends Builtin>, Builtin> builtins) {
|
Map<Class<? extends Builtin>, Builtin> builtins) {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
Type supertype = null;
|
Type supertype = null;
|
||||||
if (getSuperType() != null) {
|
if (getSuperType() != null) {
|
||||||
var s = builtins.get(getSuperType());
|
var s = builtins.get(getSuperType());
|
||||||
s.initialize(language, module, builder, scope, builtins);
|
|
||||||
supertype = s.getType();
|
supertype = s.getType();
|
||||||
|
s.initialize(language, module, builder, builtins);
|
||||||
}
|
}
|
||||||
type =
|
type =
|
||||||
containsValues()
|
containsValues()
|
||||||
@ -76,7 +80,7 @@ public abstract class Builtin {
|
|||||||
var conses = getDeclaredConstructors();
|
var conses = getDeclaredConstructors();
|
||||||
constructors = new AtomConstructor[conses.size()];
|
constructors = new AtomConstructor[conses.size()];
|
||||||
for (int i = 0; i < constructors.length; i++) {
|
for (int i = 0; i < constructors.length; i++) {
|
||||||
var cons = conses.get(i).build(language, builder, scope, type);
|
var cons = conses.get(i).build(language, builder, type);
|
||||||
constructors[i] = cons;
|
constructors[i] = cons;
|
||||||
type.registerConstructor(cons);
|
type.registerConstructor(cons);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ public final class Builtins {
|
|||||||
|
|
||||||
builtins =
|
builtins =
|
||||||
initializeBuiltinTypes(
|
initializeBuiltinTypes(
|
||||||
loadedBuiltinConstructors, language, scopeBuilder, null /* as no scope */);
|
loadedBuiltinConstructors, language, scopeBuilder);
|
||||||
builtinsByName =
|
builtinsByName =
|
||||||
builtins.values().stream()
|
builtins.values().stream()
|
||||||
.collect(
|
.collect(
|
||||||
@ -381,8 +381,7 @@ public final class Builtins {
|
|||||||
private Map<Class<? extends Builtin>, Builtin> initializeBuiltinTypes(
|
private Map<Class<? extends Builtin>, Builtin> initializeBuiltinTypes(
|
||||||
List<Constructor<? extends Builtin>> constrs,
|
List<Constructor<? extends Builtin>> constrs,
|
||||||
EnsoLanguage language,
|
EnsoLanguage language,
|
||||||
ModuleScope.Builder builder,
|
ModuleScope.Builder builder) {
|
||||||
ModuleScope scope) {
|
|
||||||
Map<Class<? extends Builtin>, Builtin> builtins = new HashMap<>();
|
Map<Class<? extends Builtin>, Builtin> builtins = new HashMap<>();
|
||||||
|
|
||||||
for (var constr : constrs) {
|
for (var constr : constrs) {
|
||||||
@ -394,7 +393,7 @@ public final class Builtins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var b : builtins.values()) {
|
for (var b : builtins.values()) {
|
||||||
b.initialize(language, getModule(), builder, scope, builtins);
|
b.initialize(language, getModule(), builder, builtins);
|
||||||
}
|
}
|
||||||
return builtins;
|
return builtins;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ public final class AtomConstructor implements EnsoObject {
|
|||||||
private Layout[] unboxingLayouts = new Layout[0];
|
private Layout[] unboxingLayouts = new Layout[0];
|
||||||
|
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
private FunctionSchema schema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Atom constructor for a given name.The constructor is not valid until {@link
|
* Creates a new Atom constructor for a given name.The constructor is not valid until {@link
|
||||||
@ -115,20 +116,36 @@ public final class AtomConstructor implements EnsoObject {
|
|||||||
LocalScope.root(),
|
LocalScope.root(),
|
||||||
scope,
|
scope,
|
||||||
new ExpressionNode[0],
|
new ExpressionNode[0],
|
||||||
reads,
|
reads);
|
||||||
new Annotation[0],
|
|
||||||
args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the fields of this {@link AtomConstructor} and generates a constructor function.
|
* Sets the fields of this {@link AtomConstructor} and generates a constructor function.
|
||||||
*
|
*
|
||||||
* @param scopeBuilder the module scope's builder where the accessor should be registered at
|
* @param scopeBuilder the module scope's builder where the accessor should be registered at
|
||||||
|
* @param args
|
||||||
* @return {@code this}, for convenience
|
* @return {@code this}, for convenience
|
||||||
*/
|
*/
|
||||||
public AtomConstructor initializeBuilder(
|
public AtomConstructor initializeBuilder(
|
||||||
EnsoLanguage language, ModuleScope.Builder scopeBuilder) {
|
EnsoLanguage language, ModuleScope.Builder scopeBuilder, ArgumentDefinition[] args) {
|
||||||
|
assert boxedLayout == null : "Don't initialize twice: " + this.name;
|
||||||
this.accessor = generateQualifiedAccessor(language, scopeBuilder);
|
this.accessor = generateQualifiedAccessor(language, scopeBuilder);
|
||||||
|
var schemaBldr =
|
||||||
|
FunctionSchema.newBuilder()
|
||||||
|
.argumentDefinitions(
|
||||||
|
new ArgumentDefinition(
|
||||||
|
0, "self", null, null, ArgumentDefinition.ExecutionMode.EXECUTE));
|
||||||
|
if (type.isProjectPrivate()) {
|
||||||
|
schemaBldr.projectPrivate();
|
||||||
|
}
|
||||||
|
this.schema = schemaBldr.build();
|
||||||
|
if (args.length == 0) {
|
||||||
|
cachedInstance = BoxingAtom.singleton(this);
|
||||||
|
} else {
|
||||||
|
cachedInstance = null;
|
||||||
|
}
|
||||||
|
this.boxedLayout = Layout.createBoxed(args);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,20 +164,11 @@ public final class AtomConstructor implements EnsoObject {
|
|||||||
LocalScope localScope,
|
LocalScope localScope,
|
||||||
ModuleScope scope,
|
ModuleScope scope,
|
||||||
ExpressionNode[] assignments,
|
ExpressionNode[] assignments,
|
||||||
ExpressionNode[] varReads,
|
ExpressionNode[] varReads) {
|
||||||
Annotation[] annotations,
|
|
||||||
ArgumentDefinition... args) {
|
|
||||||
CompilerDirectives.transferToInterpreterAndInvalidate();
|
CompilerDirectives.transferToInterpreterAndInvalidate();
|
||||||
assert boxedLayout == null : "Don't initialize twice: " + this.name;
|
|
||||||
if (args.length == 0) {
|
|
||||||
cachedInstance = BoxingAtom.singleton(this);
|
|
||||||
} else {
|
|
||||||
cachedInstance = null;
|
|
||||||
}
|
|
||||||
boxedLayout = Layout.createBoxed(args);
|
|
||||||
this.constructorFunction =
|
this.constructorFunction =
|
||||||
buildConstructorFunction(
|
buildConstructorFunction(
|
||||||
language, section, localScope, scope, assignments, varReads, annotations, args);
|
language, section, localScope, scope, assignments, varReads);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,9 +191,8 @@ public final class AtomConstructor implements EnsoObject {
|
|||||||
LocalScope localScope,
|
LocalScope localScope,
|
||||||
ModuleScope scope,
|
ModuleScope scope,
|
||||||
ExpressionNode[] assignments,
|
ExpressionNode[] assignments,
|
||||||
ExpressionNode[] varReads,
|
ExpressionNode[] varReads
|
||||||
Annotation[] annotations,
|
) {
|
||||||
ArgumentDefinition[] args) {
|
|
||||||
ExpressionNode instantiateNode = InstantiateNode.build(this, varReads);
|
ExpressionNode instantiateNode = InstantiateNode.build(this, varReads);
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
instantiateNode.setSourceLocation(section.getCharIndex(), section.getCharLength());
|
instantiateNode.setSourceLocation(section.getCharIndex(), section.getCharLength());
|
||||||
@ -195,25 +202,13 @@ public final class AtomConstructor implements EnsoObject {
|
|||||||
MethodRootNode.buildConstructor(
|
MethodRootNode.buildConstructor(
|
||||||
language, localScope, scope, instantiateBlock, section, this);
|
language, localScope, scope, instantiateBlock, section, this);
|
||||||
RootCallTarget callTarget = rootNode.getCallTarget();
|
RootCallTarget callTarget = rootNode.getCallTarget();
|
||||||
var schemaBldr = FunctionSchema.newBuilder().annotations(annotations).argumentDefinitions(args);
|
return new Function(callTarget, null, schema);
|
||||||
if (type.isProjectPrivate()) {
|
|
||||||
schemaBldr.projectPrivate();
|
|
||||||
}
|
|
||||||
return new Function(callTarget, null, schemaBldr.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Function generateQualifiedAccessor(EnsoLanguage lang, ModuleScope.Builder scopeBuilder) {
|
private Function generateQualifiedAccessor(EnsoLanguage lang, ModuleScope.Builder scopeBuilder) {
|
||||||
var node = new QualifiedAccessorNode(lang, this, getDefinitionScope());
|
var node = new QualifiedAccessorNode(lang, this, getDefinitionScope());
|
||||||
var callTarget = node.getCallTarget();
|
var callTarget = node.getCallTarget();
|
||||||
var schemaBldr =
|
var function = new Function(callTarget, null, schema);
|
||||||
FunctionSchema.newBuilder()
|
|
||||||
.argumentDefinitions(
|
|
||||||
new ArgumentDefinition(
|
|
||||||
0, "self", null, null, ArgumentDefinition.ExecutionMode.EXECUTE));
|
|
||||||
if (type.isProjectPrivate()) {
|
|
||||||
schemaBldr.projectPrivate();
|
|
||||||
}
|
|
||||||
var function = new Function(callTarget, null, schemaBldr.build());
|
|
||||||
scopeBuilder.registerMethod(type.getEigentype(), this.name, function);
|
scopeBuilder.registerMethod(type.getEigentype(), this.name, function);
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@ package org.enso.interpreter.runtime.scope;
|
|||||||
import com.oracle.truffle.api.CompilerDirectives;
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
import com.oracle.truffle.api.library.ExportLibrary;
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
import com.oracle.truffle.api.library.ExportMessage;
|
import com.oracle.truffle.api.library.ExportMessage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.enso.compiler.context.CompilerContext;
|
import org.enso.compiler.context.CompilerContext;
|
||||||
import org.enso.interpreter.runtime.Module;
|
import org.enso.interpreter.runtime.Module;
|
||||||
import org.enso.interpreter.runtime.callable.function.Function;
|
import org.enso.interpreter.runtime.callable.function.Function;
|
||||||
@ -281,6 +284,7 @@ public final class ModuleScope implements EnsoObject {
|
|||||||
private final Map<Type, Map<Type, Function>> conversions;
|
private final Map<Type, Map<Type, Function>> conversions;
|
||||||
private final Set<ImportExportScope> imports;
|
private final Set<ImportExportScope> imports;
|
||||||
private final Set<ImportExportScope> exports;
|
private final Set<ImportExportScope> exports;
|
||||||
|
private final List<Consumer<ModuleScope>> onScope = new ArrayList<>();
|
||||||
|
|
||||||
public Builder(Module module) {
|
public Builder(Module module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
@ -461,6 +465,15 @@ public final class ModuleScope implements EnsoObject {
|
|||||||
return new Builder(this.module, new LinkedHashMap<>(this.types));
|
return new Builder(this.module, new LinkedHashMap<>(this.types));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Registers a callback to be notified when {@link #build()} is called
|
||||||
|
* @param callback the callback to notify
|
||||||
|
* @return this builder
|
||||||
|
*/
|
||||||
|
public Builder onScope(Consumer<ModuleScope> callback) {
|
||||||
|
onScope.add(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Materializes the builder and ensures that no further modifications to ModuleScope are
|
* Materializes the builder and ensures that no further modifications to ModuleScope are
|
||||||
* possible. Action is idempotent.
|
* possible. Action is idempotent.
|
||||||
@ -469,7 +482,7 @@ public final class ModuleScope implements EnsoObject {
|
|||||||
*/
|
*/
|
||||||
public ModuleScope build() {
|
public ModuleScope build() {
|
||||||
if (moduleScope == null) {
|
if (moduleScope == null) {
|
||||||
return moduleScope =
|
moduleScope =
|
||||||
new ModuleScope(
|
new ModuleScope(
|
||||||
module,
|
module,
|
||||||
associatedType,
|
associatedType,
|
||||||
@ -479,6 +492,11 @@ public final class ModuleScope implements EnsoObject {
|
|||||||
Collections.unmodifiableMap(conversions),
|
Collections.unmodifiableMap(conversions),
|
||||||
Collections.unmodifiableSet(imports),
|
Collections.unmodifiableSet(imports),
|
||||||
Collections.unmodifiableSet(exports));
|
Collections.unmodifiableSet(exports));
|
||||||
|
for (var c : onScope) {
|
||||||
|
c.accept(moduleScope);
|
||||||
|
}
|
||||||
|
onScope.clear();
|
||||||
|
return moduleScope;
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError("Already built");
|
throw new AssertionError("Already built");
|
||||||
}
|
}
|
||||||
|
@ -247,13 +247,18 @@ class IrToTruffle(
|
|||||||
val asType = scopeBuilder.getType(tpDef.name.name, true)
|
val asType = scopeBuilder.getType(tpDef.name.name, true)
|
||||||
val atomConstructors =
|
val atomConstructors =
|
||||||
atomDefs.map(cons => asType.getConstructors.get(cons.name.name))
|
atomDefs.map(cons => asType.getConstructors.get(cons.name.name))
|
||||||
atomConstructors
|
val trippleStream = atomConstructors
|
||||||
.zip(atomDefs)
|
.zip(atomDefs)
|
||||||
.foreach { case (atomCons, _) =>
|
.foreach { case (atomCons, atomDefn) =>
|
||||||
|
val argDefs =
|
||||||
|
new Array[ArgumentDefinition](atomDefn.arguments.size)
|
||||||
|
|
||||||
atomCons.initializeBuilder(
|
atomCons.initializeBuilder(
|
||||||
language,
|
language,
|
||||||
scopeBuilder
|
scopeBuilder,
|
||||||
|
argDefs
|
||||||
)
|
)
|
||||||
|
(atomCons, atomDefn, argDefs)
|
||||||
}
|
}
|
||||||
asType.generateGetters(scopeBuilder, language)
|
asType.generateGetters(scopeBuilder, language)
|
||||||
}
|
}
|
||||||
@ -364,7 +369,7 @@ class IrToTruffle(
|
|||||||
assignments.toArray,
|
assignments.toArray,
|
||||||
reads.toArray,
|
reads.toArray,
|
||||||
annotations.toArray,
|
annotations.toArray,
|
||||||
argDefs: _*
|
argDefs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user