summaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java124
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java145
2 files changed, 144 insertions, 125 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
new file mode 100644
index 0000000..c421ca4
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rust/RustGenerator.java
@@ -0,0 +1,124 @@
+package org.zwobble.hobgoblin.compiler.output.generators.rust;
+
+import org.zwobble.hobgoblin.compiler.output.lang.rust.RustWriter;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
+import org.zwobble.hobgoblin.compiler.types.*;
+import org.zwobble.hobgoblin.compiler.util.Casing;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class RustGenerator {
+ private final Path outputPath;
+ private final RustGeneratorConfig config;
+
+ public RustGenerator(Path outputPath, RustGeneratorConfig config) {
+ this.outputPath = outputPath;
+ this.config = config;
+ }
+
+ public void write(RustModule rustModule) throws IOException {
+ var path = this.outputPath.resolve(
+ rustModule.name().stream()
+ .map(name -> name.value())
+ .collect(Collectors.joining(File.separator)) + ".rs"
+ );
+ try (var writer = RustWriter.file(path)) {
+ writer.writeModule(rustModule);
+ }
+ }
+
+ public RustType generateRustTypeExpression(Type type) {
+ return switch (type) {
+ case ConstructedNativeType constructedNativeType -> {
+ // TODO: avoid cast
+ var rustType = (RustTypePath) generateRustTypeExpression(
+ constructedNativeType.constructor().genericType()
+ );
+ var rustArgs = constructedNativeType.args().stream()
+ .map(arg -> generateRustTypeExpression(arg))
+ .toList();
+ yield rustType.withArgs(rustArgs);
+ }
+
+ case EnumType enumType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case SimpleNativeType simpleNativeType -> {
+ yield this.config.nativeTypeConfig(simpleNativeType)
+ .map(config -> config.type())
+ .orElseGet(() -> generateTypePath(
+ simpleNativeType.namespaceName(),
+ simpleNativeType.name()
+ ));
+ }
+
+ case StructType structType -> {
+ yield generateTypePath(
+ structType.namespaceName(),
+ structType.name()
+ );
+ }
+
+ case SumType sumType -> {
+ yield generateTypePath(
+ sumType.namespaceName(),
+ sumType.name()
+ );
+ }
+
+ case TypeLevelValueType typeLevelValueType -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ case TypeParam typeParam -> {
+ throw new UnsupportedOperationException("TODO");
+ }
+ };
+ }
+
+ private RustType generateTypePath(NamespaceName namespaceName, String typeName) {
+ var segments = new ArrayList<RustTypePathSegment>();
+ segments.add(RustTypePathSegment.crate());
+ for (var moduleName : this.namespaceNameToRustCrateModulePath(namespaceName)) {
+ segments.add(RustTypePathSegment.of(moduleName));
+ }
+ segments.add(RustTypePathSegment.of(generateTypeName(typeName)));
+ return new RustTypePath(segments);
+ }
+
+ private List<RustIdentifier> namespaceNameToRustCrateModulePath(NamespaceName namespaceName) {
+ return namespaceName.parts().stream()
+ .map(part -> generateModuleName(part))
+ .toList();
+ }
+
+ public RustIdentifier generateFieldName(String fieldName) {
+ return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(fieldName));
+ }
+
+ public RustIdentifier generateTypeName(String typeName) {
+ return new RustIdentifier(typeName);
+ }
+
+ public RustIdentifier generateModuleName(String part) {
+ return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(part));
+ }
+
+ public RustIdentifier generateVariantName(String enumVariantName) {
+ return generateTypeName(Casing.lowerCamelCaseToUpperCamelCase(enumVariantName));
+ }
+
+ public RustIdentifier generateVariantName(Type type) {
+ if (type instanceof StructType structType) {
+ return generateTypeName(structType.name());
+ } else {
+ throw new UnsupportedOperationException("TODO");
+ }
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
index 66a19fe..d1248b4 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttypes/RustTypesGenerator.java
@@ -3,21 +3,19 @@ package org.zwobble.hobgoblin.compiler.output.generators.rusttypes;
import org.zwobble.hobgoblin.compiler.ast.typed.*;
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.RustWriter;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.*;
import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo;
-import org.zwobble.hobgoblin.compiler.types.*;
-import org.zwobble.hobgoblin.compiler.util.Casing;
+import org.zwobble.hobgoblin.compiler.types.NamespaceName;
+import org.zwobble.hobgoblin.compiler.types.Type;
import org.zwobble.json5.reader.Json5ObjectReader;
-import java.io.File;
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.Collectors;
public class RustTypesGenerator implements Generator {
public static final String NAME = "rust-types";
@@ -33,15 +31,17 @@ public class RustTypesGenerator implements Generator {
var rustConfig = RustGeneratorConfig.parseLangsConfig(langsJson);
- return new RustTypesGenerator(outputPath, rustConfig);
+ var rustGenerator = new RustGenerator(outputPath, rustConfig);
+
+ return new RustTypesGenerator(rustGenerator, rustConfig);
};
}
- private final Path outputPath;
+ private final RustGenerator rustGenerator;
private final RustGeneratorConfig config;
- private RustTypesGenerator(Path outputPath, RustGeneratorConfig config) {
- this.outputPath = outputPath;
+ private RustTypesGenerator(RustGenerator rustGenerator, RustGeneratorConfig config) {
+ this.rustGenerator = rustGenerator;
this.config = config;
}
@@ -51,18 +51,7 @@ public class RustTypesGenerator implements Generator {
var context = new Context(namespace.namespaceName());
var rustModule = generateNamespace(namespace, context);
- write(rustModule);
- }
- }
-
- private void write(RustModule rustModule) throws IOException {
- var path = this.outputPath.resolve(
- rustModule.name().stream()
- .map(name -> name.value())
- .collect(Collectors.joining(File.separator)) + ".rs"
- );
- try (var writer = RustWriter.file(path)) {
- writer.writeModule(rustModule);
+ this.rustGenerator.write(rustModule);
}
}
@@ -78,7 +67,7 @@ public class RustTypesGenerator implements Generator {
private List<RustIdentifier> generateNamespaceName(NamespaceName namespaceName) {
return namespaceName.parts().stream()
- .map(part -> generateModuleName(part))
+ .map(part -> this.rustGenerator.generateModuleName(part))
.toList();
}
@@ -109,11 +98,11 @@ public class RustTypesGenerator implements Generator {
TypedEnumDefinitionNode enumDefinition,
Context context
) {
- var rustEnumName = generateTypeName(enumDefinition.name());
+ var rustEnumName = this.rustGenerator.generateTypeName(enumDefinition.name());
var rustVariants = enumDefinition.variants().stream()
.map(variant -> new RustEnumVariant(
- generateVariantName(variant.name()),
+ this.rustGenerator.generateVariantName(variant.name()),
new RustEnumVariantNoFields()
))
.toList();
@@ -131,11 +120,11 @@ public class RustTypesGenerator implements Generator {
TypedStructDefinitionNode structDefinition,
Context context
) {
- var rustStructName = generateTypeName(structDefinition.name());
+ var rustStructName = this.rustGenerator.generateTypeName(structDefinition.name());
var rustFields = structDefinition.fields().stream()
.map(field -> new RustStructField(
- generateFieldName(field.name()),
+ this.rustGenerator.generateFieldName(field.name()),
generateRustTypeExpression(field.type(), context)
))
.toList();
@@ -151,7 +140,7 @@ public class RustTypesGenerator implements Generator {
) {
var items = new ArrayList<RustItem>();
- var rustEnumName = generateTypeName(sumDefinition.name());
+ var rustEnumName = this.rustGenerator.generateTypeName(sumDefinition.name());
var rustVariants = sumDefinition.variants().stream()
.map(variant -> {
@@ -163,7 +152,7 @@ public class RustTypesGenerator implements Generator {
}
return new RustEnumVariant(
- generateVariantName(variant.type().value()),
+ this.rustGenerator.generateVariantName(variant.type().value()),
new RustEnumVariantTuple(List.of(
new RustTupleField(variantType)
))
@@ -176,7 +165,7 @@ public class RustTypesGenerator implements Generator {
for (var variant : sumDefinition.variants()) {
var variantType = generateRustTypeExpression(variant.type(), context);
- var variantName = generateVariantName(variant.type().value());
+ var variantName = this.rustGenerator.generateVariantName(variant.type().value());
var innerValueName = new RustIdentifier("value");
RustExpression innerValue = new RustPathInExpression(List.of(
new RustPathExprSegment(
@@ -195,7 +184,7 @@ public class RustTypesGenerator implements Generator {
var fromImpl = new RustTraitImpl(
RustTypePath.global("std", "convert", "From")
.withArgs(List.of(variantType)),
- generateRustTypeExpression(sumDefinition.type(), context),
+ this.rustGenerator.generateRustTypeExpression(sumDefinition.type()),
List.of(
new RustFunction(
new RustIdentifier("from"),
@@ -223,101 +212,7 @@ public class RustTypesGenerator implements Generator {
TypedTypeLevelExpressionNode<Type> type,
Context context
) {
- return generateRustTypeExpression(type.value(), context);
- }
-
- private RustType generateRustTypeExpression(Type type, Context context) {
- return switch (type) {
- case ConstructedNativeType constructedNativeType -> {
- // TODO: avoid cast
- var rustType = (RustTypePath) generateRustTypeExpression(
- constructedNativeType.constructor().genericType(),
- context
- );
- var rustArgs = constructedNativeType.args().stream()
- .map(arg -> generateRustTypeExpression(arg, context))
- .toList();
- yield rustType.withArgs(rustArgs);
- }
-
- case EnumType enumType -> {
- throw new UnsupportedOperationException("TODO");
- }
-
- case SimpleNativeType simpleNativeType -> {
- yield this.config.nativeTypeConfig(simpleNativeType)
- .map(config -> config.type())
- .orElseGet(() -> generateTypePath(
- simpleNativeType.namespaceName(),
- simpleNativeType.name(),
- context
- ));
- }
-
- case StructType structType -> {
- yield generateTypePath(
- structType.namespaceName(),
- structType.name(),
- context
- );
- }
-
- case SumType sumType -> {
- yield generateTypePath(
- sumType.namespaceName(),
- sumType.name(),
- context
- );
- }
-
- case TypeLevelValueType typeLevelValueType -> {
- throw new UnsupportedOperationException("TODO");
- }
-
- case TypeParam typeParam -> {
- throw new UnsupportedOperationException("TODO");
- }
- };
- }
-
- private RustType generateTypePath(NamespaceName namespaceName, String typeName, Context context) {
- var segments = new ArrayList<RustTypePathSegment>();
- segments.add(RustTypePathSegment.crate());
- for (var moduleName : this.namespaceNameToRustCrateModulePath(namespaceName)) {
- segments.add(RustTypePathSegment.of(moduleName));
- }
- segments.add(RustTypePathSegment.of(generateTypeName(typeName)));
- return new RustTypePath(segments);
- }
-
- private List<RustIdentifier> namespaceNameToRustCrateModulePath(NamespaceName namespaceName) {
- return namespaceName.parts().stream()
- .map(part -> generateModuleName(part))
- .toList();
- }
-
- private RustIdentifier generateFieldName(String fieldName) {
- return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(fieldName));
- }
-
- private RustIdentifier generateTypeName(String typeName) {
- return new RustIdentifier(typeName);
- }
-
- private RustIdentifier generateModuleName(String part) {
- return new RustIdentifier(Casing.lowerCamelCaseToSnakeCase(part));
- }
-
- private RustIdentifier generateVariantName(String enumVariantName) {
- return generateTypeName(Casing.lowerCamelCaseToUpperCamelCase(enumVariantName));
- }
-
- private RustIdentifier generateVariantName(Type type) {
- if (type instanceof StructType structType) {
- return generateTypeName(structType.name());
- } else {
- throw new UnsupportedOperationException("TODO");
- }
+ return this.rustGenerator.generateRustTypeExpression(type.value());
}
private static class Context {