summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-07-04 23:31:53 +0100
committerMichael Williamson <mike@zwobble.org>2026-07-04 23:31:53 +0100
commit06ae500619b2c2401548f6eac9e97fce09fceb58 (patch)
tree8db4968d3db0d33a888285a07051cf7737cf1121 /src
parent5d15eac0f3fd7656f9b78c5796d936182572c297 (diff)
Support encode/decode of Int32 and structs
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java175
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java2
2 files changed, 161 insertions, 16 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
index 5f91c1f..0837855 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatransient0/JavaTransient0Generator.java
@@ -2,17 +2,20 @@ package org.zwobble.hobgoblin.compiler.output.generators.javatransient0;
import org.zwobble.hobgoblin.compiler.ast.DocComment;
import org.zwobble.hobgoblin.compiler.ast.typed.*;
+import org.zwobble.hobgoblin.compiler.builtins.NativeTypes;
import org.zwobble.hobgoblin.compiler.config.OutputConfig;
import org.zwobble.hobgoblin.compiler.output.generators.Generator;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGeneratorConfig;
import org.zwobble.hobgoblin.compiler.output.lang.java.ast.*;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
+import org.zwobble.hobgoblin.compiler.types.*;
import org.zwobble.hobgoblin.compiler.util.Casing;
import org.zwobble.json5.reader.Json5ObjectReader;
import java.io.IOException;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@@ -22,6 +25,9 @@ public class JavaTransient0Generator implements Generator {
private static final JavaIdentifier ENCODE_METHOD_NAME = JavaIdentifier.of("encode");
private static final JavaIdentifier DECODE_METHOD_NAME = JavaIdentifier.of("decode");
+ private static final JavaIdentifier VALUE_NAME = JavaIdentifier.of("value");
+ private static final JavaIdentifier OUTPUT_STREAM_NAME = JavaIdentifier.of("outputStream");
+ private static final JavaIdentifier INPUT_STREAM_NAME = JavaIdentifier.of("inputStream");
public static OutputConfig parseGeneratorConfig(
Path projectRoot,
@@ -107,10 +113,6 @@ public class JavaTransient0Generator implements Generator {
}
case TypedStructDefinitionNode structDefinition -> {
- var valueName = JavaIdentifier.of("value");
- var outputStreamName = JavaIdentifier.of("outputStream");
- var inputStreamName = JavaIdentifier.of("inputStream");
-
var structJavaTypeRef = this.javaGenerator.generateTypeRef(structDefinition.type());
yield Stream.of(
@@ -120,17 +122,25 @@ public class JavaTransient0Generator implements Generator {
JavaMethodKind.STATIC,
JavaTypeRef.VOID,
List.of(
- new JavaParam(
- structJavaTypeRef,
- valueName
- ),
+ new JavaParam(structJavaTypeRef, VALUE_NAME),
new JavaParam(
JavaTypeRef.OUTPUT_STREAM,
- outputStreamName
+ OUTPUT_STREAM_NAME
)
),
- List.of(),
- new JavaBlock(List.of())
+ List.of(JavaTypeRef.IO_EXCEPTION),
+ new JavaBlock(
+ structDefinition.fields().stream()
+ .flatMap(field -> generateEncode(
+ new JavaMethodCall(
+ new JavaRef(VALUE_NAME),
+ this.javaGenerator.generateFieldName(field.name()),
+ List.of()
+ ),
+ field.type().value()
+ ))
+ .toList()
+ )
),
new JavaMethodDeclaration(
DECODE_METHOD_NAME,
@@ -140,13 +150,25 @@ public class JavaTransient0Generator implements Generator {
List.of(
new JavaParam(
JavaTypeRef.INPUT_STREAM,
- inputStreamName
+ INPUT_STREAM_NAME
)
),
- List.of(),
- new JavaBlock(List.of(
- new JavaReturn(new JavaNullLiteral())
- ))
+ List.of(JavaTypeRef.IO_EXCEPTION),
+ new JavaBlock(
+ Stream.concat(
+ structDefinition.fields().stream()
+ .flatMap(field -> generateDecode(
+ this.javaGenerator.generateFieldName(field.name()),
+ field.type().value()
+ )),
+ Stream.of(new JavaReturn(new JavaNewExpression(
+ structJavaTypeRef,
+ structDefinition.fields().stream()
+ .<JavaExpression>map(field -> new JavaRef(this.javaGenerator.generateFieldName(field.name())))
+ .toList()
+ )))
+ ).toList()
+ )
)
);
}
@@ -157,6 +179,127 @@ public class JavaTransient0Generator implements Generator {
};
}
+ private Stream<JavaBlockStatement> generateEncode(JavaExpression value, Type type) {
+ return switch (type) {
+ case ConstructedNativeType constructedNativeType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case EnumType enumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SimpleNativeType simpleNativeType -> {
+ if (simpleNativeType.equals(NativeTypes.INT_32)) {
+ yield generateEncodeInt32(value);
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ case StructType structType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SumType sumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeLevelValueType typeLevelValueType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeParam typeParam -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ };
+ }
+
+ private Stream<JavaBlockStatement> generateDecode(JavaIdentifier target, Type type) {
+ return switch (type) {
+ case ConstructedNativeType constructedNativeType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case EnumType enumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SimpleNativeType simpleNativeType -> {
+ if (simpleNativeType.equals(NativeTypes.INT_32)) {
+ yield generateDecodeInt32(target);
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+
+ case StructType structType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SumType sumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeLevelValueType typeLevelValueType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeParam typeParam -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ };
+ }
+
+ private static Stream<JavaBlockStatement> generateEncodeInt32(JavaExpression value) {
+ return Stream.of(0, 8, 16, 24)
+ .map(shiftBy -> new JavaExpressionStatement(
+ new JavaMethodCall(
+ new JavaRef(OUTPUT_STREAM_NAME),
+ JavaIdentifier.of("write"),
+ List.of(new JavaBinaryOperation(
+ JavaBinaryOperator.BITWISE_AND,
+ new JavaBinaryOperation(
+ JavaBinaryOperator.UNSIGNED_RIGHT_SHIFT,
+ value,
+ new JavaIntegerLiteral(shiftBy)
+ ),
+ new JavaIntegerLiteral(0xff)
+ ))
+ )
+ ));
+ }
+
+ private static Stream<JavaBlockStatement> generateDecodeInt32(
+ JavaIdentifier target
+ ) {
+ var statements = new ArrayList<JavaBlockStatement>();
+
+ statements.add(new JavaLocalVariableDeclaration(target, new JavaIntegerLiteral(0)));
+
+ for (var shiftBy : List.of(0, 8, 16, 24)) {
+ statements.add(new JavaExpressionStatement(new JavaBinaryOperation(
+ JavaBinaryOperator.ASSIGN,
+ new JavaRef(target),
+ new JavaBinaryOperation(
+ JavaBinaryOperator.BITWISE_OR,
+ new JavaRef(target),
+ new JavaBinaryOperation(
+ JavaBinaryOperator.LEFT_SHIFT,
+ new JavaMethodCall(
+ new JavaRef(INPUT_STREAM_NAME),
+ JavaIdentifier.of("read"),
+ List.of()
+ ),
+ new JavaIntegerLiteral(shiftBy)
+ )
+ )
+ )));
+ }
+
+ return statements.stream();
+ }
+
private static class Context {
private final TypesInfo typesInfo;
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
index b2478ed..1d1274e 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/java/ast/JavaTypeRef.java
@@ -58,6 +58,8 @@ public record JavaTypeRef(JavaPackageName packageName, List<JavaIdentifier> type
public static final JavaTypeRef INPUT_STREAM = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("InputStream"));
+ public static final JavaTypeRef IO_EXCEPTION = topLevel(JavaPackages.JAVA_IO, JavaIdentifier.of("IOException"));
+
public static final JavaTypeRef LIST = topLevel(JavaPackages.JAVA_UTIL, JavaIdentifier.of("List"));
public static JavaTypeRef list(JavaTypeRef elementType) {