diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-12-21 10:40:28 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-12-21 10:40:28 +0000 |
| commit | 2dba29dfa74c32a3102a9317455e16cd9a5a35a7 (patch) | |
| tree | 6cee1e7886c35305ae24df5ba00c759dfe828d01 /src/main/java | |
| parent | f570b54bd3e0fe6ebc134101e3c54be5bc49253d (diff) | |
Compile methods into free functions
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java | 65 | ||||
| -rw-r--r-- | src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java | 4 |
2 files changed, 45 insertions, 24 deletions
diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java index b0c33578..280e94b8 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -474,6 +474,12 @@ public class ShidCodeGen { for (var statement : statementsAfterHoisting) { context = compileNamespaceStatement(statement, context); } + for (var statement : statementsAfterHoisting) { + if (statement instanceof TypedStructDefinitionNode structDefinitionNode) { + // TODO: test method hoisting + context = compileStructDefinitionMethods(structDefinitionNode, context); + } + } for (var fieldName : node.fieldNames()) { var localName = context.shedVariableToLocal(fieldName); @@ -549,31 +555,11 @@ public class ShidCodeGen { ) { var structType = node.typeOrConstructor().toType(); - var methods = new ArrayList<ShidDefineStruct.Method>(); - for (var methodNode : node.methods()) { - var shidFunctionName = context.generateLocalNameForVariable( - structType.name() + "__" + methodNode.name() - ); - context = compileFunction( - shidFunctionName, - methodNode.signature().params(), - methodNode.body(), - ShidDefineFunction.Variant.FUNCTION, - methodNode.source(), - context - ); - methods.add(new ShidDefineStruct.Method( - methodNode.name(), - shidFunctionName - )); - } - var defineStructInstruction = new ShidDefineStruct( structType, node.fields().stream() .map(field -> new ShidDefineStruct.Field(field.name(), field.source())) .toList(), - methods, node.source() ); @@ -585,6 +571,45 @@ public class ShidCodeGen { .addInstruction(storeInstruction); } + static Context compileStructDefinitionMethods( + TypedStructDefinitionNode node, + Context context + ) { + var structType = node.typeOrConstructor().toType(); + + for (var methodNode : node.methods()) { + var shidFunctionName = context.generateLocalNameForVariable( + "$methods__" + String.join("_", structType.namespaceName().parts()) + "__" + structType.name() + "__" + methodNode.name() + ); + context = compileFunction( + shidFunctionName, + methodNode.signature().params(), + methodNode.body(), + ShidDefineFunction.Variant.FUNCTION, + methodNode.source(), + context + ); + + context = context.addInstruction( + new ShidLocalStore(shidFunctionName, methodNode.source()) + ); + + context = context.addInstruction( + new ShidLocalLoad(shidFunctionName, methodNode.source()) + ); + + context = context.addInstruction( + new ShidNamespaceFieldStore( + structType.namespaceName(), + shidFunctionName, + methodNode.source() + ) + ); + } + + return context; + } + private static Context compileSumTypeDefinition( TypedSumTypeDefinitionNode node, Context context diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java index c76b4f20..d3ed9e10 100644 --- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java @@ -13,15 +13,11 @@ public record ShidDefineStruct( SimpleStructType type, // TODO: remove fields? We should have fields from the type info. List<Field> fields, - List<Method> methods, Source source ) implements ShidInstruction { public record Field(String name, Source source) { } - public record Method(String methodName, String shidFunctionName) { - } - @Override public boolean isBlockTerminator() { return false; |
