diff options
| author | Michael Williamson <mike@zwobble.org> | 2025-03-08 13:39:40 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2025-03-08 13:39:40 +0000 |
| commit | 8cfdfc92fcf41f5db6d30015b20457ca64f0c3ce (patch) | |
| tree | 7dfd0d403b6b8add040eb1e09515194ca6b26065 /src | |
| parent | 2462a913d149fe896134519d95d65c3adfa30e47 (diff) | |
Support method calls from other namespaces (without Wasm support)
Diffstat (limited to 'src')
16 files changed, 100 insertions, 34 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/PatioBackends.java b/src/main/java/org/shedlang/compiler/backends/PatioBackends.java index bc90c6b4..b8f93ca3 100644 --- a/src/main/java/org/shedlang/compiler/backends/PatioBackends.java +++ b/src/main/java/org/shedlang/compiler/backends/PatioBackends.java @@ -13,6 +13,7 @@ import org.shedlang.compiler.types.NamespaceName; import java.io.IOException; import java.util.List; +import java.util.Optional; public class PatioBackends { public interface PatioToTarget { @@ -36,30 +37,39 @@ public class PatioBackends { TypeInfos typeInfos, PatioToTarget patioToTarget ) throws IOException, InterruptedException { - var shidToPatioContext = ShidToPatioContext.forTypeInfos(typeInfos); + var shidToPatioGlobalContext = ShidToPatioContext.GlobalContext.forTypeInfos(typeInfos); for (var namespace : namespaces) { + var shidToPatioContext = ShidToPatioContext.initialForCompilationUnit( + Optional.of(namespace.namespaceName()), + shidToPatioGlobalContext + ); var patioCompilationUnitResult = ShidToPatio.generateNamespace( namespace, shidToPatioContext ); var patioCompilationUnit = patioCompilationUnitResult.value(); - shidToPatioContext = patioCompilationUnitResult.context(); + shidToPatioGlobalContext = patioCompilationUnitResult.context(); patioToTarget = patioToTarget.namespace(namespace.namespaceName(), patioCompilationUnit); } for (var bin : config.bins()) { - generateMain(profileConfig, bin, shidToPatioContext, patioToTarget); + generateMain(profileConfig, bin, shidToPatioGlobalContext, patioToTarget); } } private static void generateMain( ProfileConfig profileConfig, BinConfig binConfig, - ShidToPatioContext shidToPatioContext, + ShidToPatioContext.GlobalContext shidToPatioGlobalContext, PatioToTarget patioToTarget ) throws IOException, InterruptedException { + var shidToPatioContext = ShidToPatioContext.initialForCompilationUnit( + Optional.empty(), + shidToPatioGlobalContext + ); + // TODO: set appropriate source var source = Sources.NULL; @@ -78,7 +88,7 @@ public class PatioBackends { var patioCompilationUnitResult = shidToPatioContext.toCompilationUnit(source); var patioCompilationUnit = patioCompilationUnitResult.value(); - shidToPatioContext = patioCompilationUnitResult.context(); + shidToPatioGlobalContext = patioCompilationUnitResult.context(); patioToTarget.bin( binConfig.name(), diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java index a27168c4..97f5d4cd 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatio.java @@ -108,7 +108,7 @@ public class ShidToPatio { return context.toResult(mainFunctionName); } - public static ShidToPatioResult<PatioCompilationUnit> generateNamespace( + public static ShidToPatioContext.GlobalContext.Result<PatioCompilationUnit> generateNamespace( ShidNamespace shidNamespace, ShidToPatioContext context ) { diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java index ac8f0094..397ce996 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java @@ -172,14 +172,28 @@ public record ShidToPatioContext( } public record CompilationUnitContext( + Optional<NamespaceName> namespaceName, OrderedPMap<String, PatioCompilationUnitElement> elementsByName ) { - public static CompilationUnitContext EMPTY = new CompilationUnitContext(OrderedPMap.empty()); + public static CompilationUnitContext EMPTY = initial(Optional.empty()); + + public static CompilationUnitContext initial(Optional<NamespaceName> namespaceName) { + return new CompilationUnitContext( + namespaceName, + OrderedPMap.empty() + ); + } + + @CheckReturnValue + public Optional<NamespaceName> namespaceName() { + return this.namespaceName; + } @CheckReturnValue public CompilationUnitContext addElement(PatioCompilationUnitElement element) { // TODO: handle existing element with name. return new CompilationUnitContext( + this.namespaceName, this.elementsByName.plus(element.name(), element) ); } @@ -212,6 +226,7 @@ public record ShidToPatioContext( } return new CompilationUnitContext( + this.namespaceName, this.elementsByName.plus(element.name(), element) ); } @@ -224,6 +239,7 @@ public record ShidToPatioContext( if (existingElement == null) { return new CompilationUnitContext( + this.namespaceName, this.elementsByName.plus(element.name(), element) ); } else if (existingElement.equals(element)) { @@ -528,17 +544,13 @@ public record ShidToPatioContext( ); @CheckReturnValue - public static ShidToPatioContext forTypeInfos(TypeInfos typeInfos) { - return initialForCompilationUnit( - GlobalContext.forTypeInfos(typeInfos) - ); - } - - @CheckReturnValue - private static ShidToPatioContext initialForCompilationUnit(GlobalContext globalContext) { + public static ShidToPatioContext initialForCompilationUnit( + Optional<NamespaceName> namespaceName, + GlobalContext globalContext + ) { return new ShidToPatioContext( globalContext, - CompilationUnitContext.EMPTY, + CompilationUnitContext.initial(namespaceName), P.stack(), FunctionContext.EMPTY ); @@ -580,6 +592,11 @@ public record ShidToPatioContext( } @CheckReturnValue + public Optional<NamespaceName> namespaceName() { + return this.compilationUnitContext.namespaceName(); + } + + @CheckReturnValue public ShidToPatioResult<String> allocateCompilationUnitElementName( ShidToPatioCompilationUnitElementSpace space, String name @@ -957,8 +974,8 @@ public record ShidToPatioContext( } @CheckReturnValue - public ShidToPatioResult<PatioCompilationUnit> toCompilationUnit(Source source) { - return initialForCompilationUnit(this.globalContext).toResult(new PatioCompilationUnit( + public GlobalContext.Result<PatioCompilationUnit> toCompilationUnit(Source source) { + return this.globalContext.toResult(new PatioCompilationUnit( new ArrayList<>(this.compilationUnitContext.elementsByName.values()), source )); diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethods.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethods.java index 96f3a83c..6dfaf6a4 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethods.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethods.java @@ -1,5 +1,6 @@ package org.shedlang.compiler.shidtopatio; +import org.shedlang.compiler.patio.PatioDataElementMutableDeclaration; import org.shedlang.compiler.patio.PatioDataElementMutableDefinition; import org.shedlang.compiler.patio.PatioVisibility; import org.shedlang.compiler.patio.instructions.PatioMemoryLoad; @@ -10,10 +11,12 @@ import org.shedlang.compiler.patio.operands.PatioOperand; import org.shedlang.compiler.patio.types.PatioDataLayouts; import org.shedlang.compiler.patio.types.PatioDataValues; import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.types.SimpleConcreteType; import java.text.MessageFormat; import java.util.List; +import java.util.Optional; import static org.shedlang.compiler.shidtopatio.ShidToPatioNamespaces.namespaceNameToPatioIdentifier; @@ -28,6 +31,14 @@ public class ShidToPatioMethods { Source source, ShidToPatioContext context ) { + if (!context.namespaceName().equals(Optional.of(type.namespaceName()))) { + context = context.ensureCompilationUnitElement(new PatioDataElementMutableDeclaration( + globalNameMethod(type, methodName), + PatioDataLayouts.fromType(ShidToPatioTypes.VALUE_TYPE), + Sources.NULL + )); + } + context = context.addInstruction(new PatioMemoryLoad( destination, globalOperandMethod(type, methodName), @@ -48,7 +59,7 @@ public class ShidToPatioMethods { ) { context = context.addCompilationUnitElement(new PatioDataElementMutableDefinition( globalNameMethod(type, methodName), - PatioVisibility.PRIVATE, + PatioVisibility.PUBLIC, PatioDataValues.int_(0), source )); diff --git a/src/test/java/org/shedlang/compiler/backends/wasm/Wasm32ExampleTests.java b/src/test/java/org/shedlang/compiler/backends/wasm/Wasm32ExampleTests.java index 7b0ab151..f1dbee2c 100644 --- a/src/test/java/org/shedlang/compiler/backends/wasm/Wasm32ExampleTests.java +++ b/src/test/java/org/shedlang/compiler/backends/wasm/Wasm32ExampleTests.java @@ -23,6 +23,7 @@ public class Wasm32ExampleTests extends ExampleTests { } private static final Set<String> DISABLED = Set.of( + "40-imported-struct-methods" ); @Override diff --git a/src/test/java/org/shedlang/compiler/backends/wasm/Wasm64ExampleTests.java b/src/test/java/org/shedlang/compiler/backends/wasm/Wasm64ExampleTests.java index 71d5f17b..0a4cfd7b 100644 --- a/src/test/java/org/shedlang/compiler/backends/wasm/Wasm64ExampleTests.java +++ b/src/test/java/org/shedlang/compiler/backends/wasm/Wasm64ExampleTests.java @@ -23,6 +23,7 @@ public class Wasm64ExampleTests extends ExampleTests { } private static final Set<String> DISABLED = Set.of( + "40-imported-struct-methods" ); @Override diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineEffectTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineEffectTests.java index 686f708c..f3ca07a0 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineEffectTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineEffectTests.java @@ -38,7 +38,7 @@ public class ShidToPatioDefineEffectTests { ) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos); + var context = ShidToPatioTesting.createContext(typeInfos); var result = ShidToPatio.generateInstruction(instruction, context); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineStructTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineStructTests.java index b363cbb8..cb9268fb 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineStructTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioDefineStructTests.java @@ -38,7 +38,7 @@ public class ShidToPatioDefineStructTests { .withFieldsArePositional(false) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos); + var context = ShidToPatioTesting.createContext(typeInfos); var result = ShidToPatio.generateInstruction(instruction, context); @@ -64,7 +64,7 @@ public class ShidToPatioDefineStructTests { .withFieldsArePositional(true) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos); + var context = ShidToPatioTesting.createContext(typeInfos); var result = ShidToPatio.generateInstruction(instruction, context); @@ -83,7 +83,7 @@ public class ShidToPatioDefineStructTests { var typeInfos = TypeInfos.EMPTY .addStructTypeInfo(structType1, StructTypeInfo.builder().build()) .addStructTypeInfo(structType2, StructTypeInfo.builder().build()); - var context = ShidToPatioContext.forTypeInfos(typeInfos); + var context = ShidToPatioTesting.createContext(typeInfos); context = ShidToPatio.generateInstruction(instruction1, context); context = ShidToPatio.generateInstruction(instruction2, context); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioFieldLoadTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioFieldLoadTests.java index 3f5fd284..10644e07 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioFieldLoadTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioFieldLoadTests.java @@ -31,7 +31,7 @@ public class ShidToPatioFieldLoadTests { .build() ) .toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); @@ -54,7 +54,7 @@ public class ShidToPatioFieldLoadTests { .addField("isActive", Types.BOOL) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); @@ -77,7 +77,7 @@ public class ShidToPatioFieldLoadTests { .addMethod("read", FunctionType.builder().build()) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodLoadTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodLoadTests.java index 6fc4abc2..f7d24389 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodLoadTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodLoadTests.java @@ -11,18 +11,36 @@ import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.types.Types; import java.io.IOException; +import java.util.Optional; import static org.shedlang.compiler.shidtopatio.ShidToPatioTesting.serialize; @ExtendWith({SnapshotResolver.class}) public class ShidToPatioMethodLoadTests { @Test - public void canGenerateCodeForMethodLoad(Snapshotter snapshotter) throws IOException { + public void canGenerateCodeForMethodLoadInSameNamespace(Snapshotter snapshotter) throws IOException { var namespaceName = NamespaceName.of("Example", "Project"); var structType = Types.struct(namespaceName, "User"); var shidInstruction = Shid.methodLoad(structType, "name"); var typeInfo = TypeCheckerContext.EMPTY.toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfo) + var globalContext = ShidToPatioContext.GlobalContext.forTypeInfos(typeInfo); + var context = ShidToPatioContext.initialForCompilationUnit(Optional.of(namespaceName), globalContext) + .temporaryPush(new PatioLocalRef("a")); + + var result = ShidToPatio.generateInstruction(shidInstruction, context); + + snapshotter.assertSnapshot(serialize(result)); + } + + @Test + public void canGenerateCodeForMethodLoadInDifferentNamespace(Snapshotter snapshotter) throws IOException { + var namespaceName = NamespaceName.of("Example", "Project"); + var otherNamespaceName = NamespaceName.of("Example", "Project2"); + var structType = Types.struct(namespaceName, "User"); + var shidInstruction = Shid.methodLoad(structType, "name"); + var typeInfo = TypeCheckerContext.EMPTY.toTypeInfos(); + var globalContext = ShidToPatioContext.GlobalContext.forTypeInfos(typeInfo); + var context = ShidToPatioContext.initialForCompilationUnit(Optional.of(otherNamespaceName), globalContext) .temporaryPush(new PatioLocalRef("a")); var result = ShidToPatio.generateInstruction(shidInstruction, context); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodStoreTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodStoreTests.java index 447a925a..65386f61 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodStoreTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioMethodStoreTests.java @@ -22,7 +22,7 @@ public class ShidToPatioMethodStoreTests { var structType = Types.struct(namespaceName, "User"); var shidInstruction = Shid.methodStore(structType, "name"); var typeInfo = TypeCheckerContext.EMPTY.toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfo) + var context = ShidToPatioTesting.createContext(typeInfo) .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceFieldStoreTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceFieldStoreTests.java index c57f9572..436bd92c 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceFieldStoreTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceFieldStoreTests.java @@ -32,7 +32,7 @@ public class ShidToPatioNamespaceFieldStoreTests { .build() ) .toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfo) + var context = ShidToPatioTesting.createContext(typeInfo) .temporaryPush(new PatioLocalRef("a")) .temporaryPush(new PatioLocalRef("b")); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceTests.java index 561a420f..67a97d96 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioNamespaceTests.java @@ -45,7 +45,7 @@ public class ShidToPatioNamespaceTests { .addField("y", Types.STRING) .build() ); - var context = ShidToPatioContext.forTypeInfos(typeInfos); + var context = ShidToPatioTesting.createContext(typeInfos); var shidNamespace = new ShidNamespace(namespaceName, instructions, Sources.NULL); var result = ShidToPatio.generateNamespace(shidNamespace, context); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioSwitchTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioSwitchTests.java index b22e7572..d40da05b 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioSwitchTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioSwitchTests.java @@ -46,7 +46,7 @@ public class ShidToPatioSwitchTests { var typeInfos = TypeInfos.EMPTY .addStructTypeInfo(structType1, StructTypeInfo.builder().build()) .addStructTypeInfo(structType2, StructTypeInfo.builder().build()); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .temporaryPush(new PatioLocalRef("other")) .temporaryPush(new PatioLocalRef("condition")); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTesting.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTesting.java index 644371eb..c384d7c4 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTesting.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTesting.java @@ -1,10 +1,18 @@ package org.shedlang.compiler.shidtopatio; import org.shedlang.compiler.patio.PatioSerializer; +import org.shedlang.compiler.typechecker.TypeInfos; + +import java.util.Optional; class ShidToPatioTesting { private ShidToPatioTesting() {} + static ShidToPatioContext createContext(TypeInfos typeInfos) { + var globalContext = ShidToPatioContext.GlobalContext.forTypeInfos(typeInfos); + return ShidToPatioContext.initialForCompilationUnit(Optional.empty(), globalContext); + } + static String serialize(ShidToPatioContext context) { var builder = new StringBuilder(); diff --git a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTryTests.java b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTryTests.java index 5166449d..f7cfb141 100644 --- a/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTryTests.java +++ b/src/test/java/org/shedlang/compiler/shidtopatio/ShidToPatioTryTests.java @@ -37,7 +37,7 @@ public class ShidToPatioTryTests { .build() ) .toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .temporaryPush(new PatioLocalRef("other")) .temporaryPush(new PatioLocalRef("handlerA")) .temporaryPush(new PatioLocalRef("handlerC")) @@ -68,7 +68,7 @@ public class ShidToPatioTryTests { .build() ) .toTypeInfos(); - var context = ShidToPatioContext.forTypeInfos(typeInfos) + var context = ShidToPatioTesting.createContext(typeInfos) .stashGcRootStackIndex(new PatioLocalRef("gcRootStackIndex")) .temporaryPush(new PatioLocalRef("other")) .temporaryPush(new PatioLocalRef("handlerA")); |
