summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-05-02 09:24:55 +0100
committerMichael Williamson <mike@zwobble.org>2026-05-02 09:30:31 +0100
commitca4873eaf5fb950caa2559651274374ae088c4e5 (patch)
treed79c398bd2bd810eb6eaacff07d1a7b851873407 /src
parentbf1d5239ea0b6a2017e8f82049446bfc3de2beda (diff)
Have record implement interface if variant of sum
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java23
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/java/JavaWriter.java62
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/java/ast/JavaRecordDeclaration.java3
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java1
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValueType.java5
5 files changed, 77 insertions, 17 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
index 6e876f2..43e35b4 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java
@@ -18,6 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public class JavaTypesGenerator implements Generator {
@@ -51,6 +52,21 @@ public class JavaTypesGenerator implements Generator {
private List<JavaCompilationUnit> generateNamespace(TypedNamespaceNode namespace) {
var packageParts = namespaceToJavaPackageParts(namespace.namespaceName());
+ var javaClassToImplementsType = new HashMap<String, List<JavaTypeRef>>();
+ for (var statement : namespace.body()) {
+ if (statement instanceof TypedSumDefinitionNode sumDefinition) {
+ for (var variant : sumDefinition.variants()) {
+ var variantTypeName = variant.type().value().name();
+ javaClassToImplementsType.putIfAbsent(
+ variantTypeName,
+ new ArrayList<>()
+ );
+ javaClassToImplementsType.get(variantTypeName)
+ .add(generateTypeRef(sumDefinition.type()));
+ }
+ }
+ }
+
var javaCompilationUnits = new ArrayList<JavaCompilationUnit>();
for (var statement : namespace.body()) {
@@ -65,7 +81,8 @@ public class JavaTypesGenerator implements Generator {
generateTypeRef(field.type()),
field.name()
))
- .toList()
+ .toList(),
+ javaClassToImplementsType.getOrDefault(structDefinition.name(), List.of())
)
);
@@ -73,7 +90,6 @@ public class JavaTypesGenerator implements Generator {
}
case TypedSumDefinitionNode sumDefinition -> {
- throw new UnsupportedOperationException("TODO");
}
}
}
@@ -89,7 +105,10 @@ public class JavaTypesGenerator implements Generator {
private JavaTypeRef generateTypeRef(TypedTypeLevelExpressionNode<Type> typeNode) {
var type = typeNode.value();
+ return generateTypeRef(type);
+ }
+ private JavaTypeRef generateTypeRef(Type type) {
return switch (type) {
case StructType structType ->
new JavaTypeRef(namespaceToJavaPackageParts(structType.namespaceName()), structType.name());
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/java/JavaWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/java/JavaWriter.java
index 36da8ba..1de6950 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/java/JavaWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/java/JavaWriter.java
@@ -1,8 +1,8 @@
package org.zwobble.hobgoblin.compiler.output.java;
import org.zwobble.hobgoblin.compiler.output.CodeWriter;
-import org.zwobble.hobgoblin.compiler.output.java.ast.JavaRecordDeclaration;
import org.zwobble.hobgoblin.compiler.output.java.ast.JavaCompilationUnit;
+import org.zwobble.hobgoblin.compiler.output.java.ast.JavaRecordDeclaration;
import org.zwobble.hobgoblin.compiler.output.java.ast.JavaTypeDeclaration;
import org.zwobble.hobgoblin.compiler.output.java.ast.JavaTypeRef;
@@ -43,22 +43,29 @@ public class JavaWriter implements AutoCloseable {
this.writer.write(recordDeclaration.name());
this.writer.write("(");
- var isFirst = true;
- for (var component : recordDeclaration.components()) {
- if (!isFirst) {
- writer.write(", ");
- }
-
- writeTypeRef(component.type());
+ writeWithSeparator(
+ recordDeclaration.components(),
+ component -> {
+ writeTypeRef(component.type());
+ writer.write(" ");
+ writer.write(component.name());
+ },
+ () -> writer.write(", ")
+ );
+
+ writer.write(") ");
+
+ if (!recordDeclaration.implementsTypes().isEmpty()) {
+ this.writer.write("implements ");
+ writeWithSeparator(
+ recordDeclaration.implementsTypes(),
+ this::writeTypeRef,
+ () -> writer.write(", ")
+ );
writer.write(" ");
- writer.write(component.name());
-
- if (isFirst) {
- isFirst = false;
- }
}
- this.writer.write(") {");
+ this.writer.write("{");
this.writer.newLine();
this.writer.write("}");
@@ -73,4 +80,31 @@ public class JavaWriter implements AutoCloseable {
writer.write(type.name());
}
+
+ private <T> void writeWithSeparator(
+ Iterable<T> iterable,
+ WriteElement<T> writeElement,
+ WriteSeparator writeSeparator
+ ) throws IOException {
+ var isFirst = true;
+ for (var element : iterable) {
+ if (!isFirst) {
+ writeSeparator.write();
+ }
+
+ writeElement.write(element);
+
+ if (isFirst) {
+ isFirst = false;
+ }
+ }
+ }
+
+ interface WriteElement<T> {
+ void write(T element) throws IOException;
+ }
+
+ interface WriteSeparator {
+ void write() throws IOException;
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/java/ast/JavaRecordDeclaration.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/java/ast/JavaRecordDeclaration.java
index cbebf74..7398eb9 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/java/ast/JavaRecordDeclaration.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/java/ast/JavaRecordDeclaration.java
@@ -4,6 +4,7 @@ import java.util.List;
public record JavaRecordDeclaration(
String name,
- List<JavaRecordComponent> components
+ List<JavaRecordComponent> components,
+ List<JavaTypeRef> implementsTypes
) implements JavaTypeDeclaration {
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
index bb3f375..4155d05 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
@@ -1,4 +1,5 @@
package org.zwobble.hobgoblin.compiler.types;
public sealed interface Type extends TypeLevelValue permits ScalarType, StructType, SumType, TypeLevelValueType {
+ String name();
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValueType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValueType.java
index b885c25..f2a2e47 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValueType.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeLevelValueType.java
@@ -2,6 +2,11 @@ package org.zwobble.hobgoblin.compiler.types;
public record TypeLevelValueType(TypeLevelValue value) implements Type {
@Override
+ public String name() {
+ return "TypeLevelValue";
+ }
+
+ @Override
public String describe() {
return "TypeLevelValue[" + value.describe() + "]";
}