diff options
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() + "]"; } |
