aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-12-21 10:40:28 +0000
committerMichael Williamson <mike@zwobble.org>2024-12-21 10:40:28 +0000
commit2dba29dfa74c32a3102a9317455e16cd9a5a35a7 (patch)
tree6cee1e7886c35305ae24df5ba00c759dfe828d01 /src/main/java
parentf570b54bd3e0fe6ebc134101e3c54be5bc49253d (diff)
Compile methods into free functions
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java65
-rw-r--r--src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java4
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;