summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java8
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java208
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPath.java4
4 files changed, 213 insertions, 11 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
index 1b05b47..db572fb 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
@@ -32,15 +32,15 @@ public class RustGenerator {
}
}
- public RustType generateRustTypeExpression(Type type) {
+ public RustPath generateRustTypeExpression(Type type) {
return switch (type) {
case ConstructedNativeType constructedNativeType -> {
// TODO: avoid cast
- var rustType = (RustPath) generateRustTypeExpression(
+ var rustType = generateRustTypeExpression(
constructedNativeType.constructor().genericType()
);
var rustArgs = constructedNativeType.args().stream()
- .map(arg -> generateRustTypeExpression(arg))
+ .<RustType>map(arg -> generateRustTypeExpression(arg))
.toList();
yield rustType.withArgs(rustArgs);
}
@@ -82,7 +82,7 @@ public class RustGenerator {
};
}
- private RustType generateTypePath(NamespaceName namespaceName, String typeName) {
+ private RustPath generateTypePath(NamespaceName namespaceName, String typeName) {
var segments = new ArrayList<RustPathSegment>();
segments.add(RustPathSegment.crate());
for (var moduleName : this.namespaceNameToRustCrateModulePath(namespaceName)) {
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java
index 27a6dc8..584527f 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustNativeTypeConfig.java
@@ -1,8 +1,8 @@
package org.zwobble.hobgoblin.compiler.output.generators.rust;
-import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath;
public record RustNativeTypeConfig(
- RustType type
+ RustPath type
) {
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
index 6f53ba2..d67ccd6 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
@@ -1,13 +1,14 @@
package org.zwobble.hobgoblin.compiler.output.generators.rusttransient0;
-import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode;
+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.rust.RustGenerator;
import org.zwobble.hobgoblin.compiler.output.generators.rust.RustGeneratorConfig;
-import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustIdentifier;
-import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustModule;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
+import org.zwobble.hobgoblin.compiler.types.Type;
import org.zwobble.json5.reader.Json5ObjectReader;
import java.io.IOException;
@@ -15,10 +16,15 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Stream;
public class RustTransient0Generator implements Generator {
public static final String NAME = "rust-transient-0";
+ private static final RustIdentifier VALUE_NAME = RustIdentifier.of("value");
+ private static final RustIdentifier READER_NAME = RustIdentifier.of("reader");
+ private static final RustIdentifier WRITER_NAME = RustIdentifier.of("writer");
+
public static OutputConfig parseGeneratorConfig(
Path projectRoot,
Json5ObjectReader output,
@@ -59,7 +65,203 @@ public class RustTransient0Generator implements Generator {
return new RustModule(
moduleName,
+ namespace.body().stream()
+ .flatMap(statement -> this.generateNamespaceStatement(statement))
+ .toList()
+ );
+ }
+
+ private Stream<RustItem> generateNamespaceStatement(
+ TypedNamespaceStatementNode statement
+ ) {
+ return switch (statement) {
+ case TypedEnumDefinitionNode enumDefinition -> {
+ yield Stream.of();
+ }
+
+ case TypedNativeTypeDefinitionNode nativeTypeDefinition -> {
+ yield Stream.of();
+ }
+
+ case TypedStructDefinitionNode structDefinition -> {
+ // TODO: remove cast
+ var rustType = this.rustGenerator.generateRustTypeExpression(structDefinition.type());
+
+ yield Stream.of(
+ generateEncodeFunction(
+ structDefinition.type(),
+ new RustBlockExpression(
+ structDefinition.fields().stream()
+ .flatMap(field -> generateEncode(
+ new RustFieldExpression(
+ RustPath.of(VALUE_NAME),
+ this.rustGenerator.generateFieldName(field.name())
+ ),
+ field.type().value()
+ ).stream())
+ .toList(),
+ Optional.empty()
+ )
+ ),
+ generateDecodeFunction(
+ structDefinition.type(),
+ new RustBlockExpression(
+ structDefinition.fields().stream()
+ .<RustStatement>map(field -> new RustLetStatement(
+ this.rustGenerator.generateFieldName(field.name()),
+ false,
+ generateDecode(field.type().value())
+ ))
+ .toList(),
+ Optional.of(new RustStructExpression(
+ rustType,
+ structDefinition.fields().stream()
+ .map(field -> new RustStructExprField(
+ this.rustGenerator.generateFieldName(field.name()),
+ RustPath.of(this.rustGenerator.generateFieldName(field.name()))
+ ))
+ .toList()
+ ))
+ )
+ )
+ );
+ }
+
+ case TypedSumDefinitionNode sumDefinition -> {
+ yield Stream.of();
+ }
+ };
+ }
+
+ private RustItem generateEncodeFunction(
+ Type type,
+ RustBlockExpression body
+ ) {
+ var rustType = this.rustGenerator.generateRustTypeExpression(type);
+
+ return new RustFunction(
+ Optional.of(RustVisibility.PUB),
+ encodeMethodName(type),
+ List.of(
+ new RustFunctionParam(VALUE_NAME, new RustSharedReferenceType(rustType)),
+ new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write"))))
+ ),
+ Optional.empty(),
+ Optional.of(body)
+ );
+ }
+
+ private RustItem generateDecodeFunction(
+ Type type,
+ RustBlockExpression body
+ ) {
+ var rustType = this.rustGenerator.generateRustTypeExpression(type);
+
+ return new RustFunction(
+ Optional.of(RustVisibility.PUB),
+ decodeMethodName(type),
+ List.of(
+ new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read"))))
+ ),
+ Optional.of(rustType),
+ Optional.of(body)
+ );
+ }
+
+ private List<RustStatement> generateEncode(RustExpression value, Type type) {
+ if (type.equals(NativeTypes.INT_32)) {
+ return List.of(
+ new RustExpressionStatement(
+ generateWriterWrite(new RustPrefixExpression(
+ RustPrefixOperator.BORROW,
+ new RustCallExpression(
+ new RustFieldExpression(
+ value,
+ RustIdentifier.of("to_le_bytes")
+ ),
+ List.of()
+ )
+ ))
+ )
+ );
+ } else {
+ return List.of(new RustExpressionStatement(generateTodo()));
+ }
+ }
+
+ private RustExpression generateDecode(Type type) {
+ if (type.equals(NativeTypes.INT_32)) {
+ var bytes = RustIdentifier.of("bytes");
+ return new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ bytes,
+ false,
+ generateReaderReadExact(4)
+ )
+ ),
+ Optional.of(new RustCallExpression(
+ RustPath.of("i32", "from_le_bytes"),
+ List.of(RustPath.of(bytes))
+ ))
+ );
+ } else {
+ return generateTodo();
+ }
+ }
+
+ private RustExpression generateWriterWrite(RustExpression valueToWrite) {
+ return new RustCallExpression(
+ new RustFieldExpression(
+ RustPath.of(WRITER_NAME),
+ RustIdentifier.of("write_all")
+ ),
+ List.of(valueToWrite)
+ );
+ }
+
+ private RustExpression generateReaderReadExact(int length) {
+ var bytes = RustIdentifier.of("bytes");
+
+ return new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ bytes,
+ true,
+ new RustArrayRepeatExpression(
+ new RustIntegerLiteral(0),
+ new RustIntegerLiteral(length)
+ )
+ ),
+ new RustExpressionStatement(new RustCallExpression(
+ new RustFieldExpression(
+ RustPath.of(READER_NAME),
+ RustIdentifier.of("read_exact")
+ ),
+ List.of(
+ new RustPrefixExpression(
+ RustPrefixOperator.BORROW_MUTABLE,
+ RustPath.of(bytes)
+ )
+ )
+ ))
+ ),
+ Optional.of(RustPath.of(bytes))
+ );
+ }
+
+ private RustExpression generateTodo() {
+ return new RustCallExpression(
+ RustPath.of("todo!"),
List.of()
);
}
+
+ private RustIdentifier encodeMethodName(Type type) {
+ return this.rustGenerator.generateFieldName("encode" + type.name());
+ }
+
+ private RustIdentifier decodeMethodName(Type type) {
+ return this.rustGenerator.generateFieldName("decode" + type.name());
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPath.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPath.java
index 895e194..315271b 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPath.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustPath.java
@@ -55,7 +55,7 @@ public record RustPath(java.util.List<org.zwobble.hobgoblin.compiler.output.lang
return new RustPath(segments);
}
- public static RustType of(RustIdentifier... names) {
+ public static RustPath of(RustIdentifier... names) {
var segments = Arrays.stream(names)
.map(name -> new RustPathSegment(
new RustPathIdentSegmentIdentifier(name),
@@ -65,7 +65,7 @@ public record RustPath(java.util.List<org.zwobble.hobgoblin.compiler.output.lang
return new RustPath(segments);
}
- public static RustType crate(String... names) {
+ public static RustPath crate(String... names) {
return qualified(RustPathSegment.crate(), names);
}