diff options
6 files changed, 257 insertions, 109 deletions
diff --git a/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs index e899c4c..2945bdc 100644 --- a/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs +++ b/examples/10-transient-0/output/rust/src/gen/data/transient_0.rs @@ -1,103 +1,68 @@ // Generated by hobgoblin. pub fn encode_struct_with_bool(value: &crate::data::StructWithBool, writer: &mut impl std::io::Write) { - todo!(); - todo!(); + crate::transient_0::encode_bool(&value.a, writer); + crate::transient_0::encode_bool(&value.b, writer); } pub fn decode_struct_with_bool(reader: &mut impl std::io::Read) -> crate::data::StructWithBool { - let a = todo!(); - let b = todo!(); + let a = crate::transient_0::decode_bool(reader); + let b = crate::transient_0::decode_bool(reader); crate::data::StructWithBool { a: a, b: b } } pub fn encode_struct_with_int_32(value: &crate::data::StructWithInt32, writer: &mut impl std::io::Write) { - writer.write_all(&value.a.to_le_bytes()); - writer.write_all(&value.b.to_le_bytes()); + crate::transient_0::encode_int_32(&value.a, writer); + crate::transient_0::encode_int_32(&value.b, writer); } pub fn decode_struct_with_int_32(reader: &mut impl std::io::Read) -> crate::data::StructWithInt32 { - let a = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; - let b = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; + let a = crate::transient_0::decode_int_32(reader); + let b = crate::transient_0::decode_int_32(reader); crate::data::StructWithInt32 { a: a, b: b } } pub fn encode_struct_with_int_64(value: &crate::data::StructWithInt64, writer: &mut impl std::io::Write) { - todo!(); - todo!(); + crate::transient_0::encode_int_64(&value.a, writer); + crate::transient_0::encode_int_64(&value.b, writer); } pub fn decode_struct_with_int_64(reader: &mut impl std::io::Read) -> crate::data::StructWithInt64 { - let a = todo!(); - let b = todo!(); + let a = crate::transient_0::decode_int_64(reader); + let b = crate::transient_0::decode_int_64(reader); crate::data::StructWithInt64 { a: a, b: b } } pub fn encode_struct_with_string(value: &crate::data::StructWithString, writer: &mut impl std::io::Write) { - todo!(); - todo!(); + crate::transient_0::encode_string(&value.a, writer); + crate::transient_0::encode_string(&value.b, writer); } pub fn decode_struct_with_string(reader: &mut impl std::io::Read) -> crate::data::StructWithString { - let a = todo!(); - let b = todo!(); + let a = crate::transient_0::decode_string(reader); + let b = crate::transient_0::decode_string(reader); crate::data::StructWithString { a: a, b: b } } pub fn encode_outer_struct(value: &crate::data::OuterStruct, writer: &mut impl std::io::Write) { todo!(); - writer.write_all(&value.c.to_le_bytes()); + crate::transient_0::encode_int_32(&value.c, writer); } pub fn decode_outer_struct(reader: &mut impl std::io::Read) -> crate::data::OuterStruct { let inner = todo!(); - let c = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; + let c = crate::transient_0::decode_int_32(reader); crate::data::OuterStruct { inner: inner, c: c } } pub fn encode_inner_struct(value: &crate::data::InnerStruct, writer: &mut impl std::io::Write) { - writer.write_all(&value.a.to_le_bytes()); - writer.write_all(&value.b.to_le_bytes()); + crate::transient_0::encode_int_32(&value.a, writer); + crate::transient_0::encode_int_32(&value.b, writer); } pub fn decode_inner_struct(reader: &mut impl std::io::Read) -> crate::data::InnerStruct { - let a = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; - let b = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; + let a = crate::transient_0::decode_int_32(reader); + let b = crate::transient_0::decode_int_32(reader); crate::data::InnerStruct { a: a, b: b } } @@ -124,26 +89,19 @@ pub fn decode_struct_with_option(reader: &mut impl std::io::Read) -> crate::data } pub fn encode_variant_one(value: &crate::data::VariantOne, writer: &mut impl std::io::Write) { - writer.write_all(&value.a.to_le_bytes()); + crate::transient_0::encode_int_32(&value.a, writer); } pub fn decode_variant_one(reader: &mut impl std::io::Read) -> crate::data::VariantOne { - let a = { - let bytes = { - let mut bytes = [0; 4]; - reader.read_exact(&mut bytes); - bytes - }; - i32::from_le_bytes(bytes) - }; + let a = crate::transient_0::decode_int_32(reader); crate::data::VariantOne { a: a } } pub fn encode_variant_two(value: &crate::data::VariantTwo, writer: &mut impl std::io::Write) { - todo!(); + crate::transient_0::encode_int_64(&value.a, writer); } pub fn decode_variant_two(reader: &mut impl std::io::Read) -> crate::data::VariantTwo { - let a = todo!(); + let a = crate::transient_0::decode_int_64(reader); crate::data::VariantTwo { a: a } } diff --git a/examples/10-transient-0/output/rust/src/gen/transient_0.rs b/examples/10-transient-0/output/rust/src/gen/transient_0.rs new file mode 100644 index 0000000..18a605c --- /dev/null +++ b/examples/10-transient-0/output/rust/src/gen/transient_0.rs @@ -0,0 +1,38 @@ +// Generated by hobgoblin. + +pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::Write) { + todo!(); +} + +pub fn decode_bool(reader: &mut impl std::io::Read) -> ::core::primitive::bool { + todo!() +} + +pub fn encode_int_32(value: &::core::primitive::i32, writer: &mut impl std::io::Write) { + writer.write_all(&value.to_le_bytes()); +} + +pub fn decode_int_32(reader: &mut impl std::io::Read) -> ::core::primitive::i32 { + let bytes = { + let mut bytes = [0; 4]; + reader.read_exact(&mut bytes); + bytes + }; + i32::from_le_bytes(bytes) +} + +pub fn encode_int_64(value: &::core::primitive::i64, writer: &mut impl std::io::Write) { + todo!(); +} + +pub fn decode_int_64(reader: &mut impl std::io::Read) -> ::core::primitive::i64 { + todo!() +} + +pub fn encode_string(value: &::std::string::String, writer: &mut impl std::io::Write) { + todo!(); +} + +pub fn decode_string(reader: &mut impl std::io::Read) -> ::std::string::String { + todo!() +} diff --git a/examples/10-transient-0/output/rust/src/lib.rs b/examples/10-transient-0/output/rust/src/lib.rs index 865555e..56be8ca 100644 --- a/examples/10-transient-0/output/rust/src/lib.rs +++ b/examples/10-transient-0/output/rust/src/lib.rs @@ -1,4 +1,5 @@ pub mod data; +pub mod transient_0; #[cfg(test)] mod test { diff --git a/examples/10-transient-0/output/rust/src/transient_0.rs b/examples/10-transient-0/output/rust/src/transient_0.rs new file mode 100644 index 0000000..8b2b800 --- /dev/null +++ b/examples/10-transient-0/output/rust/src/transient_0.rs @@ -0,0 +1 @@ +include!("./gen/transient_0.rs"); 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 d67ccd6..46ebb20 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 @@ -8,6 +8,8 @@ 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.*; import org.zwobble.hobgoblin.compiler.typechecker.TypesInfo; +import org.zwobble.hobgoblin.compiler.types.NamespaceName; +import org.zwobble.hobgoblin.compiler.types.SimpleNativeType; import org.zwobble.hobgoblin.compiler.types.Type; import org.zwobble.json5.reader.Json5ObjectReader; @@ -52,6 +54,8 @@ public class RustTransient0Generator implements Generator { @Override public void generate(List<TypedNamespaceNode> namespaces, TypesInfo typesInfo) throws IOException { + generateBuiltins(); + for (var namespace : namespaces) { var rustModule = generateNamespace(namespace); @@ -59,9 +63,138 @@ public class RustTransient0Generator implements Generator { } } + private void generateBuiltins() throws IOException { + var rustModuleName = this.generateTransient0ModuleName(NamespaceName.of()); + var rustModule = new RustModule( + rustModuleName, + List.of( + generateEncodeBoolFunction(), + generateDecodeBoolFunction(), + generateEncodeInt32Function(), + generateDecodeInt32Function(), + generateEncodeInt64Function(), + generateDecodeInt64Function(), + generateEncodeStringFunction(), + generateDecodeStringFunction() + ) + ); + + this.rustGenerator.write(rustModule); + } + + private RustItem generateEncodeBoolFunction() { + return generateEncodeFunction( + NativeTypes.BOOL, + new RustBlockExpression( + List.of( + new RustExpressionStatement(generateTodo()) + ), + Optional.empty() + ) + ); + } + + private RustItem generateDecodeBoolFunction() { + return generateDecodeFunction( + NativeTypes.BOOL, + new RustBlockExpression( + List.of(), + Optional.of(generateTodo()) + ) + ); + } + + private RustItem generateEncodeInt32Function() { + return generateEncodeFunction( + NativeTypes.INT_32, + new RustBlockExpression( + List.of( + new RustExpressionStatement( + generateWriterWrite(new RustPrefixExpression( + RustPrefixOperator.BORROW, + new RustCallExpression( + new RustFieldExpression( + RustPath.of(VALUE_NAME), + RustIdentifier.of("to_le_bytes") + ), + List.of() + ) + )) + ) + ), + Optional.empty() + ) + ); + } + + private RustItem generateDecodeInt32Function() { + var bytes = RustIdentifier.of("bytes"); + + return generateDecodeFunction( + NativeTypes.INT_32, + 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)) + )) + ) + ); + } + + private RustItem generateEncodeInt64Function() { + return generateEncodeFunction( + NativeTypes.INT_64, + new RustBlockExpression( + List.of( + new RustExpressionStatement(generateTodo()) + ), + Optional.empty() + ) + ); + } + + private RustItem generateDecodeInt64Function() { + return generateDecodeFunction( + NativeTypes.INT_64, + new RustBlockExpression( + List.of(), + Optional.of(generateTodo()) + ) + ); + } + + private RustItem generateEncodeStringFunction() { + return generateEncodeFunction( + NativeTypes.STRING, + new RustBlockExpression( + List.of( + new RustExpressionStatement(generateTodo()) + ), + Optional.empty() + ) + ); + } + + private RustItem generateDecodeStringFunction() { + return generateDecodeFunction( + NativeTypes.STRING, + new RustBlockExpression( + List.of(), + Optional.of(generateTodo()) + ) + ); + } + private RustModule generateNamespace(TypedNamespaceNode namespace) { - var moduleName = new ArrayList<>(this.rustGenerator.namespaceNameToRustCrateModulePath(namespace.namespaceName())); - moduleName.add(RustIdentifier.of("transient_0")); + var namespaceName = namespace.namespaceName(); + var moduleName = generateTransient0ModuleName(namespaceName); return new RustModule( moduleName, @@ -71,6 +204,12 @@ public class RustTransient0Generator implements Generator { ); } + private ArrayList<RustIdentifier> generateTransient0ModuleName(NamespaceName namespaceName) { + var moduleName = new ArrayList<>(this.rustGenerator.namespaceNameToRustCrateModulePath(namespaceName)); + moduleName.add(RustIdentifier.of("transient_0")); + return moduleName; + } + private Stream<RustItem> generateNamespaceStatement( TypedNamespaceStatementNode statement ) { @@ -84,7 +223,6 @@ public class RustTransient0Generator implements Generator { } case TypedStructDefinitionNode structDefinition -> { - // TODO: remove cast var rustType = this.rustGenerator.generateRustTypeExpression(structDefinition.type()); yield Stream.of( @@ -93,9 +231,12 @@ public class RustTransient0Generator implements Generator { new RustBlockExpression( structDefinition.fields().stream() .flatMap(field -> generateEncode( - new RustFieldExpression( - RustPath.of(VALUE_NAME), - this.rustGenerator.generateFieldName(field.name()) + new RustPrefixExpression( + RustPrefixOperator.BORROW, + new RustFieldExpression( + RustPath.of(VALUE_NAME), + this.rustGenerator.generateFieldName(field.name()) + ) ), field.type().value() ).stream()) @@ -169,45 +310,50 @@ public class RustTransient0Generator implements Generator { } 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() - ) + return switch (type) { + case SimpleNativeType nativeType -> { + var rustEncodeFunctionPathSegments = new ArrayList<>( + this.generateTransient0ModuleName(nativeType.namespaceName()) + ); + rustEncodeFunctionPathSegments.add(encodeMethodName(nativeType)); + var rustEncodeFunctionPath = RustPath.crate( + rustEncodeFunctionPathSegments + ); + + yield List.of( + new RustExpressionStatement(new RustCallExpression( + rustEncodeFunctionPath, + List.of(value, RustPath.of(WRITER_NAME)) )) - ) - ); - } else { - return List.of(new RustExpressionStatement(generateTodo())); - } + ); + } + default -> { + yield 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(); - } + return switch (type) { + case SimpleNativeType nativeType -> { + var rustDecodeFunctionPathSegments = new ArrayList<>( + this.generateTransient0ModuleName(nativeType.namespaceName()) + ); + rustDecodeFunctionPathSegments.add(decodeMethodName(nativeType)); + var rustDecodeFunctionPath = RustPath.crate( + rustDecodeFunctionPathSegments + ); + + yield new RustCallExpression( + rustDecodeFunctionPath, + List.of(RustPath.of(READER_NAME)) + ); + } + + default -> { + yield generateTodo(); + } + }; } private RustExpression generateWriterWrite(RustExpression valueToWrite) { 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 315271b..137df41 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 @@ -73,6 +73,10 @@ public record RustPath(java.util.List<org.zwobble.hobgoblin.compiler.output.lang return qualified(RustPathSegment.global(), names); } + public static RustPath crate(List<RustIdentifier> names) { + return qualified(RustPathSegment.crate(), names.toArray(new RustIdentifier[0])); + } + public static RustPath selfType() { return qualified(RustPathSegment.selfType(), new String[0]); } |
