From d5a6c854dd182d4d770c9ae6a6da8d04e7899059 Mon Sep 17 00:00:00 2001 From: Vasily Levchenko Date: Thu, 22 Sep 2016 12:12:34 +0300 Subject: [PATCH] translator-bc: is copy of translator, currently... it was copied to inject byte code generation instead of llvm asm via domestic interop library --- experiments/translator-bc/LICENSE | 21 + experiments/translator-bc/Makefile | 46 + experiments/translator-bc/README.md | 64 + experiments/translator-bc/build.gradle | 38 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + experiments/translator-bc/gradlew | 160 ++ experiments/translator-bc/gradlew.bat | 90 ++ experiments/translator-bc/kotstd/Makefile | 49 + .../translator-bc/kotstd/include/Assert.kt | 8 + .../kotstd/include/BooleanArray.kt | 121 ++ .../translator-bc/kotstd/include/ByteArray.kt | 121 ++ .../kotstd/include/CodedInputStream.kt | 216 +++ .../kotstd/include/CodedOutputStream.kt | 167 ++ .../translator-bc/kotstd/include/Console.kt | 171 +++ .../translator-bc/kotstd/include/IntArray.kt | 195 +++ .../translator-bc/kotstd/include/Iterators.kt | 94 ++ .../kotstd/include/KotlinInputStream.kt | 25 + .../kotstd/include/KotlinOutputStream.kt | 20 + .../translator-bc/kotstd/include/LongArray.kt | 118 ++ .../kotstd/include/Primitives.kt | 251 +++ .../kotstd/include/Progressions.kt | 50 + .../translator-bc/kotstd/include/Ranges.kt | 25 + .../kotstd/include/ShortArray.kt | 120 ++ .../kotstd/include/WireFormat.kt | 164 ++ .../translator-bc/kotstd/include/WireType.kt | 29 + .../kotstd/include/progressionUtil.kt | 71 + .../translator-bc/kotstd/libc/array_c.c | 32 + .../translator-bc/kotstd/libc/assert_c.c | 9 + .../translator-bc/kotstd/libc/memory.c | 82 + .../translator-bc/kotstd/libc/primitives_c.c | 57 + experiments/translator-bc/run_one_test.sh | 78 + experiments/translator-bc/run_tests.sh | 104 ++ experiments/translator-bc/settings.gradle | 2 + .../src/main/kotlin/DefaultArguments.kt | 39 + .../translator-bc/src/main/kotlin/main.kt | 30 + .../translator/ProjectTranslator.kt | 77 + .../translator/TranslationState.kt | 116 ++ .../translator/VariableManager.kt | 48 + .../translator/codegens/BlockCodegen.kt | 1121 ++++++++++++++ .../translator/codegens/ClassCodegen.kt | 84 + .../translator/codegens/FunctionCodegen.kt | 138 ++ .../translator/codegens/ObjectCodegen.kt | 43 + .../translator/codegens/PropertyCodegen.kt | 33 + .../translator/codegens/StructCodegen.kt | 252 +++ .../kotlinnative/translator/debug/debug.kt | 59 + .../exceptions/TranslationException.kt | 5 + .../exceptions/UnimplementedException.kt | 5 + .../translator/llvm/LLVMBuilder.kt | 252 +++ .../kotlinnative/translator/llvm/LLVMCall.kt | 11 + .../translator/llvm/LLVMClassVariable.kt | 8 + .../translator/llvm/LLVMConstant.kt | 13 + .../translator/llvm/LLVMExpression.kt | 9 + .../kotlinnative/translator/llvm/LLVMLabel.kt | 7 + .../kotlinnative/translator/llvm/LLVMNode.kt | 3 + .../kotlinnative/translator/llvm/LLVMScope.kt | 11 + .../translator/llvm/LLVMSingleValue.kt | 10 + .../translator/llvm/LLVMVariable.kt | 13 + .../translator/llvm/generators.kt | 63 + .../translator/llvm/types/LLVMArray.kt | 9 + .../translator/llvm/types/LLVMBooleanType.kt | 69 + .../translator/llvm/types/LLVMByteType.kt | 42 + .../translator/llvm/types/LLVMCharType.kt | 41 + .../translator/llvm/types/LLVMDoubleType.kt | 61 + .../translator/llvm/types/LLVMFloatType.kt | 61 + .../translator/llvm/types/LLVMFunctionType.kt | 37 + .../translator/llvm/types/LLVMIntType.kt | 89 ++ .../translator/llvm/types/LLVMLongType.kt | 84 + .../translator/llvm/types/LLVMNullType.kt | 20 + .../llvm/types/LLVMReferenceType.kt | 32 + .../translator/llvm/types/LLVMShortType.kt | 45 + .../translator/llvm/types/LLVMStringType.kt | 23 + .../translator/llvm/types/LLVMType.kt | 55 + .../translator/llvm/types/LLVMVoidType.kt | 17 + .../array_extensions_1/array_extensions_1.kt | 63 + .../array_extensions_1/array_extensions_1.txt | 5 + .../array_extensions_2/array_extensions_2.kt | 11 + .../array_extensions_2/array_extensions_2.txt | 1 + .../assignment_operators_1.kt | 17 + .../assignment_operators_1.txt | 3 + .../tests/booleanarray_1/booleanarray_1.kt | 10 + .../tests/booleanarray_1/booleanarray_1.txt | 2 + .../kotlin/tests/bytearray_1/bytearray_1.kt | 25 + .../kotlin/tests/bytearray_1/bytearray_1.txt | 2 + .../kotlin/tests/callbacks_1/callbacks_1.c | 4 + .../kotlin/tests/callbacks_1/callbacks_1.kt | 26 + .../kotlin/tests/callbacks_1/callbacks_1.txt | 6 + .../class_alignment_1/class_alignment_1.kt | 10 + .../class_alignment_1/class_alignment_1.txt | 1 + .../class_class_argument_1.kt | 12 + .../class_class_argument_1.txt | 1 + .../class_default_argument_1.kt | 10 + .../class_default_argument_1.txt | 1 + .../class_init_section_1.kt | 14 + .../class_init_section_1.txt | 1 + .../class_method_access_1.kt | 20 + .../class_method_access_1.txt | 1 + .../tests/class_methods_1/class_methods_1.kt | 10 + .../tests/class_methods_1/class_methods_1.txt | 1 + .../class_reassignment_1.kt | 12 + .../class_reassignment_1.txt | 1 + .../class_reassignment_2.kt | 15 + .../class_reassignment_2.txt | 1 + .../class_variable_access_1.kt | 18 + .../class_variable_access_1.txt | 1 + .../tests/classfields_1/classfields_1.kt | 19 + .../tests/classfields_1/classfields_1.txt | 2 + .../tests/classfields_2/classfields_2.kt | 26 + .../tests/classfields_2/classfields_2.txt | 3 + .../companion_object_1/companion_object_1.kt | 13 + .../companion_object_1/companion_object_1.txt | 1 + .../companion_object_2/companion_object_2.kt | 14 + .../companion_object_2/companion_object_2.txt | 1 + .../complex_dot_expr/complex_dot_expr.kt | 7 + .../complex_dot_expr/complex_dot_expr.txt | 2 + .../declaration_test_1/declaration_test_1.kt | 18 + .../declaration_test_1/declaration_test_1.txt | 2 + .../src/test/kotlin/tests/dfs_1/dfs_1.kt | 45 + .../src/test/kotlin/tests/dfs_1/dfs_1.txt | 3 + .../different_type_binary_operator_1.kt | 11 + .../different_type_binary_operator_1.txt | 3 + .../kotlin/tests/do_while_1/do_while_1.kt | 7 + .../kotlin/tests/do_while_1/do_while_1.txt | 2 + .../src/test/kotlin/tests/elvis_1/elvis_1.kt | 20 + .../src/test/kotlin/tests/elvis_1/elvis_1.txt | 3 + .../kotlin/tests/enum_complex/enum_complex.kt | 20 + .../tests/enum_complex/enum_complex.txt | 1 + .../enum_inner_fields/enum_inner_fields.kt | 4 + .../enum_inner_fields/enum_inner_fields.txt | 2 + .../floating_point_operators_1.kt | 12 + .../floating_point_operators_1.txt | 2 + .../src/test/kotlin/tests/for_1/for_1.kt | 7 + .../src/test/kotlin/tests/for_1/for_1.txt | 1 + .../function_default_arguments_1.kt | 59 + .../function_default_arguments_1.txt | 9 + .../kotlin/tests/function_eq/function_eq.kt | 7 + .../kotlin/tests/function_eq/function_eq.txt | 3 + .../function_extensions_1.kt | 7 + .../function_extensions_1.txt | 1 + .../function_extensions_double_argument_1.kt | 31 + .../function_extensions_double_argument_1.txt | 1 + .../get_set_operators_1.kt | 22 + .../get_set_operators_1.txt | 2 + .../tests/global_vars_1/global_vars_1.kt | 11 + .../tests/global_vars_1/global_vars_1.txt | 2 + .../src/test/kotlin/tests/if_1/if_1.kt | 30 + .../src/test/kotlin/tests/if_1/if_1.txt | 4 + .../src/test/kotlin/tests/if_2/if_2.kt | 7 + .../src/test/kotlin/tests/if_2/if_2.txt | 2 + .../if_boolean_argument_1.kt | 3 + .../if_boolean_argument_1.txt | 2 + .../tests/if_expression_1/if_expression_1.kt | 9 + .../tests/if_expression_1/if_expression_1.txt | 4 + .../initialization_in_place_and_this_1.kt | 21 + .../initialization_in_place_and_this_1.txt | 1 + .../initialized_class_fields_1.kt | 8 + .../initialized_class_fields_1.txt | 1 + .../kotlin/tests/intarray_1/intarray_1.kt | 5 + .../kotlin/tests/intarray_1/intarray_1.txt | 1 + .../long_operations_1/long_operations_1.kt | 5 + .../long_operations_1/long_operations_1.txt | 1 + .../tests/nested_classes/nested_classes.kt | 24 + .../tests/nested_classes/nested_classes.txt | 2 + .../null_comparison_1/null_comparison_1.kt | 32 + .../null_comparison_1/null_comparison_1.txt | 3 + .../kotlin/tests/nullable_1/nullable_1.kt | 30 + .../kotlin/tests/nullable_1/nullable_1.txt | 4 + .../nullable_class_fields_1.kt | 32 + .../nullable_class_fields_1.txt | 3 + .../nullable_primitive_types_1.kt | 41 + .../nullable_primitive_types_1.txt | 5 + .../numeric_literals_1/numeric_literals_1.kt | 13 + .../numeric_literals_1/numeric_literals_1.txt | 3 + .../test/kotlin/tests/object_1/object_1.kt | 16 + .../test/kotlin/tests/object_1/object_1.txt | 2 + .../test/kotlin/tests/postfix_1/postfix_1.kt | 35 + .../test/kotlin/tests/postfix_1/postfix_1.txt | 6 + .../kotlin/tests/primitives_1/primitives_1.kt | 11 + .../tests/primitives_1/primitives_1.txt | 6 + .../proto_crossbranch_test.kt | 1073 +++++++++++++ .../proto_crossbranch_test.txt | 3 + .../proto_location_test.kt | 466 ++++++ .../proto_location_test.txt | 3 + .../proto_multiple_messages.kt | 495 ++++++ .../proto_multiple_messages.txt | 3 + .../proto_repeated_varint.kt | 1365 +++++++++++++++++ .../proto_repeated_varint.txt | 4 + .../proto_repeated_zigzag.kt | 567 +++++++ .../proto_repeated_zigzag.txt | 4 + .../proto_tagorder_test.kt | 788 ++++++++++ .../proto_tagorder_test.txt | 2 + .../kotlin/tests/proto_varint/proto_varint.kt | 491 ++++++ .../tests/proto_varint/proto_varint.txt | 5 + .../kotlin/tests/proto_zigzag/proto_zigzag.kt | 217 +++ .../tests/proto_zigzag/proto_zigzag.txt | 6 + .../range_operator_1/range_operator_1.kt | 10 + .../range_operator_1/range_operator_1.txt | 1 + .../tests/reassigment_0/reassigment_0.kt | 4 + .../tests/reassigment_0/reassigment_0.txt | 1 + .../tests/reassigment_1/reassigment_1.kt | 7 + .../tests/reassigment_1/reassigment_1.txt | 1 + .../referential_equality_1.kt | 54 + .../referential_equality_1.txt | 8 + .../referential_equality_2.kt | 28 + .../referential_equality_2.txt | 2 + .../test/kotlin/tests/return_1/return_1.kt | 3 + .../test/kotlin/tests/return_1/return_1.txt | 1 + .../safe_access_operator.kt | 14 + .../safe_access_operator.txt | 1 + .../secondary_constructor_1.kt | 28 + .../secondary_constructor_1.txt | 2 + .../serialization_test/serialization_test.kt | 556 +++++++ .../serialization_test/serialization_test.txt | 2 + .../tests/simple_class_2/simple_class_2.kt | 20 + .../tests/simple_class_2/simple_class_2.txt | 3 + .../simple_proto_test_1.kt | 296 ++++ .../simple_proto_test_1.txt | 1 + .../tests/simply_class_1/simply_class_1.kt | 10 + .../tests/simply_class_1/simply_class_1.txt | 1 + .../kotlin/tests/smartcast_1/smartcast_1.kt | 11 + .../kotlin/tests/smartcast_1/smartcast_1.txt | 1 + .../tests/stress_test_1/stress_test_1.kt | 414 +++++ .../tests/stress_test_1/stress_test_1.txt | 1 + .../string_print_test_1.kt | 11 + .../string_print_test_1.txt | 2 + .../kotlin/tests/this_test_1/this_test_1.kt | 12 + .../kotlin/tests/this_test_1/this_test_1.txt | 1 + .../unary_operators_1/unary_operators_1.kt | 11 + .../unary_operators_1/unary_operators_1.txt | 6 + .../variables_assigment_1.kt | 6 + .../variables_assigment_1.txt | 1 + .../kotlin/tests/when_block/when_block.kt | 9 + .../kotlin/tests/when_block/when_block.txt | 3 + .../when_expression_1/when_expression_1.kt | 22 + .../when_expression_1/when_expression_1.txt | 7 + .../src/test/kotlin/tests/while_1/while_1.kt | 8 + .../src/test/kotlin/tests/while_1/while_1.txt | 1 + .../src/test/kotlin/tests/while_2/while_2.c | 3 + .../src/test/kotlin/tests/while_2/while_2.kt | 7 + .../src/test/kotlin/tests/while_2/while_2.txt | 1 + .../while_argument_side_effects_1.kt | 15 + .../while_argument_side_effects_1.txt | 1 + .../tests/while_break_1/while_break_1.kt | 9 + .../tests/while_break_1/while_break_1.txt | 1 + experiments/translator-bc/translate.sh | 4 + 245 files changed, 14136 insertions(+) create mode 100644 experiments/translator-bc/LICENSE create mode 100644 experiments/translator-bc/Makefile create mode 100644 experiments/translator-bc/README.md create mode 100644 experiments/translator-bc/build.gradle create mode 100644 experiments/translator-bc/gradle/wrapper/gradle-wrapper.jar create mode 100644 experiments/translator-bc/gradle/wrapper/gradle-wrapper.properties create mode 100755 experiments/translator-bc/gradlew create mode 100644 experiments/translator-bc/gradlew.bat create mode 100644 experiments/translator-bc/kotstd/Makefile create mode 100644 experiments/translator-bc/kotstd/include/Assert.kt create mode 100644 experiments/translator-bc/kotstd/include/BooleanArray.kt create mode 100644 experiments/translator-bc/kotstd/include/ByteArray.kt create mode 100644 experiments/translator-bc/kotstd/include/CodedInputStream.kt create mode 100644 experiments/translator-bc/kotstd/include/CodedOutputStream.kt create mode 100644 experiments/translator-bc/kotstd/include/Console.kt create mode 100644 experiments/translator-bc/kotstd/include/IntArray.kt create mode 100644 experiments/translator-bc/kotstd/include/Iterators.kt create mode 100644 experiments/translator-bc/kotstd/include/KotlinInputStream.kt create mode 100644 experiments/translator-bc/kotstd/include/KotlinOutputStream.kt create mode 100644 experiments/translator-bc/kotstd/include/LongArray.kt create mode 100644 experiments/translator-bc/kotstd/include/Primitives.kt create mode 100644 experiments/translator-bc/kotstd/include/Progressions.kt create mode 100644 experiments/translator-bc/kotstd/include/Ranges.kt create mode 100644 experiments/translator-bc/kotstd/include/ShortArray.kt create mode 100644 experiments/translator-bc/kotstd/include/WireFormat.kt create mode 100644 experiments/translator-bc/kotstd/include/WireType.kt create mode 100644 experiments/translator-bc/kotstd/include/progressionUtil.kt create mode 100644 experiments/translator-bc/kotstd/libc/array_c.c create mode 100644 experiments/translator-bc/kotstd/libc/assert_c.c create mode 100644 experiments/translator-bc/kotstd/libc/memory.c create mode 100644 experiments/translator-bc/kotstd/libc/primitives_c.c create mode 100755 experiments/translator-bc/run_one_test.sh create mode 100755 experiments/translator-bc/run_tests.sh create mode 100644 experiments/translator-bc/settings.gradle create mode 100644 experiments/translator-bc/src/main/kotlin/DefaultArguments.kt create mode 100644 experiments/translator-bc/src/main/kotlin/main.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/BlockCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ClassCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/FunctionCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ObjectCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/PropertyCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/StructCodegen.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/debug/debug.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/TranslationException.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMCall.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstant.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMNode.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMSingleValue.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.c create mode 100644 experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.c create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.txt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.kt create mode 100644 experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.txt create mode 100755 experiments/translator-bc/translate.sh diff --git a/experiments/translator-bc/LICENSE b/experiments/translator-bc/LICENSE new file mode 100644 index 00000000000..75651683ad4 --- /dev/null +++ b/experiments/translator-bc/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nikolay Igotti + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/experiments/translator-bc/Makefile b/experiments/translator-bc/Makefile new file mode 100644 index 00000000000..a99b77bc367 --- /dev/null +++ b/experiments/translator-bc/Makefile @@ -0,0 +1,46 @@ +DIRECTORY = "src/test/kotlin/tests" +OUTPUT = $(shell ls ${DIRECTORY}/*/*.txt) +OBJECTS = $(OUTPUT:.txt=.out) +green = '\033[0;32m' +red = '\033[0;31m' +lightRed = '\033[1;31m' +orange = '\033[0;33m' +nc = '\033[0m' +KOTSTD='../kotstd' +SOURCELIB=build/sources + +# +# ! Disabled stdlib/test compilation (because we've imported only translator) +# + +#stdlib: +# cd $(KOTSTD) && make clean && make +# +#%.out: stdlib %.txt +# @./run_one_test.sh $(@:.out=.txt) +# +#tests: stdlib $(OBJECTS) +# @date + + +build: + ./gradlew jar + +all: build #tests; + +clean: + ./gradlew clean + +#compile: build +# mkdir -p $(SOURCELIB) +# rm -f $(SOURCELIB)/linked.ll +# rm -f $(SOURCELIB)/linked.ll +# java -jar build/libs/translator-1.0.jar -I $(KOTSTD)/kt $(files) -o $(SOURCELIB)/build.ll +# llvm-link-3.6 -S $(KOTSTD)/build/stdlib_x86.ll $(SOURCELIB)/build.ll >> $(SOURCELIB)/linked.ll +# clang-3.6 $(SOURCELIB)/linked.ll -o $(output) +# rm $(SOURCELIB)/linked.ll +# rm $(SOURCELIB)/build.ll + +.DEFAULT_GOAL := all +.FORCE: build, all +.PHONY: tests, stdlib, build, all, compile diff --git a/experiments/translator-bc/README.md b/experiments/translator-bc/README.md new file mode 100644 index 00000000000..5778ef83e0e --- /dev/null +++ b/experiments/translator-bc/README.md @@ -0,0 +1,64 @@ +# Translator from Kotlin to LLVM + +## Fast build +If you want to use the translator without going into any technical details, this section is for you. Using following commands you will be able to compile your Kotlin files, the resulting executable file + + $ make compile files=$(KTFILES) output=$(OUTPUT) + +where + - $(KTFILES) - list of your Kotlin files separated by spaces + - $(OUTPUT) - the resulting file + + **NOTE:** when you use a fast build, the name of your your entry point function must be **main** and it should not receive arguments + +## Building + +For build translator into jar, you must run gradle target + + $ ./gradlew jar + +**NOTE:** make sure you have jdk version 1.8 or higher + + +Assembled the translator can be found in the following folder + + $ cd build/libs/translator + +## Using compiler + $ java -jar $(PATH_TO_TRANSLATOR_JAR) -I $(PATH_TO_KOTLIB) $(KOTLIN_SOURCES) + where + - $(PATH_TO_TRANSLATOR_JAR) - path to jar, which you got in building step, by default it `build/libs/translator-1.0.jar` + - $(PATH_TO_KOTLIB) - path to standard kotlin lib, by default it `./kotstd/include` + - $(KOTLIN_SOURCES) - the different files that you want to compile + +### Optional arguments + - -M - specified entry point of your project, by default it is main + + **NOTE:** your entry point function should not receive arguments + + - -o - file to redirect output of the generated code + + +## Using generated code + +To execute the generated code you should use should link your code with kotlin native runtime. By default, you can find the appropriate library at +`../kotstd/build/stdlib_x86.ll` + +If this file is missing you can assemble it yourself + + $ cd ../kotstd && make clean && make + +For linking, run the following command + + $ llvm-link-3.6 -S $(KOTLIN_NATIVE_RUNTIME) $(COMPILED_LLVM_CODE) + +where $(COMPILED_LLVM_CODE) - code obtained in the step compiler + +**NOTE:** The translator supports the llvm version number 3.6. Please make sure you have the correct version of llvm. + +## Run + + $ lli-3.6 $(LINKED_CODE) + +where $(LINKED_CODE) - code obtained in the previous step + diff --git a/experiments/translator-bc/build.gradle b/experiments/translator-bc/build.gradle new file mode 100644 index 00000000000..71b194df7fc --- /dev/null +++ b/experiments/translator-bc/build.gradle @@ -0,0 +1,38 @@ +group 'translator' +version '1.0' + +buildscript { + ext.kotlin_version = '1.0.3' + + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.2" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +repositories { + mavenCentral() + maven { url "https://jitpack.io" } +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.1" + compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler', version: '1.0.3' + compile 'com.github.jshmrsn:karg:a636b3e' + testCompile group: 'junit', name: 'junit', version: '4.11' +} + +jar { + manifest { + attributes 'Main-Class': 'MainKt' + } + + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } +} + diff --git a/experiments/translator-bc/gradle/wrapper/gradle-wrapper.jar b/experiments/translator-bc/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..941144813d241db74e1bf25b6804c679fbe7f0a3 GIT binary patch literal 53636 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 DXC5Z7 literal 0 HcmV?d00001 diff --git a/experiments/translator-bc/gradle/wrapper/gradle-wrapper.properties b/experiments/translator-bc/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..87174db222c --- /dev/null +++ b/experiments/translator-bc/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jul 07 16:27:28 MSK 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip diff --git a/experiments/translator-bc/gradlew b/experiments/translator-bc/gradlew new file mode 100755 index 00000000000..2f205f5ba69 --- /dev/null +++ b/experiments/translator-bc/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:function=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/experiments/translator-bc/gradlew.bat b/experiments/translator-bc/gradlew.bat new file mode 100644 index 00000000000..aec99730b4e --- /dev/null +++ b/experiments/translator-bc/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/experiments/translator-bc/kotstd/Makefile b/experiments/translator-bc/kotstd/Makefile new file mode 100644 index 00000000000..fdd6cf55107 --- /dev/null +++ b/experiments/translator-bc/kotstd/Makefile @@ -0,0 +1,49 @@ + +BUILD_DIR=$(PWD)/build +INCLUDE_DIR=$(PWD)/include +LIB_ARM_DIR=$(PWD)/lib/arm +LIB_X86_DIR=$(PWD)/lib/x86 +LIBC=$(PWD)/libc + +KT=$(PWD)/../translator/build/libs/translator-1.0.jar +LLINK=llvm-link-3.6 +CC=clang-3.6 + +CCFLAGS_ARM=-g -S -Wall -m32 -emit-llvm -nostdlib -ffreestanding -march=armv7-m -mthumb -flto -O0 -target arm-none-eabi -DARM +CCFLAGS=-g -O0 -S -Wall -emit-llvm -nostdlib -ffreestanding +CCFLAGS_DEBUG=-g -O0 -S -Wall -emit-llvm -nostdlib -ffreestanding -DDBG +LLINK_FLAGS=-S + +KT_ALL_DEPS=java -jar $(KT) +LLINK_ALL_DEPS=$(LLINK) $(LLINK_FLAGS) $(filter %.ll,$^) > $@ + +all: memory $(BUILD_DIR) $(BUILD_DIR)/stdlib_arm.ll $(BUILD_DIR)/stdlib_x86.ll +debug: memory_debug $(BUILD_DIR) $(BUILD_DIR)/stdlib_arm.ll $(BUILD_DIR)/stdlib_x86.ll + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +$(BUILD_DIR)/stdlib_x86.ll: $(LIB_X86_DIR)/*.ll + $(LLINK_ALL_DEPS) + +$(BUILD_DIR)/stdlib_arm.ll: $(LIB_ARM_DIR)/*.ll + $(LLINK_ALL_DEPS) + +$(BUILD_DIR)/classes_x86.ll: $(INCLUDE_DIR)/*.kt + $(KT_ALL_DEPS) -o $@ $(filter %.kt,$^) + +$(BUILD_DIR)/classes_arm.ll: $(INCLUDE_DIR)/*.kt + $(KT_ALL_DEPS) --arm -o $@ $(filter %.kt,$^) + +memory: + $(CC) $(CCFLAGS) $(LIBC)/memory.c -o $(LIB_X86_DIR)/memory.ll + $(CC) $(CCFLAGS_ARM) $(LIBC)/memory.c -o $(LIB_ARM_DIR)/memory.ll + +memory_debug: + $(CC) $(CCFLAGS_DEBUG) $(LIBC)/memory.c -o $(LIB_X86_DIR)/memory.ll + +clean: + rm -rf $(BUILD_DIR) + +.PHONY: all clean + diff --git a/experiments/translator-bc/kotstd/include/Assert.kt b/experiments/translator-bc/kotstd/include/Assert.kt new file mode 100644 index 00000000000..fc253e0f13e --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Assert.kt @@ -0,0 +1,8 @@ +package kotlin + +external fun assert_c(value: Boolean) + +fun assert(value: Boolean) { + println(value) + assert_c(value) +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/BooleanArray.kt b/experiments/translator-bc/kotstd/include/BooleanArray.kt new file mode 100644 index 00000000000..7df7eb81e46 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/BooleanArray.kt @@ -0,0 +1,121 @@ +package kotlin + +external fun kotlinclib_boolean_size(): Int + +class BooleanArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //size: Int + + init { + this.data = malloc_array(kotlinclib_boolean_size() * this.size) + var index = 0 + while (index < this.size) { + set(index, false) + index = index + 1 + } + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + operator fun get(index: Int): Boolean { + val res = kotlinclib_get_byte(this.data, index) == 1.toByte() + return res + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + operator fun set(index: Int, value: Boolean) { + if (value == true) { + kotlinclib_set_byte(this.data, index, 1.toByte()) + } else { + kotlinclib_set_byte(this.data, index, 0.toByte()) + } + } + + + fun clone(): BooleanArray { + val newInstance = BooleanArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } +} + +fun BooleanArray.print() { + var index = 0 + print('[') + while (index < size) { + print(get(index)) + index++ + if (index < size){ + print(';') + print(' ') + } + } + print(']') +} + +fun BooleanArray.println() { + this.print() + //println() +} + + +fun BooleanArray.copyOf(newSize: Int): BooleanArray { + val newInstance = BooleanArray(newSize) + var index = 0 + val end = if (newSize > this.size) this.size else newSize + while (index < end) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + while (index < newSize) { + newInstance.set(index, false) + index = index + 1 + } + + return newInstance +} + +fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray { + val newInstance = BooleanArray(toIndex - fromIndex) + var index = fromIndex + while (index < toIndex) { + val value = this.get(index) + newInstance.set(index - fromIndex, value) + index = index + 1 + } + + return newInstance +} + +operator fun BooleanArray.plus(element: Boolean): BooleanArray { + val index = size + val result = this.copyOf(index + 1) + result[index] = element + return result +} + +operator fun BooleanArray.plus(elements: BooleanArray): BooleanArray { + val thisSize = size + val arraySize = elements.size + val resultSize = thisSize + arraySize + val newInstance = this.copyOf(resultSize) + var index = thisSize + + while (index < resultSize) { + val value = elements.get(index - thisSize) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/ByteArray.kt b/experiments/translator-bc/kotstd/include/ByteArray.kt new file mode 100644 index 00000000000..8952a07eb1f --- /dev/null +++ b/experiments/translator-bc/kotstd/include/ByteArray.kt @@ -0,0 +1,121 @@ +package kotlin + +external fun malloc_array(size: Int): Int +external fun kotlinclib_get_byte(src: Int, index: Int): Byte +external fun kotlinclib_set_byte(src: Int, index: Int, value: Byte) +external fun kotlinclib_byte_size(): Int + + +class ByteArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //size: Int + + init { + this.data = malloc_array(kotlinclib_byte_size() * this.size) + var index = 0 + + while (index < this.size) { + set(index, 0) + index = index + 1 + } + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + operator fun get(index: Int): Byte { + return kotlinclib_get_byte(this.data, index) + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + operator fun set(index: Int, value: Byte) { + kotlinclib_set_byte(this.data, index, value) + } + + + fun clone(): ByteArray { + val newInstance = ByteArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } + +} + +fun ByteArray.print() { + var index = 0 + print('[') + while (index < size) { + print(get(index)) + index++ + if (index < size){ + print(';') + print(' ') + } + } + print(']') +} + +fun ByteArray.println() { + this.print() + //println() +} + +fun ByteArray.copyOf(newSize: Int): ByteArray { + val newInstance = ByteArray(newSize) + var index = 0 + val end = if (newSize > this.size) this.size else newSize + while (index < end) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + while (index < newSize) { + newInstance.set(index, 0) + index = index + 1 + } + + return newInstance +} + +fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray { + val newInstance = ByteArray(toIndex - fromIndex) + var index = fromIndex + while (index < toIndex) { + val value = this.get(index) + newInstance.set(index - fromIndex, value) + index = index + 1 + } + + return newInstance +} + +operator fun ByteArray.plus(element: Byte): ByteArray { + val index = size + val result = this.copyOf(index + 1) + result[index] = element + return result +} + +operator fun ByteArray.plus(elements: ByteArray): ByteArray { + val thisSize = size + val arraySize = elements.size + val resultSize = thisSize + arraySize + val newInstance = this.copyOf(resultSize) + var index = thisSize + + while (index < resultSize) { + val value = elements.get(index - thisSize) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/CodedInputStream.kt b/experiments/translator-bc/kotstd/include/CodedInputStream.kt new file mode 100644 index 00000000000..bb5b6e47cae --- /dev/null +++ b/experiments/translator-bc/kotstd/include/CodedInputStream.kt @@ -0,0 +1,216 @@ +/** + * Created by Dmitry Savvinov on 7/6/16. + * + * Hides details of work with Protobuf encoding + * + * Note that CodedInputStream reads protobuf-defined types from stream (such as int32, sint32, etc), + * while CodedOutputStream has methods for writing Kotlin-types (such as Boolean, Int, Long, Short, etc) + * + */ + +// TODO: refactor correctness checks into readTag +class CodedInputStream(val buffer: ByteArray) { + val inputStream: KotlinInputStream + init { + inputStream = KotlinInputStream(buffer) + } + + fun mark() { + inputStream.mark() + } + + fun reset() { + inputStream.reset() + } + + fun readInt32(expectedFieldNumber: Int): Int { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readInt32NoTag() + } + + // Note that unsigned integer types are stored as their signed counterparts with top bit + // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all + // methods reading unsigned ints simply redirect call to corresponding signed-reading method + fun readUInt32(expectedFieldNumber: Int): Int { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readUInt32NoTag() + } + + fun readUInt32NoTag(): Int { + return readInt32NoTag() + } + + fun readInt64(expectedFieldNumber: Int): Long { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readInt64NoTag() + } + + // See note on unsigned integers implementations above + fun readUInt64(expectedFieldNumber: Int): Long { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readUInt64NoTag() + } + + fun readUInt64NoTag(): Long { + return readInt64NoTag() + } + + fun readBool(expectedFieldNumber: Int): Boolean { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readBoolNoTag() + } + + fun readBoolNoTag(): Boolean { + val readValue = readInt32NoTag() + val boolValue = when (readValue) { + 0 -> false + 1 -> true + else -> false + } + return boolValue + } + + // Reading enums is like reading one int32 number. Caller is responsible for converting this ordinal to enum-object + fun readEnum(expectedFieldNumber: Int): Int { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readEnumNoTag() + } + + fun readEnumNoTag(): Int { + return readUInt32NoTag() + } + + fun readSInt32(expectedFieldNumber: Int): Int { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readSInt32NoTag() + } + + fun readSInt32NoTag(): Int { + return readZigZag32NoTag() + } + + fun readSInt64(expectedFieldNumber: Int): Long { + val tag = readTag(expectedFieldNumber, WireType.VARINT) + return readSInt64NoTag() + } + + fun readSInt64NoTag(): Long { + return readZigZag64NoTag() + } + fun readBytes(expectedFieldNumber: Int): ByteArray { + val tag = readTag(expectedFieldNumber, WireType.LENGTH_DELIMITED) + return readBytesNoTag() + } + + fun readBytesNoTag(): ByteArray { + val length = readInt32NoTag() + return readRawBytes(length) + } + + /** ============ Utility methods ================== + * They are left non-private for cases when one wants to implement her/his own protocol format. + * Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags. + */ + + fun checkFieldCorrectness( + expectedFieldNumber: Int, + actualFieldNumber: Int, + expectedWireType: WireType, + actualWireType: WireType) { + if (expectedFieldNumber != actualFieldNumber) { + return + } + + if (expectedWireType.id != actualWireType.id) { + return + } + } + + fun readRawBytes(count: Int): ByteArray { + val ba = ByteArray(count) + var i = 0 + while (i < count) { + ba[i] = inputStream.read().toByte() + i++ + } + return ba + } + + // reads tag. Note that it returns 0 for the end of message! + fun readTag(expectedFieldNumber: Int, expectedWireType: WireType): Int { + if (isAtEnd()) { + return 0 // we can safely return 0 as sign of end of message, because 0-tags are illegal + } + val tag = readInt32NoTag() + if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted + return 0 + } + + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, expectedWireType, actualWireType) + return tag + } + + // reads varint not larger than 32-bit integer according to protobuf varint-encoding + fun readInt32NoTag(): Int { + var done: Boolean = false + var result: Long = 0 + var step: Int = 0 + while (!done) { + val byte: Int = inputStream.read().toInt() + result = result or + ( + (byte and WireFormat.VARINT_INFO_BITS_MASK).toLong() + shl + (WireFormat.VARINT_INFO_BITS_COUNT * step) + ).toLong() + step++ + if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0) { + done = true + } + } + return result.toInt() + } + + // reads varint not larger than 64-bit integer according to protobuf varint-encoding + fun readInt64NoTag(): Long { + var done: Boolean = false + var result: Long = 0 + var step: Int = 0 + while (!done) { + val byte: Int = inputStream.read().toInt() + result = result or + ( + (byte and WireFormat.VARINT_INFO_BITS_MASK).toLong() + shl + (WireFormat.VARINT_INFO_BITS_COUNT * step) + ) + step++ + if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0 /* || byte == -1 ???? */) { + done = true + } + } + return result + } + + // reads zig-zag encoded integer not larger than 32-bit long + fun readZigZag32NoTag(): Int { + val value = readInt32NoTag() + return (value ushr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number + } + + // reads zig-zag encoded integer not larger than 64-bit long + fun readZigZag64NoTag(): Long { + val value = readInt64NoTag() + return (value ushr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number + } + + // checks if at least one more byte can be read from underlying input stream + fun isAtEnd(): Boolean { + return inputStream.isAtEnd() + } +} diff --git a/experiments/translator-bc/kotstd/include/CodedOutputStream.kt b/experiments/translator-bc/kotstd/include/CodedOutputStream.kt new file mode 100644 index 00000000000..9c40747b99c --- /dev/null +++ b/experiments/translator-bc/kotstd/include/CodedOutputStream.kt @@ -0,0 +1,167 @@ +/** + * Created by user on 7/6/16. + */ + +class CodedOutputStream(val buffer: ByteArray) { + val output = KotlinOutputStream(buffer) + + fun toByteArray(): ByteArray { + return buffer + } + + fun writeTag(fieldNumber: Int, type: WireType) { + val tag = (fieldNumber shl 3) or type.id + writeRawVarint32(tag) + } + + fun writeInt32(fieldNumber: Int, value: Int) { + writeTag(fieldNumber, WireType.VARINT) + writeInt32NoTag(value) + } + + fun writeInt32NoTag(value: Int) { + if (value < 0) { // sign-extend negative values + writeRawVarint64(value.toLong()) + return + } + writeRawVarint32(value) + } + + // Note that unsigned integer types are stored as their signed counterparts with top bit + // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all + // methods, writing unsigned ints simply redirect call to corresponding signed-writing method + fun writeUInt32(fieldNumber: Int, value: Int) { + writeTag(fieldNumber, WireType.VARINT) + writeUInt32NoTag(value) + } + + fun writeUInt32NoTag(value: Int) { + writeRawVarint32(value) + } + + fun writeInt64(fieldNumber: Int, value: Long) { + writeTag(fieldNumber, WireType.VARINT) + writeInt64NoTag(value) + } + + fun writeInt64NoTag(value: Long) { + writeRawVarint64(value) + } + + // See notes on unsigned integers implementation above + fun writeUInt64(fieldNumber: Int, value: Long) { + writeTag(fieldNumber, WireType.VARINT) + writeUInt64NoTag(value) + } + + fun writeUInt64NoTag(value: Long) { + writeRawVarint64(value) + } + + fun writeBool(fieldNumber: Int, value: Boolean) { + writeTag(fieldNumber, WireType.VARINT) + writeBoolNoTag(value) + } + + fun writeBoolNoTag(value: Boolean) { + writeRawVarint32(if (value) 1 else 0) + } + + // Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal + fun writeEnum(fieldNumber: Int, value: Int) { + writeTag(fieldNumber, WireType.VARINT) + writeEnumNoTag(value) + } + + fun writeEnumNoTag(value: Int) { + writeRawVarint32(value) + } + + fun writeSInt32(fieldNumber: Int, value: Int) { + writeTag(fieldNumber, WireType.VARINT) + writeSInt32NoTag(value) + } + + fun writeSInt32NoTag(value: Int) { + writeUInt32NoTag((value shl 1) xor (value shr 31)) + } + + fun writeSInt64(fieldNumber: Int, value: Long) { + writeTag(fieldNumber, WireType.VARINT) + writeSInt64NoTag(value) + } + + fun writeSInt64NoTag(value: Long) { + writeUInt64NoTag((value shl 1) xor (value shr 63)) + } + + fun writeBytes(fieldNumber: Int, value: ByteArray) { + if (value.size == 0) { + return + } + writeTag(fieldNumber, WireType.LENGTH_DELIMITED) + writeBytesNoTag(value) + } + + fun writeBytesNoTag(value: ByteArray) { + writeRawVarint32(value.size) + output.write(value) + } + + /** ============ Utility methods ================== + * They are left non-private for cases when one wants to implement her/his own protocol format. + * Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags. + */ + + fun writeRawVarint32(value: Int) { + var curValue: Int = value + + // we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding + val res = ByteArray(5) + + var resSize = 0 + do { + // encode current 7 bits + var curByte = (curValue and WireFormat.VARINT_INFO_BITS_MASK) + + // discard encoded bits. Note that unsigned shift is needed for cases with negative numbers + curValue = curValue ushr WireFormat.VARINT_INFO_BITS_COUNT + + // check if there will be next byte in encoding and set util bit if needed + if (curValue != 0) { + curByte = curByte or WireFormat.VARINT_UTIL_BIT_MASK + } + + res[resSize] = curByte.toByte() + resSize++ + } while (curValue != 0) + output.write(res, 0, resSize) + } + + fun writeRawVarint64(value: Long) { + var curValue: Long = value + + // we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding + val res = ByteArray(10) + + var resSize = 0 + do { + // encode current 7 bits + var curByte = (curValue and WireFormat.VARINT_INFO_BITS_MASK.toLong()) + + // discard encoded bits. Note that unsigned shift is needed for cases with negative numbers + curValue = curValue ushr WireFormat.VARINT_INFO_BITS_COUNT + + // check if there will be next byte and set util bit if needed + if (curValue != 0L) { + curByte = curByte or WireFormat.VARINT_UTIL_BIT_MASK.toLong() + } + + res[resSize] = curByte.toByte() + resSize++ + } while(curValue != 0L) + output.write(res, 0, resSize) + } + + +} diff --git a/experiments/translator-bc/kotstd/include/Console.kt b/experiments/translator-bc/kotstd/include/Console.kt new file mode 100644 index 00000000000..c4077be14d4 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Console.kt @@ -0,0 +1,171 @@ +package kotlin + +/* +* Library for console interaction +*/ + +external fun kotlinclib_print_int(message: Int) +external fun kotlinclib_print_long(message: Long) +external fun kotlinclib_print_byte(message: Byte) +external fun kotlinclib_print_short(message: Short) +external fun kotlinclib_print_char(message: Char) +external fun kotlinclib_print_boolean(message: Boolean) +external fun kotlinclib_print_float(message: Float) +external fun kotlinclib_print_double(message: Double) +external fun kotlinclib_print_string(message: String) +external fun kotlinclib_println_int(message: Int) +external fun kotlinclib_println_long(message: Long) +external fun kotlinclib_println_byte(message: Byte) +external fun kotlinclib_println_short(message: Short) +external fun kotlinclib_println_char(message: Char) +external fun kotlinclib_println_boolean(message: Boolean) +external fun kotlinclib_println_float(message: Float) +external fun kotlinclib_println_double(message: Double) +external fun kotlinclib_println_string(message: String) +external fun kotlinclib_println() + +/** Prints the given message to the standard output stream. */ +fun print(message: Int) { + kotlinclib_print_int(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Long) { + kotlinclib_print_long(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Byte) { + kotlinclib_print_byte(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Short) { + kotlinclib_print_short(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Char) { + kotlinclib_print_char(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Boolean) { + kotlinclib_print_boolean(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Float) { + kotlinclib_print_float(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: Double) { + kotlinclib_print_double(message) +} + +/** Prints the given message to the standard output stream. */ +fun print(message: String) { + kotlinclib_print_string(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun print(message: ByteArray) { + message.print() +} + +/** Prints the given message and newline to the standard output stream. */ +fun print(message: BooleanArray) { + message.print() +} + +/** Prints the given message and newline to the standard output stream. */ +fun print(message: IntArray) { + message.print() +} + +/** Prints the given message and newline to the standard output stream. */ +fun print(message: LongArray) { + message.print() +} + +/** Prints the given message and newline to the standard output stream. */ +fun print(message: ShortArray) { + message.print() +} + + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Int) { + kotlinclib_println_int(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Long) { + kotlinclib_println_long(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Byte) { + kotlinclib_println_byte(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Short) { + kotlinclib_println_short(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Char) { + kotlinclib_println_char(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Boolean) { + kotlinclib_println_boolean(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Float) { + kotlinclib_println_float(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: Double) { + kotlinclib_println_double(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: String) { + kotlinclib_println_string(message) +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: ByteArray) { + message.println() +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: BooleanArray) { + message.println() +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: IntArray) { + message.println() +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: LongArray) { + message.println() +} + +/** Prints the given message and newline to the standard output stream. */ +fun println(message: ShortArray) { + message.println() +} + +/** Prints newline to the standard output stream. */ +fun println() { + kotlinclib_println() +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/IntArray.kt b/experiments/translator-bc/kotstd/include/IntArray.kt new file mode 100644 index 00000000000..09767b162b9 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/IntArray.kt @@ -0,0 +1,195 @@ +package kotlin + +external fun kotlinclib_get_int(src: Int, index: Int): Int +external fun kotlinclib_set_int(src: Int, index: Int, value: Int) +external fun kotlinclib_int_size(): Int + + +class IntArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //size: Int + + init { + this.data = malloc_array(kotlinclib_int_size() * this.size) + var index = 0 + while (index < this.size) { + set(index, 0) + index = index + 1 + } + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + operator fun get(index: Int): Int { + return kotlinclib_get_int(this.data, index) + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + operator fun set(index: Int, value: Int) { + kotlinclib_set_int(this.data, index, value) + } + + + fun clone(): IntArray { + val newInstance = IntArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } + +} + +fun IntArray.print() { + var index = 0 + print('[') + while (index < size) { + print(get(index)) + index++ + if (index < size) { + print(';') + print(' ') + } + } + print(']') +} + +fun IntArray.println() { + this.print() + //println() +} + +fun IntArray.copyOf(newSize: Int): IntArray { + val newInstance = IntArray(newSize) + var index = 0 + val end = if (newSize > this.size) this.size else newSize + while (index < end) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + while (index < newSize) { + newInstance.set(index, 0) + index = index + 1 + } + + return newInstance +} + +fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray { + val newInstance = IntArray(toIndex - fromIndex) + var index = fromIndex + while (index < toIndex) { + val value = this.get(index) + newInstance.set(index - fromIndex, value) + index = index + 1 + } + + return newInstance +} + +operator fun IntArray.plus(element: Int): IntArray { + val index = size + val result = this.copyOf(index + 1) + result[index] = element + return result +} + +operator fun IntArray.plus(elements: IntArray): IntArray { + val thisSize = size + val arraySize = elements.size + val resultSize = thisSize + arraySize + val newInstance = this.copyOf(resultSize) + var index = thisSize + + while (index < resultSize) { + val value = elements.get(index - thisSize) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance +} + +fun IntArray.max(from: Int = 0): Int { + var result = from + var i = from + while (i < size - 1) { + result = if (get(i) > get(result)) i else result + i++ + } + + return get(result) +} + +fun IntArray.min(from: Int = 0): Int { + var result = from + var i = from + while (i < size - 1) { + result = if (this.get(i) < this.get(result)) i else result + i++ + } + + return this.get(result) +} + +fun IntArray.sum(): Int { + var result = 0 + var i = 0 + while (i < size - 1) { + result += this.get(i) + i++ + } + + return result +} + +fun IntArray.sort(): IntArray { + val result = this.clone() + var i = 0 + while (i < size - 1) { + result[i] = this.max(i) + i++ + } + + return result +} + +fun IntArray.mean(): Int = + this.sum() / this.size + +fun IntArray.median(): Int = + this.sort()[this.size / 2] + +fun IntArray.filter(predicate: (Int) -> Boolean): IntArray { + var resultSize = 0 + var i = 0 + while (i < size - 1) { + if (predicate(get(i))) { + resultSize++ + } + + i++ + } + + val result = IntArray(resultSize) + var j = 0 + i = 0 + while (i < size - 1) { + if (predicate(get(i))) { + result[j] = get(i) + j++ + } + + i++ + } + + return result +} diff --git a/experiments/translator-bc/kotstd/include/Iterators.kt b/experiments/translator-bc/kotstd/include/Iterators.kt new file mode 100644 index 00000000000..836b06babe9 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Iterators.kt @@ -0,0 +1,94 @@ +package kotlin.collections + +/** An iterator over a sequence of values of type `Byte`. */ +public abstract class ByteIterator { + final fun next() = nextByte() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextByte(): Byte + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Char`. */ +public abstract class CharIterator { + final fun next() = nextChar() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextChar(): Char + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Short`. */ +public abstract class ShortIterator { + final fun next() = nextShort() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextShort(): Short + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Int`. */ +class IntIterator(first: Int, last: Int, val step: Int) { + private var next = first + private val finalElement = last + private var hasNext: Boolean = if (step > 0) first <= last else first >= last + + final fun next() = nextInt () + + fun hasNext(): Boolean = hasNext + + fun nextInt(): Int { + val value = next + if (value == finalElement) { + hasNext = false + } + else { + next += step + } + return value + } +} + + +/** An iterator over a sequence of values of type `Long`. */ +public abstract class LongIterator { + final fun next() = nextLong() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextLong(): Long + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Float`. */ +public abstract class FloatIterator { + final fun next() = nextFloat() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextFloat(): Float + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Double`. */ +public abstract class DoubleIterator { + final fun next() = nextDouble() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextDouble(): Double + + public abstract fun hasNext(): Boolean +} + +/** An iterator over a sequence of values of type `Boolean`. */ +public abstract class BooleanIterator { + final fun next() = nextBoolean() + + /** Returns the next value in the sequence without boxing. */ + public abstract fun nextBoolean(): Boolean + + public abstract fun hasNext(): Boolean +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/KotlinInputStream.kt b/experiments/translator-bc/kotstd/include/KotlinInputStream.kt new file mode 100644 index 00000000000..ee2c40aa387 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/KotlinInputStream.kt @@ -0,0 +1,25 @@ +/** + * Created by user on 8/8/16. + */ + +class KotlinInputStream(val buffer: ByteArray) { + var pos = 0 + var mark_ = 0 + + fun read(): Byte { + pos += 1 + return buffer[pos - 1] + } + + fun isAtEnd(): Boolean { + return pos >= buffer.size + } + + fun mark() { + mark_ = pos + } + + fun reset() { + pos = mark_ + } +} diff --git a/experiments/translator-bc/kotstd/include/KotlinOutputStream.kt b/experiments/translator-bc/kotstd/include/KotlinOutputStream.kt new file mode 100644 index 00000000000..51f80aaf766 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/KotlinOutputStream.kt @@ -0,0 +1,20 @@ +/** + * Created by user on 8/8/16. + */ + +class KotlinOutputStream(val buffer: ByteArray) { + var pos = 0 + + fun write (data: ByteArray) { + write(data, 0, data.size) + } + + fun write (data: ByteArray, begin: Int, size: Int) { + var i = begin + while (i < begin + size) { + buffer[pos] = data[i] + pos += 1 + i++ + } + } +} diff --git a/experiments/translator-bc/kotstd/include/LongArray.kt b/experiments/translator-bc/kotstd/include/LongArray.kt new file mode 100644 index 00000000000..f8ae4fe7d03 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/LongArray.kt @@ -0,0 +1,118 @@ +package kotlin + +external fun kotlinclib_get_long(src: Int, index: Int): Long +external fun kotlinclib_set_long(src: Int, index: Int, value: Long) +external fun kotlinclib_long_size(): Int + + +class LongArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //size: Int + + init { + this.data = malloc_array(kotlinclib_long_size() * this.size) + var index = 0 + while (index < this.size) { + set(index, 0) + index = index + 1 + } + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + operator fun get(index: Int): Long { + return kotlinclib_get_long(this.data, index) + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + operator fun set(index: Int, value: Long) { + kotlinclib_set_long(this.data, index, value) + } + + + fun clone(): LongArray { + val newInstance = LongArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } +} + +fun LongArray.print() { + var index = 0 + print('[') + while (index < size) { + print(get(index)) + index++ + if (index < size) { + print(';') + print(' ') + } + } + print(']') +} + +fun LongArray.println() { + this.print() + //println() +} + +fun LongArray.copyOf(newSize: Int): LongArray { + val newInstance = LongArray(newSize) + var index = 0 + val end = if (newSize > this.size) this.size else newSize + while (index < end) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + while (index < newSize) { + newInstance.set(index, 0) + index = index + 1 + } + + return newInstance +} + +fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray { + val newInstance = LongArray(toIndex - fromIndex) + var index = fromIndex + while (index < toIndex) { + val value = this.get(index) + newInstance.set(index - fromIndex, value) + index = index + 1 + } + + return newInstance +} + +operator fun LongArray.plus(element: Long): LongArray { + val index = size + val result = this.copyOf(index + 1) + result[index] = element + return result +} + +operator fun LongArray.plus(elements: LongArray): LongArray { + val thisSize = size + val arraySize = elements.size + val resultSize = thisSize + arraySize + val newInstance = this.copyOf(resultSize) + var index = thisSize + + while (index < resultSize) { + val value = elements.get(index - thisSize) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/Primitives.kt b/experiments/translator-bc/kotstd/include/Primitives.kt new file mode 100644 index 00000000000..3da2e500545 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Primitives.kt @@ -0,0 +1,251 @@ +package kotlin + +external fun kotlinclib_byteToChar(value: Byte): Char +external fun kotlinclib_byteToShort(value: Byte): Short +external fun kotlinclib_byteToInt(value: Byte): Int +external fun kotlinclib_byteToLong(value: Byte): Long +external fun kotlinclib_byteToFloat(value: Byte): Float +external fun kotlinclib_byteToDouble(value: Byte): Double + + +fun Byte.toByte(): Byte { + return this +} + +fun Byte.toInt(): Int { + return kotlinclib_byteToInt(this) +} + +fun Byte.toChar(): Char { + return kotlinclib_byteToChar(this) +} + +fun Byte.toShort(): Short { + return kotlinclib_byteToShort(this) +} + +fun Byte.toLong(): Long { + return kotlinclib_byteToLong(this) +} + +fun Byte.toFloat(): Float { + return kotlinclib_byteToFloat(this) +} + +fun Byte.toDouble(): Double { + return kotlinclib_byteToDouble(this) +} + +external fun kotlinclib_charToByte(value: Char): Byte +external fun kotlinclib_charToShort(value: Char): Short +external fun kotlinclib_charToInt(value: Char): Int +external fun kotlinclib_charToLong(value: Char): Long +external fun kotlinclib_charToFloat(value: Char): Float +external fun kotlinclib_charToDouble(value: Char): Double + + +fun Char.toByte(): Byte { + return kotlinclib_charToByte(this) +} + +fun Char.toInt(): Int { + return kotlinclib_charToInt(this) +} + +fun Char.toChar(): Char { + return this +} + +fun Char.toShort(): Short { + return kotlinclib_charToShort(this) +} + +fun Char.toLong(): Long { + return kotlinclib_charToLong(this) +} + +fun Char.toFloat(): Float { + return kotlinclib_charToFloat(this) +} + +fun Char.toDouble(): Double { + return kotlinclib_charToDouble(this) +} + +external fun kotlinclib_doubleToByte(value: Double): Byte +external fun kotlinclib_doubleToChar(value: Double): Char +external fun kotlinclib_doubleToShort(value: Double): Short +external fun kotlinclib_doubleToInt(value: Double): Int +external fun kotlinclib_doubleToLong(value: Double): Long +external fun kotlinclib_doubleToFloat(value: Double): Float + +fun Double.toByte(): Byte { + return kotlinclib_doubleToByte(this) +} + +fun Double.toChar(): Char { + return kotlinclib_doubleToChar(this) +} + +fun Double.toShort(): Short { + return kotlinclib_doubleToShort(this) +} + +fun Double.toInt(): Int { + return kotlinclib_doubleToInt(this) +} + +fun Double.toLong(): Long { + return kotlinclib_doubleToLong(this) +} + +fun Double.toFloat(): Float { + return kotlinclib_doubleToFloat(this) +} + +fun Double.toDouble(): Double { + return this +} + + +external fun kotlinclib_floatToByte(value: Float): Byte +external fun kotlinclib_floatToChar(value: Float): Char +external fun kotlinclib_floatToShort(value: Float): Short +external fun kotlinclib_floatToInt(value: Float): Int +external fun kotlinclib_floatToLong(value: Float): Long +external fun kotlinclib_floatToDouble(value: Float): Double + +fun Float.toByte(): Byte { + return kotlinclib_floatToByte(this) +} + +fun Float.toChar(): Char { + return kotlinclib_floatToChar(this) +} + +fun Float.toShort(): Short { + return kotlinclib_floatToShort(this) +} + +fun Float.toInt(): Int { + return kotlinclib_floatToInt(this) +} + +fun Float.toLong(): Long { + return kotlinclib_floatToLong(this) +} + +fun Float.toFloat(): Float { + return this +} + +fun Float.toDouble(): Double { + return kotlinclib_floatToDouble(this) +} + + +external fun kotlinclib_intToByte(value: Int): Byte +external fun kotlinclib_intToChar(value: Int): Char +external fun kotlinclib_intToShort(value: Int): Short +external fun kotlinclib_intToLong(value: Int): Long +external fun kotlinclib_intToFloat(value: Int): Float +external fun kotlinclib_intToDouble(value: Int): Double + +fun Int.toByte(): Byte { + return kotlinclib_intToByte(this) +} + +fun Int.toInt(): Int { + return this +} + +fun Int.toChar(): Char { + return kotlinclib_intToChar(this) +} + +fun Int.toShort(): Short { + return kotlinclib_intToShort(this) +} + +fun Int.toLong(): Long { + return kotlinclib_intToLong(this) +} + +fun Int.toFloat(): Float { + return kotlinclib_intToFloat(this) +} + +fun Int.toDouble(): Double { + return kotlinclib_intToDouble(this) +} + +external fun kotlinclib_longToByte(value: Long): Byte +external fun kotlinclib_longToChar(value: Long): Char +external fun kotlinclib_longToShort(value: Long): Short +external fun kotlinclib_longToInt(value: Long): Int +external fun kotlinclib_longToFloat(value: Long): Float +external fun kotlinclib_longToDouble(value: Long): Double + +fun Long.toByte(): Byte { + return kotlinclib_longToByte(this) +} + +fun Long.toLong(): Long { + return this +} + +fun Long.toChar(): Char { + return kotlinclib_longToChar(this) +} + +fun Long.toShort(): Short { + return kotlinclib_longToShort(this) +} + +fun Long.toInt(): Int { + return kotlinclib_longToInt(this) +} + +fun Long.toFloat(): Float { + return kotlinclib_longToFloat(this) +} + +fun Long.toDouble(): Double { + return kotlinclib_longToDouble(this) +} + +external fun kotlinclib_shortToByte(value: Short): Byte +external fun kotlinclib_shortToChar(value: Short): Char +external fun kotlinclib_shortToInt(value: Short): Int +external fun kotlinclib_shortToLong(value: Short): Long +external fun kotlinclib_shortToFloat(value: Short): Float +external fun kotlinclib_shortToDouble(value: Short): Double + + +fun Short.toByte(): Byte { + return kotlinclib_shortToByte(this) +} + +fun Short.toInt(): Int { + return kotlinclib_shortToInt(this) +} + +fun Short.toChar(): Char { + return kotlinclib_shortToChar(this) +} + +fun Short.toShort(): Short { + return this +} + +fun Short.toLong(): Long { + return kotlinclib_shortToLong(this) +} + +fun Short.toFloat(): Float { + return kotlinclib_shortToFloat(this) +} + +fun Short.toDouble(): Double { + return kotlinclib_shortToDouble(this) +} diff --git a/experiments/translator-bc/kotstd/include/Progressions.kt b/experiments/translator-bc/kotstd/include/Progressions.kt new file mode 100644 index 00000000000..ec9bbb3ec09 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Progressions.kt @@ -0,0 +1,50 @@ +package kotlin + +/** + * A progression of values of type `Int`. + */ +public open class IntProgression +constructor +( + start: Int, + endInclusive: Int, + val step: Int +) { + init { + if (step == 0) { + println("Step must be non-zero.") + assert(false) + } + } + + /** + * The first element in the progression. + */ + public val first: Int = start + + /** + * The last element in the progression. + */ + public val last: Int = getProgressionLastElement(start.toInt(), endInclusive.toInt(), step).toInt() + + + fun iterator(): IntIterator = IntIterator(first, last, step) + + /** Checks if the progression is empty. */ + public open fun isEmpty(): Boolean = if (step > 0) first > last else first < last + + //[TODO] equals + + override fun hashCode(): Int = + if (isEmpty()) -1 else (31 * (31 * first + last) + step) + + companion object { + /** + * Creates IntProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Int, rangeEnd: Int, step: Int): IntProgression = IntProgression(rangeStart, rangeEnd, step) + } +} diff --git a/experiments/translator-bc/kotstd/include/Ranges.kt b/experiments/translator-bc/kotstd/include/Ranges.kt new file mode 100644 index 00000000000..4c12faa5e3d --- /dev/null +++ b/experiments/translator-bc/kotstd/include/Ranges.kt @@ -0,0 +1,25 @@ +package kotlin.ranges + +import kotlin.IntProgression +import kotlin.collections.IntIterator + +public class IntRange(val start: Int, val endInclusive: Int) { + val progression = IntProgression(start, endInclusive, 1) + val first: Int + val last: Int + + init { + this.first = progression.first + this.last = progression.last + } + + fun contains(value: Int): Boolean = first <= value && value <= last + + fun isEmpty(): Boolean = first > last + + fun iterator(): IntIterator = progression.iterator() + + override fun hashCode(): Int = + if (isEmpty()) -1 else (31 * first + last) + +} diff --git a/experiments/translator-bc/kotstd/include/ShortArray.kt b/experiments/translator-bc/kotstd/include/ShortArray.kt new file mode 100644 index 00000000000..3d1cf82a40e --- /dev/null +++ b/experiments/translator-bc/kotstd/include/ShortArray.kt @@ -0,0 +1,120 @@ +package kotlin + +external fun kotlinclib_get_short(src: Int, index: Int): Short +external fun kotlinclib_set_short(src: Int, index: Int, value: Short) +external fun kotlinclib_short_size(): Int + + +class ShortArray(var size: Int) { + val data: Int + + /** Returns the number of elements in the array. */ + //size: Int + + init { + this.data = malloc_array(kotlinclib_short_size() * this.size) + var index = 0 + while (index < this.size) { + set(index, 0) + index = index + 1 + } + } + + /** Returns the array element at the given [index]. This method can be called using the index operator. */ + operator fun get(index: Int): Short { + return kotlinclib_get_short(this.data, index) + } + + + /** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */ + operator fun set(index: Int, value: Short) { + kotlinclib_set_short(this.data, index, value) + } + + + fun clone(): ShortArray { + val newInstance = ShortArray(this.size) + var index = 0 + while (index < this.size) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance + } + +} + +fun ShortArray.print() { + var index = 0 + print('[') + while (index < size) { + print(get(index)) + index++ + if (index < size) { + print(';') + print(' ') + } + } + print(']') +} + +fun ShortArray.println() { + this.print() + //println() +} + + +fun ShortArray.copyOf(newSize: Int): ShortArray { + val newInstance = ShortArray(newSize) + var index = 0 + val end = if (newSize > this.size) this.size else newSize + while (index < end) { + val value = this.get(index) + newInstance.set(index, value) + index = index + 1 + } + + while (index < newSize) { + newInstance.set(index, 0) + index = index + 1 + } + + return newInstance +} + +fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray { + val newInstance = ShortArray(toIndex - fromIndex) + var index = fromIndex + while (index < toIndex) { + val value = this.get(index) + newInstance.set(index - fromIndex, value) + index = index + 1 + } + + return newInstance +} + +operator fun ShortArray.plus(element: Short): ShortArray { + val index = size + val result = this.copyOf(index + 1) + result[index] = element + return result +} + +operator fun ShortArray.plus(elements: ShortArray): ShortArray { + val thisSize = size + val arraySize = elements.size + val resultSize = thisSize + arraySize + val newInstance = this.copyOf(resultSize) + var index = thisSize + + while (index < resultSize) { + val value = elements.get(index - thisSize) + newInstance.set(index, value) + index = index + 1 + } + + return newInstance +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/include/WireFormat.kt b/experiments/translator-bc/kotstd/include/WireFormat.kt new file mode 100644 index 00000000000..d43c6e37003 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/WireFormat.kt @@ -0,0 +1,164 @@ + +object WireFormat { + // couple of constants for magic numbers + val TAG_TYPE_BITS: Int = 3 + val TAG_TYPE_MASK: Int = (1 shl TAG_TYPE_BITS) - 1 + val VARINT_INFO_BITS_COUNT: Int = 7 + val VARINT_INFO_BITS_MASK: Int = 0b01111111 // mask for separating lowest 7 bits, where actual information stored + val VARINT_UTIL_BIT_MASK: Int = 0b10000000 // mask for separating highest bit, that indicates next byte presence + val FIXED_32_BYTE_SIZE: Int = 4 + val FIXED_64_BYTE_SIZE: Int = 8 + + fun getTagWireType(tag: Int): WireType { + return WireType.from((tag and TAG_TYPE_MASK).toByte()) + } + + fun getTagFieldNumber(tag: Int): Int { + return tag ushr TAG_TYPE_BITS + } + + // TODO: refactor casts into function overloading as soon as translator will support it + fun getTagSize(fieldNumber: Int, wireType: WireType): Int { + return getVarint32Size((fieldNumber shl 3) or wireType.id) + } + + fun getVarint32Size(value: Int): Int { + var curValue = value + var size = 0 + do { + size += 1 + curValue = curValue ushr VARINT_INFO_BITS_COUNT + } while (curValue != 0) + return size + } + + fun getVarint64Size(value: Long): Int { + var curValue = value + var size = 0 + do { + size += 1 + curValue = curValue ushr VARINT_INFO_BITS_COUNT + }while (curValue != 0L) + return size + } + + fun getZigZag32Size(value: Int): Int { + return getVarint32Size((value shl 1) xor (value shr 31)) + } + + fun getZigZag64Size(value: Long): Int { + return getVarint64Size((value shl 1) xor (value shr 63)) + } + + fun getInt32Size(fieldNumber: Int, value: Int): Int { + return getTagSize(fieldNumber, WireType.VARINT) + getInt32SizeNoTag(value) + } + + fun getInt32SizeNoTag(value: Int): Int { + if (value < 0) { + return getVarint64Size(value.toLong()) + } + return getVarint32Size(value) + } + + fun getUInt32Size(fieldNumber: Int, value: Int): Int { + return getTagSize(fieldNumber, WireType.VARINT) + getUInt32SizeNoTag(value) + } + + fun getUInt32SizeNoTag(value: Int): Int { + return getVarint32Size(value) + } + + fun getInt64Size(fieldNumber: Int, value: Long): Int { + return getTagSize(fieldNumber, WireType.VARINT) + getUInt64SizeNoTag(value) + } + + fun getInt64SizeNoTag(value: Long): Int { + return getVarint64Size(value) + } + + fun getUInt64Size(fieldNumber: Int, value: Long): Int { + return getInt64Size(fieldNumber, value) + } + + fun getUInt64SizeNoTag(value: Long): Int { + return getVarint64Size(value) + } + + fun getBoolSize(fieldNumber: Int, value: Boolean): Int { + val intValue = if (value) 1 else 0 + return getInt32Size(fieldNumber, intValue) + } + + fun getBoolSizeNoTag(value: Boolean): Int { + val intValue = if (value) 1 else 0 + return getInt32SizeNoTag(intValue) + } + + fun getEnumSize(fieldNumber: Int, value: Int): Int { + return getInt32Size(fieldNumber, value) + } + + fun getEnumSizeNoTag(value: Int): Int { + return getInt32SizeNoTag(value) + } + + fun getSInt32Size(fieldNumber: Int, value: Int): Int { + return getTagSize(fieldNumber, WireType.VARINT) + getZigZag32Size(value) + } + + fun getSInt32SizeNoTag(value: Int): Int { + return getZigZag32Size(value) + } + + fun getSInt64Size(fieldNumber: Int, value: Long): Int { + return getTagSize(fieldNumber, WireType.VARINT) + getZigZag64Size(value) + } + + fun getSInt64SizeNoTag(value: Long): Int { + return getZigZag64Size(value) + } + + fun getFixed32Size(fieldNumber: Int, value: Int): Int { + return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE + } + + fun getFixed32SizeNoTag(value: Int): Int { + return FIXED_32_BYTE_SIZE + } + + fun getFixed64Size(fieldNumber: Int, value: Long): Int { + return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE + } + + fun getFixed64SizeNoTag(value: Long): Int { + return FIXED_64_BYTE_SIZE + } + + fun getDoubleSize(fieldNumber: Int, value: Double): Int { + return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE + } + + fun getDoubleSizeNoTag(value: Double): Int { + return FIXED_64_BYTE_SIZE + } + + fun getFloatSize(fieldNumber: Int, value: Float): Int { + return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE + } + + fun getFloatSizeNoTag(value: Float): Int { + return FIXED_32_BYTE_SIZE + } + + fun getBytesSize(fieldNumber: Int, value: ByteArray): Int { + if (value.size == 0) + return 0 + var size = 0 + return value.size + getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + getVarint32Size(value.size) + } + + fun getBytesSizeNoTag(value: ByteArray): Int { + return value.size + getVarint32Size(value.size) + } +} diff --git a/experiments/translator-bc/kotstd/include/WireType.kt b/experiments/translator-bc/kotstd/include/WireType.kt new file mode 100644 index 00000000000..4ffc150fa68 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/WireType.kt @@ -0,0 +1,29 @@ +/** + * Created by Dmitry Savvinov on 7/6/16. + * Enum for possible WireTypes. + * See details at [official Google reference](https://developers.google.com/protocol-buffers/docs/encoding#structure) + */ + +enum class WireType(val id: Int) { + VARINT(0), // int32, int64, uint32, uint64, sint32, sint64, bool, enum + FIX_64(1), // fixed64, sfixed64, double + LENGTH_DELIMITED(2), // string, bytes, embedded messages, packed repeated fields + START_GROUP(3), // groups (deprecated) + END_GROUP(4), // groups (deprecated) + FIX_32(5), // fixed32, sfixed32, float + UNDEFINED(6); // indicates error when parsing from Int + + companion object { + fun from (value: Byte): WireType { + return when (value) { + 0.toByte() -> VARINT + 1.toByte() -> FIX_64 + 2.toByte() -> LENGTH_DELIMITED + 3.toByte() -> START_GROUP + 4.toByte() -> END_GROUP + 5.toByte() -> FIX_32 + else -> UNDEFINED + } + } + } +} diff --git a/experiments/translator-bc/kotstd/include/progressionUtil.kt b/experiments/translator-bc/kotstd/include/progressionUtil.kt new file mode 100644 index 00000000000..a03312f71e4 --- /dev/null +++ b/experiments/translator-bc/kotstd/include/progressionUtil.kt @@ -0,0 +1,71 @@ +package kotlin + +// a mod b (in arithmetical sense) +private fun mod(a: Int, b: Int): Int { + val mod = a % b + return if (mod >= 0) mod else mod + b +} + +private fun mod(a: Long, b: Long): Long { + val mod = a % b + return if (mod >= 0) mod else mod + b +} + +// (a - b) mod c +private fun differenceModulo(a: Int, b: Int, c: Int): Int { + return mod(mod(a, c) - mod(b, c), c) +} + +private fun differenceModulo(a: Long, b: Long, c: Long): Long { + return mod(mod(a, c) - mod(b, c), c) +} + +/** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative + * [step]. + * + * No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * `step > 0` and `start >= end`, or `step < 0` and`start >= end`. + * @param start first element of the progression + * @param end ending bound for the progression + * @param step increment, or difference of successive elements in the progression + * @return the final element of the progression + * @suppress + */ +fun getProgressionLastElement(start: Int, end: Int, step: Int): Int { + if (step > 0) { + return end - differenceModulo(end, start, step) + } else if (step < 0) { + return end + differenceModulo(start, end, -step) + } else { + println("Step is zero.") + assert(false) + return -1 + } +} + +/** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative + * [step]. + * + * No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * `step > 0` and `start >= end`, or `step < 0` and`start >= end`. + * @param start first element of the progression + * @param end ending bound for the progression + * @param step increment, or difference of successive elements in the progression + * @return the final element of the progression + * @suppress + */ +internal fun getProgressionLastElement(start: Long, end: Long, step: Long): Long { + if (step > 0) { + return end - differenceModulo(end, start, step) + } else if (step < 0) { + return end + differenceModulo(start, end, -step) + } else { + println("Step is zero.") + assert(false) + return -1L + } +} diff --git a/experiments/translator-bc/kotstd/libc/array_c.c b/experiments/translator-bc/kotstd/libc/array_c.c new file mode 100644 index 00000000000..8b80a3534cc --- /dev/null +++ b/experiments/translator-bc/kotstd/libc/array_c.c @@ -0,0 +1,32 @@ +extern char *malloc(int size); + +int malloc_array(int x) { + return (int) malloc(x); +} + +char kotlinclib_get_byte(int data, int index) { + return *((char *) data + index); +} + +void kotlinclib_set_byte(int data, int index, char value) { + char *ptr = (char *) data; + *(ptr + index) = value; +} + +int kotlinclib_get_int(int data, int index) { + return *((int *) data + index); +} + +void kotlinclib_set_int(int data, int index, int value) { + int *ptr = (int *) data; + *(ptr + index) = value; +} + +short kotlinclib_get_short(int data, int index) { + return *((short *) data + index); +} + +void kotlinclib_set_short(int data, int index, short value) { + short *ptr = (short *) data; + *(ptr + index) = value; +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/libc/assert_c.c b/experiments/translator-bc/kotstd/libc/assert_c.c new file mode 100644 index 00000000000..e526eaaca41 --- /dev/null +++ b/experiments/translator-bc/kotstd/libc/assert_c.c @@ -0,0 +1,9 @@ +#include +#include + +void assert_c(int value) { + if (!value) { + printf("Exception in thread \"main\" java.lang.AssertionError: Assertion failed\n"); + abort(); + } +} \ No newline at end of file diff --git a/experiments/translator-bc/kotstd/libc/memory.c b/experiments/translator-bc/kotstd/libc/memory.c new file mode 100644 index 00000000000..18844c7c0ef --- /dev/null +++ b/experiments/translator-bc/kotstd/libc/memory.c @@ -0,0 +1,82 @@ + +#define STATIC_AREA_SIZE 30000 +#define DYNAMIC_AREA_SIZE 30000 + +#define STATIC_HEAP 0 +#define DYNAMIC_HEAP 1 + +#ifdef ARM + +char static_area[STATIC_AREA_SIZE]; +char dynamic_area[DYNAMIC_AREA_SIZE]; + +char* heaps[2] = { + (char*) static_area, + (char*) dynamic_area +}; + +int heap_tails[2] = {0, 0}; +int active_heap = STATIC_HEAP; + +int dynamic_heap_consume = 0; +int dynamic_heap_max = 0; + +#else +char* malloc(int); +#endif + +#ifdef DBG + static int total = 0; + int printf(const char * restrict format, ... ); +#endif + +char* malloc_heap(int size) { +#ifdef ARM + char* ptr = heaps[active_heap] + heap_tails[active_heap]; + heap_tails[active_heap] += size; + + return ptr; + +#else + #ifdef DBG + total = total + size; + printf("Alloc [%d] TOTAL: [%d]\n", size, total); + #endif + return malloc(size); +#endif +} + +void set_active_heap(int heap) { +#ifdef ARM + active_heap = heap; +#endif +} + +void clean_dynamic_heap() { +#ifdef ARM + dynamic_heap_consume += heap_tails[DYNAMIC_HEAP]; + if (heap_tails[DYNAMIC_HEAP] > dynamic_heap_max) { + dynamic_heap_max = heap_tails[DYNAMIC_HEAP]; + } + + heap_tails[DYNAMIC_HEAP] = 0; +#endif +} + +#ifdef ARM +int dynamic_heap_tail() { + return heap_tails[DYNAMIC_HEAP]; +} + +int static_heap_tail() { + return heap_tails[STATIC_HEAP]; +} + +int dynamic_heap_max_bytes() { + return dynamic_heap_max; +} + +int dynamic_heap_total() { + return dynamic_heap_consume; +} +#endif diff --git a/experiments/translator-bc/kotstd/libc/primitives_c.c b/experiments/translator-bc/kotstd/libc/primitives_c.c new file mode 100644 index 00000000000..5f1eb3c2f52 --- /dev/null +++ b/experiments/translator-bc/kotstd/libc/primitives_c.c @@ -0,0 +1,57 @@ +#define MAKE_CONVERT(from, from_type, to, to_type) to_type kotlinclib_ ## from ## To ## to ( from_type value ) { return (to_type) value;} + + +MAKE_CONVERT(int, int, Byte, char) +MAKE_CONVERT(int, int, Char, char) +MAKE_CONVERT(int, int, Short, short) +MAKE_CONVERT(int, int, Long, long) +MAKE_CONVERT(int, int, Float, float) +MAKE_CONVERT(int, int, Double, double) + + +MAKE_CONVERT(byte, char, Char, char) +MAKE_CONVERT(byte, char, Short, short) +MAKE_CONVERT(byte, char, Int, int) +MAKE_CONVERT(byte, char, Long, long) +MAKE_CONVERT(byte, char, Float, float) +MAKE_CONVERT(byte, char, Double, double) + + +MAKE_CONVERT(char, char, Byte, char) +MAKE_CONVERT(char, char, Short, short) +MAKE_CONVERT(char, char, Int, int) +MAKE_CONVERT(char, char, Long, long) +MAKE_CONVERT(char, char, Float, float) +MAKE_CONVERT(char, char, Double, double) + + +MAKE_CONVERT(short, short, Byte, char) +MAKE_CONVERT(short, short, Char, char) +MAKE_CONVERT(short, short, Int, int) +MAKE_CONVERT(short, short, Long, long) +MAKE_CONVERT(short, short, Float, float) +MAKE_CONVERT(short, short, Double, double) + + +MAKE_CONVERT(long, long, Byte, char) +MAKE_CONVERT(long, long, Char, char) +MAKE_CONVERT(long, long, Short, short) +MAKE_CONVERT(long, long, Int, int) +MAKE_CONVERT(long, long, Float, float) +MAKE_CONVERT(long, long, Double, double) + + +MAKE_CONVERT(float, float, Byte, char) +MAKE_CONVERT(float, float, Char, char) +MAKE_CONVERT(float, float, Short, short) +MAKE_CONVERT(float, float, Int, int) +MAKE_CONVERT(float, float, Long, long) +MAKE_CONVERT(float, float, Double, double) + + +MAKE_CONVERT(double, double, Byte, char) +MAKE_CONVERT(double, double, Char, char) +MAKE_CONVERT(double, double, Short, short) +MAKE_CONVERT(double, double, Int, int) +MAKE_CONVERT(double, double, Long, long) +MAKE_CONVERT(double, double, Float, float) \ No newline at end of file diff --git a/experiments/translator-bc/run_one_test.sh b/experiments/translator-bc/run_one_test.sh new file mode 100755 index 00000000000..cd3cb154876 --- /dev/null +++ b/experiments/translator-bc/run_one_test.sh @@ -0,0 +1,78 @@ +#!/bin/bash +green='\033[0;32m' +red='\033[0;31m' +lightRed='\033[1;31m' +orange='\033[0;33m' +KOTSTD='../kotstd/kt' + +cd ../translator + +i=$1 +TEST=`basename $i ".txt"` +DIRECTORY="src/test/kotlin/tests" +MAIN="$DIRECTORY/$TEST/linked/main.c" +rm -f $DIRECTORY/$TEST/linked/* +mkdir -p $DIRECTORY/$TEST/linked + +echo "#include " >> $MAIN +echo "#include " >> $MAIN +echo "#include " >> $MAIN + +echo "int main(){" >> $MAIN +echo "printf(\"%stest: $TEST%s\n\", \"\x1B[33m\", \"\x1B[0m\");" >> $MAIN +cat "$i" | while read LINE +do + echo " assert($LINE);" >> $MAIN + echo " printf(\"%s[OK]:%s $LINE\n\", \"\x1B[32m\", \"\x1B[0m\");" >> $MAIN +done + +echo "printf(\"TEST RESULT: OK\n\");" >> $MAIN +echo "return 0;}" >> $MAIN + +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Error somewhere in main.c generation${nc}" + exit 1 +fi + +clang-3.6 -S -emit-llvm $DIRECTORY/$TEST/linked/main.c -o $DIRECTORY/$TEST/linked/main.ll -Wno-implicit-function-declaration +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Error building main.c${nc}" + exit 1 +fi + +cp ../kotstd/build/stdlib_x86.ll $DIRECTORY/$TEST/linked/ +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Error copying ../kotstd/build/stdlib_x86.ll to ${DIRECTORY}/${TEST}/linked/${nc}" + exit 1 +fi + +if [ -f "$DIRECTORY/$TEST/$TEST.c" ] + then + clang-3.6 -S -emit-llvm "$DIRECTORY/$TEST/$TEST.c" -o $DIRECTORY/$TEST/linked/$TEST"_c.ll" -Wno-implicit-function-declaration + if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Error building: ${DIRECTORY}/${TEST}/linked/${TEST}_c.ll${nc}" + fi +fi + +java -jar build/libs/translator-1.0.jar -I $KOTSTD $DIRECTORY/$TEST/$TEST.kt > $DIRECTORY/$TEST/linked/$TEST.ll + +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Translation error: ${DIRECTORY}/$TEST/${TEST}.kt${nc}" +fi + +llvm-link-3.6 -S $DIRECTORY/$TEST/linked/*.ll > $DIRECTORY/$TEST/linked/run.ll +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${red}Error linking with llvm${nc}" +fi + +lli-3.6 $DIRECTORY/$TEST/linked/run.ll +if [ $? -ne 0 ]; then + echo -e "${orange}test: ${TEST}${nc}" + echo -e "${lightRed}Error running test${nc}" +fi diff --git a/experiments/translator-bc/run_tests.sh b/experiments/translator-bc/run_tests.sh new file mode 100755 index 00000000000..d9ff0f3031b --- /dev/null +++ b/experiments/translator-bc/run_tests.sh @@ -0,0 +1,104 @@ +#!/bin/bash +green='\033[0;32m' +red='\033[0;31m' +lightRed='\033[1;31m' +orange='\033[0;33m' +nc='\033[0m' +KOTSTD='../kotstd/kt' + +if [ "$3" == "--debug" ]; then + cd ../kotstd && make clean && make debug +else + cd ../kotstd && make clean && make +fi + +if [ $? -ne 0 ]; then + echo -e "${red}Error building kotstd lib${nc}" + exit 1 +fi + +cd ../translator + +DIRECTORY="src/test/kotlin/tests" +TESTS=$( ls $DIRECTORY/*/*.txt $1) # Note that "ls $DIRECTORY/input $1" is wrong. Why? Because it's bash. + +if [ "$2" == "--proto" ]; then + TESTS=$( ls $DIRECTORY/*/proto*.txt $1) +fi +total_scripts=0 +successful_scripts=0 + +for i in $TESTS; do + TEST=`basename $i ".txt"` + MAIN="$DIRECTORY/$TEST/linked/main.c" + rm -f $DIRECTORY/$TEST/linked/* + mkdir -p $DIRECTORY/$TEST/linked + successful=1 + echo -e "${orange}test: ${TEST}${nc}" + echo "#include " >> $MAIN + echo "#include " >> $MAIN + echo "#include " >> $MAIN + + echo "int main(){" >> $MAIN + cat "$i" | while read LINE + do + echo " assert($LINE);" >> $MAIN + echo " printf(\"%s[OK]:%s $LINE\n\", \"\x1B[32m\", \"\x1B[0m\");" >> $MAIN + done + + echo "printf(\"TEST RESULT: OK\n\");" >> $MAIN + echo "return 0;}" >> $MAIN + + if [ $? -ne 0 ]; then + echo -e "${red}Error somewhere in main.c generation${nc}" + exit 1 + fi + + clang-3.6 -S -emit-llvm $DIRECTORY/$TEST/linked/main.c -o $DIRECTORY/$TEST/linked/main.ll -Wno-implicit-function-declaration + if [ $? -ne 0 ]; then + echo -e "${red}Error building main.c${nc}" + exit 1 + fi + + + cp ../kotstd/build/stdlib_x86.ll $DIRECTORY/$TEST/linked/ + if [ $? -ne 0 ]; then + echo -e "${red}Error copying ../kotstd/build/stdlib_x86.ll to ${DIRECTORY}/${TEST}/linked/${nc}" + exit 1 + fi + + if [ -f "$DIRECTORY/$TEST/$TEST.c" ] + then + clang-3.6 -S -emit-llvm "$DIRECTORY/$TEST/$TEST.c" -o $DIRECTORY/$TEST/linked/$TEST"_c.ll" -Wno-implicit-function-declaration + if [ $? -ne 0 ]; then + echo -e "${red}Error building: ${DIRECTORY}/${TEST}/linked/${TEST}_c.ll${nc}" + fi + fi + + java -jar build/libs/translator-1.0.jar -I $KOTSTD $DIRECTORY/$TEST/$TEST.kt > $DIRECTORY/$TEST/linked/$TEST.ll + + if [ $? -ne 0 ]; then + echo -e "${red}Translation error: ${DIRECTORY}/$TEST/${TEST}.kt${nc}" + successful=0 + fi + + llvm-link-3.6 -S $DIRECTORY/$TEST/linked/*.ll > $DIRECTORY/$TEST/linked/run.ll + if [ $? -ne 0 ]; then + echo -e "${red}Error linking with llvm${nc}" + successful=0 + fi + + lli-3.6 $DIRECTORY/$TEST/linked/run.ll + if [ $? -ne 0 ]; then + echo -e "${lightRed}Error running test${nc}" + successful=0 + fi + + if [ "$2" == "--once" ]; then + exit + fi + successful_scripts=$((successful_scripts+successful)) + total_scripts=$((total_scripts+1)) +done + +echo -e "Result: ${orange} [${successful_scripts}]/[${total_scripts}]" diff --git a/experiments/translator-bc/settings.gradle b/experiments/translator-bc/settings.gradle new file mode 100644 index 00000000000..4636f58628e --- /dev/null +++ b/experiments/translator-bc/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'translator' + diff --git a/experiments/translator-bc/src/main/kotlin/DefaultArguments.kt b/experiments/translator-bc/src/main/kotlin/DefaultArguments.kt new file mode 100644 index 00000000000..4f5bfcbd9a1 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/DefaultArguments.kt @@ -0,0 +1,39 @@ +import com.jshmrsn.karg.Arguments +import com.jshmrsn.karg.RawArguments + +class DefaultArguments(raw: RawArguments) : Arguments(raw, name = "default") { + + val includeDir = optionalParameter( + name = "include directory", + aliasNames = listOf("include"), + shortNames = listOf('I') + ) + + val arm = optionalFlag( + name = "arm", + description = "enable arm build", + aliasNames = listOf("arm"), + default = false + ) + + val output = optionalParameter( + name = "output", + description = "output file path", + shortNames = listOf('o') + ) + + val mainClass = optionalParameter( + name = "main class", + aliasNames = listOf("main"), + default = "main", + shortNames = listOf('M') + ) + + //[TODO] files with [] or another marking + val sources = positionalArguments( + name = "sources", + description = "source files", + minCount = 1 + ) + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/main.kt b/experiments/translator-bc/src/main/kotlin/main.kt new file mode 100644 index 00000000000..5a91b7b8633 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/main.kt @@ -0,0 +1,30 @@ +import com.intellij.openapi.util.Disposer +import com.jshmrsn.karg.parseArguments +import org.kotlinnative.translator.ProjectTranslator +import org.kotlinnative.translator.TranslationState +import java.io.* + +fun main(args: Array) { + // TODO make good help message (ex. is rm --help) + val arguments = parseArguments(args, ::DefaultArguments) + val disposer = Disposer.newDisposable() + val analyzedFiles = arguments.sources.toMutableList() + + if (arguments.includeDir != null) { + val libraryFiles = File(arguments.includeDir).walk().filter { !it.isDirectory }.map { it.absolutePath } + analyzedFiles.addAll(libraryFiles) + } + + val translationState = TranslationState.createTranslationState(analyzedFiles, disposer, arguments.mainClass, arguments.arm) + val code:String = ProjectTranslator( + translationState.environment.getSourceFiles(), + translationState + ).generateCode() + + if (arguments.output == null) { + println(code) + } else { + val output = File(arguments.output) + output.writeText(code) + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt new file mode 100644 index 00000000000..8974b5042da --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -0,0 +1,77 @@ +package org.kotlinnative.translator + +import org.jetbrains.kotlin.psi.* +import org.kotlinnative.translator.codegens.ClassCodegen +import org.kotlinnative.translator.codegens.FunctionCodegen +import org.kotlinnative.translator.codegens.ObjectCodegen +import org.kotlinnative.translator.codegens.PropertyCodegen + +class ProjectTranslator(val files: List, + val state: TranslationState) { + private var codeBuilder = state.codeBuilder + + fun generateCode(): String { + with(files) { + map { addClassDeclarations(it) } + map { addObjectDeclarations(it) } + map { addFunctionDeclarations(it) } + map { addPropertyDeclarations(it) } + } + generateProjectBody() + return codeBuilder.toString() + } + + fun addFunctionDeclarations(file: KtFile) { + val variableManager = VariableManager(state.globalVariableCollection) + for (declaration in file.declarations.filterIsInstance()) { + val function = FunctionCodegen(state, variableManager, declaration, codeBuilder) + if (function.external) { + state.externalFunctions.put(function.fullName, function) + } else { + state.functions.put(function.fullName, function) + } + } + } + + fun addClassDeclarations(file: KtFile) { + val variableManager = VariableManager(state.globalVariableCollection) + for (declaration in file.declarations.filterIsInstance()) { + val codegen = ClassCodegen(state, variableManager, declaration, codeBuilder) + state.classes.put(codegen.structName, codegen) + } + } + + fun addPropertyDeclarations(file: KtFile) { + val variableManager = VariableManager(state.globalVariableCollection) + for (declaration in file.declarations.filterIsInstance()) { + val property = PropertyCodegen(state, variableManager, declaration, codeBuilder) + state.properties.put(declaration.name!!, property) + } + } + + fun addObjectDeclarations(file: KtFile) { + val variableManager = VariableManager(state.globalVariableCollection) + for (declaration in file.declarations.filterIsInstance()) { + val codegen = ObjectCodegen(state, variableManager, declaration, codeBuilder) + state.objects.put(codegen.structName, codegen) + } + } + + private fun generateProjectBody() { + with(state) { + properties.values.map { it.generate() } + objects.values.map { it.prepareForGenerate() } + classes.values.map { it.prepareForGenerate() } + objects.values.map { it.generate() } + classes.values.map { it.generate() } + externalFunctions.values.map { it.generate() } + functions.values.filter { it.isExtensionDeclaration }.map { it.generate() } + functions.values.filter { !it.isExtensionDeclaration }.map { it.generate() } + } + + if (state.mainFunction != "main") { + codeBuilder.declareEntryPoint(state.mainFunction) + } + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt new file mode 100644 index 00000000000..8b929412fdc --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -0,0 +1,116 @@ +package org.kotlinnative.translator + +import com.intellij.openapi.Disposable +import org.jetbrains.kotlin.analyzer.AnalysisResult +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.config.getModuleName +import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.config.addKotlinSourceRoots +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM +import org.jetbrains.kotlin.utils.PathUtil +import org.kotlinnative.translator.codegens.ClassCodegen +import org.kotlinnative.translator.codegens.FunctionCodegen +import org.kotlinnative.translator.codegens.ObjectCodegen +import org.kotlinnative.translator.codegens.PropertyCodegen +import org.kotlinnative.translator.exceptions.TranslationException +import org.kotlinnative.translator.llvm.LLVMBuilder +import org.kotlinnative.translator.llvm.LLVMVariable +import java.util.* + + +class TranslationState +private constructor +( + val environment: KotlinCoreEnvironment, + val bindingContext: BindingContext, + val mainFunction: String, arm: Boolean +) { + var externalFunctions = HashMap() + var functions = HashMap() + var classes = HashMap() + var objects = HashMap() + var properties = HashMap() + val codeBuilder = LLVMBuilder(arm) + val extensionFunctions = HashMap>() + val globalVariableCollection = HashMap() + + init { + POINTER_ALIGN = if (arm) 4 else 8 + POINTER_SIZE = if (arm) 4 else 8 + } + + companion object { + var POINTER_ALIGN = 4 + var POINTER_SIZE = 4 + + fun createTranslationState(sources: List, disposer: Disposable, mainFunction: String, arm: Boolean = false): TranslationState { + + val configuration = CompilerConfiguration() + val messageCollector = object : MessageCollector { + private var hasError = false + + override fun hasErrors(): Boolean = hasError + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { + if (severity.isError) { + System.err.println("[${severity.toString()}]${location.path} ${location.line}:${location.column} $message") + hasError = true + } + } + } + + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) + configuration.put(JVMConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME) + + configuration.addKotlinSourceRoots(sources) + + val environment = KotlinCoreEnvironment.createForProduction(disposer, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + val bindingContext = analyze(environment)?.bindingContext ?: throw TranslationException("Can't initialize binding context for project") + + return TranslationState(environment, bindingContext, mainFunction, arm) + } + + private fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? { + val collector = environment.configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + + val analyzer = AnalyzerWithCompilerReport(collector) + analyzer.analyzeAndReport(environment.getSourceFiles(), object : AnalyzerWithCompilerReport.Analyzer { + override fun analyze(): AnalysisResult { + val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace() + val moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, environment.getModuleName()) + + return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( + moduleContext, + environment.getSourceFiles(), + sharedTrace, + environment.configuration.get(JVMConfigurationKeys.MODULES), + environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), + JvmPackagePartProvider(environment)) + } + + override fun reportEnvironmentErrors() { + val files = environment.configuration.jvmClasspathRoots + val runtimes = files.map { it.canonicalFile }.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() } + collector.report(CompilerMessageSeverity.ERROR, runtimes.joinToString { it.path }, CompilerMessageLocation.NO_LOCATION) + System.err.println(runtimes.joinToString { it.toString() }) + } + }) + + return if (analyzer.hasErrors()) null else analyzer.analysisResult + } + + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt new file mode 100644 index 00000000000..bb0ff4bb229 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -0,0 +1,48 @@ +package org.kotlinnative.translator + +import org.kotlinnative.translator.llvm.LLVMScope +import org.kotlinnative.translator.llvm.LLVMVariable +import org.kotlinnative.translator.llvm.types.LLVMType +import java.util.* + +class VariableManager(val globalVariableCollection: HashMap) { + + private var fileVariableCollectionTree = HashMap>>() + + private companion object UniqueGenerator { + private var unique = 0 + fun generateUniqueString() = + ".unique." + unique++ + } + + operator fun get(variableName: String): LLVMVariable? { + return fileVariableCollectionTree[variableName]?.peek()?.first ?: globalVariableCollection[variableName] + } + + operator fun contains(variableName: String): Boolean { + return (fileVariableCollectionTree.contains(variableName) && !fileVariableCollectionTree[variableName]!!.empty()) || globalVariableCollection.containsKey(variableName) + } + + fun pullOneUpwardLevelVariable(variableName: String) { + fileVariableCollectionTree[variableName]?.pop() + } + + fun pullUpwardsLevel(level: Int) { + fileVariableCollectionTree.forEach { s, stack -> while (!stack.empty() && stack.peek().second >= level) stack.pop() } + } + + fun addVariable(name: String, variable: LLVMVariable, level: Int) { + val stack = fileVariableCollectionTree.getOrDefault(name, Stack>()) + stack.push(Pair(variable, level)) + fileVariableCollectionTree.put(name, stack) + } + + fun addGlobalVariable(name: String, variable: LLVMVariable) { + globalVariableCollection.put(name, variable) + } + + fun receiveVariable(name: String, type: LLVMType, scope: LLVMScope, pointer: Int): LLVMVariable { + return LLVMVariable("managed${generateUniqueString()}.$name", type, name, scope, pointer) + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/BlockCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/BlockCodegen.kt new file mode 100644 index 00000000000..be04b431c66 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/BlockCodegen.kt @@ -0,0 +1,1121 @@ +package org.kotlinnative.translator.codegens + +import com.intellij.psi.PsiElement +import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.tree.IElementType +import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.* +import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument +import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument +import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument +import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl +import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.llvm.* +import org.kotlinnative.translator.llvm.types.* +import java.lang.RuntimeException +import java.lang.UnsupportedOperationException +import java.rmi.UnexpectedException +import kotlin.comparisons.compareBy + + +abstract class BlockCodegen(val state: TranslationState, + val variableManager: VariableManager, + val codeBuilder: LLVMBuilder) { + + val topLevelScopeDepth = 2 + var returnType: LLVMVariable? = null + + fun evaluateCodeBlock(expr: PsiElement?, + startLabel: LLVMLabel? = null, + nextIterationLabel: LLVMLabel? = null, + breakLabel: LLVMLabel? = null, + scopeDepth: Int = 0, + isBlock: Boolean = true) { + codeBuilder.markWithLabel(startLabel) + if (isBlock) { + expressionWalker(expr, breakLabel, scopeDepth) + } else { + var result = evaluateExpression(expr, scopeDepth) + ?: throw UnexpectedException("Can't evaluate expression " + expr!!.text) + when (result) { + is LLVMVariable -> { + if (result.type is LLVMReferenceType) { + generateReferenceReturn(result) + } else { + result = codeBuilder.receivePointedArgument(result, requirePointer = 0) + codeBuilder.addReturnOperator(result) + } + } + else -> codeBuilder.addAnyReturn(result.type, result.toString()) + } + + } + codeBuilder.addUnconditionalJump(nextIterationLabel ?: return) + } + + fun evaluateExpression(expr: PsiElement?, + scopeDepth: Int): LLVMSingleValue? = + when (expr) { + is KtBlockExpression -> { + expressionWalker(expr.lBrace, breakLabel = null, scopeDepth = scopeDepth + 1) + null + } + is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) + is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth) + is KtPrefixExpression -> evaluatePrefixExpression(expr, scopeDepth) + is KtConstantExpression -> evaluateConstantExpression(expr) + is KtCallExpression -> evaluateCallExpression(expr, scopeDepth) + is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth) + is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr) + is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth) + is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth) + is KtIfExpression -> evaluateIfOperator(expr, scopeDepth + 1) + is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr) + is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth) + is KtThisExpression -> evaluateThisExpression() + is KtSafeQualifiedExpression -> evaluateSafeAccessExpression(expr, scopeDepth) + is KtParenthesizedExpression -> evaluateExpression(expr.expression, scopeDepth) + null -> null + is PsiElement -> evaluatePsiElement(expr, scopeDepth) + else -> throw UnsupportedOperationException() + } + + fun evaluateConstructorDelegationReferenceExpression(expr: KtConstructorDelegationReferenceExpression, + structCodegen: StructCodegen, + constructorArguments: List, + scopeDepth: Int): LLVMSingleValue? { + val targetCall = state.bindingContext.get(BindingContext.CALL, expr) + val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth) + val args = codeBuilder.loadArgsIfRequired(names, constructorArguments) + return evaluateConstructorCallExpression( + LLVMVariable(structCodegen.structName + LLVMType.mangleFunctionArguments(names), + structCodegen.type, + scope = LLVMVariableScope()), + args) + } + + fun evaluateMemberMethodOrField(receiver: LLVMVariable, + selectorName: String, + scopeDepth: Int, + call: PsiElement? = null): LLVMSingleValue? { + val type = receiver.type as LLVMReferenceType + val clazz = resolveClassOrObjectLocation(type) + ?: throw UnexpectedException(type.toString() + receiver.toString()) + val field = clazz.fieldsIndex[selectorName] + + if (field != null) { + return evaluateClassField(receiver, field) + } else { + return evaluateMemberMethod(receiver, clazz, scopeDepth, call as? KtCallExpression + ?: throw UnexpectedException("$receiver:$selectorName")) + } + } + + fun addPrimitiveBinaryOperation(operator: IElementType, + firstOp: LLVMSingleValue, + secondOp: LLVMSingleValue, + referenceName: KtSimpleNameExpression? = null): LLVMVariable { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + val secondNativeOp = codeBuilder.receiveNativeValue(secondOp) + + val llvmExpression = when (operator) { + KtTokens.PLUS -> firstOp.type.operatorPlus(firstNativeOp, secondNativeOp) + KtTokens.MINUS -> firstOp.type.operatorMinus(firstNativeOp, secondNativeOp) + KtTokens.MUL -> firstOp.type.operatorTimes(firstNativeOp, secondNativeOp) + KtTokens.DIV -> firstOp.type.operatorDiv(firstNativeOp, secondNativeOp) + KtTokens.LT -> firstOp.type.operatorLt(firstNativeOp, secondNativeOp) + KtTokens.GT -> firstOp.type.operatorGt(firstNativeOp, secondNativeOp) + KtTokens.LTEQ -> firstOp.type.operatorLeq(firstNativeOp, secondNativeOp) + KtTokens.GTEQ -> firstOp.type.operatorGeq(firstNativeOp, secondNativeOp) + KtTokens.EQEQ -> + if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) { + val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1) + val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1) + firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument) + } else + firstOp.type.operatorEq(firstNativeOp, secondNativeOp) + KtTokens.EQEQEQ -> { + val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1) + val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1) + firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument) + } + KtTokens.EXCLEQ -> { + if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) { + val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1) + val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1) + firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument) + } else + firstOp.type.operatorNeq(firstNativeOp, secondNativeOp) + } + KtTokens.EXCLEQEQEQ -> { + val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1) + val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1) + firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument) + } + KtTokens.EQ -> { + if (secondOp.type is LLVMNullType) { + codeBuilder.storeNull(firstOp as LLVMVariable) + return firstOp + } + + val result = firstOp as LLVMVariable + val sourceArgument: LLVMSingleValue + if ((firstOp.pointer == 2) && secondOp.type.isPrimitive && (secondOp.pointer == 0)) { + sourceArgument = codeBuilder.getNewVariable(secondOp.type, pointer = 1) + codeBuilder.allocStaticVar(sourceArgument, asValue = true) + codeBuilder.storeVariable(sourceArgument, secondOp) + } else { + sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp + } + + codeBuilder.storeVariable(result, sourceArgument) + return result + } + else -> addPrimitiveReferenceOperationByName(referenceName!!.getReferencedName(), firstOp, secondNativeOp) + } + return codeBuilder.saveExpression(llvmExpression) + } + + private fun expressionWalker(expr: PsiElement?, + breakLabel: LLVMLabel?, + scopeDepth: Int) { + when (expr) { + is KtBlockExpression -> expressionWalker(expr.lBrace, breakLabel, scopeDepth + 1) + is KtProperty -> evaluateValExpression(expr, scopeDepth) + is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth) + is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) + is KtCallExpression -> evaluateCallExpression(expr, scopeDepth) + is KtDoWhileExpression -> evaluateDoWhileExpression(expr, scopeDepth + 1) + is KtBreakExpression -> evaluateBreakExpression(breakLabel!!) + is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth) + is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth) + is PsiElement -> evaluateExpression(expr.firstChild, scopeDepth + 1) + null -> { + variableManager.pullUpwardsLevel(scopeDepth) + return + } + else -> UnsupportedOperationException() + } + + expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments(), breakLabel, scopeDepth) + } + + private fun evaluateBreakExpression(breakLabel: LLVMLabel) = + codeBuilder.addUnconditionalJump(breakLabel) + + private fun evaluateDoWhileExpression(expr: KtDoWhileExpression, scopeDepth: Int) = + executeWhileBlock(expr.condition!!, expr.body!!, scopeDepth, checkConditionBeforeExecute = false) + + private fun evaluateThisExpression(): LLVMSingleValue? = + variableManager["this"] + + fun evaluateStringTemplateExpression(expr: KtStringTemplateExpression): LLVMSingleValue? { + val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr) as TypedCompileTimeConstant + val value = receiveValue.getValue(receiveValue.type) ?: return null + val variable = + variableManager.receiveVariable(".str", + LLVMStringType(value.toString().length, isLoaded = false), + LLVMVariableScope(), + pointer = 0) + + codeBuilder.addStringConstant(variable, value.toString()) + return variable + } + + private fun evaluateCallableReferenceExpression(expr: KtCallableReferenceExpression): LLVMSingleValue? { + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! + val result = LLVMInstanceOfStandardType(expr.callableReference.text, kotlinType, LLVMVariableScope(), state) + return LLVMVariable(result.label + (result.type as LLVMFunctionType).mangleArgs(), + result.type, + result.kotlinName, + result.scope, + result.pointer) + } + + private fun evaluateSafeAccessExpression(expr: KtSafeQualifiedExpression, + scopeDepth: Int): LLVMSingleValue? { + val receiver = expr.receiverExpression + val selector = expr.selectorExpression + + val left = evaluateExpression(receiver, scopeDepth)!! + val loadedLeft = codeBuilder.receiveNativeValue(left) + val expectedType = LLVMMapStandardType(state.bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expr)!!, state) as LLVMReferenceType + + val result = codeBuilder.getNewVariable(expectedType, pointer = 2) + codeBuilder.allocStaticVar(result, pointer = true) + + val condition = left.type.operatorEq(loadedLeft, LLVMVariable("", LLVMNullType())) + val nullLabel = codeBuilder.getNewLabel(prefix = "safe.access") + val notNullLabel = codeBuilder.getNewLabel(prefix = "safe.access") + val endLabel = codeBuilder.getNewLabel(prefix = "safe.access") + + val conditionResult = codeBuilder.saveExpression(condition) + codeBuilder.addCondition(conditionResult, nullLabel, notNullLabel) + + codeBuilder.markWithLabel(nullLabel) + codeBuilder.storeNull(result) + codeBuilder.addUnconditionalJump(endLabel) + + codeBuilder.markWithLabel(notNullLabel) + val right = evaluateDotBody(receiver, selector!!, scopeDepth) as LLVMVariable + val rightLoaded = codeBuilder.loadAndGetVariable(right) + codeBuilder.storeVariable(result, rightLoaded) + codeBuilder.addUnconditionalJump(endLabel) + + codeBuilder.markWithLabel(endLabel) + + return result + } + + private fun evaluateDotExpression(expr: KtDotQualifiedExpression, + scopeDepth: Int): LLVMSingleValue? { + val receiverExpr = expr.receiverExpression + val selectorExpr = expr.selectorExpression!! + + return evaluateDotBody(receiverExpr, selectorExpr, scopeDepth) + } + + private fun evaluateDotBody(receiverExpr: KtExpression, + selectorExpr: KtExpression, + scopeDepth: Int): LLVMSingleValue? { + var receiverName = receiverExpr.text + var receiver = when (receiverExpr) { + is KtCallExpression, + is KtPrefixExpression, + is KtPostfixExpression, + is KtBinaryExpression -> evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable + is KtDotQualifiedExpression -> { + val codegen = resolveCodegenByName(receiverName) + if (codegen != null) null else evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable + } + is KtNameReferenceExpression -> { + val referenceContext = state.bindingContext.get(BindingContext.REFERENCE_TARGET, receiverExpr) + receiverName = referenceContext!!.fqNameSafe.asString() + when (referenceContext) { + is PropertyDescriptorImpl -> { + val receiverThis = variableManager["this"]!! + evaluateMemberMethodOrField(receiverThis, receiverName, topLevelScopeDepth, call = null)!! as LLVMVariable + } + else -> variableManager[receiverName] + } + } + else -> variableManager[receiverName] + } + + val isExtension = selectorExpr is KtCallExpression && + selectorExpr.getFunctionResolvedCallWithAssert(state.bindingContext).extensionReceiver != null + + if (isExtension) { + return evaluateExtensionExpression(receiverExpr, receiver, selectorExpr as KtCallExpression, scopeDepth) + } + + val selectorName = when (selectorExpr) { + is KtNameReferenceExpression -> state.bindingContext.get(BindingContext.REFERENCE_TARGET, selectorExpr) + ?.fqNameSafe?.asString() ?: selectorExpr.text + else -> selectorExpr.text + } + + if (receiver != null) { + if (receiver.pointer == 2) { + receiver = codeBuilder.loadAndGetVariable(receiver) + } + when (receiver.type) { + is LLVMReferenceType -> return evaluateMemberMethodOrField(receiver, selectorName, scopeDepth, selectorExpr) + else -> return evaluateExtensionExpression(receiverExpr, receiver, selectorExpr as KtCallExpression, scopeDepth) + } + } + + val clazz = resolveCodegen(receiverExpr) + ?: return evaluateExtensionExpression(receiverExpr, receiver, selectorExpr as? KtCallExpression + ?: throw UnexpectedException("Failed evaluate dot expression: " + selectorExpr.text), scopeDepth) + return evaluateClassScopedDotExpression(clazz, selectorExpr, scopeDepth, receiver) + } + + private fun evaluateExtensionExpression(receiver: KtExpression, + receiverExpressionArgument: LLVMVariable?, + selector: KtCallExpression, + scopeDepth: Int): LLVMSingleValue? { + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver)!!.type!! + val receiverType = LLVMMapStandardType(kotlinType, state) + + val targetFunction = state.bindingContext.get(BindingContext.CALL, selector.calleeExpression) + val candidateDescriptor = state.bindingContext.get(BindingContext.RESOLVED_CALL, targetFunction)!!.candidateDescriptor + val targetFunctionName = candidateDescriptor.fqNameSafe.convertToNativeName() + val nameWithoutMangling = candidateDescriptor.name.asString().replace(Regex("""(.?)"""), "") + val packageNameFirst = targetFunction?.calleeExpression?.getContainingKtFile()?.packageFqName?.convertToNativeName().orEmpty() + val packageNameSecond = candidateDescriptor.containingDeclaration.fqNameSafe.convertToNativeName() + + val names = parseArgList(selector, scopeDepth) + val type = LLVMType.mangleFunctionArguments(names) + + val constructedFunctionName = receiverType.mangle + nameWithoutMangling.addBeforeIfNotEmpty(".") + type + val targetExtension = state.extensionFunctions[receiverType.toString()] + + val extensionCodegen = targetExtension?.get(packageNameFirst.addAfterIfNotEmpty(".") + constructedFunctionName) ?: + targetExtension?.get(packageNameSecond.addAfterIfNotEmpty(".") + constructedFunctionName) ?: + targetExtension?.get(targetFunctionName) + ?: throw UnexpectedException(constructedFunctionName) + val receiverExpression = receiverExpressionArgument ?: evaluateExpression(receiver, scopeDepth + 1)!! + + val args = mutableListOf(codeBuilder.receivePointedArgument(receiverExpression, requirePointer = if (receiverType is LLVMReferenceType) 1 else 0)) + args.addAll(codeBuilder.loadArgsIfRequired(names, extensionCodegen.args)) + return evaluateFunctionCallExpression(LLVMVariable(extensionCodegen.fullName, extensionCodegen.returnType!!.type, scope = LLVMVariableScope()), args) + } + + private fun evaluateClassScopedDotExpression(clazz: StructCodegen, + selector: KtExpression, + scopeDepth: Int, + receiver: LLVMVariable? = null): LLVMSingleValue? = + when (selector) { + is KtCallExpression -> evaluateCallExpression(selector, scopeDepth, clazz, caller = receiver) + is KtReferenceExpression -> evaluateReferenceExpression(selector, scopeDepth, clazz) + else -> throw UnsupportedOperationException() + } + + private fun evaluateClassField(receiver: LLVMVariable, + field: LLVMClassVariable): LLVMVariable { + val result = codeBuilder.getNewVariable(field.type, pointer = field.pointer + 1) + codeBuilder.loadClassField(result, receiver, field.offset) + return result + } + + private fun evaluateMemberMethod(receiver: LLVMVariable, + clazz: StructCodegen, + scopeDepth: Int, + call: KtCallExpression): LLVMSingleValue? { + val resolvedCall = call.getCall(state.bindingContext)!!.getResolvedCallWithAssert(state.bindingContext) + val functionDescriptor = resolvedCall.candidateDescriptor + val functionArguments = functionDescriptor.valueParameters.map { it -> it.type }.map { LLVMMapStandardType(it, state) } + val methodName = functionDescriptor.fqNameSafe.asString() + LLVMType.mangleFunctionTypes(functionArguments) + + val method = clazz.methods[methodName] ?: throw UnexpectedException(methodName) + val returnType = method.returnType!!.type + + val arguments = resolvedCall.valueArguments.toSortedMap(compareBy { it.index }).values + val substitutionArguments = parseArgumentsWithDefaultValues(arguments, method.defaultValues, scopeDepth) + val loadedArgs = codeBuilder.loadArgsIfRequired(substitutionArguments, method.args) + + val callArgs = mutableListOf(receiver) + callArgs.addAll(loadedArgs) + + return evaluateFunctionCallExpression(LLVMVariable(methodName, returnType, scope = LLVMVariableScope()), callArgs) + } + + private fun resolveClassOrObjectLocation(type: LLVMReferenceType): StructCodegen? { + val typeLocations = type.type.split('.') + val currentLocation = StringBuilder() + var codegen: ClassCodegen? = null + var currentIndex = 0 + + do { + currentLocation.append((if (currentIndex > 0) "." else "") + typeLocations[currentIndex]) + if (state.classes.containsKey(currentLocation.toString())) { + codegen = state.classes[currentLocation.toString()] + } else if (state.objects.containsKey(currentLocation.toString())) { + return state.objects[currentLocation.toString()] + } + currentIndex++ + } while ((currentIndex < typeLocations.size) && (codegen == null)) + + while (currentIndex < typeLocations.size - 1) { + currentLocation.append('.' + typeLocations[currentIndex]) + currentIndex++ + codegen = codegen?.nestedClasses?.get(currentLocation.toString()) + } + + if (codegen?.companionObjectCodegen != null && type.type == codegen?.companionObjectCodegen?.structName) { + return codegen?.companionObjectCodegen!! + } + + return if (codegen?.structName == type.type) codegen else codegen?.nestedClasses?.get(type.type) + } + + private fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, + scope: Int): LLVMSingleValue? { + val arrayNameVariable = evaluateExpression(expr.arrayExpression, scope) as LLVMVariable + return when (arrayNameVariable.type) { + is LLVMReferenceType -> { + val callMaker = state.bindingContext.get(BindingContext.CALL, expr) + when (callMaker!!.callType) { + Call.CallType.ARRAY_SET_METHOD, + Call.CallType.ARRAY_GET_METHOD -> { + val arrayActionType = if (callMaker.callType == Call.CallType.ARRAY_SET_METHOD) "set" else "get" + val explicitReceiver = callMaker.explicitReceiver as ExpressionReceiver + val receiver = evaluateExpression(explicitReceiver.expression, scope)!! as LLVMVariable + val pureReceiver = codeBuilder.receivePointedArgument(receiver, requirePointer = 1) + + val targetClassName = (receiver.type as LLVMReferenceType).type + + val names = parseValueArguments(callMaker.valueArguments, scope) + val methodName = "$targetClassName.$arrayActionType${LLVMType.mangleFunctionArguments(names)}" + val clazz = resolveClassOrObjectLocation(receiver.type) + ?: throw UnexpectedException(receiver.type.toString()) + + val method = clazz.methods[methodName] ?: throw UnexpectedException(expr.text) + val returnType = method.returnType!!.type + + val loadedArgs = codeBuilder.loadArgsIfRequired(names, method.args) + val callArgs = mutableListOf(pureReceiver) + callArgs.addAll(loadedArgs) + + return evaluateFunctionCallExpression(LLVMVariable(methodName, returnType, scope = LLVMVariableScope()), callArgs) + } + else -> throw UnexpectedException("Unknown array access method") + } + } + else -> { + val arrayIndex = evaluateConstantExpression(expr.indexExpressions.first() as KtConstantExpression) + val arrayReceivedVariable = codeBuilder.loadAndGetVariable(arrayNameVariable) + val arrayElementType = (arrayNameVariable.type as LLVMArray).arrayElementType + val arrayElement = codeBuilder.getNewVariable(arrayElementType, pointer = 1) + codeBuilder.loadVariableOffset(arrayElement, arrayReceivedVariable, arrayIndex) + arrayElement + } + } + } + + private fun evaluateReferenceExpression(expr: KtReferenceExpression, + scopeDepth: Int, + classScope: StructCodegen? = null): LLVMSingleValue? { + val targetName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)?.fqNameSafe?.convertToNativeName() + return when { + expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1) + isEnumClassField(expr, classScope) -> resolveEnumClassField(expr, classScope) + (targetName != null) && variableManager.contains(targetName) -> variableManager[targetName] + ((expr is KtNameReferenceExpression) && (classScope != null)) -> + evaluateNameReferenceExpression(targetName!!, classScope.parentCodegen!! as ClassCodegen) + else -> { + val clazz = classScope ?: resolveCodegen(expr) + val receiver = if (clazz != null) variableManager[clazz.structName] ?: variableManager["this"] else variableManager["this"] + targetName ?: throw UnexpectedException("Can't find target in reference expression " + expr.firstChild.text) + evaluateMemberMethodOrField(receiver ?: throw UnexpectedException(targetName), targetName, topLevelScopeDepth) + } + } + } + + private fun evaluateNameReferenceExpression(fieldName: String, + classScope: ClassCodegen): LLVMSingleValue? { + val companionObject = classScope.companionObjectCodegen!! + val field = companionObject.fieldsIndex[fieldName] ?: return null + val receiver = variableManager[companionObject.structName]!! + val result = codeBuilder.getNewVariable(field.type, pointer = 1) + + codeBuilder.loadClassField(result, receiver, field.offset) + return result + } + + private fun resolveEnumClassField(expr: KtReferenceExpression, + classScope: StructCodegen?): LLVMSingleValue = + (classScope ?: resolveCodegen(expr))!!.enumFields[expr.text]!! + + private fun isEnumClassField(expr: KtReferenceExpression, + classScope: StructCodegen?): Boolean = + (classScope ?: resolveCodegen(expr))?.enumFields?.containsKey(expr.text) ?: false + + private fun resolveCodegen(expr: KtExpression): StructCodegen? { + val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)?.type + ?: expr.getQualifiedExpressionForReceiver()?.getType(state.bindingContext) + + val name = type?.constructor?.declarationDescriptor?.fqNameSafe?.asString() ?: throw UnexpectedException(expr.text) + + return resolveCodegenByName(name) + } + + private fun resolveCodegenByName(name: String): StructCodegen? = + resolveClassOrObjectLocation(LLVMReferenceType(name, prefix = "class")) + + private fun evaluateCallExpression(expr: KtCallExpression, + scopeDepth: Int, + classScope: StructCodegen? = null, + caller: LLVMVariable? = null): LLVMSingleValue? { + var names = parseArgList(expr, scopeDepth) + val targetFunction = state.bindingContext.get(BindingContext.CALL, expr.calleeExpression) + var resolvedCall = state.bindingContext.get(BindingContext.RESOLVED_CALL, targetFunction) + if (resolvedCall is VariableAsFunctionResolvedCallImpl) { + resolvedCall = resolvedCall.variableCall + } + + val functionDescriptor = resolvedCall!!.candidateDescriptor + val targetFunctionName = functionDescriptor.fqNameSafe.convertToNativeName() + val externalFunctionName = functionDescriptor.name.asString() + val arguments = resolvedCall.valueArguments.toSortedMap(compareBy { it.index }).values + + val external = state.externalFunctions.containsKey(externalFunctionName) + val functionArguments = functionDescriptor.valueParameters.map { it -> it.type }.map { LLVMMapStandardType(it, state) } + val function = "$targetFunctionName${if (!external) LLVMType.mangleFunctionTypes(functionArguments) else ""}" + + if (function in state.functions || externalFunctionName in state.externalFunctions) { + val descriptor = state.functions[function] ?: state.externalFunctions[externalFunctionName]!! + names = parseArgumentsWithDefaultValues(arguments, descriptor.defaultValues, scopeDepth) + val args = codeBuilder.loadArgsIfRequired(names, descriptor.args) + return evaluateFunctionCallExpression(LLVMVariable(descriptor.name, descriptor.returnType!!.type, scope = LLVMVariableScope()), args) + } + + if (targetFunctionName in state.classes || classScope?.structName == targetFunctionName) { + val descriptor = state.classes[targetFunctionName] ?: classScope ?: return null + val detectedConstructor = LLVMType.mangleFunctionTypes(functionArguments) + val args = codeBuilder.loadArgsIfRequired(names, descriptor.constructorFields[detectedConstructor]!!) + return evaluateConstructorCallExpression(LLVMVariable(descriptor.structName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), args) + } + + if (targetFunctionName in variableManager) { + val type = variableManager[targetFunctionName]!!.type as LLVMFunctionType + val args = codeBuilder.loadArgsIfRequired(names, type.arguments) + return evaluateFunctionCallExpression(LLVMVariable(targetFunctionName, type.returnType.type, scope = LLVMRegisterScope()), args) + } + + val nestedConstructor = classScope?.nestedClasses?.get(expr.calleeExpression!!.text) + if (nestedConstructor != null) { + val args = codeBuilder.loadArgsIfRequired(names, nestedConstructor.constructorFields[nestedConstructor.primaryConstructorIndex]!!) + return evaluateConstructorCallExpression(LLVMVariable(nestedConstructor.structName, nestedConstructor.type, scope = LLVMVariableScope()), args) + } + + val containingClass = resolveContainingClass(expr) ?: return null + val method = containingClass.methods[function] ?: throw RuntimeException("Cannot find function $targetFunctionName") + val args = mutableListOf() + + if (caller != null) { + args.add(caller) + } else if (containingClass.structName in variableManager) { + args.add(variableManager[containingClass.structName]!!) + } else { + args.add(variableManager["this"]!!) + } + + args.addAll(codeBuilder.loadArgsIfRequired(names, method.args)) + + return evaluateFunctionCallExpression(LLVMVariable(method.fullName, method.returnType?.type ?: LLVMVoidType(), scope = LLVMVariableScope()), args) + } + + private fun resolveContainingClass(expr: KtElement): StructCodegen? { + val name = expr.getResolvedCallWithAssert(state.bindingContext).dispatchReceiver?.type?.constructor?.declarationDescriptor?.fqNameSafe?.asString() ?: return null + return resolveCodegenByName(name) + } + + private fun evaluateFunctionCallExpression(function: LLVMVariable, + names: List): LLVMSingleValue? { + val returnType = function.type + when (returnType) { + is LLVMVoidType -> { + codeBuilder.addLLVMCodeToLocalPlace(LLVMCall(LLVMVoidType(), function.toString(), names).toString()) + return null + } + is LLVMReferenceType -> { + val returnVar = codeBuilder.getNewVariable(returnType, pointer = 2) + codeBuilder.allocStaticVar(returnVar, pointer = true) + + val args = mutableListOf(returnVar) + args.addAll(names) + + codeBuilder.addLLVMCodeToLocalPlace(LLVMCall(LLVMVoidType(), function.toString(), args).toString()) + if (returnVar.pointer == 2) { + return returnVar + } else { + return codeBuilder.loadAndGetVariable(returnVar) + } + } + else -> { + val result = codeBuilder.saveExpression(LLVMCall(returnType, function.toString(), names)) + + val resultPtr = codeBuilder.getNewVariable(returnType, pointer = 1) + codeBuilder.allocStackVar(resultPtr, pointer = true) + codeBuilder.storeVariable(resultPtr, result) + return resultPtr + } + } + } + + private fun evaluateConstructorCallExpression(function: LLVMVariable, + names: List): LLVMSingleValue? { + val store = codeBuilder.getNewVariable(function.type, pointer = 1) + codeBuilder.allocStaticVar(store, pointer = true) + + val result = codeBuilder.getNewVariable(function.type, pointer = 2) + codeBuilder.allocStackVar(result, pointer = true) + codeBuilder.storeVariable(result, store) + + val args = mutableListOf(store) + args.addAll(names) + + codeBuilder.addLLVMCodeToLocalPlace(LLVMCall( + LLVMVoidType(), + function.toString(), + args + ).toString()) + + return result + } + + private fun parseArgList(expr: KtCallExpression, + scopeDepth: Int): List = + parseValueArguments(expr.getValueArgumentsInParentheses(), scopeDepth) + + private fun parseValueArguments(args: List, scopeDepth: Int): List = + args.map { evaluateExpression(it.getArgumentExpression(), scopeDepth) as LLVMSingleValue } + + private fun parseArgumentsWithDefaultValues(args: MutableCollection, defaultValues: List, scopeDepth: Int): List = + args.mapIndexed(fun(i: Int, value: ResolvedValueArgument): LLVMSingleValue { + return when (value) { + is DefaultValueArgument -> evaluateExpression(defaultValues[i], scopeDepth)!! + is ExpressionValueArgument -> evaluateExpression((value.valueArgument as KtValueArgument).getArgumentExpression()!!, scopeDepth)!! + else -> throw UnexpectedException("Wrong parser argument") + } + }).toList() + + private fun evaluateBinaryExpression(expr: KtBinaryExpression, + scopeDepth: Int): LLVMVariable? { + val operator = expr.operationToken + + if (operator == KtTokens.ELVIS) { + return evaluateElvisOperator(expr, scopeDepth) + } + + val left = evaluateExpression(expr.left, scopeDepth) + if (expr.left is KtArrayAccessExpression) { + val callMaker = state.bindingContext.get(BindingContext.CALL, expr.left) + if (callMaker!!.callType == Call.CallType.ARRAY_SET_METHOD) { + return left as LLVMVariable? + } + } + + left ?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}") + val right = evaluateExpression(expr.right, scopeDepth) + ?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}") + + return addPrimitiveBinaryOperation(operator, left, right, expr.operationReference) + } + + private fun evaluatePostfixExpression(expr: KtPostfixExpression, + scopeDepth: Int): LLVMSingleValue? { + val operator = expr.operationToken + val left = evaluateExpression(expr.baseExpression, scopeDepth) + ?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}") + return addPrimitivePostfixOperation(operator, left as LLVMVariable) + } + + private fun evaluatePrefixExpression(expr: KtPrefixExpression, + scopeDepth: Int): LLVMSingleValue? { + val operator = expr.operationToken + val left = evaluateExpression(expr.baseExpression, scopeDepth) + ?: throw UnsupportedOperationException("Wrong binary expression") + return addPrimitivePrefixOperation(operator, left) + } + + private fun addPrimitivePostfixOperation(operator: IElementType?, + firstOp: LLVMVariable): LLVMSingleValue? = + when (operator) { + KtTokens.PLUSPLUS, KtTokens.MINUSMINUS -> { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + val oldValue = codeBuilder.getNewVariable(firstOp.type, firstOp.pointer) + codeBuilder.allocStackVar(oldValue, asValue = true) + codeBuilder.copyVariable(firstOp, oldValue) + + val llvmExpression = when (operator) { + KtTokens.PLUSPLUS -> firstOp.type.operatorInc(firstNativeOp) + KtTokens.MINUSMINUS -> firstOp.type.operatorDec(firstNativeOp) + else -> throw IllegalAccessError() + } + + val resultOp = codeBuilder.saveExpression(llvmExpression) + codeBuilder.storeVariable(firstOp, resultOp) + oldValue + } + KtTokens.EXCLEXCL -> { + var result = firstOp + val nullLabel = codeBuilder.getNewLabel(prefix = "nullCheck") + val notNullLabel = codeBuilder.getNewLabel(prefix = "nullCheck") + val nullCheck = codeBuilder.nullCheck(firstOp) + codeBuilder.addCondition(nullCheck, nullLabel, notNullLabel) + codeBuilder.markWithLabel(nullLabel) + codeBuilder.addExceptionCall("KotlinNullPointerException") + codeBuilder.addUnconditionalJump(notNullLabel) + codeBuilder.markWithLabel(notNullLabel) + if (firstOp.type.isPrimitive) { + result = codeBuilder.receivePointedArgument(firstOp, requirePointer = 0) as LLVMVariable + } + result + } + else -> throw UnsupportedOperationException() + } + + + private fun addPrimitivePrefixOperation(operator: IElementType?, + firstOp: LLVMSingleValue): LLVMSingleValue? = + when (operator) { + KtTokens.MINUS, + KtTokens.PLUS -> addPrimitiveBinaryOperation(operator!!, LLVMConstant("0", firstOp.type), firstOp) + KtTokens.EXCL -> { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + val llvmExpression = addPrimitiveReferenceOperationByName("xor", LLVMConstant("true", LLVMBooleanType()), firstNativeOp) + codeBuilder.saveExpression(llvmExpression) + } + else -> throw UnsupportedOperationException() + } + + + private fun evaluateElvisOperator(expr: KtBinaryExpression, + scopeDepth: Int): LLVMVariable { + val left = evaluateExpression(expr.left, scopeDepth) + ?: throw UnsupportedOperationException("Wrong binary expression") + val lptr = codeBuilder.loadAndGetVariable(left as LLVMVariable) + + val condition = lptr.type.operatorEq(lptr, LLVMVariable("", LLVMNullType())) + + val conditionResult = codeBuilder.saveExpression(condition) + + val notNull = codeBuilder.getNewLabel(prefix = "elvis") + val endLabel = codeBuilder.getNewLabel(prefix = "elvis") + + codeBuilder.addCondition(conditionResult, notNull, endLabel) + + codeBuilder.markWithLabel(notNull) + var right = evaluateExpression(expr.right, scopeDepth + 1) + if (right != null) { + right = codeBuilder.loadAndGetVariable(right as LLVMVariable) + codeBuilder.storeVariable(left, right) + } + + codeBuilder.addUnconditionalJump(endLabel) + codeBuilder.markWithLabel(endLabel) + + return left + } + + private fun addPrimitiveReferenceOperationByName(operator: String, + firstOp: LLVMSingleValue, + secondNativeOp: LLVMSingleValue): LLVMExpression { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + + return when (operator) { + "||", + "or" -> firstNativeOp.type.operatorOr(firstNativeOp, secondNativeOp) + "xor" -> firstNativeOp.type.operatorXor(firstNativeOp, secondNativeOp) + "&&", + "and" -> firstNativeOp.type.operatorAnd(firstNativeOp, secondNativeOp) + "%" -> firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp) + "shl" -> firstNativeOp.type.operatorShl(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type)) + "shr" -> firstNativeOp.type.operatorShr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type)) + "ushr" -> firstNativeOp.type.operatorUshr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type)) + "+=" -> { + val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorPlus(firstNativeOp, secondNativeOp)) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}") + } + "-=" -> { + val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorMinus(firstNativeOp, secondNativeOp)) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}") + } + "*=" -> { + val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorTimes(firstNativeOp, secondNativeOp)) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}") + } + "%=" -> { + val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp)) + codeBuilder.storeVariable(firstOp, resultOp) + return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}") + } + ".." -> { + val descriptor = state.classes["kotlin.ranges.${firstOp.type.mangle}Range"] + val arguments = listOf(firstOp, secondNativeOp) + val detectedConstructor = LLVMType.mangleFunctionTypes(arguments.map { it.type }) + val result = evaluateConstructorCallExpression(LLVMVariable(descriptor!!.structName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), arguments) + return LLVMExpression(result!!.type, "load ${descriptor.type}** $result, align ${descriptor.type.align}", pointer = 1) + } + else -> throw UnsupportedOperationException("Unknown binary operator: $operator(${firstNativeOp.type}, ${secondNativeOp.type})") + } + } + + private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMConstant { + val expressionKotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! + val expressionValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)?.getValue(expressionKotlinType) + val type = LLVMMapStandardType(expressionKotlinType, state) + return LLVMConstant(expressionValue?.toString().orEmpty(), type, pointer = 0) + } + + private fun evaluatePsiElement(element: PsiElement, + scopeDepth: Int): LLVMSingleValue? = + when (element) { + is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth) + is KtConstantExpression -> evaluateConstantExpression(element) + else -> null + } + + + private fun evaluateLeafPsiElement(element: LeafPsiElement, + scopeDepth: Int): LLVMVariable? { + return when (element.elementType) { + KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) + KtTokens.IF_KEYWORD -> evaluateIfOperator(element.context as KtIfExpression, scopeDepth, isExpression = false) + KtTokens.WHILE_KEYWORD -> evaluateWhileOperator(element.context as KtWhileExpression, scopeDepth) + KtTokens.FOR_KEYWORD -> evaluateForOperator(element.context as KtForExpression, scopeDepth) + else -> null + } + } + + private fun evaluateForOperator(expr: KtForExpression, + scopeDepth: Int): LLVMVariable? { + val range = evaluateExpression(expr.loopRange, scopeDepth + 1)!! + val conditionLabel = codeBuilder.getNewLabel(prefix = "for_condition") + val bodyLabel = codeBuilder.getNewLabel(prefix = "for_body") + val exitLabel = codeBuilder.getNewLabel(prefix = "for_exit") + val rangeTypeName = (range.type as LLVMReferenceType).type + + val descriptor = state.classes[rangeTypeName] ?: throw UnexpectedException("Error occurred in evaluating range expression") + val method = descriptor.methods["$rangeTypeName.iterator"] ?: throw UnexpectedException("Cant receive iterator $rangeTypeName.iterator") + val returnType = method.returnType!!.type + val returnTypeName = (returnType as LLVMReferenceType).type + val iteratorDescriptor = state.classes[returnTypeName] + val nextDescriptor = iteratorDescriptor!!.methods["$returnTypeName.next"] ?: throw UnexpectedException("$returnTypeName.nextInt") + + val conditionIterator = evaluateFunctionCallExpression(LLVMVariable("$rangeTypeName.iterator", returnType, scope = LLVMVariableScope()), listOf(range))!! + val iteratorThisArgument = codeBuilder.receivePointedArgument(conditionIterator, requirePointer = 1) + codeBuilder.addUnconditionalJump(conditionLabel) + codeBuilder.markWithLabel(conditionLabel) + var conditionResult = evaluateFunctionCallExpression(LLVMVariable("$returnTypeName.hasNext", LLVMBooleanType(), scope = LLVMVariableScope()), listOf(iteratorThisArgument))!! + conditionResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0) + codeBuilder.addCondition(conditionResult, bodyLabel, exitLabel) + + codeBuilder.addUnconditionalJump(bodyLabel) + codeBuilder.markWithLabel(bodyLabel) + val loopParameter = evaluateFunctionCallExpression(LLVMVariable("$returnTypeName.next", LLVMIntType(), scope = LLVMVariableScope()), listOf(iteratorThisArgument))!! + val loopParameterDescriptor = state.bindingContext.get(BindingContext.VALUE_PARAMETER, expr.loopParameter!!)?.fqNameSafe?.asString() ?: expr.loopParameter!!.name!! + + val allocVar = variableManager.receiveVariable(loopParameterDescriptor, nextDescriptor.returnType!!.type, LLVMRegisterScope(), pointer = + nextDescriptor.returnType!!.pointer + 1) + variableManager.addVariable(loopParameterDescriptor, allocVar, scopeDepth + 1) + codeBuilder.allocStackVar(allocVar, pointer = true) + + addPrimitiveBinaryOperation(KtTokens.EQ, allocVar, loopParameter, null) + + evaluateCodeBlock(expr.body, startLabel = null, nextIterationLabel = conditionLabel, breakLabel = exitLabel, scopeDepth = scopeDepth + 1) + codeBuilder.markWithLabel(exitLabel) + + return null + } + + private fun evaluateWhenItem(item: KtWhenEntry, + target: LLVMSingleValue, + resultVariable: LLVMVariable, + elseLabel: LLVMLabel, + endLabel: LLVMLabel, + isElse: Boolean, + scopeDepth: Int) { + val successConditionsLabel = codeBuilder.getNewLabel(prefix = "when_condition_success") + var nextLabel = codeBuilder.getNewLabel(prefix = "when_condition_condition") + + codeBuilder.addUnconditionalJump(nextLabel) + + for (condition in item.conditions) { + codeBuilder.markWithLabel(nextLabel) + nextLabel = codeBuilder.getNewLabel(prefix = "when_condition_condition") + + val currentConditionExpression = + evaluateExpression((condition as KtWhenConditionWithExpression).expression, scopeDepth + 1)!! + val conditionResult = addPrimitiveBinaryOperation(KtTokens.EQEQ, target, currentConditionExpression) + + codeBuilder.addCondition(conditionResult, successConditionsLabel, nextLabel) + } + + codeBuilder.markWithLabel(nextLabel) + codeBuilder.addUnconditionalJump(if (isElse) successConditionsLabel else elseLabel) + codeBuilder.markWithLabel(successConditionsLabel) + + var successExpression = evaluateExpression(item.expression, scopeDepth + 1) + + if (successExpression != null && !LLVMType.nullOrVoidType(resultVariable.type)) { + successExpression = codeBuilder.receivePointedArgument(successExpression, requirePointer = 0) + codeBuilder.storeVariable(resultVariable, successExpression) + } + + codeBuilder.addUnconditionalJump(endLabel) + } + + private fun evaluateWhenExpression(expr: KtWhenExpression, + scopeDepth: Int): LLVMVariable? { + codeBuilder.addComment("start when expression") + val whenExpression = expr.subjectExpression + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! + val expressionType = LLVMMapStandardType(kotlinType, state) + + val targetExpression = evaluateExpression(whenExpression, scopeDepth + 1) ?: LLVMConstant("true", LLVMBooleanType()) + val resultVariable = codeBuilder.getNewVariable(expressionType, pointer = 1) + + when (expressionType) { + is LLVMVoidType, + is LLVMNullType -> { + } + is LLVMReferenceType -> codeBuilder.allocStaticVar(resultVariable, asValue = true) + else -> codeBuilder.allocStackVar(resultVariable, asValue = true) + } + + var nextLabel = codeBuilder.getNewLabel(prefix = "when_start") + val endLabel = codeBuilder.getNewLabel(prefix = "when_end") + codeBuilder.addUnconditionalJump(nextLabel) + for (item in expr.entries) { + codeBuilder.markWithLabel(nextLabel) + nextLabel = codeBuilder.getNewLabel(prefix = "when_item") + evaluateWhenItem(item, targetExpression, resultVariable, nextLabel, endLabel, item.isElse, scopeDepth + 1) + } + + codeBuilder.markWithLabel(nextLabel) + codeBuilder.addUnconditionalJump(endLabel) + codeBuilder.markWithLabel(endLabel) + return resultVariable + } + + private fun evaluateWhileOperator(expr: KtWhileExpression, + scopeDepth: Int): LLVMVariable? = + executeWhileBlock(expr.condition!!, expr.body!!, scopeDepth, checkConditionBeforeExecute = true) + + private fun executeWhileBlock(condition: KtExpression, bodyExpression: PsiElement, scopeDepth: Int, checkConditionBeforeExecute: Boolean): LLVMVariable? { + val conditionLabel = codeBuilder.getNewLabel(prefix = "while") + val bodyLabel = codeBuilder.getNewLabel(prefix = "while") + val exitLabel = codeBuilder.getNewLabel(prefix = "while") + + codeBuilder.addUnconditionalJump(if (checkConditionBeforeExecute) conditionLabel else bodyLabel) + codeBuilder.markWithLabel(conditionLabel) + var conditionResult = evaluateExpression(condition, scopeDepth + 1)!! + conditionResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0) + + codeBuilder.addCondition(conditionResult, bodyLabel, exitLabel) + evaluateCodeBlock(bodyExpression, startLabel = bodyLabel, nextIterationLabel = conditionLabel, breakLabel = exitLabel, scopeDepth = scopeDepth + 1) + codeBuilder.markWithLabel(exitLabel) + + return null + } + + private fun evaluateIfOperator(element: KtIfExpression, + scopeDepth: Int, + isExpression: Boolean = true): LLVMVariable? { + val conditionResult = evaluateExpression(element.condition, scopeDepth)!! + val conditionNativeResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0) + + return if (isExpression) + executeIfExpression(conditionNativeResult, element.then!!, element.`else`, element, scopeDepth + 1) + else + executeIfBlock(conditionNativeResult, element.then!!, element.`else`, scopeDepth + 1) + } + + private fun executeIfExpression(conditionResult: LLVMSingleValue, + thenExpression: KtExpression, + elseExpression: PsiElement?, + ifExpression: KtIfExpression, + scopeDepth: Int): LLVMVariable? { + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, ifExpression)!!.type!! + val expressionType = LLVMInstanceOfStandardType("type", kotlinType, LLVMVariableScope(), state).type + val resultVariable = codeBuilder.getNewVariable(expressionType, pointer = 1) + + when (resultVariable.type) { + is LLVMReferenceType -> codeBuilder.allocStaticVar(resultVariable, asValue = true) + else -> codeBuilder.allocStackVar(resultVariable, asValue = true) + } + val thenLabel = codeBuilder.getNewLabel(prefix = "if_then") + val elseLabel = codeBuilder.getNewLabel(prefix = "if_else") + val endLabel = codeBuilder.getNewLabel(prefix = "if_end") + + codeBuilder.addCondition(conditionResult, thenLabel, elseLabel) + codeBuilder.markWithLabel(thenLabel) + val thenResultExpression = evaluateExpression(thenExpression, scopeDepth + 1) ?: throw UnexpectedException("Can't evaluate then in if expression") + val thenResultNativeExpression = codeBuilder.receiveNativeValue(thenResultExpression) + codeBuilder.storeVariable(resultVariable, thenResultNativeExpression) + codeBuilder.addUnconditionalJump(endLabel) + codeBuilder.markWithLabel(elseLabel) + + val elseResultExpression = evaluateExpression(elseExpression, scopeDepth + 1) ?: throw UnexpectedException("Can't evaluate else in if expression") + val elseResultNativeExpression = codeBuilder.receiveNativeValue(elseResultExpression) + codeBuilder.storeVariable(resultVariable, elseResultNativeExpression) + codeBuilder.addUnconditionalJump(endLabel) + codeBuilder.markWithLabel(endLabel) + return resultVariable + } + + private fun executeIfBlock(conditionResult: LLVMSingleValue, + thenExpression: PsiElement, + elseExpression: PsiElement?, + scopeDepth: Int): LLVMVariable? { + val thenLabel = codeBuilder.getNewLabel(prefix = "if") + val elseLabel = codeBuilder.getNewLabel(prefix = "if") + val endLabel = codeBuilder.getNewLabel(prefix = "if") + + codeBuilder.addCondition(conditionResult, thenLabel, if (elseExpression != null) elseLabel else endLabel) + + evaluateCodeBlock(thenExpression, startLabel = thenLabel, nextIterationLabel = endLabel, breakLabel = endLabel, scopeDepth = scopeDepth + 1) + if (elseExpression != null) { + evaluateCodeBlock(elseExpression, startLabel = elseLabel, nextIterationLabel = endLabel, breakLabel = endLabel, scopeDepth = scopeDepth + 1) + } + + codeBuilder.markWithLabel(endLabel) + return null + } + + private fun evaluateValExpression(element: KtProperty, + scopeDepth: Int): LLVMVariable? { + val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!! + val identifier = variable.fqNameSafe.convertToNativeName() + + val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth) + val expectedExpressionType = LLVMInstanceOfStandardType("", variable.type, state = state) + + val primitivePointer = LLVMMapStandardType(variable.type, state).isPrimitive + + val allocVar = variableManager.receiveVariable(identifier, expectedExpressionType.type, LLVMRegisterScope(), pointer = expectedExpressionType.pointer + 1) + codeBuilder.allocStackVar(allocVar, pointer = true) + + variableManager.addVariable(identifier, allocVar, scopeDepth) + if (assignExpression != null) { + if ((primitivePointer) && (assignExpression.type is LLVMReferenceType)) { + throw UnexpectedException(element.text) + } + addPrimitiveBinaryOperation(KtTokens.EQ, allocVar, assignExpression, null) + } + + return null + } + + private fun evaluateReturnInstruction(element: PsiElement, + scopeDepth: Int): LLVMVariable? { + val next = element.getNextSiblingIgnoringWhitespaceAndComments() + var retVar = evaluateExpression(next, scopeDepth) + val type = retVar?.type ?: LLVMVoidType() + + when (type) { + is LLVMReferenceType -> generateReferenceReturn(retVar!!) + is LLVMNullType -> { + retVar = when (retVar) { + is LLVMConstant -> LLVMConstant(retVar.value, LLVMNullType(returnType!!.type), returnType!!.pointer - 1) + is LLVMVariable -> LLVMVariable(retVar.label, LLVMNullType(returnType!!.type), retVar.kotlinName, retVar.scope, returnType!!.pointer - 1) + else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue") + } + generateReferenceReturn(retVar!!) + } + is LLVMVoidType -> codeBuilder.addAnyReturn(LLVMVoidType()) + else -> { + val retNativeValue = codeBuilder.receiveNativeValue(retVar!!) + codeBuilder.addReturnOperator(retNativeValue) + } + } + + return null + } + + private fun generateReferenceReturn(retVar: LLVMSingleValue) { + var result = retVar + if (result.pointer == 2) { + result = codeBuilder.loadAndGetVariable(retVar as LLVMVariable) + } + + codeBuilder.storeVariable(returnType!!, result) + codeBuilder.addAnyReturn(LLVMVoidType()) + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ClassCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ClassCodegen.kt new file mode 100644 index 00000000000..b9f3619474a --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ClassCodegen.kt @@ -0,0 +1,84 @@ +package org.kotlinnative.translator.codegens + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.resolve.BindingContext +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.exceptions.TranslationException +import org.kotlinnative.translator.llvm.LLVMBuilder +import org.kotlinnative.translator.llvm.types.LLVMReferenceType +import org.kotlinnative.translator.llvm.types.LLVMType + +class ClassCodegen(state: TranslationState, + variableManager: VariableManager, + val clazz: KtClass, + codeBuilder: LLVMBuilder, + parentCodegen: StructCodegen? = null) : + StructCodegen(state, variableManager, clazz, codeBuilder, parentCodegen) { + + val annotation: Boolean + val enum: Boolean + var companionObjectCodegen: ObjectCodegen? = null + val descriptor: ClassDescriptor + + override var size: Int = 0 + override val structName: String = clazz.fqName?.asString()!! + override val type: LLVMReferenceType + + init { + type = LLVMReferenceType(structName, "class", align = TranslationState.POINTER_ALIGN, size = TranslationState.POINTER_SIZE, byRef = true) + descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException("Can't receive descriptor of class " + clazz.name) + + annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS + enum = descriptor.kind == ClassKind.ENUM_CLASS + + type.align = TranslationState.POINTER_ALIGN + } + + override fun prepareForGenerate() { + val parameterList = clazz.getPrimaryConstructorParameterList()?.parameters ?: listOf() + indexFields(parameterList) + generateInnerFields(clazz.declarations) + + type.size = calculateTypeSize() + + if (annotation) { + return + } + + super.prepareForGenerate() + nestedClasses.forEach { x, classCodegen -> classCodegen.prepareForGenerate() } + + if (descriptor.companionObjectDescriptor != null) { + val companionObject = clazz.getCompanionObjects().first() + companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this) + companionObjectCodegen!!.prepareForGenerate() + } + } + + override fun generate() { + if (annotation) { + return + } + + super.generate() + nestedClasses.forEach { x, classCodegen -> classCodegen.generate() } + companionObjectCodegen?.generate() + } + + private fun indexFields(parameters: MutableList) { + if (annotation) { + return + } + + val currentConstructorFields = parameters.mapIndexed { i, it -> resolveType(it, state.bindingContext.get(BindingContext.TYPE, it.typeReference)!!, fields.size + i) } + fields.addAll(currentConstructorFields) + fieldsIndex.putAll(currentConstructorFields.map { Pair(it.label, it) }) + primaryConstructorIndex = LLVMType.mangleFunctionArguments(currentConstructorFields) + constructorFields.put(primaryConstructorIndex!!, currentConstructorFields) + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/FunctionCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/FunctionCodegen.kt new file mode 100644 index 00000000000..ed2a4a8df72 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/FunctionCodegen.kt @@ -0,0 +1,138 @@ +package org.kotlinnative.translator.codegens + +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.source.KotlinSourceElement +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.llvm.* +import org.kotlinnative.translator.llvm.types.LLVMFunctionType +import org.kotlinnative.translator.llvm.types.LLVMReferenceType +import org.kotlinnative.translator.llvm.types.LLVMType +import org.kotlinnative.translator.llvm.types.LLVMVoidType +import java.util.* + + +class FunctionCodegen(state: TranslationState, + variableManager: VariableManager, + val function: KtNamedFunction, + codeBuilder: LLVMBuilder) : + BlockCodegen(state, variableManager, codeBuilder) { + + var name: String + var args = LinkedList() + val isExtensionDeclaration = function.isExtensionDeclaration() + var functionNamePrefix = "" + val external: Boolean + val defaultValues: List + val fullName: String + get() = functionNamePrefix + name + + init { + val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!! + args.addAll(descriptor.valueParameters.map { + LLVMInstanceOfStandardType(it?.fqNameSafe?.asString() ?: it.name.toString(), it.type, state = state) + }) + + returnType = LLVMInstanceOfStandardType("instance", descriptor.returnType!!, state = state) + if (returnType!!.type is LLVMReferenceType) { + returnType!!.pointer = 2 + } + external = descriptor.isExternal + name = if (external) function.name!! else function.fqName!!.convertToNativeName() + LLVMType.mangleFunctionArguments(args) + + if (isExtensionDeclaration) { + name = "${function.name}${if (!external) LLVMType.mangleFunctionArguments(args) else ""}" + val receiverType = descriptor.extensionReceiverParameter!!.type + val translatorType = LLVMMapStandardType(receiverType, state) + val packageName = (function.containingFile as KtFile).packageFqName.asString() + functionNamePrefix = packageName.addAfterIfNotEmpty(".") + translatorType.mangle + "." + + val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap()) + extensionFunctionsOfThisType.put(fullName, this) + state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType) + } + + defaultValues = descriptor.valueParameters.indices.map { + val parameterDescriptor = descriptor.valueParameters[it] + if (parameterDescriptor.declaresDefaultValue()) { + val initializer = (parameterDescriptor.source as KotlinSourceElement).psi as KtParameter + initializer.defaultValue + } else { + null + } + } + } + + fun generate(this_type: LLVMVariable? = null) { + generateDeclaration(this_type) + + if (external) { + return + } + + codeBuilder.addStartExpression() + generateLoadArguments() + evaluateCodeBlock(function.bodyExpression, scopeDepth = topLevelScopeDepth, isBlock = function.hasBlockBody()) + + if (returnType?.type is LLVMVoidType){ + codeBuilder.addAnyReturn(LLVMVoidType()) + } + codeBuilder.addEndExpression() + } + + private fun generateDeclaration(this_type: LLVMVariable? = null) { + var actualReturnType: LLVMType = returnType!!.type + val actualArgs = ArrayList() + + if (returnType!!.pointer > 0) { + actualReturnType = LLVMVoidType() + actualArgs.add(returnType!!) + } + + if (isExtensionDeclaration) { + val receiverParameter = state.bindingContext.get(BindingContext.FUNCTION, function)!!.extensionReceiverParameter!! + val receiverType = receiverParameter.type + val translatorType = LLVMMapStandardType(receiverType, state) + + val classVal = when (translatorType) { + is LLVMReferenceType -> LLVMVariable("classvariable.this", translatorType, pointer = 1) + else -> LLVMVariable("type", translatorType, pointer = 0) + } + + variableManager.addVariable("this", classVal, level = 0) + actualArgs.add(classVal) + } + + if (this_type != null) { + actualArgs.add(this_type) + } + + actualArgs.addAll(args) + + codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(fullName, actualArgs, actualReturnType, external)) + } + + private fun generateLoadArguments() { + args.forEach(fun(it: LLVMVariable) { + if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && it.type.byRef)) { + variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevelScopeDepth) + return + } + + if (it.type !is LLVMReferenceType || it.type.byRef) { + val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = it.pointer) + val allocVar = codeBuilder.loadArgument(loadVariable) + variableManager.addVariable(it.label, allocVar, topLevelScopeDepth) + } else { + variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 0), topLevelScopeDepth) + } + }) + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ObjectCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ObjectCodegen.kt new file mode 100644 index 00000000000..4f58ad3d000 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/ObjectCodegen.kt @@ -0,0 +1,43 @@ +package org.kotlinnative.translator.codegens + +import org.jetbrains.kotlin.psi.KtObjectDeclaration +import org.jetbrains.kotlin.resolve.BindingContext +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.llvm.LLVMBuilder +import org.kotlinnative.translator.llvm.LLVMVariable +import org.kotlinnative.translator.llvm.LLVMVariableScope +import org.kotlinnative.translator.llvm.types.LLVMReferenceType +import org.kotlinnative.translator.llvm.types.LLVMType + +class ObjectCodegen(state: TranslationState, + variableManager: VariableManager, + val objectDeclaration: KtObjectDeclaration, + codeBuilder: LLVMBuilder, + parentCodegen: StructCodegen? = null) : + StructCodegen(state, variableManager, objectDeclaration, codeBuilder, parentCodegen) { + + override var size: Int = 0 + override val structName: String = objectDeclaration.fqName?.asString()!! + override val type = LLVMReferenceType(structName, "class") + + init { + primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList()) + constructorFields.put(primaryConstructorIndex!!, arrayListOf()) + } + + override fun prepareForGenerate() { + generateInnerFields(objectDeclaration.declarations) + type.size = calculateTypeSize() + + super.prepareForGenerate() + + val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1) + codeBuilder.addGlobalInitialize(classInstance, fields, initializedFields.map { + val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, it.value)!!.type!! + Pair(it.key, state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, it.value)!!.getValue(type).toString()) + }.toMap(), type) + variableManager.addGlobalVariable(structName, classInstance) + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/PropertyCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/PropertyCodegen.kt new file mode 100644 index 00000000000..ca21816d604 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/PropertyCodegen.kt @@ -0,0 +1,33 @@ +package org.kotlinnative.translator.codegens + +import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.resolve.BindingContext +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.llvm.LLVMBuilder +import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType +import org.kotlinnative.translator.llvm.LLVMVariable +import org.kotlinnative.translator.llvm.LLVMVariableScope + + +class PropertyCodegen(val state: TranslationState, + val variableManager: VariableManager, + val property: KtProperty, + val codeBuilder: LLVMBuilder) { + + fun generate() { + val varInfo = state.bindingContext.get(BindingContext.VARIABLE, property)?.compileTimeInitializer ?: return + + val kotlinType = varInfo.type + val value = varInfo.value + if (kotlinType.nameIfStandardType != null) { + val variableType = LLVMInstanceOfStandardType(property.name ?: return, kotlinType, state = state).type + val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMVariableScope()) + variableManager.addGlobalVariable(property.name.toString(), variable) + codeBuilder.defineGlobalVariable(variable, variableType.parseArg(value.toString())) + variable.pointer++ + } + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/StructCodegen.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/StructCodegen.kt new file mode 100644 index 00000000000..92021d7b054 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/codegens/StructCodegen.kt @@ -0,0 +1,252 @@ +package org.kotlinnative.translator.codegens + +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.VariableManager +import org.kotlinnative.translator.llvm.* +import org.kotlinnative.translator.llvm.types.LLVMCharType +import org.kotlinnative.translator.llvm.types.LLVMReferenceType +import org.kotlinnative.translator.llvm.types.LLVMType +import org.kotlinnative.translator.llvm.types.LLVMVoidType +import java.util.* + +/* + * TODO make high level description of code generation process + * and structure of generated code. + */ +abstract class StructCodegen(val state: TranslationState, + val variableManager: VariableManager, + val classOrObject: KtClassOrObject, + val codeBuilder: LLVMBuilder, + val parentCodegen: StructCodegen? = null) { + + val fields = ArrayList() + val fieldsIndex = HashMap() + val nestedClasses = HashMap() + val enumFields = HashMap() + val constructorFields = HashMap>() + var primaryConstructorIndex: String? = null + val initializedFields = HashMap() + var methods = HashMap() + + abstract val type: LLVMReferenceType + abstract var size: Int + abstract val structName: String + + open fun prepareForGenerate() { + generateStruct() + classOrObject.declarations.filterIsInstance().map { + val function = FunctionCodegen(state, variableManager, it, codeBuilder) + methods.put(function.name, function) + } + } + + fun calculateTypeSize(): Int { + val classAlignment = fields.map { it.type.align }.max()?.toInt() ?: 0 + var alignmentRemainder = 0 + size = 0 + + for (item in fields) { + val currentFieldSize = if (item.pointer > 0) TranslationState.POINTER_ALIGN else item.type.align + alignmentRemainder -= (alignmentRemainder % currentFieldSize) + if (alignmentRemainder < currentFieldSize) { + size += classAlignment + alignmentRemainder = classAlignment - currentFieldSize + } else { + alignmentRemainder -= currentFieldSize + } + } + return size + } + + open fun generate() { + generateEnumFields() + generatePrimaryConstructor() + classOrObject.getSecondaryConstructors().map { generateSecondaryConstructor(it) } + + val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive) 0 else 1) + variableManager.addVariable("this", classVal, level = 0) + + methods.values.map { it.generate(classVal) } + } + + fun generateInnerFields(declarations: List) { + for (declaration in declarations) { + when (declaration) { + is KtProperty -> { + val ktType = state.bindingContext.get(BindingContext.TYPE, declaration.typeReference) + ?: state.bindingContext.get(BindingContext.VARIABLE, declaration)!!.type + val field = resolveType(declaration, ktType, fields.size) + + if (declaration.initializer != null) { + initializedFields.put(field, declaration.initializer!!) + } + + fields.add(field) + fieldsIndex[field.label] = field + } + is KtEnumEntry -> { + val name = declaration.name!! + val field = LLVMVariable("class.$structName.$name", type, scope = LLVMVariableScope(), pointer = 2) + enumFields.put(name, field) + } + is KtClass -> + nestedClasses.put(declaration.fqName!!.asString(), + ClassCodegen(state, + VariableManager(state.globalVariableCollection), + declaration, codeBuilder, this)) + } + } + } + + private fun generateEnumFields() { + val enumEntries = classOrObject.declarations.filterIsInstance() + + for (declaration in enumEntries) { + val name = declaration.name!! + val initializer = declaration.initializerList!!.initializers[0] + val arguments = (initializer as KtSuperTypeCallEntry).valueArguments.map { it.getArgumentExpression()!!.text } + + val field = codeBuilder.getNewVariable(type, scope = LLVMVariableScope()) + val enumField = enumFields[name]!! + + codeBuilder.defineGlobalVariable(field, codeBuilder.makeStructInitializer(constructorFields[primaryConstructorIndex]!!, arguments)) + codeBuilder.defineGlobalVariable(LLVMVariable(enumField.label, enumField.type, enumField.kotlinName, enumField.scope, enumField.pointer - 1), field.toString()) + } + } + + private fun generateStruct() = + codeBuilder.createClass(structName, fields) + + private fun generateSecondaryConstructor(secondaryConstructor: KtSecondaryConstructor) { + val thisCall = secondaryConstructor.getDelegationCall().calleeExpression + val descriptor = state.bindingContext.get(BindingContext.CONSTRUCTOR, secondaryConstructor) + + val classVal = LLVMVariable("classvariable.this", type, pointer = 1) + variableManager.addVariable("this", classVal, level = 0) + + val secondaryConstructorArguments = descriptor!!.valueParameters.map { + LLVMInstanceOfStandardType(it.fqNameSafe.convertToNativeName(), it.type, state = state) + } + + val argFields = mutableListOf(classVal) + argFields.addAll(secondaryConstructorArguments) + val currentConstructorIndex = LLVMType.mangleFunctionArguments(secondaryConstructorArguments) + constructorFields.put(currentConstructorIndex, argFields) + codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + currentConstructorIndex, argFields, LLVMVoidType())) + + codeBuilder.addStartExpression() + + secondaryConstructorArguments.map { variableManager.addVariable(it.label, it, level = 2) } + + val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {} + val mainConstructorThis = blockCodegen.evaluateConstructorDelegationReferenceExpression(thisCall!!, this, secondaryConstructorArguments, 1) as LLVMVariable + variableManager.addVariable("this", mainConstructorThis, level = 0) + + blockCodegen.evaluateCodeBlock(secondaryConstructor.bodyExpression, scopeDepth = 1) + generateReturn(codeBuilder.receivePointedArgument(variableManager["this"]!!, requirePointer = 1) as LLVMVariable) + codeBuilder.addAnyReturn(LLVMVoidType()) + codeBuilder.addEndExpression() + } + + private fun generatePrimaryConstructor() { + val classVal = LLVMVariable("classvariable.this", type, pointer = 1) + variableManager.addVariable("this", classVal, level = 0) + + val argFields = mutableListOf(classVal) + argFields.addAll(constructorFields[primaryConstructorIndex]!!) + + codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + primaryConstructorIndex, argFields, LLVMVoidType())) + + codeBuilder.addStartExpression() + generateLoadArguments(classVal) + generateAssignments() + generateReturn(LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)) + genClassInitializers() + codeBuilder.addAnyReturn(LLVMVoidType()) + codeBuilder.addEndExpression() + } + + private fun generateLoadArguments(thisField: LLVMVariable) { + val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 0) + codeBuilder.loadArgument(thisVariable, false) + + constructorFields[primaryConstructorIndex]!!.filter { it.type !is LLVMReferenceType }.forEach { + val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope()) + codeBuilder.loadArgument(loadVariable) + } + } + + private fun generateAssignments() { + constructorFields[primaryConstructorIndex]!!.forEach { + when (it.type) { + is LLVMReferenceType -> { + val classField = codeBuilder.getNewVariable(it.type, pointer = it.pointer + 1) + codeBuilder.loadClassField(classField, LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset) + codeBuilder.storeVariable(classField, it) + } + else -> { + val argument = codeBuilder.loadAndGetVariable(LLVMVariable("${it.label}.addr", it.type, scope = LLVMRegisterScope(), pointer = it.pointer + 1)) + val classField = codeBuilder.getNewVariable(it.type, pointer = 1) + codeBuilder.loadClassField(classField, LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset) + codeBuilder.storeVariable(classField, argument) + } + } + } + + val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {} + val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1) + variableManager.addVariable("this", receiverThis, level = 2) + + for ((variable, initializer) in initializedFields) { + val left = blockCodegen.evaluateMemberMethodOrField(receiverThis, variable.label, blockCodegen.topLevelScopeDepth, call = null)!! + val right = blockCodegen.evaluateExpression(initializer, scopeDepth = blockCodegen.topLevelScopeDepth)!! + blockCodegen.addPrimitiveBinaryOperation(KtTokens.EQ, left, right) + } + + variableManager.pullOneUpwardLevelVariable("this") + } + + private fun generateReturn(src: LLVMVariable) { + val dst = LLVMVariable("classvariable.this", type, scope = LLVMRegisterScope(), pointer = 1) + + val castedDst = codeBuilder.bitcast(dst, LLVMCharType(), pointer = 1) + val castedSrc = codeBuilder.bitcast(src, LLVMCharType(), pointer = 1) + + codeBuilder.memcpy(castedDst, castedSrc, size) + } + + protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType, offset: Int): LLVMClassVariable { + val annotations = parseFieldAnnotations(field) + val fieldName = state.bindingContext.get(BindingContext.VALUE_PARAMETER, field as?KtParameter)?.fqNameSafe?.convertToNativeName() + ?: field.fqName?.asString() + ?: field.name!! + + val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state) + + if (state.classes.containsKey(field.name!!)) { + return LLVMClassVariable(result.label, state.classes[fieldName]!!.type, result.pointer) + } + + if (annotations.contains("Plain")) { + result.pointer = 0 + } + + return LLVMClassVariable(result.label, result.type, result.pointer, offset) + } + + private fun parseFieldAnnotations(field: KtNamedDeclaration): Set = + field.annotationEntries.map { state.bindingContext.get(BindingContext.ANNOTATION, it)?.type.toString() }.toHashSet() + + protected fun genClassInitializers() = + classOrObject.getAnonymousInitializers().map { + object : BlockCodegen(state, variableManager, codeBuilder) { + fun generate() = evaluateCodeBlock(it.body, scopeDepth = topLevelScopeDepth) + } + }.map { it.generate() } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/debug/debug.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/debug/debug.kt new file mode 100644 index 00000000000..345a7416faa --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/debug/debug.kt @@ -0,0 +1,59 @@ +package org.kotlinnative.translator.debug + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.impl.source.tree.CompositeElement +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction + +fun debugPrintNode(node: Any?, indent: Int = 0): Unit { + if (node == null) { + return + } + + for (i in 0..indent) { + print(" ") + } + + println(node.toString()) + + when (node) { + is CompositeElement -> { + debugPrintNode(node.firstChildNode, indent + 2) + debugPrintNode(node.treeNext, indent) + } + is PsiElement -> { + debugPrintNode(node.firstChild, indent + 2) + debugPrintNode(node.nextSibling, indent) + } + is PsiWhiteSpace -> { + debugPrintNode(node.firstChild, indent + 2) + debugPrintNode(node.nextSibling, indent) + } + else -> { + print(" not supported: " + node.javaClass.canonicalName) + } + } + +} + +fun printFunction(function: KtNamedFunction) { + debugPrintNode(function.node) +} + +fun printClass(function: KtClass) { + debugPrintNode(function.node) +} + +fun printFile(file: KtFile) { + + for (declaration in file.declarations) { + + when (declaration) { + is KtNamedFunction -> printFunction(declaration) + is KtClass -> printClass(declaration) + else -> println(declaration.toString()) + } + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/TranslationException.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/TranslationException.kt new file mode 100644 index 00000000000..4b132fcbbcc --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/TranslationException.kt @@ -0,0 +1,5 @@ +package org.kotlinnative.translator.exceptions + +import java.lang.Exception + +class TranslationException(message: String) : Exception(message) diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt new file mode 100644 index 00000000000..e4b2b0dd4bc --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt @@ -0,0 +1,5 @@ +package org.kotlinnative.translator.exceptions + +import java.lang.Exception + +class UnimplementedException() : Exception() diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt new file mode 100644 index 00000000000..894419bdc56 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -0,0 +1,252 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.llvm.types.* +import java.rmi.UnexpectedException +import java.util.* + +class LLVMBuilder(arm: Boolean = false) { + + private val localCode: StringBuilder = StringBuilder() + private val globalCode: StringBuilder = StringBuilder() + private var variableCount = 0 + private var labelCount = 0 + private val exceptions = mapOf( + Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException"))) + + + init { + val declares = arrayOf( + "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)", + "declare i8* @malloc_heap(i32)", + "declare i32 @printf(i8*, ...)", + "declare void @abort()", + "%class.Nothing = type { }") + + declares.forEach { addLLVMCodeToGlobalPlace(it) } + + if (arm) { + val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" + addLLVMCodeToGlobalPlace(functionAttributes) + } + } + + fun addLLVMCodeToLocalPlace(code: String) = + localCode.appendln(code) + + fun addLLVMCodeToGlobalPlace(code: String) = + globalCode.appendln(code) + + fun addComment(comment: String) = + addLLVMCodeToLocalPlace("; " + comment) + + fun addStartExpression() = + addLLVMCodeToLocalPlace("{") + + fun addEndExpression() = + addLLVMCodeToLocalPlace("unreachable\n}") + + fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) = + addLLVMCodeToLocalPlace("$lhs = $rhs") + + fun addReturnOperator(llvmVariable: LLVMSingleValue) = + addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable") + + fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) = + addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value") + + fun addStringConstant(variable: LLVMVariable, value: String) = + addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1") + + fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) = + addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel") + + fun addUnconditionalJump(label: LLVMLabel) = + addLLVMCodeToLocalPlace("br label $label") + + fun addExceptionCall(exceptionName: String) { + val exception = exceptions[exceptionName] + val printResult = getNewVariable(LLVMIntType(), pointer = 0) + addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))") + addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList()) + } + + fun addFunctionCall(functionName: LLVMVariable, arguments: List) = + addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})") + + fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { + val type = if (asValue) target.type.toString() else target.pointedType + addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}") + } + + fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { + val allocated = getNewVariable(LLVMCharType(), pointer = 1) + val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size + + addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)") + addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*") + } + + fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList, initializers: Map, classType: LLVMType) { + val code = "$target = internal global $classType { ${ + fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString() + } }, align ${classType.align}" + addLLVMCodeToGlobalPlace(code) + } + + fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable { + val empty = getNewVariable(llvmType, pointer = pointer) + addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}") + return empty + } + + fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue { + var resultVariable = variable + if (variable.type != targetType) { + val convertedExpression = targetType.convertFrom(variable) + resultVariable = saveExpression(convertedExpression) + } + return resultVariable + } + + fun copyVariable(from: LLVMVariable, to: LLVMVariable) = + when { + from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0) + else -> copyVariableValue(to, from) + } + + fun createClass(name: String, fields: List) = + addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }") + + fun declareEntryPoint(name: String) { + addLLVMCodeToLocalPlace("define weak void @main()") + addStartExpression() + addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf()) + addAnyReturn(LLVMVoidType()) + addEndExpression() + } + + fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) = + addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}") + + fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable { + variableCount++ + return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer) + } + + fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel { + labelCount++ + return LLVMLabel("label.$prefix.$labelCount", scope) + } + + fun loadArgsIfRequired(names: List, args: List) = + names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue { + return receivePointedArgument(value, args[i].pointer) + }).toList() + + fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { + val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1) + allocStackVar(allocVar, asValue = false, pointer = true) + if (store) { + storeVariable(allocVar, llvmVariable) + } + return allocVar + } + + fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) = + addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset") + + fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) = + addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}") + + fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { + assert(source.pointer > 0) + val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName) + addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}") + return target + } + + fun makeStructInitializer(args: List, values: List) + = "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }" + + fun markWithLabel(label: LLVMLabel?) { + if (label != null) + addLLVMCodeToLocalPlace("${label.label}:") + } + + fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) = + addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)") + + fun nullCheck(variable: LLVMVariable): LLVMVariable { + val result = getNewVariable(LLVMBooleanType(), pointer = 0) + val loaded = loadAndGetVariable(variable) + addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded") + return result + } + + fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue = + when { + firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp + firstOp is LLVMVariable -> loadAndGetVariable(firstOp) + else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue") + } + + fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue { + var result = value + + while (result.pointer > requirePointer) { + result = receiveNativeValue(result) + } + + if ((value.type is LLVMStringType) && !(value.type.isLoaded)) { + val newVariable = getNewVariable(value.type, pointer = result.pointer + 1) + allocStackVar(newVariable, asValue = true) + copyVariable(result as LLVMVariable, newVariable) + result = loadAndGetVariable(newVariable) + } + + return result + } + + fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) { + val code = "store ${target.type} getelementptr inbounds (" + + "${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}" + (target.type as LLVMStringType).isLoaded = true + addLLVMCodeToLocalPlace(code) + } + + fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) { + if ((source.type is LLVMStringType) && !(source.type.isLoaded)) { + storeString(target as LLVMVariable, source as LLVMVariable, 0) + } else { + addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}") + } + } + + fun saveExpression(expression: LLVMSingleValue): LLVMVariable { + val resultOp = getNewVariable(expression.type, pointer = expression.pointer) + addAssignment(resultOp, expression) + return resultOp + } + + fun storeNull(result: LLVMVariable) = + addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}") + + override fun toString() = globalCode.toString() + localCode.toString() + + private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) { + var from = source + if (source.pointer > 0) { + from = getNewVariable(source.type, source.pointer) + addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}") + } + addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}") + } + + private fun initializeExceptionString(string: String): LLVMVariable { + val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.") + addStringConstant(result, string) + return result + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMCall.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMCall.kt new file mode 100644 index 00000000000..b704798aa0d --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMCall.kt @@ -0,0 +1,11 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +class LLVMCall(val returnType: LLVMType, + val name: String, + val arguments: Collection) : LLVMSingleValue(returnType) { + + override fun toString() = "call $returnType $name(${arguments.joinToString { "${it.pointedType} ${it.toString()}" }})" + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt new file mode 100644 index 00000000000..780fb40d759 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt @@ -0,0 +1,8 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +class LLVMClassVariable(label: String, + type: LLVMType, + pointer: Int = 0, + var offset: Int = 0) : LLVMVariable(label, type, pointer = pointer) \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstant.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstant.kt new file mode 100644 index 00000000000..17a4bd69af2 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstant.kt @@ -0,0 +1,13 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +open class LLVMConstant(value: String, + type: LLVMType, + pointer: Int = 0) : LLVMSingleValue(type, pointer) { + + val value = type.parseArg(value) + + override fun toString() = value + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt new file mode 100644 index 00000000000..bd67bac1daa --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt @@ -0,0 +1,9 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +class LLVMExpression(type: LLVMType, val llvmCode: String, pointer: Int = 0) : LLVMSingleValue(type, pointer) { + + override fun toString() = llvmCode + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt new file mode 100644 index 00000000000..ea6e23d2a07 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt @@ -0,0 +1,7 @@ +package org.kotlinnative.translator.llvm + +class LLVMLabel(val label: String, val scope: LLVMScope) : LLVMNode() { + + override fun toString() = "$scope$label" + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMNode.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMNode.kt new file mode 100644 index 00000000000..402b191f78e --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMNode.kt @@ -0,0 +1,3 @@ +package org.kotlinnative.translator.llvm + +abstract class LLVMNode \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt new file mode 100644 index 00000000000..6932d837bc9 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt @@ -0,0 +1,11 @@ +package org.kotlinnative.translator.llvm + +abstract class LLVMScope + +class LLVMVariableScope : LLVMScope() { + override fun toString() = "@" +} + +class LLVMRegisterScope : LLVMScope() { + override fun toString() = "%" +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMSingleValue.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMSingleValue.kt new file mode 100644 index 00000000000..5a8ccc6ff71 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMSingleValue.kt @@ -0,0 +1,10 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +open class LLVMSingleValue(val type: LLVMType, var pointer: Int = 0) : LLVMNode() { + + open val pointedType: String + get() = type.toString() + "*".repeat(pointer) + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt new file mode 100644 index 00000000000..342a12977db --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -0,0 +1,13 @@ +package org.kotlinnative.translator.llvm + +import org.kotlinnative.translator.llvm.types.LLVMType + +open class LLVMVariable(val label: String, + type: LLVMType, + var kotlinName: String? = null, + val scope: LLVMScope = LLVMRegisterScope(), + pointer: Int = 0) : LLVMSingleValue(type, pointer) { + + override fun toString() = "$scope$label" + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt new file mode 100644 index 00000000000..ea1b234f28a --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -0,0 +1,63 @@ +package org.kotlinnative.translator.llvm + +import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype +import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.typeUtil.isUnit +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.llvm.types.* + + +fun LLVMFunctionDescriptor(name: String, + argTypes: List?, + returnType: LLVMType, + declare: Boolean = false) = + "${if (declare) "declare" else "define weak"} $returnType @$name(${ + argTypes?.mapIndexed { i: Int, s: LLVMVariable -> + "${s.pointedType} ${if (s.type is LLVMReferenceType && !s.type.byRef) "byval" else ""} %${s.label}" + }?.joinToString()}) #0" + +fun LLVMInstanceOfStandardType(name: String, + type: KotlinType, + scope: LLVMScope = LLVMRegisterScope(), + state: TranslationState): LLVMVariable { + val typeName = type.toString().dropLastWhile { it == '?' } + val pointerMark = if (type.isMarkedNullable) 1 else 0 + return when { + type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type, state), name, scope, pointer = 1) + typeName == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope, pointerMark) + typeName == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope, pointerMark) + typeName == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope, pointerMark) + typeName == "Short" -> LLVMVariable(name, LLVMShortType(), name, scope, pointerMark) + typeName == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope, pointerMark) + typeName == "Long" -> LLVMVariable(name, LLVMLongType(), name, scope, pointerMark) + typeName == "Float" -> LLVMVariable(name, LLVMFloatType(), name, scope, pointerMark) + typeName == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope, pointerMark) + typeName == "String" -> LLVMVariable(name, LLVMStringType(0), name, scope, pointerMark) + type.nameIfStandardType.toString() == "Nothing" -> LLVMVariable(name, LLVMNullType(), name, scope) + type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope) + type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(typeName, prefix = "class"), name, scope, pointer = pointerMark) + else -> { + val declarationDescriptor = type.constructor.declarationDescriptor!! + val refName = declarationDescriptor.fqNameSafe.asString() + val refType = state.classes[type.toString()]?.type ?: LLVMReferenceType(refName, align = TranslationState.POINTER_ALIGN, prefix = "class") + + LLVMVariable(name, refType, name, scope, pointer = 1) + } + } +} + +fun LLVMMapStandardType(type: KotlinType, + state: TranslationState) = + LLVMInstanceOfStandardType("type", type, LLVMRegisterScope(), state).type + +fun String.addBeforeIfNotEmpty(add: String): String = + if (this.length > 0) add + this else this + +fun String.addAfterIfNotEmpty(add: String): String = + if (this.length > 0) this + add else this + +fun FqName.convertToNativeName(): String = + this.asString().replace(".", "") \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt new file mode 100644 index 00000000000..7176186a117 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMArray.kt @@ -0,0 +1,9 @@ +package org.kotlinnative.translator.llvm.types + +interface LLVMArray { + + val arrayElementType: LLVMType + val fullArrayType: String + val length: Int + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt new file mode 100644 index 00000000000..856a030be72 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt @@ -0,0 +1,69 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue +import java.lang.IllegalArgumentException + + +class LLVMBooleanType() : LLVMType() { + + override val align = 4 + override var size: Int = 1 + override val defaultValue = "0" + override val mangle = "Boolean" + override val isPrimitive = true + override val typename = "i1" + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "sub nsw i1 $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "mul nsw i1 $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "add nsw i1 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "sdiv i1 $firstOp, $secondOp") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i1 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i1 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i1 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i1 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "or i1 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "and i1 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "xor i1 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMBooleanType + + override fun parseArg(inputArg: String) = + when (inputArg.toLowerCase()) { + "true" -> "1" + "false" -> "0" + else -> throw IllegalArgumentException("Failed to parse boolean type") + } + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt new file mode 100644 index 00000000000..372b3c1cfe7 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt @@ -0,0 +1,42 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + +class LLVMByteType() : LLVMType() { + + override val align = 1 + override var size: Int = 1 + override val mangle = "Byte" + override val typename = "i8" + override val defaultValue = "0" + override val isPrimitive = true + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMByteType(), "srem i8 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMByteType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt new file mode 100644 index 00000000000..75dbd3bc2c5 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -0,0 +1,41 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + +class LLVMCharType() : LLVMType() { + + override val align = 1 + override var size: Int = 1 + override val mangle = "Char" + override val typename = "i8" + override val defaultValue = "0" + override val isPrimitive = true + + override fun parseArg(inputArg: String) = inputArg.first().toInt().toString() + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMCharType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt new file mode 100644 index 00000000000..f2530e92d11 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -0,0 +1,61 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + + +class LLVMDoubleType() : LLVMType() { + + override val align = 8 + override var size: Int = 8 + override val mangle = "Double" + override val typename = "double" + override val defaultValue = "0.0" + override val isPrimitive = true + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fmul double $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") + + override fun operatorInc(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, 1.0") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fdiv double $firstOp, $secondOp") + + override fun operatorDec(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, 1.0") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp olt double $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ogt double $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ole double i32 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oge double i32 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oeq double $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp one double $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "frem double $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMDoubleType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt new file mode 100644 index 00000000000..b98b18d0b59 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFloatType.kt @@ -0,0 +1,61 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + + +class LLVMFloatType() : LLVMType() { + + override val align = 4 + override var size: Int = 4 + override val mangle = "Float" + override val typename = "float" + override val defaultValue = "0.0" + override val isPrimitive = true + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMFloatType(), "fsub float $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMFloatType(), "fmul float $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMFloatType(), "fadd float $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMFloatType(), "fdiv float $firstOp, $secondOp") + + override fun operatorInc(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fadd float $firstOp, 1.0") + + override fun operatorDec(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMDoubleType(), "fsub float $firstOp, 1.0") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp olt float $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ogt float $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp ole float i32 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oge float i32 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp oeq float" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "fcmp one float" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMFloatType(), "frem float $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMFloatType + + override fun hashCode() = + typename.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt new file mode 100644 index 00000000000..06304e8c0e1 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt @@ -0,0 +1,37 @@ +package org.kotlinnative.translator.llvm.types + +import org.jetbrains.kotlin.types.KotlinType +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType +import org.kotlinnative.translator.llvm.LLVMVariable + +class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() { + + override val defaultValue = "" + override val align: Int = 4 + override var size: Int = 4 + override val mangle: String + override val typename = "FunctionType" + + val arguments: List + val returnType: LLVMVariable + + init { + val types = type.arguments.map { LLVMInstanceOfStandardType("", it.type, state = state) }.toList() + returnType = types.last() + arguments = types.dropLast(1) + mangle = "F.${LLVMType.mangleFunctionArguments(arguments)}.EF" + } + + fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments) + + override fun toString() = + "${returnType.type} (${arguments.map { it.pointedType }.joinToString()})" + + override fun equals(other: Any?) = + (other is LLVMFunctionType) && (mangle == other.mangle) + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt new file mode 100644 index 00000000000..efd61f3a4ed --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -0,0 +1,89 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.exceptions.UnimplementedException +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + + +class LLVMIntType() : LLVMType() { + + override val align = 4 + override var size: Int = 4 + override val defaultValue = "0" + override val mangle = "Int" + override val typename = "i32" + override val isPrimitive = true + + override fun convertFrom(source: LLVMSingleValue) = + when (source.type) { + is LLVMBooleanType, + is LLVMByteType, + is LLVMCharType, + is LLVMShortType -> LLVMExpression(LLVMIntType(), " sext ${source.type} $source to i32") + else -> throw UnimplementedException() + } + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "or i32 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "and i32 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "xor i32 $firstOp, $secondOp") + + override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "shl i32 $firstOp, $secondOp") + + override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "ashr i32 $firstOp, $secondOp") + + override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "lshr i32 $firstOp, $secondOp") + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sdiv i32 $firstOp, $secondOp") + + override fun operatorInc(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, 1") + + override fun operatorDec(firstOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, 1") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i32 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMIntType(), "srem i32 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMIntType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt new file mode 100644 index 00000000000..eafcde9c8ef --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMLongType.kt @@ -0,0 +1,84 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.exceptions.UnimplementedException +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + + +class LLVMLongType() : LLVMType() { + + override val align = 8 + override var size = 8 + override val defaultValue = "0" + override val typename = "i64" + override val mangle = "Long" + override val isPrimitive = true + + override fun convertFrom(source: LLVMSingleValue) = + when (source.type) { + is LLVMBooleanType, + is LLVMByteType, + is LLVMCharType, + is LLVMShortType, + is LLVMIntType -> LLVMExpression(LLVMLongType(), " sext ${source.type} $source to i64") + else -> throw UnimplementedException() + } + + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "or i64 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "and i64 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "xor i64 $firstOp, $secondOp") + + override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "shl i64 $firstOp, $secondOp") + + override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "ashr i64 $firstOp, $secondOp") + + override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "lshr i64 $firstOp, $secondOp") + + override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "sub nsw i64 $firstOp, $secondOp") + + override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "mul nsw i64 $firstOp, $secondOp") + + override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "add nsw i64 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "sdiv i64 $firstOp, $secondOp") + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i64 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMLongType(), "srem i64 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMLongType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt new file mode 100644 index 00000000000..c5d3c935c2b --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt @@ -0,0 +1,20 @@ +package org.kotlinnative.translator.llvm.types + +class LLVMNullType(var baseType: LLVMType? = null) : LLVMType() { + + override val align = 1 + override var size = 0 + override val defaultValue = "null" + override val mangle = "" + override val typename = baseType?.typename.orEmpty() + + override fun parseArg(inputArg: String) = "null" + override fun toString() = baseType?.toString().orEmpty() + + override fun equals(other: Any?) = + other is LLVMNullType + + override fun hashCode() = + "null".hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt new file mode 100644 index 00000000000..86182e1ef4c --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt @@ -0,0 +1,32 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue +import org.kotlinnative.translator.llvm.addAfterIfNotEmpty + + +class LLVMReferenceType(val type: String, + var prefix: String = "", + override var align: Int = TranslationState.POINTER_ALIGN, + override var size: Int = TranslationState.POINTER_SIZE, + var byRef: Boolean = true) : LLVMType() { + + override val defaultValue: String = "null" + override val mangle = "Ref_$type" + override val typename = prefix.addAfterIfNotEmpty(".") + type + + override fun toString() = "%$typename" + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}") + + override fun equals(other: Any?) = + (other is LLVMReferenceType) and (typename.equals((other as LLVMReferenceType).typename)) + + override fun hashCode() = + typename.hashCode() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt new file mode 100644 index 00000000000..bb4b07167cf --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -0,0 +1,45 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + +class LLVMShortType() : LLVMType() { + + override val align = 2 + override var size: Int = 2 + override val defaultValue = "0" + override val typename = "i16" + override val mangle = "Short" + override val isPrimitive = true + + override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp slt i16 $firstOp, $secondOp") + + override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sgt i16 $firstOp, $secondOp") + + override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sle i16 $firstOp, $secondOp") + + override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp sge i16 $firstOp, $secondOp") + + override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp eq i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMBooleanType(), "icmp ne i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp") + + override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMShortType(), "srem i16 $firstOp, $secondOp") + + override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) = + LLVMExpression(LLVMShortType(), "sdiv i16 $firstOp, $secondOp") + + override fun equals(other: Any?) = + other is LLVMShortType + + override fun hashCode() = + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt new file mode 100644 index 00000000000..463429c9249 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMStringType.kt @@ -0,0 +1,23 @@ +package org.kotlinnative.translator.llvm.types + +class LLVMStringType(override val length: Int, var isLoaded: Boolean = true) : LLVMArray, LLVMType() { + + override val align = 8 + override var size: Int = 1 + override val defaultValue = "" + override val typename = "i8*" + override val mangle = "String" + override val arrayElementType = LLVMCharType() + override val fullArrayType = "[${length + 1} x i8]" + + override fun equals(other: Any?) = + when (other) { + is LLVMStringType -> this.length == other.length + else -> false + } + + override fun hashCode() = + length * 31 + if (isLoaded) 1 else 0 + + mangle.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt new file mode 100644 index 00000000000..09bb453ae22 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -0,0 +1,55 @@ +package org.kotlinnative.translator.llvm.types + +import org.kotlinnative.translator.exceptions.UnimplementedException +import org.kotlinnative.translator.llvm.LLVMExpression +import org.kotlinnative.translator.llvm.LLVMSingleValue + +abstract class LLVMType() { + + companion object { + fun mangleFunctionArguments(names: List) = + mangleFunctionTypes(names.map { it.type }) + + fun mangleFunctionTypes(names: List) = + if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else "" + + fun nullOrVoidType(type: LLVMType): Boolean = + (type is LLVMNullType) or (type is LLVMVoidType) + + fun isReferredType(type: LLVMType?): Boolean = + (type is LLVMNullType) or (type is LLVMReferenceType) + + } + + abstract val align: Int + abstract val typename: String + abstract var size: Int + abstract val defaultValue: String + abstract val mangle: String + open val isPrimitive: Boolean = false + + open fun parseArg(inputArg: String) = inputArg + open fun convertFrom(source: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + override fun toString() = typename + + open fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + open fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt new file mode 100644 index 00000000000..74d7359ad53 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -0,0 +1,17 @@ +package org.kotlinnative.translator.llvm.types + +class LLVMVoidType() : LLVMType() { + + override val align = 0 + override var size = 0 + override val defaultValue = "" + override val typename = "void" + override val mangle = "" + + override fun equals(other: Any?) = + other is LLVMVoidType + + override fun hashCode() = + typename.hashCode() + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.kt b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.kt new file mode 100644 index 00000000000..0e36a037c22 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.kt @@ -0,0 +1,63 @@ +fun array_extensions_1_copyOf(): Int { + val array = IntArray(3) + array[0] = 1 + array[1] = 20 + array[2] = 333 + val minimize = array.copyOf(2) + return minimize[1] + minimize.size +} + +fun array_extensions_1_copyOf_extend(): Int { + val array = IntArray(3) + array[0] = 1 + array[1] = 20 + array[2] = 333 + val minimize = array.copyOf(7) + return minimize[2] + minimize[3] + minimize[4] + minimize[5] + minimize[6] + minimize.size +} + +fun array_extensions_1_copyOfRange(): Int { + val array = IntArray(7) + array[0] = 1 + array[1] = 20 + array[2] = 333 + array[3] = 444 + array[4] = 555 + array[5] = 666 + array[6] = 777 + + val minimize = array.copyOfRange(2, 4) + val ans = minimize[0] + minimize[1] + minimize.size + return ans +} + +fun array_extensions_1_plus_element(): Int { + val array = IntArray(7) + array[0] = 1 + array[1] = 20 + array[2] = 333 + array[3] = 444 + array[4] = 555 + array[5] = 666 + array[6] = 777 + + val minimize = array.plus(2148) + return minimize[6] + minimize[7] + minimize.size +} + +fun array_extensions_1_plus_array(): Int { + val array = IntArray(3) + array[0] = 1 + array[1] = 20 + array[2] = 333 + val secondArray = IntArray(4) + secondArray[0] = 9999 + secondArray[1] = 2789 + secondArray[2] = 11792 + secondArray[3] = 67820 + + val maximize = array.plus(secondArray) + val ans = maximize[2] + maximize[5] + maximize.size + return ans +} + diff --git a/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.txt b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.txt new file mode 100644 index 00000000000..7856f082977 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_1/array_extensions_1.txt @@ -0,0 +1,5 @@ +array_extensions_1_copyOf() == 22 +array_extensions_1_copyOfRange() == 779 +array_extensions_1_copyOf_extend() == 340 +array_extensions_1_plus_element() == 2933 +array_extensions_1_plus_array() == 12132 diff --git a/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.kt b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.kt new file mode 100644 index 00000000000..3fa1227e323 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.kt @@ -0,0 +1,11 @@ +fun array_extensions_2_plus_array_slave(): Int { + var array = IntArray(0) + array = array.plus(10) + println(array[0]) + + return array[0] +} + +fun array_extensions_2_plus_array(): Int{ + return array_extensions_2_plus_array_slave() +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.txt b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.txt new file mode 100644 index 00000000000..5c5aa70cd5d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/array_extensions_2/array_extensions_2.txt @@ -0,0 +1 @@ +array_extensions_2_plus_array() == 10 diff --git a/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.kt b/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.kt new file mode 100644 index 00000000000..7e05899e992 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.kt @@ -0,0 +1,17 @@ +fun assignment_operators_1_plus(x: Int): Int { + var nzk = x + nzk += 6 + return nzk +} + +fun assignment_operators_1_minus(x: Int): Int { + var nzk = x + nzk -= 6 + return nzk +} + +fun assignment_operators_1_times(x: Int): Int { + var nzk = x + nzk *= 6 + return nzk +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.txt b/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.txt new file mode 100644 index 00000000000..e1d861a6018 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/assignment_operators_1/assignment_operators_1.txt @@ -0,0 +1,3 @@ +assignment_operators_1_plus_Int(11) == 17 +assignment_operators_1_minus_Int(11) == 5 +assignment_operators_1_times_Int(11) == 66 diff --git a/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.kt b/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.kt new file mode 100644 index 00000000000..b05d0a9e391 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.kt @@ -0,0 +1,10 @@ +fun booleanarray_1_slave(x: Boolean): Boolean { + val z = BooleanArray(10) + z.set(1, x) + return z.get(1) +} + +fun booleanarray_1(x: Boolean): Int { + return if (booleanarray_1_slave(x)) 1 else 0 +} + diff --git a/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.txt b/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.txt new file mode 100644 index 00000000000..b63930e4883 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/booleanarray_1/booleanarray_1.txt @@ -0,0 +1,2 @@ +booleanarray_1_Boolean(1) == 1 +booleanarray_1_Boolean(0) == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.kt b/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.kt new file mode 100644 index 00000000000..416ad831173 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.kt @@ -0,0 +1,25 @@ +fun bytearray_1(x: Byte): Byte { + val z = ByteArray(10) + z.set(1, x) + val r = z.clone() + return r.get(1) +} + +fun bytearray_1_array(): Int { + val size = 256 + val z= ByteArray(size) + var ind = 0 + while(ind < size){ + z[ind] = ind.toByte() + ind +=1 + } + val newInstance = z.clone() + ind = 0 + var result = true + while(ind < size){ + result = result and (newInstance[ind] == ind.toByte()) + ind += 1 + } + assert(result) + return 1 +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.txt b/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.txt new file mode 100644 index 00000000000..21a08e21200 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/bytearray_1/bytearray_1.txt @@ -0,0 +1,2 @@ +bytearray_1_Byte(123) == 123 +bytearray_1_array() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.c b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.c new file mode 100644 index 00000000000..2e4fdfd61c0 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.c @@ -0,0 +1,4 @@ + +int apply_c(int x, int (*foo)(int)) { + return foo(x); +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.kt b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.kt new file mode 100644 index 00000000000..6142fd0e975 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.kt @@ -0,0 +1,26 @@ + +external fun apply_c(arg: Int, x: (Int)-> Int): Int + +fun callback_1_inc(i: Int): Int { + return i + 1 +} + +fun callback_1_dec(i: Int): Int { + return i - 1 +} + +fun callback_1_apply(arg: Int, x: (Int) -> Int): Int { + return x(arg) +} + +fun compact_test(x: Int): Int { + return callback_1_apply(callback_1_apply(callback_1_apply(x, ::callback_1_inc), ::callback_1_inc), ::callback_1_dec) +} + +fun external_test(x: Int): Int { + return apply_c(apply_c(apply_c(x, ::callback_1_dec), ::callback_1_dec), ::callback_1_inc) +} + +fun mixed_test(x: Int): Int { + return callback_1_apply(apply_c(callback_1_apply(apply_c(callback_1_apply(x, ::callback_1_inc), ::callback_1_inc), ::callback_1_inc), ::callback_1_dec), ::callback_1_inc) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.txt b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.txt new file mode 100644 index 00000000000..b52a69f4b95 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/callbacks_1/callbacks_1.txt @@ -0,0 +1,6 @@ +compact_test_Int(1) == 2 +compact_test_Int(3) == 4 +external_test_Int(3) == 2 +external_test_Int(4) == 3 +mixed_test_Int(1) == 4 +mixed_test_Int(9) == 12 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.kt new file mode 100644 index 00000000000..38519d4616d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.kt @@ -0,0 +1,10 @@ +class class_alignment_1_class(var field1: Long, var field2: Int, var field3: Long) + + +fun class_alignment_1(): Long { + val b = class_alignment_1_class(100L, 200, 300L) + assert(b.field1 == 100L) + assert(b.field2 == 200) + assert(b.field3 == 300L) + return b.field3 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.txt new file mode 100644 index 00000000000..5a69fd59e36 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_alignment_1/class_alignment_1.txt @@ -0,0 +1 @@ +class_alignment_1() == 300 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.kt new file mode 100644 index 00000000000..053600335da --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.kt @@ -0,0 +1,12 @@ +class class_class_argument_1_slave + +class class_class_argument_1_master(val buffer: class_class_argument_1_slave) { + var pos = 99999 +} + + +fun class_class_argument_1(): Int { + val buffer = class_class_argument_1_slave() + val output = class_class_argument_1_master(buffer) + return output.pos +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.txt new file mode 100644 index 00000000000..ce212b26272 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_class_argument_1/class_class_argument_1.txt @@ -0,0 +1 @@ +class_class_argument_1() == 99999 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.kt new file mode 100644 index 00000000000..06e3bce17f3 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.kt @@ -0,0 +1,10 @@ +class class_default_argument_1_class(val classArg: Int) { + fun getDefaultValue(arg1: Int, arg2: Int = 11): Int { + return arg1 + arg2 + } +} + +fun class_default_argument_1(z:Int):Int{ + val instance = class_default_argument_1_class(11) + return instance.getDefaultValue(z) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.txt new file mode 100644 index 00000000000..275f8749e76 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_default_argument_1/class_default_argument_1.txt @@ -0,0 +1 @@ +class_default_argument_1_Int(34) == 45 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.kt new file mode 100644 index 00000000000..c072acd3d22 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.kt @@ -0,0 +1,14 @@ +class className(var z: Int) { + init { + this.z = this.z + 12345 + } + + fun getVal(): Int { + return this.z + } +} + +fun class_init_section_1(x: Int): Int { + val z = className(x) + return z.getVal() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.txt new file mode 100644 index 00000000000..45ca7bb7f25 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_init_section_1/class_init_section_1.txt @@ -0,0 +1 @@ +class_init_section_1_Int(523) == 12868 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.kt new file mode 100644 index 00000000000..2ec083afedd --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.kt @@ -0,0 +1,20 @@ +class class_method_access_1_donor(var size: Int) { + fun getSizeVal(): Int { + return size + 4 + } +} + +class class_method_access_1_owner(val arg: class_method_access_1_donor) { + val tKIopsD = 56 + fun getSize(): Int { + return arg.getSizeVal() + 8 + } +} + + +fun class_method_access_1_test(x: Int): Int { + val instance_donor = class_method_access_1_donor(x) + val instance_owner = class_method_access_1_owner(instance_donor) + + return instance_owner.getSize() +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.txt new file mode 100644 index 00000000000..a0bfb5a12c1 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_method_access_1/class_method_access_1.txt @@ -0,0 +1 @@ +class_method_access_1_test_Int(110) == 122 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.kt new file mode 100644 index 00000000000..e96a4229bf4 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.kt @@ -0,0 +1,10 @@ +class class_methods_1_class() { + fun method(t : Int): Int { + return t + 5 + } +} + +fun class_methods_1(zz: Int): Int { + val x = class_methods_1_class() + return x.method(zz) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.txt new file mode 100644 index 00000000000..47c91b155cf --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_methods_1/class_methods_1.txt @@ -0,0 +1 @@ +class_methods_1_Int(55) == 60 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.kt new file mode 100644 index 00000000000..aa04098aae1 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.kt @@ -0,0 +1,12 @@ +class class_reassignment_1_class(val field: Int) + +fun class_reassignment_1_base(): class_reassignment_1_class { + val instance = class_reassignment_1_class(567) + return instance +} + +fun class_reassignment_1(): Int { + var instance = class_reassignment_1_class(123) + instance = class_reassignment_1_base() + return instance.field +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.txt new file mode 100644 index 00000000000..1a15c1493a0 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_1/class_reassignment_1.txt @@ -0,0 +1 @@ +class_reassignment_1() == 567 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.kt b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.kt new file mode 100644 index 00000000000..0614be58541 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.kt @@ -0,0 +1,15 @@ +class class_reassignment_2_Node { + var left: class_reassignment_2_Node? = null + var right: class_reassignment_2_Node? = null + var value: Int = 0 +} + +fun class_reassignment_2(): Int { + val root: class_reassignment_2_Node = class_reassignment_2_Node() + root.value = 12 + root.left = class_reassignment_2_Node() + var current: class_reassignment_2_Node? = root + current = root.left + current!!.value = 10593 + return current.value + root.value +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.txt b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.txt new file mode 100644 index 00000000000..bc9cdca2635 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_reassignment_2/class_reassignment_2.txt @@ -0,0 +1 @@ +class_reassignment_2() == 10605 diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.kt b/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.kt new file mode 100644 index 00000000000..5b26f1dd992 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.kt @@ -0,0 +1,18 @@ +class class_variable_access_1_donor(var size: Int) { + val data: Int = 5 +} + +class class_variable_access_1_owner(val arg: class_variable_access_1_donor) { + val tKIopsD = 56 + fun getSize(): Int { + return arg.size + 8 + } +} + + +fun class_variable_access_1_test(x: Int): Int { + val instance_donor = class_variable_access_1_donor(x) + val instance_owner = class_variable_access_1_owner(instance_donor) + + return instance_owner.getSize() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.txt b/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.txt new file mode 100644 index 00000000000..70a561973bc --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/class_variable_access_1/class_variable_access_1.txt @@ -0,0 +1 @@ +class_variable_access_1_test_Int(22) == 30 diff --git a/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.kt b/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.kt new file mode 100644 index 00000000000..336e735340b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.kt @@ -0,0 +1,19 @@ + +class WithFields(var i: Int) { + + var j: Int + + init { + this.j = this.i + } +} + +fun test_simple_field(): Int { + val i = WithFields(1) + return i.j +} + +fun test_field_assignment(i: Int): Int { + val k = WithFields(i) + return k.j +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.txt b/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.txt new file mode 100644 index 00000000000..c9752a96500 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/classfields_1/classfields_1.txt @@ -0,0 +1,2 @@ +test_simple_field() == 1 +test_field_assignment_Int(10) == 10 diff --git a/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.kt b/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.kt new file mode 100644 index 00000000000..df314f3ef48 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.kt @@ -0,0 +1,26 @@ +class classfields_2_class { + var i = 0 + + fun method() { + i = 5 + } + + fun changeI(): Int { + method() + return i + } +} + +fun test1(): Int { + val main = classfields_2_class() + return main.changeI() +} + +fun test2(): Int { + val main = classfields_2_class() + return main.i +} + +fun test3(): Int { + return classfields_2_class().changeI() +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.txt b/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.txt new file mode 100644 index 00000000000..bfd66e4ee12 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/classfields_2/classfields_2.txt @@ -0,0 +1,3 @@ +test1() == 5 +test2() == 0 +test3() == 5 diff --git a/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.kt b/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.kt new file mode 100644 index 00000000000..e5f449ac530 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.kt @@ -0,0 +1,13 @@ +class companion_object_1 { + companion object { + val fieldCompanion: Int = 5790 + + fun create(): Int { + return 5 + } + } +} + +fun companion_object_1_test(): Int { + return companion_object_1.create() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.txt b/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.txt new file mode 100644 index 00000000000..36a4313f03d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/companion_object_1/companion_object_1.txt @@ -0,0 +1 @@ +companion_object_1_test() == 5 diff --git a/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.kt b/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.kt new file mode 100644 index 00000000000..8e41a27e35f --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.kt @@ -0,0 +1,14 @@ +class companion_object_2 { + companion object { + var fieldCompanion: Int = 5790 + + fun create(): Int { + return 5 + } + } +} + +fun companion_object_2_test(v: Int): Int { + companion_object_2.fieldCompanion = 239 + v + return companion_object_2.fieldCompanion +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.txt b/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.txt new file mode 100644 index 00000000000..15cd9d8666f --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/companion_object_2/companion_object_2.txt @@ -0,0 +1 @@ +companion_object_2_test_Int(5) == 244 diff --git a/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.kt b/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.kt new file mode 100644 index 00000000000..0957a99f4c0 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.kt @@ -0,0 +1,7 @@ + +class complex_dot_expr_MyClass(val i: Int) + +fun gen(i: Int) = complex_dot_expr_MyClass(i) +fun test1(q: Int) = gen(q).i +fun test2(w: Int) = complex_dot_expr_MyClass(w).i + diff --git a/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.txt b/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.txt new file mode 100644 index 00000000000..680416f84f3 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/complex_dot_expr/complex_dot_expr.txt @@ -0,0 +1,2 @@ +test1_Int(1) == 1 +test2_Int(2) == 2 diff --git a/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.kt b/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.kt new file mode 100644 index 00000000000..8fe160d884c --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.kt @@ -0,0 +1,18 @@ +class declaration_test_1_cls() + +fun declaration_test_1_variable(): Int { + val a: Int + a = 85 + return a +} + +fun declaration_test_1_class_slave(): declaration_test_1_cls { + val a: declaration_test_1_cls + a = declaration_test_1_cls() + return a +} + + +fun declaration_test_1_class(): Int { + return if (declaration_test_1_class_slave() == null) 10 else 96799 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.txt b/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.txt new file mode 100644 index 00000000000..f083d5e5193 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/declaration_test_1/declaration_test_1.txt @@ -0,0 +1,2 @@ +declaration_test_1_variable() == 85 +declaration_test_1_class() == 96799 diff --git a/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.kt b/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.kt new file mode 100644 index 00000000000..dcd5fedb968 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.kt @@ -0,0 +1,45 @@ +class dfs_1_Node { + var left: dfs_1_Node? = null + var right: dfs_1_Node? = null + var value: Int = 0 +} + +fun dfs_1_search(x: dfs_1_Node, value: Int): dfs_1_Node? { + if (x.value == value) { + return x + } + + if (x.left != null) { + val result = dfs_1_search(x.left!!, value) + if (result != null) { + return result + } + } + if (x.right != null) { + val result = dfs_1_search(x.right!!, value) + if (result != null) { + return result + } + } + return null +} + +fun dfs_1(searchObject: Int): Int { + var i = 0 + val root: dfs_1_Node? = dfs_1_Node() + root!!.value = 111 + var current = root + while (i < 10) { + current!!.left = dfs_1_Node() + current.right = dfs_1_Node() + current.value = i + current = current.left + i++ + } + val result = dfs_1_search(root, searchObject) + if (result == null) { + return -101 + } else { + return result.value + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.txt b/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.txt new file mode 100644 index 00000000000..98f7941352e --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/dfs_1/dfs_1.txt @@ -0,0 +1,3 @@ +dfs_1_Int(73) == -101 +dfs_1_Int(8) == 8 +dfs_1_Int(9) == 9 diff --git a/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.kt b/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.kt new file mode 100644 index 00000000000..d7379034506 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.kt @@ -0,0 +1,11 @@ +fun different_type_binary_operator_1_shr(x: Int, y: Long): Long { + return y shr x +} + +fun different_type_binary_operator_1_shl(x: Int, y: Long): Long { + return y shl x +} + +fun different_type_binary_operator_1_ushr(x: Int, y: Long): Long { + return y ushr x +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.txt b/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.txt new file mode 100644 index 00000000000..2e6342034ce --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/different_type_binary_operator_1/different_type_binary_operator_1.txt @@ -0,0 +1,3 @@ +different_type_binary_operator_1_shl_Int_Long(10, 5) == 5120 +different_type_binary_operator_1_shr_Int_Long(5, 5000) == 156 +different_type_binary_operator_1_ushr_Int_Long(5, 5000) == 156 diff --git a/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.kt b/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.kt new file mode 100644 index 00000000000..528bf62c37b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.kt @@ -0,0 +1,7 @@ +fun do_while_test_1(x: Int): Int { + var t = x + do { + t = t + 1 + } while (2 > 3) + return t +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.txt b/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.txt new file mode 100644 index 00000000000..623a6c1cd84 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/do_while_1/do_while_1.txt @@ -0,0 +1,2 @@ +do_while_test_1_Int(5) == 6 +do_while_test_1_Int(57) == 58 diff --git a/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.kt b/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.kt new file mode 100644 index 00000000000..e586e3ca698 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.kt @@ -0,0 +1,20 @@ + +class elvis_1_MyClass(val i: Int) + +fun elvis_test_1(x: Int): Int { + var z: elvis_1_MyClass? = null + + if (x > 1) { + z = elvis_1_MyClass(1) + } else { + } + + z ?: return 0 + return 1 +} + +fun elvis_test_2(): Int { + val i: elvis_1_MyClass? = null + i ?: return 1 + return 0 +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.txt b/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.txt new file mode 100644 index 00000000000..5d10fe216cc --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/elvis_1/elvis_1.txt @@ -0,0 +1,3 @@ +elvis_test_1_Int(0) == 0 +elvis_test_1_Int(2) == 1 +elvis_test_2() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.kt b/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.kt new file mode 100644 index 00000000000..3754ffc5bb2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.kt @@ -0,0 +1,20 @@ + +class Holder() { + + enum class nested(val id: Int) { + FIRST(0), + SECOND(1), + THIRD(3); + + companion object { + fun functor(ord: Int): Int { + return nested.FIRST.id + } + } + } +} + +fun enum_complex_test1(): Int { + val h = Holder() + return Holder.nested.functor(0) +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.txt b/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.txt new file mode 100644 index 00000000000..4eea6541a24 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/enum_complex/enum_complex.txt @@ -0,0 +1 @@ +enum_complex_test1() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.kt b/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.kt new file mode 100644 index 00000000000..b9aa36677d4 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.kt @@ -0,0 +1,4 @@ + +fun enum_field_test1(i: Byte): Int { + return WireType.from(i).id +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.txt b/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.txt new file mode 100644 index 00000000000..b569ec5c82d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/enum_inner_fields/enum_inner_fields.txt @@ -0,0 +1,2 @@ +enum_field_test1_Byte(1) == 1 +enum_field_test1_Byte(2) == 2 diff --git a/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.kt b/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.kt new file mode 100644 index 00000000000..951a1fb499b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.kt @@ -0,0 +1,12 @@ +fun floating_point_operators_1_double_leq(x: Double, y: Double): Int { + if (x < y){ + return 1 + } + else{ + return 0 + } +} + +fun floating_point_operators_1_getValue(b: Boolean): Boolean{ + return b +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.txt b/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.txt new file mode 100644 index 00000000000..af281b291ce --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/floating_point_operators_1/floating_point_operators_1.txt @@ -0,0 +1,2 @@ +floating_point_operators_1_double_leq_Double_Double(14.9301, 5.6) == 0 +floating_point_operators_1_double_leq_Double_Double(1.49301, 5.6) == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.kt b/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.kt new file mode 100644 index 00000000000..a540d0fe8ef --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.kt @@ -0,0 +1,7 @@ +fun for_1_simple(): Int { + var sum = 0 + for (i in 10..20) { + sum += i + } + return sum +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.txt b/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.txt new file mode 100644 index 00000000000..3fa1d39457b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/for_1/for_1.txt @@ -0,0 +1 @@ +for_1_simple() == 165 diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.kt b/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.kt new file mode 100644 index 00000000000..d61ee8e9c67 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.kt @@ -0,0 +1,59 @@ +class function_default_arguments_1_argClass(val classArgument: Int) + +fun function_default_arguments_1_add(x: Int, t: function_default_arguments_1_argClass = function_default_arguments_1_argClass(124), y: Int = 53, z: Int = 777): Int { + return x + y +} + +fun function_default_arguments_1_add_class(x: Int, t: function_default_arguments_1_argClass = function_default_arguments_1_argClass(124), y: Int = 53, z: Int = 777): Int { + return x + t.classArgument +} + +fun function_default_arguments_1_add_class_arg(): Int { + return function_default_arguments_1_add_class(190) +} + +fun function_default_arguments_1_mixed(): Int { + return function_default_arguments_1_add(23, t = function_default_arguments_1_argClass(29), z = 8) +} + +fun function_default_arguments_1_last_missed_fun(z: Int, u: Int = 954): Int { + return z + u +} + +fun function_default_arguments_1_last_missed(x: Int): Int { + return function_default_arguments_1_last_missed_fun(x) +} + +fun function_default_arguments_1_last_present(x: Int): Int { + return function_default_arguments_1_last_missed_fun(x, 29) +} + +fun function_default_arguments_1_position_fun(first: Int, second: Int = 324 + , third: Int = 2531): Int { + return first + 2 * second + 3 * third +} + +fun function_default_arguments_1_position_third_only(x: Int): Int { + return function_default_arguments_1_position_fun(11, third = x) +} + +fun function_default_arguments_1_position_all_reverse(x: Int): Int { + return function_default_arguments_1_position_fun(11, third = x, second = 32) +} + +fun function_default_arguments_1_position_all_right_order(x: Int): Int { + return function_default_arguments_1_position_fun(11, second = 32, third = x) +} + +fun function_default_arguments_1_position_all_default(x: Int): Int { + return function_default_arguments_1_position_fun(x) +} + +fun function_default_arguments_1_all_position_fun(first: Int = 31, second: Int = 32 + , third: Int = 33): Int { + return first + 2 * second + 3 * third +} + +fun function_default_arguments_1_all_position(): Int { + return function_default_arguments_1_all_position_fun() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.txt b/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.txt new file mode 100644 index 00000000000..11457898ed6 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_default_arguments_1/function_default_arguments_1.txt @@ -0,0 +1,9 @@ +function_default_arguments_1_mixed() == 76 +function_default_arguments_1_last_missed_Int(23) == 977 +function_default_arguments_1_last_present_Int(25) == 54 +function_default_arguments_1_position_third_only_Int(19) == 716 +function_default_arguments_1_position_all_reverse_Int(17) == 126 +function_default_arguments_1_position_all_right_order_Int(17) == 126 +function_default_arguments_1_position_all_default_Int(27) ==8268 +function_default_arguments_1_all_position() == 194 +function_default_arguments_1_add_class_arg() == 314 diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.kt b/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.kt new file mode 100644 index 00000000000..c4a81cd9a52 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.kt @@ -0,0 +1,7 @@ +class function_eq_MyClass(val i: Int) + +fun function_eq_inc(i: Int) = i + 1 +fun function_eq_dinc(i: Int) = function_eq_inc(function_eq_inc(i)) +fun function_eq_sum(i: Int, j: Int) = i + j +fun function_eq_gen() = function_eq_MyClass(1) + diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.txt b/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.txt new file mode 100644 index 00000000000..d82c425eb18 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_eq/function_eq.txt @@ -0,0 +1,3 @@ +function_eq_inc_Int(1) == 2 +function_eq_dinc_Int(1) == 3 +function_eq_sum_Int_Int(1, 1) == 2 \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.kt b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.kt new file mode 100644 index 00000000000..8629bc20b33 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.kt @@ -0,0 +1,7 @@ +fun Int.compareTo(x: Int) : Int{ + return this + x + 5 +} + +fun function_extensions_1(x : Int): Int { + return x.compareTo(1) + 39.compareTo(123) +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.txt b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.txt new file mode 100644 index 00000000000..02d21684ce2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_1/function_extensions_1.txt @@ -0,0 +1 @@ +function_extensions_1_Int(118) == 291 diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.kt b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.kt new file mode 100644 index 00000000000..1e752421e68 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.kt @@ -0,0 +1,31 @@ +class function_extensions_double_argument_1_slave(val buffer: IntArray) { + var pos = 0 + + fun read(): Int { + pos += 1 + val pe = pos - 1 + return buffer[pe] + } + + fun isAtEnd(): Boolean { + return pos >= buffer.size + } +} + +fun function_extensions_double_argument_1_master(inputStream: function_extensions_double_argument_1_slave): Int { + return inputStream.read().toInt() +} + +fun function_extensions_double_argument_1(): Int { + val array = IntArray(7) + array[0] = 129 + array[1] = 20 + array[2] = 333 + array[3] = 444 + array[4] = 555 + array[5] = 666 + array[6] = 777 + + val kis = function_extensions_double_argument_1_slave(array) + return function_extensions_double_argument_1_master(kis) +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.txt b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.txt new file mode 100644 index 00000000000..9707169f1ff --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/function_extensions_double_argument_1/function_extensions_double_argument_1.txt @@ -0,0 +1 @@ +function_extensions_double_argument_1() == 129 diff --git a/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.kt b/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.kt new file mode 100644 index 00000000000..be0cf8f2055 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.kt @@ -0,0 +1,22 @@ +class get_set_operators_1_class { + var cap = 9 + + operator fun get(x: Int): Int { + return x + 8 + } + + operator fun set(x: Int, y: Int): Unit { + cap = x + y + } +} + +fun get_set_operators_1_get(arg: Int): Int { + val b = get_set_operators_1_class() + return b[arg] +} + +fun get_set_operators_1_set(ind: Int, arg: Int): Int { + val b = get_set_operators_1_class() + b[ind] = arg + return b.cap +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.txt b/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.txt new file mode 100644 index 00000000000..3d5585514ca --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/get_set_operators_1/get_set_operators_1.txt @@ -0,0 +1,2 @@ +get_set_operators_1_get_Int(210) == 218 +get_set_operators_1_set_Int_Int(8, 903) == 911 diff --git a/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.kt b/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.kt new file mode 100644 index 00000000000..e3b461b4d81 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.kt @@ -0,0 +1,11 @@ + +val MY_FIRST_CONSTANT: Int = 3000 +val MY_SECOND_CONSTANT: Int = 4000 + +fun global_test1(): Int { + return MY_FIRST_CONSTANT +} + +fun global_test2(): Int { + return MY_SECOND_CONSTANT + 1 +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.txt b/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.txt new file mode 100644 index 00000000000..49891d465b9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/global_vars_1/global_vars_1.txt @@ -0,0 +1,2 @@ +global_test1() == 3000 +global_test2() == 4001 diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.kt b/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.kt new file mode 100644 index 00000000000..59a1cace462 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.kt @@ -0,0 +1,30 @@ +fun if_test_1(x: Int): Int { + var a = 0 + if (x > 5) { + a = 10 + } else { + + } + return a +} + +class MyClass_if_1() + +fun if_test_null(x: Int): Int { + val y: MyClass_if_1? = null + if (y == null) { + return 1 + } else { + return 0 + } +} + +fun if_test_null_2(x: Int): Int { + val y: MyClass_if_1? = MyClass_if_1() + + if (y == null) { + return 1 + } else { + return 0 + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.txt b/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.txt new file mode 100644 index 00000000000..04b802d5ac2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_1/if_1.txt @@ -0,0 +1,4 @@ +if_test_1_Int(11) == 10 +if_test_1_Int(0) == 0 +if_test_null_Int(0) == 1 +if_test_null_2_Int(0) == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.kt b/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.kt new file mode 100644 index 00000000000..a8285242c9e --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.kt @@ -0,0 +1,7 @@ +fun if_without_else_2(x: Int): Int { + var res = 1256 + if (x > 10) { + res = res + 64 + } + return res +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.txt b/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.txt new file mode 100644 index 00000000000..8032016fa28 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_2/if_2.txt @@ -0,0 +1,2 @@ +if_without_else_2_Int(5) == 1256 +if_without_else_2_Int(55) == 1320 diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.kt b/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.kt new file mode 100644 index 00000000000..3d0dc982a00 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.kt @@ -0,0 +1,3 @@ +fun if_boolean_argument_1(value: Boolean): Int { + return if (value) 11 else 411 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.txt b/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.txt new file mode 100644 index 00000000000..ac65c173312 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_boolean_argument_1/if_boolean_argument_1.txt @@ -0,0 +1,2 @@ +if_boolean_argument_1_Boolean(1) == 11 +if_boolean_argument_1_Boolean(0) == 411 diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.kt b/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.kt new file mode 100644 index 00000000000..f54b5975929 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.kt @@ -0,0 +1,9 @@ +fun if_expression_1(x: Int): Int{ + return if (x > 55) 2323 else 678934 +} + +fun if_expression_1_variable(x: Int): Int{ + val first = 5 + val second = 7 + return if (x > 55) first else second +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.txt b/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.txt new file mode 100644 index 00000000000..7de745ef4c7 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/if_expression_1/if_expression_1.txt @@ -0,0 +1,4 @@ +if_expression_1_Int(56) == 2323 +if_expression_1_Int(-58) == 678934 +if_expression_1_variable_Int(100) == 5 +if_expression_1_variable_Int(-100) == 7 diff --git a/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.kt b/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.kt new file mode 100644 index 00000000000..9e933327051 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.kt @@ -0,0 +1,21 @@ +class initialization_in_place_and_this_1_slave_1(var size: Int) + +class initialization_in_place_and_this_1_master(var buffer: initialization_in_place_and_this_1_slave_1) { + var output = initialization_in_place_and_this_1_slave_2(buffer) +} + +class initialization_in_place_and_this_1_slave_2(val buffer: initialization_in_place_and_this_1_slave_1) { + var pos = 897 + var sz: Int + + init { + sz = buffer.size + } +} + + +fun initialization_in_place_and_this_1(): Int { + val slave = initialization_in_place_and_this_1_slave_1(100) + val master = initialization_in_place_and_this_1_master(slave) + return master.output.sz +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.txt b/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.txt new file mode 100644 index 00000000000..c36054ac9bd --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/initialization_in_place_and_this_1/initialization_in_place_and_this_1.txt @@ -0,0 +1 @@ +initialization_in_place_and_this_1() == 100 diff --git a/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.kt b/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.kt new file mode 100644 index 00000000000..7fd9f5e7010 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.kt @@ -0,0 +1,8 @@ +class initialized_class_fields_1_class { + var pos: Int = 524 +} + +fun initialized_class_fields_1(): Int { + val instance = initialized_class_fields_1_class() + return instance.pos +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.txt b/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.txt new file mode 100644 index 00000000000..b84e32f984d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/initialized_class_fields_1/initialized_class_fields_1.txt @@ -0,0 +1 @@ +initialized_class_fields_1() == 524 diff --git a/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.kt b/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.kt new file mode 100644 index 00000000000..7260c911f01 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.kt @@ -0,0 +1,5 @@ +fun intarray_1(x: Int): Int { + val z = IntArray(10) + z.set(1, x) + return z.get(1) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.txt b/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.txt new file mode 100644 index 00000000000..c80b9ebecd9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/intarray_1/intarray_1.txt @@ -0,0 +1 @@ +intarray_1_Int(123) == 123 diff --git a/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.kt b/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.kt new file mode 100644 index 00000000000..9d89e8603c5 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.kt @@ -0,0 +1,5 @@ +fun long_operations_1_Multiplication():Int { + assert(546344378L * 54321678L == 29678343378826284L) + assert(4556656L*67879230 == 309302300654880L) + return 29 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.txt b/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.txt new file mode 100644 index 00000000000..9ed3453cf6b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/long_operations_1/long_operations_1.txt @@ -0,0 +1 @@ +long_operations_1_Multiplication() == 29 diff --git a/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.kt b/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.kt new file mode 100644 index 00000000000..c0dfd2b4f93 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.kt @@ -0,0 +1,24 @@ + +class Outer() { + + class Nested(var i: Int) { + + fun test(): Int { + this.i = 5 + return this.i + } + } +} + +fun nested_test_1(k: Int): Int { + val j = Outer.Nested(k - 1) + j.i = k + + return j.i +} + +fun nested_test_2(k: Int): Int { + val j = Outer.Nested(k - 1) + + return j.test() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.txt b/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.txt new file mode 100644 index 00000000000..bf3c12da2a9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nested_classes/nested_classes.txt @@ -0,0 +1,2 @@ +nested_test_1_Int(1) == 1 +nested_test_2_Int(1) == 5 diff --git a/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.kt b/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.kt new file mode 100644 index 00000000000..6c767687bff --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.kt @@ -0,0 +1,32 @@ +class null_comparison_1_class + +fun null_comparison_1_getClass(): null_comparison_1_class? { + return null +} + +fun null_comparison_1(): Int { + val a: null_comparison_1_class? = null_comparison_1_getClass() + println(if (a == null) 555 else 9990) + if (a == null) { + return 87 + } + return 945 +} + +fun null_comparison_1_reassigned(): Int { + var a: null_comparison_1_class? = null_comparison_1_class() + a = null_comparison_1_getClass() + if (a == null) { + return 87 + } + return 945 +} + +fun null_comparison_1_declaration(): Int { + val a: null_comparison_1_class? + a = null_comparison_1_getClass() + if (a == null) { + return 87 + } + return 945 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.txt b/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.txt new file mode 100644 index 00000000000..697fbb8bfa7 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/null_comparison_1/null_comparison_1.txt @@ -0,0 +1,3 @@ +null_comparison_1() == 87 +null_comparison_1_reassigned() == 87 +null_comparison_1_declaration() == 87 diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.kt b/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.kt new file mode 100644 index 00000000000..854042d2a9d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.kt @@ -0,0 +1,30 @@ +class nullable_1_MyAwesomeClass(var i: Int) + +fun nullable_1_test(i: Int): Int { + var x: nullable_1_MyAwesomeClass? = null + x = nullable_1_MyAwesomeClass(i) + return x.i +} + +fun nullable_1_test_2(i: Int): Int { + var x: nullable_1_MyAwesomeClass? = nullable_1_MyAwesomeClass(i) + x = null + x = nullable_1_MyAwesomeClass(i) + + return x.i + 1 +} + +fun nullable_1_test_2_npe_operator(i: Int): Int { + val x: nullable_1_MyAwesomeClass? = nullable_1_MyAwesomeClass(i) + x!! + return x.i + 555 +} + +fun nullable_1_test_null_return_slave():nullable_1_MyAwesomeClass?{ + return null +} + +fun nullable_1_test_null_return():Int{ + return 11 + //return if (nullable_1_test_null_return_slave() == null) 11 else -24 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.txt b/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.txt new file mode 100644 index 00000000000..94d6b6a5c9b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_1/nullable_1.txt @@ -0,0 +1,4 @@ +nullable_1_test_Int(1) == 1 +nullable_1_test_2_Int(4) == 5 +nullable_1_test_2_npe_operator_Int(23) == 578 +nullable_1_test_null_return() == 11 diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.kt b/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.kt new file mode 100644 index 00000000000..71f3a410e08 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.kt @@ -0,0 +1,32 @@ +class nullable_class_fields_1_class { + var left: nullable_class_fields_1_class? = null + var right: Int? = null +} + +fun nullable_class_fields_1_primitives(): Int { + val a = nullable_class_fields_1_class() + if (a.right == null) { + return 29 + } else { + return 28 + } +} + +fun nullable_class_fields_1_classes(): Int { + val a = nullable_class_fields_1_class() + if (a.left == null) { + return 29 + } else { + return 28 + } +} + +fun nullable_class_fields_1_classes_not_null(): Int { + val a = nullable_class_fields_1_class() + a.left = nullable_class_fields_1_class() + if (a.left == null) { + return 29 + } else { + return 28 + } +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.txt b/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.txt new file mode 100644 index 00000000000..3269ec40847 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_class_fields_1/nullable_class_fields_1.txt @@ -0,0 +1,3 @@ +nullable_class_fields_1_primitives() == 29 +nullable_class_fields_1_classes() == 29 +nullable_class_fields_1_classes_not_null() == 28 diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.kt b/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.kt new file mode 100644 index 00000000000..2f8d1b053d9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.kt @@ -0,0 +1,41 @@ +fun nullable_primitive_types_1_small(): Int { + var variable: Int? = null + variable = 29 + val art: Int? = variable + return art!! +} + +fun nullable_primitive_types_1_extern(x: Int): Int { + val variable: Int? = x + val art: Int? = variable!! + 8 + return art!! +} + +fun nullable_primitive_types_1_if_null(): Int { + val variable: Int? = null + if (variable == null) { + return 11 + } else { + return 2245 + } +} + +fun nullable_primitive_types_1_if_not_null(): Int { + val variable: Int? = null + if (variable != null) { + return 11 + } else { + return 2245 + } +} + +fun nullable_primitive_types_1_reassignment(): Int { + var z: Int? = 32 + z = null + val r = z + if (r == null) { + return 5678 + } else { + return 13 + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.txt b/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.txt new file mode 100644 index 00000000000..34fb6ab22e3 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/nullable_primitive_types_1/nullable_primitive_types_1.txt @@ -0,0 +1,5 @@ +nullable_primitive_types_1_small() == 29 +nullable_primitive_types_1_extern_Int(11) == 19 +nullable_primitive_types_1_if_null() == 11 +nullable_primitive_types_1_if_not_null() == 2245 +nullable_primitive_types_1_reassignment() == 5678 diff --git a/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.kt b/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.kt new file mode 100644 index 00000000000..f28935d2e7f --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.kt @@ -0,0 +1,13 @@ +fun numeric_literals_1(x: Int): Int { + return x +} + +fun numeric_literals_1_LL(): Long { + val k = 320L + return k +} + +fun numeric_literals_1_Binary(): Int { + val k = 0b01111111 + return k +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.txt b/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.txt new file mode 100644 index 00000000000..067b988201b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/numeric_literals_1/numeric_literals_1.txt @@ -0,0 +1,3 @@ +numeric_literals_1_Int(0x20) == 32 +numeric_literals_1_LL() == 320 +numeric_literals_1_Binary() == 127 diff --git a/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.kt b/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.kt new file mode 100644 index 00000000000..4c1cc3eac15 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.kt @@ -0,0 +1,16 @@ +object Singleton { + + val i: Int = 123456789 + + fun create(x : Int): Int { + return x * 8 + } +} + +fun singleton_test(i: Int): Int { + return Singleton.create(i) +} + +fun singleton_test2(): Int { + return Singleton.i +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.txt b/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.txt new file mode 100644 index 00000000000..b98970c95f2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/object_1/object_1.txt @@ -0,0 +1,2 @@ +singleton_test_Int(5) == 40 +singleton_test2() == 123456789 diff --git a/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.kt b/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.kt new file mode 100644 index 00000000000..593be691da8 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.kt @@ -0,0 +1,35 @@ +fun postfix_1_plus_before(x: Int): Int { + var xx = x + val z = xx++ + return z +} + +fun postfix_1_plus_after(x: Int): Int { + var xx = x + val z = xx++ + return xx +} + +fun postfix_1_plus_inside(x: Int): Int { + var xx = x + xx++ + return xx +} + +fun postfix_1_minus_before(x: Int): Int { + var xx = x + val z = xx-- + return z +} + +fun postfix_1_minus_after(x: Int): Int { + var xx = x + val z = xx-- + return xx +} + +fun postfix_1_minus_inside(x: Int): Int { + var xx = x + xx-- + return xx +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.txt b/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.txt new file mode 100644 index 00000000000..eca52ca3003 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/postfix_1/postfix_1.txt @@ -0,0 +1,6 @@ +postfix_1_plus_before_Int(20) == 20 +postfix_1_plus_after_Int(20) == 21 +postfix_1_plus_inside_Int(20) == 21 +postfix_1_minus_before_Int(20) == 20 +postfix_1_minus_after_Int(20) == 19 +postfix_1_minus_inside_Int(20) == 19 diff --git a/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.kt b/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.kt new file mode 100644 index 00000000000..ca3ea2ee390 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.kt @@ -0,0 +1,11 @@ +fun testCastToByte(X : Byte): Boolean{ + return 34.toByte() == X +} + +fun testCastToInt(X : Int): Boolean{ + return 34.toInt() == X +} + +fun testCastToShort(X : Short): Boolean{ + return 34.toShort() == X +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.txt b/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.txt new file mode 100644 index 00000000000..3da9e622a39 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/primitives_1/primitives_1.txt @@ -0,0 +1,6 @@ +testCastToInt_Int(32) == 0 +testCastToInt_Int(34) == 1 +testCastToByte_Byte(32) == 0 +testCastToByte_Byte(34) == 1 +testCastToShort_Short(32) == 0 +testCastToShort_Short(34) == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.kt new file mode 100644 index 00000000000..706ab3efe01 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.kt @@ -0,0 +1,1073 @@ +class CrossBranch private constructor () { + //========== Properties =========== + var errorCode: Int = 0 + + //========== Nested classes declarations =========== + class Grandfather private constructor (var rf: CrossBranch.Grandfather.RightFather) { + //========== Properties =========== + //message rf = 1 + + var errorCode: Int = 0 + + //========== Nested classes declarations =========== + class LeftFather private constructor () { + //========== Properties =========== + var errorCode: Int = 0 + + //========== Nested classes declarations =========== + class LeftLeftSon private constructor (var son_field: Int) { + //========== Properties =========== + //int32 son_field = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 son_field = 1 + if (son_field != 0) { + output.writeInt32 (1, son_field) + } + + } + + fun mergeWith (other: CrossBranch.Grandfather.LeftFather.LeftLeftSon) { + son_field = other.son_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + return size + } + + //========== Builder =========== + class BuilderLeftLeftSon constructor (var son_field: Int) { + //========== Properties =========== + //int32 son_field = 1 + fun setSon_field(value: Int): CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon { + son_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 son_field = 1 + if (son_field != 0) { + output.writeInt32 (1, son_field) + } + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.LeftFather.LeftLeftSon { + val res = CrossBranch.Grandfather.LeftFather.LeftLeftSon(son_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + son_field = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + return size + } + + } + + } + + class LeftRightSon private constructor (var son_field: Int) { + //========== Properties =========== + //int32 son_field = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 son_field = 1 + if (son_field != 0) { + output.writeInt32 (1, son_field) + } + + } + + fun mergeWith (other: CrossBranch.Grandfather.LeftFather.LeftRightSon) { + son_field = other.son_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + return size + } + + //========== Builder =========== + class BuilderLeftRightSon constructor (var son_field: Int) { + //========== Properties =========== + //int32 son_field = 1 + fun setSon_field(value: Int): CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon { + son_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 son_field = 1 + if (son_field != 0) { + output.writeInt32 (1, son_field) + } + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.LeftFather.LeftRightSon { + val res = CrossBranch.Grandfather.LeftFather.LeftRightSon(son_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + son_field = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != 0) { + size += WireFormat.getInt32Size(1, son_field) + } + return size + } + + } + + } + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + } + + fun mergeWith (other: CrossBranch.Grandfather.LeftFather) { + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.LeftFather.BuilderLeftFather() + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.LeftFather.BuilderLeftFather() + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + val size = 0 + return size + } + + //========== Builder =========== + class BuilderLeftFather constructor () { + //========== Properties =========== + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.LeftFather { + val res = CrossBranch.Grandfather.LeftFather() + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.LeftFather.BuilderLeftFather { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.LeftFather.BuilderLeftFather { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + val size = 0 + return size + } + + } + + } + + class RightFather private constructor (var rls: CrossBranch.Grandfather.RightFather.RightLeftSon, var rrs: CrossBranch.Grandfather.RightFather.RightRightSon) { + //========== Properties =========== + //message rls = 1 + + //message rrs = 2 + + var errorCode: Int = 0 + + //========== Nested classes declarations =========== + class RightLeftSon private constructor (var son_field: CrossBranch.Grandfather.LeftFather.LeftLeftSon) { + //========== Properties =========== + //message son_field = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message son_field = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(son_field.getSizeNoTag()) + son_field.writeTo(output) + + } + + fun mergeWith (other: CrossBranch.Grandfather.RightFather.RightLeftSon) { + son_field = other.son_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) { + size += son_field.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) { + size += son_field.getSize(1) + } + return size + } + + //========== Builder =========== + class BuilderRightLeftSon constructor (var son_field: CrossBranch.Grandfather.LeftFather.LeftLeftSon) { + //========== Properties =========== + //message son_field = 1 + fun setSon_field(value: CrossBranch.Grandfather.LeftFather.LeftLeftSon): CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon { + son_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message son_field = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(son_field.getSizeNoTag()) + son_field.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.RightFather.RightLeftSon { + val res = CrossBranch.Grandfather.RightFather.RightLeftSon(son_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + son_field.mergeFromWithSize(input, expectedSize) + if (expectedSize != son_field.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) { + size += son_field.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()) { + size += son_field.getSize(1) + } + return size + } + + } + + } + + class RightRightSon private constructor (var son_field: CrossBranch.Grandfather.LeftFather.LeftRightSon) { + //========== Properties =========== + //message son_field = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message son_field = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(son_field.getSizeNoTag()) + son_field.writeTo(output) + + } + + fun mergeWith (other: CrossBranch.Grandfather.RightFather.RightRightSon) { + son_field = other.son_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) { + size += son_field.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) { + size += son_field.getSize(1) + } + return size + } + + //========== Builder =========== + class BuilderRightRightSon constructor (var son_field: CrossBranch.Grandfather.LeftFather.LeftRightSon) { + //========== Properties =========== + //message son_field = 1 + fun setSon_field(value: CrossBranch.Grandfather.LeftFather.LeftRightSon): CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon { + son_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message son_field = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(son_field.getSizeNoTag()) + son_field.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.RightFather.RightRightSon { + val res = CrossBranch.Grandfather.RightFather.RightRightSon(son_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + son_field.mergeFromWithSize(input, expectedSize) + if (expectedSize != son_field.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) { + size += son_field.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (son_field != CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()) { + size += son_field.getSize(1) + } + return size + } + + } + + } + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message rls = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rls.getSizeNoTag()) + rls.writeTo(output) + + //message rrs = 2 + output.writeTag(2, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rrs.getSizeNoTag()) + rrs.writeTo(output) + + } + + fun mergeWith (other: CrossBranch.Grandfather.RightFather) { + rls = other.rls + rrs = other.rrs + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (rls != CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build()) { + size += rls.getSize(1) + } + if (rrs != CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) { + size += rrs.getSize(2) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (rls != CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build()) { + size += rls.getSize(1) + } + if (rrs != CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) { + size += rrs.getSize(2) + } + return size + } + + //========== Builder =========== + class BuilderRightFather constructor (var rls: CrossBranch.Grandfather.RightFather.RightLeftSon, var rrs: CrossBranch.Grandfather.RightFather.RightRightSon) { + //========== Properties =========== + //message rls = 1 + fun setRls(value: CrossBranch.Grandfather.RightFather.RightLeftSon): CrossBranch.Grandfather.RightFather.BuilderRightFather { + rls = value + return this + } + + //message rrs = 2 + fun setRrs(value: CrossBranch.Grandfather.RightFather.RightRightSon): CrossBranch.Grandfather.RightFather.BuilderRightFather { + rrs = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message rls = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rls.getSizeNoTag()) + rls.writeTo(output) + + //message rrs = 2 + output.writeTag(2, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rrs.getSizeNoTag()) + rrs.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather.RightFather { + val res = CrossBranch.Grandfather.RightFather(rls, rrs) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + rls.mergeFromWithSize(input, expectedSize) + if (expectedSize != rls.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + 2 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + rrs.mergeFromWithSize(input, expectedSize) + if (expectedSize != rrs.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.RightFather.BuilderRightFather { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.RightFather.BuilderRightFather { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (rls != CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build()) { + size += rls.getSize(1) + } + if (rrs != CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) { + size += rrs.getSize(2) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (rls != CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build()) { + size += rls.getSize(1) + } + if (rrs != CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()) { + size += rrs.getSize(2) + } + return size + } + + } + + } + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message rf = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rf.getSizeNoTag()) + rf.writeTo(output) + + } + + fun mergeWith (other: CrossBranch.Grandfather) { + rf = other.rf + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.Grandfather.BuilderGrandfather(CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.Grandfather.BuilderGrandfather(CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (rf != CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) { + size += rf.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (rf != CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) { + size += rf.getSize(1) + } + return size + } + + //========== Builder =========== + class BuilderGrandfather constructor (var rf: CrossBranch.Grandfather.RightFather) { + //========== Properties =========== + //message rf = 1 + fun setRf(value: CrossBranch.Grandfather.RightFather): CrossBranch.Grandfather.BuilderGrandfather { + rf = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message rf = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(rf.getSizeNoTag()) + rf.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): CrossBranch.Grandfather { + val res = CrossBranch.Grandfather(rf) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + rf.mergeFromWithSize(input, expectedSize) + if (expectedSize != rf.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.Grandfather.BuilderGrandfather { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.Grandfather.BuilderGrandfather { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (rf != CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) { + size += rf.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (rf != CrossBranch.Grandfather.RightFather.BuilderRightFather(CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon(CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon(0).build()).build(), CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon(CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon(0).build()).build()).build()) { + size += rf.getSize(1) + } + return size + } + + } + + } + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + } + + fun mergeWith (other: CrossBranch) { + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = CrossBranch.BuilderCrossBranch() + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = CrossBranch.BuilderCrossBranch() + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + val size = 0 + return size + } + + //========== Builder =========== + class BuilderCrossBranch constructor () { + //========== Properties =========== + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + } + + //========== Mutating methods =========== + fun build(): CrossBranch { + val res = CrossBranch() + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): CrossBranch.BuilderCrossBranch { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): CrossBranch.BuilderCrossBranch { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + val size = 0 + return size + } + + } + +} + +fun compareGrandfathers(lhs: CrossBranch.Grandfather, rhs: CrossBranch.Grandfather): Boolean { + return (lhs.rf.rls.son_field.son_field == rhs.rf.rls.son_field.son_field) and + (lhs.rf.rrs.son_field.son_field == rhs.rf.rrs.son_field.son_field) +} + +fun buildGrandfather(val1: Int, val2: Int): CrossBranch.Grandfather { + return CrossBranch.Grandfather.BuilderGrandfather( + CrossBranch.Grandfather.RightFather.BuilderRightFather( + CrossBranch.Grandfather.RightFather.RightLeftSon.BuilderRightLeftSon( + CrossBranch.Grandfather.LeftFather.LeftLeftSon.BuilderLeftLeftSon( + val1 + ).build() + ).build() + , + CrossBranch.Grandfather.RightFather.RightRightSon.BuilderRightRightSon( + CrossBranch.Grandfather.LeftFather.LeftRightSon.BuilderLeftRightSon( + val2 + ).build() + ).build() + ).build() + ).build() +} + +fun checkGFSerializationIdentity(msg: CrossBranch.Grandfather): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = buildGrandfather(0, 0) + readMsg.mergeFrom(ins) + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareGrandfathers(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun testTrivialValues(): Int { + val msg = buildGrandfather(3213213, -217864283) + return checkGFSerializationIdentity(msg) +} + +fun testMaxValues(): Int { + val msg = buildGrandfather(2147483647, 2147483647) + return checkGFSerializationIdentity(msg) +} + +fun testMinValues(): Int { + val msg = buildGrandfather(-2147483647, -2147483647) + return checkGFSerializationIdentity(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.txt new file mode 100644 index 00000000000..5587dda54e7 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_crossbranch_test/proto_crossbranch_test.txt @@ -0,0 +1,3 @@ +testTrivialValues() == 0 +testMaxValues() == 0 +testMinValues() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.kt new file mode 100644 index 00000000000..d15fbba9d83 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.kt @@ -0,0 +1,466 @@ +class LocationResponse private constructor (var locationResponseData: LocationResponse.LocationData, var code: Int, var errorMsg: Int) { + //========== Properties =========== + //message locationResponseData = 1 + + //int32 code = 2 + + //int32 errorMsg = 3 + + var errorCode: Int = 0 + + //========== Nested classes declarations =========== + class LocationData private constructor (var x: Int, var y: Int, var angle: Int) { + //========== Properties =========== + //int32 x = 1 + + //int32 y = 2 + + //int32 angle = 3 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 x = 1 + if (x != 0) { + output.writeInt32 (1, x) + } + + //int32 y = 2 + if (y != 0) { + output.writeInt32 (2, y) + } + + //int32 angle = 3 + if (angle != 0) { + output.writeInt32 (3, angle) + } + + } + + fun mergeWith (other: LocationResponse.LocationData) { + x = other.x + y = other.y + angle = other.angle + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = LocationResponse.LocationData.BuilderLocationData(0, 0, 0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = LocationResponse.LocationData.BuilderLocationData(0, 0, 0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (x != 0) { + size += WireFormat.getInt32Size(1, x) + } + if (y != 0) { + size += WireFormat.getInt32Size(2, y) + } + if (angle != 0) { + size += WireFormat.getInt32Size(3, angle) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (x != 0) { + size += WireFormat.getInt32Size(1, x) + } + if (y != 0) { + size += WireFormat.getInt32Size(2, y) + } + if (angle != 0) { + size += WireFormat.getInt32Size(3, angle) + } + return size + } + + //========== Builder =========== + class BuilderLocationData constructor (var x: Int, var y: Int, var angle: Int) { + //========== Properties =========== + //int32 x = 1 + fun setX(value: Int): LocationResponse.LocationData.BuilderLocationData { + x = value + return this + } + + //int32 y = 2 + fun setY(value: Int): LocationResponse.LocationData.BuilderLocationData { + y = value + return this + } + + //int32 angle = 3 + fun setAngle(value: Int): LocationResponse.LocationData.BuilderLocationData { + angle = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 x = 1 + if (x != 0) { + output.writeInt32 (1, x) + } + + //int32 y = 2 + if (y != 0) { + output.writeInt32 (2, y) + } + + //int32 angle = 3 + if (angle != 0) { + output.writeInt32 (3, angle) + } + + } + + //========== Mutating methods =========== + fun build(): LocationResponse.LocationData { + val res = LocationResponse.LocationData(x, y, angle) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + x = input.readInt32NoTag() + } + 2 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + y = input.readInt32NoTag() + } + 3 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + angle = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): LocationResponse.LocationData.BuilderLocationData { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): LocationResponse.LocationData.BuilderLocationData { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (x != 0) { + size += WireFormat.getInt32Size(1, x) + } + if (y != 0) { + size += WireFormat.getInt32Size(2, y) + } + if (angle != 0) { + size += WireFormat.getInt32Size(3, angle) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (x != 0) { + size += WireFormat.getInt32Size(1, x) + } + if (y != 0) { + size += WireFormat.getInt32Size(2, y) + } + if (angle != 0) { + size += WireFormat.getInt32Size(3, angle) + } + return size + } + + } + + } + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message locationResponseData = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(locationResponseData.getSizeNoTag()) + locationResponseData.writeTo(output) + + //int32 code = 2 + if (code != 0) { + output.writeInt32 (2, code) + } + + //int32 errorMsg = 3 + if (errorMsg != 0) { + output.writeInt32 (3, errorMsg) + } + + } + + fun mergeWith (other: LocationResponse) { + locationResponseData = other.locationResponseData + code = other.code + errorMsg = other.errorMsg + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = LocationResponse.BuilderLocationResponse(LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build(), 0, 0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = LocationResponse.BuilderLocationResponse(LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build(), 0, 0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (locationResponseData != LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build()) { + size += locationResponseData.getSize(1) + } + if (code != 0) { + size += WireFormat.getInt32Size(2, code) + } + if (errorMsg != 0) { + size += WireFormat.getInt32Size(3, errorMsg) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (locationResponseData != LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build()) { + size += locationResponseData.getSize(1) + } + if (code != 0) { + size += WireFormat.getInt32Size(2, code) + } + if (errorMsg != 0) { + size += WireFormat.getInt32Size(3, errorMsg) + } + return size + } + + //========== Builder =========== + class BuilderLocationResponse constructor (var locationResponseData: LocationResponse.LocationData, var code: Int, var errorMsg: Int) { + //========== Properties =========== + //message locationResponseData = 1 + fun setLocationResponseData(value: LocationResponse.LocationData): LocationResponse.BuilderLocationResponse { + locationResponseData = value + return this + } + + //int32 code = 2 + fun setCode(value: Int): LocationResponse.BuilderLocationResponse { + code = value + return this + } + + //int32 errorMsg = 3 + fun setErrorMsg(value: Int): LocationResponse.BuilderLocationResponse { + errorMsg = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message locationResponseData = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(locationResponseData.getSizeNoTag()) + locationResponseData.writeTo(output) + + //int32 code = 2 + if (code != 0) { + output.writeInt32 (2, code) + } + + //int32 errorMsg = 3 + if (errorMsg != 0) { + output.writeInt32 (3, errorMsg) + } + + } + + //========== Mutating methods =========== + fun build(): LocationResponse { + val res = LocationResponse(locationResponseData, code, errorMsg) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + locationResponseData.mergeFromWithSize(input, expectedSize) + if (expectedSize != locationResponseData.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + 2 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + code = input.readInt32NoTag() + } + 3 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + errorMsg = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): LocationResponse.BuilderLocationResponse { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): LocationResponse.BuilderLocationResponse { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (locationResponseData != LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build()) { + size += locationResponseData.getSize(1) + } + if (code != 0) { + size += WireFormat.getInt32Size(2, code) + } + if (errorMsg != 0) { + size += WireFormat.getInt32Size(3, errorMsg) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (locationResponseData != LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build()) { + size += locationResponseData.getSize(1) + } + if (code != 0) { + size += WireFormat.getInt32Size(2, code) + } + if (errorMsg != 0) { + size += WireFormat.getInt32Size(3, errorMsg) + } + return size + } + + } + +} + +fun compareLocationDatas(lhs: LocationResponse.LocationData, rhs: LocationResponse.LocationData): Boolean { + return (lhs.angle == rhs.angle) and (lhs.x == rhs.x) and (lhs.y == rhs.y) +} + +fun compareLocationResponses(lhs: LocationResponse, rhs: LocationResponse): Boolean { + return (lhs.code == rhs.code) and + (lhs.errorMsg == rhs.errorMsg) and + compareLocationDatas(lhs.locationResponseData, rhs.locationResponseData) +} + +fun buildLocationResponse(code: Int, errorMsg: Int, angle: Int, x: Int, y: Int): LocationResponse.BuilderLocationResponse { + return LocationResponse.BuilderLocationResponse( + LocationResponse.LocationData.BuilderLocationData( + x, y, angle + ).build(), + code, + errorMsg + ) +} + +fun checkLocationResponse(msg: LocationResponse): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = buildLocationResponse(0, 0, 0, 0, 0).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareLocationResponses(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun testTrivialLocationResponse(): Int { + val msg = buildLocationResponse(3125321, -12673123, 4334, 423542673, 234516534).build() + return checkLocationResponse(msg) +} + +fun testMaxLocationResponse(): Int { + val msg = buildLocationResponse(2147483647, 2147483647, 2147483647, 2147483647, 2147483647).build() + return checkLocationResponse(msg) +} + +fun testMinLocationResponse(): Int { + val msg = buildLocationResponse(-2147483647, -2147483647, -2147483647, -2147483647, -2147483647).build() + return checkLocationResponse(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.txt new file mode 100644 index 00000000000..1d001fca6b8 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_location_test/proto_location_test.txt @@ -0,0 +1,3 @@ +testTrivialLocationResponse() == 0 +testMaxLocationResponse() == 0 +testMinLocationResponse() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.kt new file mode 100644 index 00000000000..d29b594db5f --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.kt @@ -0,0 +1,495 @@ +class ThirdMessage private constructor (var second_msg: SecondMessage) { + //========== Properties =========== + //message second_msg = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message second_msg = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(second_msg.getSizeNoTag()) + second_msg.writeTo(output) + + } + + fun mergeWith (other: ThirdMessage) { + second_msg = other.second_msg + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = ThirdMessage.BuilderThirdMessage(SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = ThirdMessage.BuilderThirdMessage(SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (second_msg != SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) { + size += second_msg.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (second_msg != SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) { + size += second_msg.getSize(1) + } + return size + } + + //========== Builder =========== + class BuilderThirdMessage constructor (var second_msg: SecondMessage) { + //========== Properties =========== + //message second_msg = 1 + fun setSecond_msg(value: SecondMessage): ThirdMessage.BuilderThirdMessage { + second_msg = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message second_msg = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(second_msg.getSizeNoTag()) + second_msg.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): ThirdMessage { + val res = ThirdMessage(second_msg) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + second_msg.mergeFromWithSize(input, expectedSize) + if (expectedSize != second_msg.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): ThirdMessage.BuilderThirdMessage { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): ThirdMessage.BuilderThirdMessage { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (second_msg != SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) { + size += second_msg.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (second_msg != SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()).build()) { + size += second_msg.getSize(1) + } + return size + } + + } + +} + +class SecondMessage private constructor (var first_msg: FirstMessage) { + //========== Properties =========== + //message first_msg = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message first_msg = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(first_msg.getSizeNoTag()) + first_msg.writeTo(output) + + } + + fun mergeWith (other: SecondMessage) { + first_msg = other.first_msg + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = SecondMessage.BuilderSecondMessage(FirstMessage.BuilderFirstMessage(0).build()) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (first_msg != FirstMessage.BuilderFirstMessage(0).build()) { + size += first_msg.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (first_msg != FirstMessage.BuilderFirstMessage(0).build()) { + size += first_msg.getSize(1) + } + return size + } + + //========== Builder =========== + class BuilderSecondMessage constructor (var first_msg: FirstMessage) { + //========== Properties =========== + //message first_msg = 1 + fun setFirst_msg(value: FirstMessage): SecondMessage.BuilderSecondMessage { + first_msg = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //message first_msg = 1 + output.writeTag(1, WireType.LENGTH_DELIMITED) + output.writeInt32NoTag(first_msg.getSizeNoTag()) + first_msg.writeTo(output) + + } + + //========== Mutating methods =========== + fun build(): SecondMessage { + val res = SecondMessage(first_msg) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + do { + val expectedSize = input.readInt32NoTag() + first_msg.mergeFromWithSize(input, expectedSize) + if (expectedSize != first_msg.getSizeNoTag()) { errorCode = 3; return false } + } while(false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): SecondMessage.BuilderSecondMessage { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): SecondMessage.BuilderSecondMessage { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (first_msg != FirstMessage.BuilderFirstMessage(0).build()) { + size += first_msg.getSize(1) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (first_msg != FirstMessage.BuilderFirstMessage(0).build()) { + size += first_msg.getSize(1) + } + return size + } + + } + +} + +class FirstMessage private constructor (var int_field: Int) { + //========== Properties =========== + //int32 int_field = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 int_field = 1 + if (int_field != 0) { + output.writeInt32 (1, int_field) + } + + } + + fun mergeWith (other: FirstMessage) { + int_field = other.int_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = FirstMessage.BuilderFirstMessage(0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = FirstMessage.BuilderFirstMessage(0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int_field != 0) { + size += WireFormat.getInt32Size(1, int_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int_field != 0) { + size += WireFormat.getInt32Size(1, int_field) + } + return size + } + + //========== Builder =========== + class BuilderFirstMessage constructor (var int_field: Int) { + //========== Properties =========== + //int32 int_field = 1 + fun setInt_field(value: Int): FirstMessage.BuilderFirstMessage { + int_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 int_field = 1 + if (int_field != 0) { + output.writeInt32 (1, int_field) + } + + } + + //========== Mutating methods =========== + fun build(): FirstMessage { + val res = FirstMessage(int_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + int_field = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): FirstMessage.BuilderFirstMessage { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): FirstMessage.BuilderFirstMessage { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int_field != 0) { + size += WireFormat.getInt32Size(1, int_field) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int_field != 0) { + size += WireFormat.getInt32Size(1, int_field) + } + return size + } + + } + +} + +fun compareThirdMessages(kt1: ThirdMessage, kt2: ThirdMessage): Boolean { + return kt1.second_msg.first_msg.int_field == kt2.second_msg.first_msg.int_field +} + +fun compareSecondMessages(lhs: SecondMessage, rhs: SecondMessage): Boolean { + return lhs.first_msg.int_field == rhs.first_msg.int_field +} + +fun compareFirstMessages(lhs: FirstMessage, rhs: FirstMessage): Boolean { + return lhs.int_field == rhs.int_field +} + +fun buildThirdMessage(value: Int): ThirdMessage.BuilderThirdMessage { + return ThirdMessage.BuilderThirdMessage( + SecondMessage.BuilderSecondMessage( + FirstMessage.BuilderFirstMessage( + value + ).build() + ).build() + ) +} + +fun buildSecondMessage(value: Int): SecondMessage.BuilderSecondMessage { + return SecondMessage.BuilderSecondMessage( + FirstMessage.BuilderFirstMessage( + value + ).build() + ) +} + +fun buildFirstMessage(value: Int): FirstMessage.BuilderFirstMessage { + return FirstMessage.BuilderFirstMessage(value) +} + +fun checkThird(msg: ThirdMessage): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = buildThirdMessage(0).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareThirdMessages(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun checkSecond(msg: SecondMessage): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = buildSecondMessage(0).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareSecondMessages(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun checkFirst(msg: FirstMessage): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = buildFirstMessage(0).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareFirstMessages(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun testThirdCase(): Int { + val msg = buildThirdMessage(5).build() + return checkThird(msg) +} + +fun testSecondCase(): Int { + val msg = buildSecondMessage(-31241501).build() + return checkSecond(msg) +} + +fun testFirstCase(): Int { + val msg = buildFirstMessage(321311430).build() + return checkFirst(msg) +} + diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.txt new file mode 100644 index 00000000000..9c2f4ecabd7 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_multiple_messages/proto_multiple_messages.txt @@ -0,0 +1,3 @@ +testThirdCase() == 0 +testSecondCase() == 0 +testFirstCase() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.kt new file mode 100644 index 00000000000..5f90d979678 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.kt @@ -0,0 +1,1365 @@ +class MessageRepeatedVarints private constructor (var int: IntArray, var long: LongArray, var sint: IntArray, var slong: LongArray, var bl: BooleanArray, var uint: IntArray, var ulong: LongArray) { + //========== Properties =========== + //repeated int32 int = 1 + + //repeated int64 long = 2 + + //repeated sint32 sint = 3 + + //repeated sint64 slong = 4 + + //repeated bool bl = 5 + + //repeated uint32 uint = 7 + + //repeated uint64 ulong = 8 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated int32 int = 1 + if (int.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (int.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < int.size) { + output.writeInt32NoTag (int[i]) + i += 1 + } + } while(false) + } + + //repeated int64 long = 2 + if (long.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (long.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < long.size) { + output.writeInt64NoTag (long[i]) + i += 1 + } + } while(false) + } + + //repeated sint32 sint = 3 + if (sint.size > 0) { + output.writeTag(3, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (sint.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < sint.size) { + output.writeSInt32NoTag (sint[i]) + i += 1 + } + } while(false) + } + + //repeated sint64 slong = 4 + if (slong.size > 0) { + output.writeTag(4, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong.size) { + output.writeSInt64NoTag (slong[i]) + i += 1 + } + } while(false) + } + + //repeated bool bl = 5 + if (bl.size > 0) { + output.writeTag(5, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (bl.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < bl.size) { + output.writeBoolNoTag (bl[i]) + i += 1 + } + } while(false) + } + + //repeated uint32 uint = 7 + if (uint.size > 0) { + output.writeTag(7, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (uint.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < uint.size) { + output.writeUInt32NoTag (uint[i]) + i += 1 + } + } while(false) + } + + //repeated uint64 ulong = 8 + if (ulong.size > 0) { + output.writeTag(8, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (ulong.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < ulong.size) { + output.writeUInt64NoTag (ulong[i]) + i += 1 + } + } while(false) + } + + } + + fun mergeWith (other: MessageRepeatedVarints) { + int = int.plus((other.int)) + long = long.plus((other.long)) + sint = sint.plus((other.sint)) + slong = slong.plus((other.slong)) + bl = bl.plus((other.bl)) + uint = uint.plus((other.uint)) + ulong = ulong.plus((other.ulong)) + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = MessageRepeatedVarints.BuilderMessageRepeatedVarints(IntArray(0), LongArray(0), IntArray(0), LongArray(0), BooleanArray(0), IntArray(0), LongArray(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = MessageRepeatedVarints.BuilderMessageRepeatedVarints(IntArray(0), LongArray(0), IntArray(0), LongArray(0), BooleanArray(0), IntArray(0), LongArray(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (sint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (slong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (bl.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(5, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (uint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(7, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (ulong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(8, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (sint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (slong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (bl.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(5, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (uint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(7, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (ulong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(8, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + //========== Builder =========== + class BuilderMessageRepeatedVarints constructor (var int: IntArray, var long: LongArray, var sint: IntArray, var slong: LongArray, var bl: BooleanArray, var uint: IntArray, var ulong: LongArray) { + //========== Properties =========== + //repeated int32 int = 1 + fun setInt(value: IntArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + int = value + return this + } + fun setintByIndex(index: Int, value: Int): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + int[index] = value + return this + } + + //repeated int64 long = 2 + fun setLong(value: LongArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + long = value + return this + } + fun setlongByIndex(index: Int, value: Long): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + long[index] = value + return this + } + + //repeated sint32 sint = 3 + fun setSint(value: IntArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + sint = value + return this + } + fun setsintByIndex(index: Int, value: Int): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + sint[index] = value + return this + } + + //repeated sint64 slong = 4 + fun setSlong(value: LongArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + slong = value + return this + } + fun setslongByIndex(index: Int, value: Long): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + slong[index] = value + return this + } + + //repeated bool bl = 5 + fun setBl(value: BooleanArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + bl = value + return this + } + fun setblByIndex(index: Int, value: Boolean): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + bl[index] = value + return this + } + + //repeated uint32 uint = 7 + fun setUint(value: IntArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + uint = value + return this + } + fun setuintByIndex(index: Int, value: Int): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + uint[index] = value + return this + } + + //repeated uint64 ulong = 8 + fun setUlong(value: LongArray): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + ulong = value + return this + } + fun setulongByIndex(index: Int, value: Long): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + ulong[index] = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated int32 int = 1 + if (int.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (int.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < int.size) { + output.writeInt32NoTag (int[i]) + i += 1 + } + } while(false) + } + + //repeated int64 long = 2 + if (long.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (long.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < long.size) { + output.writeInt64NoTag (long[i]) + i += 1 + } + } while(false) + } + + //repeated sint32 sint = 3 + if (sint.size > 0) { + output.writeTag(3, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (sint.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < sint.size) { + output.writeSInt32NoTag (sint[i]) + i += 1 + } + } while(false) + } + + //repeated sint64 slong = 4 + if (slong.size > 0) { + output.writeTag(4, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong.size) { + output.writeSInt64NoTag (slong[i]) + i += 1 + } + } while(false) + } + + //repeated bool bl = 5 + if (bl.size > 0) { + output.writeTag(5, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (bl.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < bl.size) { + output.writeBoolNoTag (bl[i]) + i += 1 + } + } while(false) + } + + //repeated uint32 uint = 7 + if (uint.size > 0) { + output.writeTag(7, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (uint.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < uint.size) { + output.writeUInt32NoTag (uint[i]) + i += 1 + } + } while(false) + } + + //repeated uint64 ulong = 8 + if (ulong.size > 0) { + output.writeTag(8, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (ulong.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < ulong.size) { + output.writeUInt64NoTag (ulong[i]) + i += 1 + } + } while(false) + } + + } + + //========== Mutating methods =========== + fun build(): MessageRepeatedVarints { + val res = MessageRepeatedVarints(int, long, sint, slong, bl, uint, ulong) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0 + tmp = input.readInt32NoTag() + arraySize += 1 + readSize += WireFormat.getInt32SizeNoTag(tmp) + } + } while (false) + val newArray = IntArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readInt32NoTag() + i += 1 + } + int = newArray + } while (false) + } + 2 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0L + tmp = input.readInt64NoTag() + arraySize += 1 + readSize += WireFormat.getInt64SizeNoTag(tmp) + } + } while (false) + val newArray = LongArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readInt64NoTag() + i += 1 + } + long = newArray + } while (false) + } + 3 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0 + tmp = input.readSInt32NoTag() + arraySize += 1 + readSize += WireFormat.getSInt32SizeNoTag(tmp) + } + } while (false) + val newArray = IntArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readSInt32NoTag() + i += 1 + } + sint = newArray + } while (false) + } + 4 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0L + tmp = input.readSInt64NoTag() + arraySize += 1 + readSize += WireFormat.getSInt64SizeNoTag(tmp) + } + } while (false) + val newArray = LongArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readSInt64NoTag() + i += 1 + } + slong = newArray + } while (false) + } + 5 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = false + tmp = input.readBoolNoTag() + arraySize += 1 + readSize += WireFormat.getBoolSizeNoTag(tmp) + } + } while (false) + val newArray = BooleanArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readBoolNoTag() + i += 1 + } + bl = newArray + } while (false) + } + 7 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0 + tmp = input.readUInt32NoTag() + arraySize += 1 + readSize += WireFormat.getUInt32SizeNoTag(tmp) + } + } while (false) + val newArray = IntArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readUInt32NoTag() + i += 1 + } + uint = newArray + } while (false) + } + 8 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0L + tmp = input.readUInt64NoTag() + arraySize += 1 + readSize += WireFormat.getUInt64SizeNoTag(tmp) + } + } while (false) + val newArray = LongArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readUInt64NoTag() + i += 1 + } + ulong = newArray + } while (false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): MessageRepeatedVarints.BuilderMessageRepeatedVarints { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (sint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (slong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (bl.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(5, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (uint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(7, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (ulong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(8, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (sint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < sint.size) { + arraySize += WireFormat.getSInt32SizeNoTag(sint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (slong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (bl.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(5, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < bl.size) { + arraySize += WireFormat.getBoolSizeNoTag(bl[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (uint.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(7, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < uint.size) { + arraySize += WireFormat.getUInt32SizeNoTag(uint[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (ulong.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(8, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < ulong.size) { + arraySize += WireFormat.getUInt64SizeNoTag(ulong[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + } + +} + +fun compareIntArrays(lhs: IntArray, rhs: IntArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareLongArrays(lhs: LongArray, rhs: LongArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareBooleanArrays(lhs: BooleanArray, rhs: BooleanArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareRepeatedVarints(kt1: MessageRepeatedVarints, kt2: MessageRepeatedVarints): Boolean { + return compareIntArrays(kt1.int, kt2.int) and + compareLongArrays(kt1.long, kt2.long) and + compareIntArrays(kt1.sint, kt2.sint) and + compareLongArrays(kt1.slong, kt2.slong) and + compareBooleanArrays(kt1.bl, kt2.bl) and + compareIntArrays(kt1.uint, kt2.uint) and + compareLongArrays(kt1.ulong, kt2.ulong) +} + +fun checkRepSerializationIdentity(msg: MessageRepeatedVarints): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = MessageRepeatedVarints.BuilderMessageRepeatedVarints( + IntArray(0), + LongArray(0), + IntArray(0), + LongArray(0), + BooleanArray(0), + IntArray(0), + LongArray(0) + ).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareRepeatedVarints(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + + +object Rng { + var rngState = 0.6938893903907228 + + val point = 762939453125 + fun rng(): Double { + rngState *= point.toDouble() + rngState -= rngState.toLong().toDouble() + return rngState + } +} + +fun nextInt(minVal: Int, maxVal: Int): Int { + return (Rng.rng() * (maxVal - minVal + 1).toDouble()).toInt() +} + +fun nextLong(): Long { + val lowerHalf = nextInt(-2147483647, 2147483647) + val upperHalf = nextInt(-2147483647, 2147483647) + return (upperHalf.toLong() shl 32) + lowerHalf.toLong() +} + +fun generateIntArray(): IntArray { + val size = nextInt(0, 10000) + val arr = IntArray(size) + var i = 0 + while (i < size) { + arr[i] = nextInt(-2147483647, 2147483647) + i += 1 + } + return arr +} + +fun generateLongArray(): LongArray { + val size = nextInt(0, 10000) + val arr = LongArray(size) + var i = 0 + while (i < size) { + arr[i] = nextLong() + i += 1 + } + return arr +} + + +fun nextBool(): Boolean { + val int = nextInt(-2147483647, 2147483647) + if (int and 1 == 1) { + return true + } + return false +} + +fun generateBooleanArray(): BooleanArray { + val size = nextInt(0, 10000) + val arr = BooleanArray(size) + var i = 0 + while (i < size) { + arr[i] = nextBool() + i += 1 + } + return arr +} + +fun generateRandomMessage(): MessageRepeatedVarints { + return MessageRepeatedVarints.BuilderMessageRepeatedVarints( + generateIntArray(), + generateLongArray(), + generateIntArray(), + generateLongArray(), + generateBooleanArray(), + generateIntArray(), + generateLongArray() + ).build() +} + +fun testRepVarints(): Int { + var i = 0 + val testRuns = 100 + while (i < testRuns) { + val msg = generateRandomMessage() + if (checkRepSerializationIdentity(msg) == 1) { + return 1 + } + i += 1 + } + return 0 +} + +fun testArraysOfMinValues(): Int { + val intArr = IntArray(100) + var i = 0 + while (i < 100) { + intArr[i] = -2147483647 + i += 1 + } + + val longArr = LongArray(100) + i = 0 + while (i < 100) { + longArr[i] = -9223372036854775807L + i += 1 + } + + val boolArr = BooleanArray(100) + i = 1 + while (i < 100) { + boolArr[i] = false + i += 1 + } + + val msg = MessageRepeatedVarints.BuilderMessageRepeatedVarints( + intArr, longArr, intArr, longArr, boolArr, intArr, longArr + ).build() + return checkRepSerializationIdentity(msg) +} + +fun testArraysOfMaxValues(): Int { + val intArr = IntArray(100) + var i = 0 + while (i < 100) { + intArr[i] = 2147483647 + i += 1 + } + + val longArr = LongArray(100) + i = 0 + while (i < 100) { + longArr[i] = 9223372036854775807L + i += 1 + } + + val boolArr = BooleanArray(100) + i = 1 + while (i < 100) { + boolArr[i] = true + i += 1 + } + + val msg = MessageRepeatedVarints.BuilderMessageRepeatedVarints( + intArr, longArr, intArr, longArr, boolArr, intArr, longArr + ).build() + return checkRepSerializationIdentity(msg) +} + +fun testArraysOfDefaultValues(): Int { + val intArr = IntArray(100) + + val longArr = LongArray(100) + + val boolArr = BooleanArray(100) + + val msg = MessageRepeatedVarints.BuilderMessageRepeatedVarints( + intArr, longArr, intArr, longArr, boolArr, intArr, longArr + ).build() + + return checkRepSerializationIdentity(msg) +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.txt new file mode 100644 index 00000000000..d5e5ffa9e09 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_varint/proto_repeated_varint.txt @@ -0,0 +1,4 @@ +testArraysOfDefaultValues() == 0 +testArraysOfMinValues() == 0 +testArraysOfMaxValues() == 0 +testRepVarints() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.kt new file mode 100644 index 00000000000..9973ce5a2a7 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.kt @@ -0,0 +1,567 @@ +class MessageRepeatedZigZag private constructor (var int: IntArray, var long: LongArray) { + //========== Properties =========== + //repeated sint32 int = 1 + + //repeated sint64 long = 2 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated sint32 int = 1 + if (int.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (int.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < int.size) { + output.writeSInt32NoTag (int[i]) + i += 1 + } + } while(false) + } + + //repeated sint64 long = 2 + if (long.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (long.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < long.size) { + output.writeSInt64NoTag (long[i]) + i += 1 + } + } while(false) + } + + } + + fun mergeWith (other: MessageRepeatedZigZag) { + int = int.plus((other.int)) + long = long.plus((other.long)) + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag(IntArray(0), LongArray(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag(IntArray(0), LongArray(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + //========== Builder =========== + class BuilderMessageRepeatedZigZag constructor (var int: IntArray, var long: LongArray) { + //========== Properties =========== + //repeated sint32 int = 1 + fun setInt(value: IntArray): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + int = value + return this + } + fun setintByIndex(index: Int, value: Int): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + int[index] = value + return this + } + + //repeated sint64 long = 2 + fun setLong(value: LongArray): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + long = value + return this + } + fun setlongByIndex(index: Int, value: Long): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + long[index] = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated sint32 int = 1 + if (int.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (int.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < int.size) { + output.writeSInt32NoTag (int[i]) + i += 1 + } + } while(false) + } + + //repeated sint64 long = 2 + if (long.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (long.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < long.size) { + output.writeSInt64NoTag (long[i]) + i += 1 + } + } while(false) + } + + } + + //========== Mutating methods =========== + fun build(): MessageRepeatedZigZag { + val res = MessageRepeatedZigZag(int, long) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0 + tmp = input.readSInt32NoTag() + arraySize += 1 + readSize += WireFormat.getSInt32SizeNoTag(tmp) + } + } while (false) + val newArray = IntArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readSInt32NoTag() + i += 1 + } + int = newArray + } while (false) + } + 2 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var readSize = 0 + var arraySize = 0 + input.mark() + do { + var i = 0 + while(readSize < expectedByteSize) { + var tmp = 0L + tmp = input.readSInt64NoTag() + arraySize += 1 + readSize += WireFormat.getSInt64SizeNoTag(tmp) + } + } while (false) + val newArray = LongArray(arraySize) + input.reset() + do { + var i = 0 + while(i < arraySize) { + newArray[i] = input.readSInt64NoTag() + i += 1 + } + long = newArray + } while (false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): MessageRepeatedZigZag.BuilderMessageRepeatedZigZag { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < int.size) { + arraySize += WireFormat.getSInt32SizeNoTag(int[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (long.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < long.size) { + arraySize += WireFormat.getSInt64SizeNoTag(long[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + } + +} + +fun compareIntArrays(lhs: IntArray, rhs: IntArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareLongArrays(lhs: LongArray, rhs: LongArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareBooleanArrays(lhs: BooleanArray, rhs: BooleanArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareRepeatedZigZags(kt1: MessageRepeatedZigZag, kt2: MessageRepeatedZigZag): Boolean { + return compareIntArrays(kt1.int, kt2.int) and + compareLongArrays(kt1.long, kt2.long) +} + +fun checkRepZZSerializationIdentity(msg: MessageRepeatedZigZag): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag( + IntArray(0), + LongArray(0) + ).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareRepeatedZigZags(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + + +object Rng { + var rngState = 0.6938893903907228 + + val point = 762939453125 + fun rng(): Double { + rngState *= point.toDouble() + rngState -= rngState.toLong().toDouble() + return rngState + } +} + +fun nextInt(minVal: Int, maxVal: Int): Int { + return (Rng.rng() * (maxVal - minVal + 1).toDouble()).toInt() +} + +fun nextLong(): Long { + val lowerHalf = nextInt(-2147483647, 2147483647) + val upperHalf = nextInt(-2147483647, 2147483647) + return (upperHalf.toLong() shl 32) + lowerHalf.toLong() +} + +fun generateIntArray(): IntArray { + val size = nextInt(0, 10000) + val arr = IntArray(size) + var i = 0 + while (i < size) { + arr[i] = nextInt(-2147483647, 2147483647) + i += 1 + } + return arr +} + +fun generateLongArray(): LongArray { + val size = nextInt(0, 10000) + val arr = LongArray(size) + var i = 0 + while (i < size) { + arr[i] = nextLong() + i += 1 + } + return arr +} + +fun generateRandomMessage(): MessageRepeatedZigZag { + return MessageRepeatedZigZag.BuilderMessageRepeatedZigZag( + generateIntArray(), + generateLongArray() + ).build() +} + +fun testRepZigZag(): Int { + var i = 0 + val testRuns = 8 + while (i < testRuns) { + val msg = generateRandomMessage() + if (checkRepZZSerializationIdentity(msg) == 1) { + return 1 + } + i += 1 + } + return 0 +} + +fun testArraysOfMinValues(): Int { + val intArr = IntArray(100) + var i = 0 + while (i < 100) { + intArr[i] = -2147483647 + i += 1 + } + + val longArr = LongArray(100) + i = 0 + while (i < 100) { + longArr[i] = -9223372036854775807L + i += 1 + } + + val msg = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag(intArr, longArr).build() + return checkRepZZSerializationIdentity(msg) +} + +fun testArraysOfMaxValues(): Int { + val intArr = IntArray(100) + var i = 0 + while (i < 100) { + intArr[i] = 2147483647 + i += 1 + } + + val longArr = LongArray(100) + i = 0 + while (i < 100) { + longArr[i] = 9223372036854775807L + i += 1 + } + + val msg = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag(intArr, longArr).build() + return checkRepZZSerializationIdentity(msg) +} + +fun testArraysOfDefaultValues(): Int { + val intArr = IntArray(100) + + val longArr = LongArray(100) + + val msg = MessageRepeatedZigZag.BuilderMessageRepeatedZigZag(intArr, longArr).build() + return checkRepZZSerializationIdentity(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.txt new file mode 100644 index 00000000000..1ffd5649916 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_repeated_zigzag/proto_repeated_zigzag.txt @@ -0,0 +1,4 @@ +testRepZigZag() == 0 +testArraysOfMinValues() == 0 +testArraysOfMaxValues() == 0 +testArraysOfDefaultValues() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.kt new file mode 100644 index 00000000000..d5af1f20460 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.kt @@ -0,0 +1,788 @@ +class TagOrder private constructor (var sint: Int, var int: Int, var slong_array: LongArray, var enum_field: TagOrder.Enum) { + //========== Properties =========== + //sint32 sint = 8 + + //int32 int = 3423 + + //repeated sint64 slong_array = 12321 + + //enum enum_field = 938423 + + var errorCode: Int = 0 + + //========== Nested enums declarations =========== + enum class Enum(val id: Int) { + first_val (0), + second_val (1), + Unexpected(2); + + companion object { + fun fromIntToEnum (ord: Int): Enum { + return when (ord) { + 0 -> Enum.first_val + 1 -> Enum.second_val + else -> Unexpected + } + } + } + } + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 sint = 8 + if (sint != 0) { + output.writeSInt32 (8, sint) + } + + //int32 int = 3423 + if (int != 0) { + output.writeInt32 (3423, int) + } + + //repeated sint64 slong_array = 12321 + if (slong_array.size > 0) { + output.writeTag(12321, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong_array.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong_array.size) { + output.writeSInt64NoTag (slong_array[i]) + i += 1 + } + } while(false) + } + + //enum enum_field = 938423 + if (enum_field.id != TagOrder.Enum.fromIntToEnum(0).id) { + output.writeEnum (938423, enum_field.id) + } + + } + + fun mergeWith (other: TagOrder) { + sint = other.sint + int = other.int + slong_array = slong_array.plus((other.slong_array)) + enum_field = other.enum_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = TagOrder.BuilderTagOrder(0, 0, LongArray(0), TagOrder.Enum.fromIntToEnum(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = TagOrder.BuilderTagOrder(0, 0, LongArray(0), TagOrder.Enum.fromIntToEnum(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrder.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrder.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + return size + } + + //========== Builder =========== + class BuilderTagOrder constructor (var sint: Int, var int: Int, var slong_array: LongArray, var enum_field: TagOrder.Enum) { + //========== Properties =========== + //sint32 sint = 8 + fun setSint(value: Int): TagOrder.BuilderTagOrder { + sint = value + return this + } + + //int32 int = 3423 + fun setInt(value: Int): TagOrder.BuilderTagOrder { + int = value + return this + } + + //repeated sint64 slong_array = 12321 + fun setSlong_array(value: LongArray): TagOrder.BuilderTagOrder { + slong_array = value + return this + } + fun setslong_arrayByIndex(index: Int, value: Long): TagOrder.BuilderTagOrder { + slong_array[index] = value + return this + } + + //enum enum_field = 938423 + fun setEnum_field(value: TagOrder.Enum): TagOrder.BuilderTagOrder { + enum_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 sint = 8 + if (sint != 0) { + output.writeSInt32 (8, sint) + } + + //int32 int = 3423 + if (int != 0) { + output.writeInt32 (3423, int) + } + + //repeated sint64 slong_array = 12321 + if (slong_array.size > 0) { + output.writeTag(12321, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong_array.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong_array.size) { + output.writeSInt64NoTag (slong_array[i]) + i += 1 + } + } while(false) + } + + //enum enum_field = 938423 + if (enum_field.id != TagOrder.Enum.fromIntToEnum(0).id) { + output.writeEnum (938423, enum_field.id) + } + + } + + //========== Mutating methods =========== + fun build(): TagOrder { + val res = TagOrder(sint, int, slong_array, enum_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 8 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + sint = input.readSInt32NoTag() + } + 3423 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + int = input.readInt32NoTag() + } + 12321 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = LongArray(0) + var readSize = 0 + do { + var i = 0 + while(readSize < expectedByteSize) { + val tmp = LongArray(1) + tmp[0] = input.readSInt64NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getSInt64SizeNoTag(tmp[0]) + } + slong_array = newArray + } while (false) + } + 938423 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + enum_field = TagOrder.Enum.fromIntToEnum(input.readEnumNoTag()) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): TagOrder.BuilderTagOrder { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): TagOrder.BuilderTagOrder { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrder.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrder.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + return size + } + + } + +} + +class TagOrderShuffled private constructor (var sint: Int, var int: Int, var slong_array: LongArray, var enum_field: TagOrderShuffled.Enum) { + //========== Properties =========== + //sint32 sint = 8 + + //int32 int = 3423 + + //repeated sint64 slong_array = 12321 + + //enum enum_field = 938423 + + var errorCode: Int = 0 + + //========== Nested enums declarations =========== + enum class Enum(val id: Int) { + first_val (0), + second_val (1), + Unexpected(2); + + companion object { + fun fromIntToEnum (ord: Int): Enum { + return when (ord) { + 0 -> Enum.first_val + 1 -> Enum.second_val + else -> Unexpected + } + } + } + } + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 sint = 8 + if (sint != 0) { + output.writeSInt32 (8, sint) + } + + //int32 int = 3423 + if (int != 0) { + output.writeInt32 (3423, int) + } + + //repeated sint64 slong_array = 12321 + if (slong_array.size > 0) { + output.writeTag(12321, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong_array.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong_array.size) { + output.writeSInt64NoTag (slong_array[i]) + i += 1 + } + } while(false) + } + + //enum enum_field = 938423 + if (enum_field.id != TagOrderShuffled.Enum.fromIntToEnum(0).id) { + output.writeEnum (938423, enum_field.id) + } + + } + + fun mergeWith (other: TagOrderShuffled) { + sint = other.sint + int = other.int + slong_array = slong_array.plus((other.slong_array)) + enum_field = other.enum_field + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = TagOrderShuffled.BuilderTagOrderShuffled(0, 0, LongArray(0), TagOrderShuffled.Enum.fromIntToEnum(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = TagOrderShuffled.BuilderTagOrderShuffled(0, 0, LongArray(0), TagOrderShuffled.Enum.fromIntToEnum(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrderShuffled.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrderShuffled.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + return size + } + + //========== Builder =========== + class BuilderTagOrderShuffled constructor (var sint: Int, var int: Int, var slong_array: LongArray, var enum_field: TagOrderShuffled.Enum) { + //========== Properties =========== + //sint32 sint = 8 + fun setSint(value: Int): TagOrderShuffled.BuilderTagOrderShuffled { + sint = value + return this + } + + //int32 int = 3423 + fun setInt(value: Int): TagOrderShuffled.BuilderTagOrderShuffled { + int = value + return this + } + + //repeated sint64 slong_array = 12321 + fun setSlong_array(value: LongArray): TagOrderShuffled.BuilderTagOrderShuffled { + slong_array = value + return this + } + fun setslong_arrayByIndex(index: Int, value: Long): TagOrderShuffled.BuilderTagOrderShuffled { + slong_array[index] = value + return this + } + + //enum enum_field = 938423 + fun setEnum_field(value: TagOrderShuffled.Enum): TagOrderShuffled.BuilderTagOrderShuffled { + enum_field = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 sint = 8 + if (sint != 0) { + output.writeSInt32 (8, sint) + } + + //int32 int = 3423 + if (int != 0) { + output.writeInt32 (3423, int) + } + + //repeated sint64 slong_array = 12321 + if (slong_array.size > 0) { + output.writeTag(12321, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (slong_array.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < slong_array.size) { + output.writeSInt64NoTag (slong_array[i]) + i += 1 + } + } while(false) + } + + //enum enum_field = 938423 + if (enum_field.id != TagOrderShuffled.Enum.fromIntToEnum(0).id) { + output.writeEnum (938423, enum_field.id) + } + + } + + //========== Mutating methods =========== + fun build(): TagOrderShuffled { + val res = TagOrderShuffled(sint, int, slong_array, enum_field) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 8 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + sint = input.readSInt32NoTag() + } + 3423 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + int = input.readInt32NoTag() + } + 12321 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = LongArray(0) + var readSize = 0 + do { + var i = 0 + while(readSize < expectedByteSize) { + val tmp = LongArray(1) + tmp[0] = input.readSInt64NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getSInt64SizeNoTag(tmp[0]) + } + slong_array = newArray + } while (false) + } + 938423 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + enum_field = TagOrderShuffled.Enum.fromIntToEnum(input.readEnumNoTag()) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): TagOrderShuffled.BuilderTagOrderShuffled { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): TagOrderShuffled.BuilderTagOrderShuffled { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrderShuffled.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (sint != 0) { + size += WireFormat.getSInt32Size(8, sint) + } + if (int != 0) { + size += WireFormat.getInt32Size(3423, int) + } + if (slong_array.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(12321, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < slong_array.size) { + arraySize += WireFormat.getSInt64SizeNoTag(slong_array[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (enum_field != TagOrderShuffled.Enum.fromIntToEnum(0)) { + size += WireFormat.getEnumSize(938423, enum_field.id) + } + return size + } + + } + +} + +fun compareLongArrays(lhs: LongArray, rhs: LongArray): Boolean { + if (lhs.size != rhs.size) { + return false + } + + var i = 0 + while (i < lhs.size) { + if (lhs[i] != rhs[i]) { + return false + } + i += 1 + } + return true +} + +fun compareTagAndShuffledTag(kt1: TagOrder, kt2: TagOrderShuffled): Boolean { + return (kt1.enum_field.id == kt2.enum_field.id) and + (kt1.int == kt2.int) and + (kt1.sint == kt2.sint) and + compareLongArrays(kt1.slong_array, kt2.slong_array) +} + +fun checkTagToShuffled(msg: TagOrder): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = TagOrderShuffled.BuilderTagOrderShuffled(0, 0, LongArray(0), TagOrderShuffled.Enum.first_val).parseFrom(ins).build() + + if (compareTagAndShuffledTag(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun checkShuffledToTag(msg: TagOrderShuffled): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = TagOrder.BuilderTagOrder(0, 0, LongArray(0), TagOrder.Enum.first_val).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareTagAndShuffledTag(readMsg, msg)) { + return 0 + } else { + return 1 + } +} + +fun testTagToShuffled(): Int { + val arr = LongArray(3) + arr[0] = 94289342345678289L + arr[1] = -423643342423442342L + + val msg = TagOrder.BuilderTagOrder(312321, -34268, arr, TagOrder.Enum.first_val).build() + return checkTagToShuffled(msg) +} + +fun testShuffledToTag(): Int { + val arr = LongArray(3) + arr[0] = 94289342345678289L + arr[1] = -423643342423442342L + + val msg = TagOrderShuffled.BuilderTagOrderShuffled(312321, -34268, arr, TagOrderShuffled.Enum.first_val).build() + return checkShuffledToTag(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.txt new file mode 100644 index 00000000000..374a1b28f17 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_tagorder_test/proto_tagorder_test.txt @@ -0,0 +1,2 @@ +testTagToShuffled() == 0 +testShuffledToTag() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.kt new file mode 100644 index 00000000000..dc1043ed696 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.kt @@ -0,0 +1,491 @@ +class MessageVarints private constructor (var int: Int, var long: Long, var sint: Int, var slong: Long, var bl: Boolean, var enumField: MessageVarints.TestEnum, var uint: Int, var ulong: Long) { + //========== Properties =========== + //int32 int = 1 + + //int64 long = 2 + + //sint32 sint = 3 + + //sint64 slong = 4 + + //bool bl = 5 + + //enum enumField = 6 + + //uint32 uint = 7 + + //uint64 ulong = 8 + + var errorCode: Int = 0 + + //========== Nested enums declarations =========== + enum class TestEnum(val id: Int) { + firstVal (0), + secondVal (1), + thirdVal (2), + Unexpected(3); + + companion object { + fun fromIntToTestEnum (ord: Int): TestEnum { + return when (ord) { + 0 -> TestEnum.firstVal + 1 -> TestEnum.secondVal + 2 -> TestEnum.thirdVal + else -> Unexpected + } + } + } + } + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 int = 1 + if (int != 0) { + output.writeInt32 (1, int) + } + + //int64 long = 2 + if (long != 0L) { + output.writeInt64 (2, long) + } + + //sint32 sint = 3 + if (sint != 0) { + output.writeSInt32 (3, sint) + } + + //sint64 slong = 4 + if (slong != 0L) { + output.writeSInt64 (4, slong) + } + + //bool bl = 5 + if (bl != false) { + output.writeBool (5, bl) + } + + //enum enumField = 6 + if (enumField.id != MessageVarints.TestEnum.fromIntToTestEnum(0).id) { + output.writeEnum (6, enumField.id) + } + + //uint32 uint = 7 + if (uint != 0) { + output.writeUInt32 (7, uint) + } + + //uint64 ulong = 8 + if (ulong != 0L) { + output.writeUInt64 (8, ulong) + } + + } + + fun mergeWith (other: MessageVarints) { + int = other.int + long = other.long + sint = other.sint + slong = other.slong + bl = other.bl + enumField = other.enumField + uint = other.uint + ulong = other.ulong + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = MessageVarints.BuilderMessageVarints(0, 0L, 0, 0L, false, MessageVarints.TestEnum.fromIntToTestEnum(0), 0, 0L) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = MessageVarints.BuilderMessageVarints(0, 0L, 0, 0L, false, MessageVarints.TestEnum.fromIntToTestEnum(0), 0, 0L) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getInt64Size(2, long) + } + if (sint != 0) { + size += WireFormat.getSInt32Size(3, sint) + } + if (slong != 0L) { + size += WireFormat.getSInt64Size(4, slong) + } + if (bl != false) { + size += WireFormat.getBoolSize(5, bl) + } + if (enumField != MessageVarints.TestEnum.fromIntToTestEnum(0)) { + size += WireFormat.getEnumSize(6, enumField.id) + } + if (uint != 0) { + size += WireFormat.getUInt32Size(7, uint) + } + if (ulong != 0L) { + size += WireFormat.getUInt64Size(8, ulong) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getInt64Size(2, long) + } + if (sint != 0) { + size += WireFormat.getSInt32Size(3, sint) + } + if (slong != 0L) { + size += WireFormat.getSInt64Size(4, slong) + } + if (bl != false) { + size += WireFormat.getBoolSize(5, bl) + } + if (enumField != MessageVarints.TestEnum.fromIntToTestEnum(0)) { + size += WireFormat.getEnumSize(6, enumField.id) + } + if (uint != 0) { + size += WireFormat.getUInt32Size(7, uint) + } + if (ulong != 0L) { + size += WireFormat.getUInt64Size(8, ulong) + } + return size + } + + //========== Builder =========== + class BuilderMessageVarints constructor (var int: Int, var long: Long, var sint: Int, var slong: Long, var bl: Boolean, var enumField: MessageVarints.TestEnum, var uint: Int, var ulong: Long) { + //========== Properties =========== + //int32 int = 1 + fun setInt(value: Int): MessageVarints.BuilderMessageVarints { + int = value + return this + } + + //int64 long = 2 + fun setLong(value: Long): MessageVarints.BuilderMessageVarints { + long = value + return this + } + + //sint32 sint = 3 + fun setSint(value: Int): MessageVarints.BuilderMessageVarints { + sint = value + return this + } + + //sint64 slong = 4 + fun setSlong(value: Long): MessageVarints.BuilderMessageVarints { + slong = value + return this + } + + //bool bl = 5 + fun setBl(value: Boolean): MessageVarints.BuilderMessageVarints { + bl = value + return this + } + + //enum enumField = 6 + fun setEnumField(value: MessageVarints.TestEnum): MessageVarints.BuilderMessageVarints { + enumField = value + return this + } + + //uint32 uint = 7 + fun setUint(value: Int): MessageVarints.BuilderMessageVarints { + uint = value + return this + } + + //uint64 ulong = 8 + fun setUlong(value: Long): MessageVarints.BuilderMessageVarints { + ulong = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 int = 1 + if (int != 0) { + output.writeInt32 (1, int) + } + + //int64 long = 2 + if (long != 0L) { + output.writeInt64 (2, long) + } + + //sint32 sint = 3 + if (sint != 0) { + output.writeSInt32 (3, sint) + } + + //sint64 slong = 4 + if (slong != 0L) { + output.writeSInt64 (4, slong) + } + + //bool bl = 5 + if (bl != false) { + output.writeBool (5, bl) + } + + //enum enumField = 6 + if (enumField.id != MessageVarints.TestEnum.fromIntToTestEnum(0).id) { + output.writeEnum (6, enumField.id) + } + + //uint32 uint = 7 + if (uint != 0) { + output.writeUInt32 (7, uint) + } + + //uint64 ulong = 8 + if (ulong != 0L) { + output.writeUInt64 (8, ulong) + } + + } + + //========== Mutating methods =========== + fun build(): MessageVarints { + val res = MessageVarints(int, long, sint, slong, bl, enumField, uint, ulong) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + int = input.readInt32NoTag() + } + 2 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + long = input.readInt64NoTag() + } + 3 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + sint = input.readSInt32NoTag() + } + 4 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + slong = input.readSInt64NoTag() + } + 5 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + bl = input.readBoolNoTag() + } + 6 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + enumField = MessageVarints.TestEnum.fromIntToTestEnum(input.readEnumNoTag()) + } + 7 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + uint = input.readUInt32NoTag() + } + 8 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + ulong = input.readUInt64NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): MessageVarints.BuilderMessageVarints { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): MessageVarints.BuilderMessageVarints { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getInt64Size(2, long) + } + if (sint != 0) { + size += WireFormat.getSInt32Size(3, sint) + } + if (slong != 0L) { + size += WireFormat.getSInt64Size(4, slong) + } + if (bl != false) { + size += WireFormat.getBoolSize(5, bl) + } + if (enumField != MessageVarints.TestEnum.fromIntToTestEnum(0)) { + size += WireFormat.getEnumSize(6, enumField.id) + } + if (uint != 0) { + size += WireFormat.getUInt32Size(7, uint) + } + if (ulong != 0L) { + size += WireFormat.getUInt64Size(8, ulong) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getInt64Size(2, long) + } + if (sint != 0) { + size += WireFormat.getSInt32Size(3, sint) + } + if (slong != 0L) { + size += WireFormat.getSInt64Size(4, slong) + } + if (bl != false) { + size += WireFormat.getBoolSize(5, bl) + } + if (enumField != MessageVarints.TestEnum.fromIntToTestEnum(0)) { + size += WireFormat.getEnumSize(6, enumField.id) + } + if (uint != 0) { + size += WireFormat.getUInt32Size(7, uint) + } + if (ulong != 0L) { + size += WireFormat.getUInt64Size(8, ulong) + } + return size + } + + } + +} + +fun compareVarints(kt1: MessageVarints, kt2: MessageVarints): Boolean { + return (kt1.int == kt2.int) and + (kt1.long == kt2.long) and + (kt1.sint == kt2.sint) and + (kt1.slong == kt2.slong) and + (kt1.bl == kt2.bl) and + (kt1.uint == kt2.uint) and + (kt1.ulong == kt2.ulong) and + (kt1.enumField.id == kt2.enumField.id) +} + +fun checkVarintsSerializationIdentity(msg: MessageVarints): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = MessageVarints.BuilderMessageVarints(0, 0L, 0, 0L, false, MessageVarints.TestEnum.fromIntToTestEnum(0), 0, 0L) + .parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareVarints(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun testVarintDefaultMessage(): Int { + val msg = MessageVarints.BuilderMessageVarints(0, 0L, 0, 0L, false, MessageVarints.TestEnum.fromIntToTestEnum(0), 0, 0L).build() + return checkVarintsSerializationIdentity(msg) +} + +fun testVarintTrivialMessage(): Int { + val msg = MessageVarints.BuilderMessageVarints( + 21312, -2131231231L, 5346734, 42121313211L, true, MessageVarints.TestEnum.fromIntToTestEnum(2), 3672356, 3478787863467834678L + ).build() + return checkVarintsSerializationIdentity(msg) +} + +fun testVarintNegativeMessage(): Int { + val msg = MessageVarints.BuilderMessageVarints( + -312732, -2131231231L, -5346734, -42121313211L, true, MessageVarints.TestEnum.fromIntToTestEnum(3), 3672356, 3478787863467834678L + ).build() + + return checkVarintsSerializationIdentity(msg) +} + +fun testVarintMaxValues(): Int { + val msg = MessageVarints.BuilderMessageVarints( + 2147483647, + 9223372036854775807L, + 2147483647, + 9223372036854775807L, + true, + MessageVarints.TestEnum.fromIntToTestEnum(3), + 2147483647, + 9223372036854775807L + ).build() + + return checkVarintsSerializationIdentity(msg) +} + +fun testVarintMinValues(): Int { + val msg = MessageVarints.BuilderMessageVarints( + -2147483647, + -9223372036854775807L, + -2147483647, + -9223372036854775807L, + false, + MessageVarints.TestEnum.fromIntToTestEnum(0), + -2147483647, + -9223372036854775807L + ).build() + + return checkVarintsSerializationIdentity(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.txt new file mode 100644 index 00000000000..c610d8177a3 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_varint/proto_varint.txt @@ -0,0 +1,5 @@ +testVarintDefaultMessage() == 0 +testVarintTrivialMessage() == 0 +testVarintNegativeMessage() == 0 +testVarintMaxValues() == 0 +testVarintMinValues() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.kt b/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.kt new file mode 100644 index 00000000000..3fad3b92846 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.kt @@ -0,0 +1,217 @@ +class MessageZigZag private constructor (var int: Int, var long: Long) { + //========== Properties =========== + //sint32 int = 1 + + //sint64 long = 2 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 int = 1 + if (int != 0) { + output.writeSInt32 (1, int) + } + + //sint64 long = 2 + if (long != 0L) { + output.writeSInt64 (2, long) + } + + } + + fun mergeWith (other: MessageZigZag) { + int = other.int + long = other.long + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = MessageZigZag.BuilderMessageZigZag(0, 0L) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = MessageZigZag.BuilderMessageZigZag(0, 0L) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getSInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getSInt64Size(2, long) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getSInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getSInt64Size(2, long) + } + return size + } + + //========== Builder =========== + class BuilderMessageZigZag constructor (var int: Int, var long: Long) { + //========== Properties =========== + //sint32 int = 1 + fun setInt(value: Int): MessageZigZag.BuilderMessageZigZag { + int = value + return this + } + + //sint64 long = 2 + fun setLong(value: Long): MessageZigZag.BuilderMessageZigZag { + long = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //sint32 int = 1 + if (int != 0) { + output.writeSInt32 (1, int) + } + + //sint64 long = 2 + if (long != 0L) { + output.writeSInt64 (2, long) + } + + } + + //========== Mutating methods =========== + fun build(): MessageZigZag { + val res = MessageZigZag(int, long) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + int = input.readSInt32NoTag() + } + 2 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + long = input.readSInt64NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): MessageZigZag.BuilderMessageZigZag { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): MessageZigZag.BuilderMessageZigZag { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getSInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getSInt64Size(2, long) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (int != 0) { + size += WireFormat.getSInt32Size(1, int) + } + if (long != 0L) { + size += WireFormat.getSInt64Size(2, long) + } + return size + } + + } + +} + +fun compareZigZags(kt1: MessageZigZag, kt2: MessageZigZag): Boolean { + return (kt1.int == kt2.int) and (kt1.long == kt2.long) +} + +fun checkZigZagSerializationIdentity(msg: MessageZigZag): Int { + val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag())) + msg.writeTo(outs) + + val ins = CodedInputStream(outs.buffer) + val readMsg = MessageZigZag.BuilderMessageZigZag(0, 0L).parseFrom(ins).build() + + if (readMsg.errorCode != 0) { + return 1 + } + if (compareZigZags(msg, readMsg)) { + return 0 + } else { + return 1 + } +} + +fun testZigZagDefaultValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(0, 0L).build() + return checkZigZagSerializationIdentity(msg) +} + +fun testZigZagRandomValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(321782363, -466328364782634782L).build() + return checkZigZagSerializationIdentity(msg) +} + +fun testZigZagNegativeValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(-1321782363, -323721963313L).build() + return checkZigZagSerializationIdentity(msg) +} + +fun testZigZagPositiveValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(4788923, 240384293674L).build() + return checkZigZagSerializationIdentity(msg) +} + +fun testZigZagMaxValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(2147483647, 9223372036854775807L).build() + return checkZigZagSerializationIdentity(msg) +} + +fun testZigZagMinValues(): Int { + val msg = MessageZigZag.BuilderMessageZigZag(-2147483647, -9223372036854775807L).build() + return checkZigZagSerializationIdentity(msg) +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.txt b/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.txt new file mode 100644 index 00000000000..15156624cfd --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/proto_zigzag/proto_zigzag.txt @@ -0,0 +1,6 @@ +testZigZagDefaultValues() == 0 +testZigZagRandomValues() == 0 +testZigZagNegativeValues() == 0 +testZigZagPositiveValues() == 0 +testZigZagMaxValues() == 0 +testZigZagMinValues() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.kt b/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.kt new file mode 100644 index 00000000000..f9625d7bf92 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.kt @@ -0,0 +1,10 @@ +fun range_operator_1(): Int { + val progression = 10..20 + val a = progression.iterator() + var result = 0 + while (a.hasNext()) { + val nxt = a.nextInt() + result += nxt + } + return result +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.txt b/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.txt new file mode 100644 index 00000000000..3e48da2bc65 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/range_operator_1/range_operator_1.txt @@ -0,0 +1 @@ +range_operator_1() == 165 diff --git a/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.kt b/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.kt new file mode 100644 index 00000000000..d5becc81789 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.kt @@ -0,0 +1,4 @@ +fun reassigment_0(x: Int): Int { + val b = x + 1 + return b +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.txt b/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.txt new file mode 100644 index 00000000000..d4a18813a63 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/reassigment_0/reassigment_0.txt @@ -0,0 +1 @@ +reassigment_0_Int(5) == 6 diff --git a/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.kt b/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.kt new file mode 100644 index 00000000000..395d1db6fa9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.kt @@ -0,0 +1,7 @@ +fun reassigment_1(x: Int): Int { + var a = x + a = a + 1 + var b = a + 1 + b = b + 1 + return b +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.txt b/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.txt new file mode 100644 index 00000000000..70e248f4187 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/reassigment_1/reassigment_1.txt @@ -0,0 +1 @@ +reassigment_1_Int(5) == 8 diff --git a/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.kt b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.kt new file mode 100644 index 00000000000..987067d3b19 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.kt @@ -0,0 +1,54 @@ +class referential_equality_1 + +fun referential_equality_1_EQEQ_true(): Int { + val instance = referential_equality_1() + var instance2 = referential_equality_1() + instance2 = instance + //problem with boolean in auto generated functions in clang + return if (instance == instance2) 1 else 0 +} + +fun referential_equality_1_EQEQ_false(): Int { + val instance = referential_equality_1() + val instance2 = referential_equality_1() + return if (instance == instance2) 1 else 0 +} + +fun referential_equality_1_EQEQEQ_true(): Int { + val instance = referential_equality_1() + var instance2 = referential_equality_1() + instance2 = instance + return if (instance === instance2) 1 else 0 +} + +fun referential_equality_1_EQEQEQ_false(): Int { + val instance = referential_equality_1() + val instance2 = referential_equality_1() + return if (instance === instance2) 1 else 0 +} + +fun referential_equality_1_EXCLEQEQ_false(): Int { + val instance = referential_equality_1() + var instance2 = referential_equality_1() + instance2 = instance + return if (instance != instance2) 1 else 0 +} + +fun referential_equality_1_EXCLEQEQ_true(): Int { + val instance = referential_equality_1() + val instance2 = referential_equality_1() + return if (instance != instance2) 1 else 0 +} + +fun referential_equality_1_EXCLEQEQEQ_false(): Int { + val instance = referential_equality_1() + var instance2 = referential_equality_1() + instance2 = instance + return if (instance !== instance2) 1 else 0 +} + +fun referential_equality_1_EXCLEQEQEQ_true(): Int { + val instance = referential_equality_1() + val instance2 = referential_equality_1() + return if (instance !== instance2) 1 else 0 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.txt b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.txt new file mode 100644 index 00000000000..11f8b1d968b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_1/referential_equality_1.txt @@ -0,0 +1,8 @@ +referential_equality_1_EQEQ_true() == 1 +referential_equality_1_EQEQ_false() == 0 +referential_equality_1_EQEQEQ_true() == 1 +referential_equality_1_EQEQEQ_false() == 0 +referential_equality_1_EXCLEQEQ_true() == 1 +referential_equality_1_EXCLEQEQ_false() == 0 +referential_equality_1_EXCLEQEQEQ_true() == 1 +referential_equality_1_EXCLEQEQEQ_false() == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.kt b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.kt new file mode 100644 index 00000000000..2884645fe7f --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.kt @@ -0,0 +1,28 @@ +class referential_equality_2_A + +fun referential_equality_2_build(): referential_equality_2_A { + return referential_equality_2_A() +} + +fun referential_equality_2_EQ_slave(second_msg: referential_equality_2_A): Int { + if (second_msg == referential_equality_2_build()) { + return 0 + } + return 1 +} + +fun referential_equality_2_NEQ_slave(second_msg: referential_equality_2_A): Int { + if (second_msg != referential_equality_2_build()) { + return 1 + } + return 0 +} + + +fun referential_equality_2_EQ_master(): Int { + return referential_equality_2_EQ_slave(referential_equality_2_build()) +} + +fun referential_equality_2_NEQ_master(): Int { + return referential_equality_2_NEQ_slave(referential_equality_2_build()) +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.txt b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.txt new file mode 100644 index 00000000000..1312315a8b2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/referential_equality_2/referential_equality_2.txt @@ -0,0 +1,2 @@ +referential_equality_2_EQ_master() == 1 +referential_equality_2_NEQ_master() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.kt b/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.kt new file mode 100644 index 00000000000..c1651707bb3 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.kt @@ -0,0 +1,3 @@ +fun return_test_1(x: Int): Int { + return 101 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.txt b/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.txt new file mode 100644 index 00000000000..f6e4102f1ad --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/return_1/return_1.txt @@ -0,0 +1 @@ +return_test_1_Int(101) == 101 diff --git a/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.kt b/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.kt new file mode 100644 index 00000000000..8e3df0e76de --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.kt @@ -0,0 +1,14 @@ +class save_access_operator_Gen(val i: Int) +class save_access_operator_MyClass(val i: save_access_operator_Gen?) + +fun save_access_operator_test1(): Int { + val x: save_access_operator_MyClass? = null + val y = save_access_operator_MyClass(x?.i) + + if (y == null) { + return 0 + } else { + return 1 + } +} + diff --git a/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.txt b/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.txt new file mode 100644 index 00000000000..f7b1137a7d9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/safe_access_operator/safe_access_operator.txt @@ -0,0 +1 @@ +save_access_operator_test1() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.kt b/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.kt new file mode 100644 index 00000000000..c4025d93bac --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.kt @@ -0,0 +1,28 @@ +class secondary_constructor_1_class(var field1: Int) { + constructor(field1: Int, field2: Int) : this(field1) { + this.field1 = field1 + field2 + } +} + +fun secondary_constructor_1(x: Int): Int { + val cls = secondary_constructor_1_class(12, x) + return cls.field1 +} + +class secondary_constructor_1_class2() { + var field1: IntArray + + init { + field1 = IntArray(0) + } + + constructor(x: Int) : this() { + this.field1 = this.field1.plus(x) + } +} + +fun secondary_constructor_1_arrays(): Int { + val cls = secondary_constructor_1_class2(56) + println(cls.field1) + return cls.field1.size + cls.field1[0] +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.txt b/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.txt new file mode 100644 index 00000000000..399810aa54b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/secondary_constructor_1/secondary_constructor_1.txt @@ -0,0 +1,2 @@ +secondary_constructor_1_Int(1389) == 1401 +secondary_constructor_1_arrays() == 57 diff --git a/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.kt b/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.kt new file mode 100644 index 00000000000..69ee598a321 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.kt @@ -0,0 +1,556 @@ + +class DirectionResponse private constructor(var code: Int) { + //========== Properties =========== + //int32 code = 1 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo(output: CodedOutputStream) { + //int32 code = 1 + if (code != 0) { + output.writeInt32(1, code) + } + + } + + fun mergeWith(other: DirectionResponse) { + code = other.code + this.errorCode = other.errorCode + } + + fun mergeFromWithSize(input: CodedInputStream, expectedSize: Int) { + val builder = DirectionResponse.BuilderDirectionResponse(0) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom(input: CodedInputStream) { + val builder = DirectionResponse.BuilderDirectionResponse(0) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (code != 0) { + size += WireFormat.getInt32Size(1, code) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (code != 0) { + size += WireFormat.getInt32Size(1, code) + } + return size + } + + //========== Builder =========== + class BuilderDirectionResponse constructor(var code: Int) { + //========== Properties =========== + //int32 code = 1 + fun setCode(value: Int): DirectionResponse.BuilderDirectionResponse { + code = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo(output: CodedOutputStream) { + //int32 code = 1 + if (code != 0) { + output.writeInt32(1, code) + } + + } + + //========== Mutating methods =========== + fun build(): DirectionResponse { + val res = DirectionResponse(code) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { + return false + } + val tag = input.readInt32NoTag() + if (tag == 0) { + return false + } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when (fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + code = input.readInt32NoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): DirectionResponse.BuilderDirectionResponse { + while (getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { + errorCode = 2 + } + return this + } + + fun parseFrom(input: CodedInputStream): DirectionResponse.BuilderDirectionResponse { + while (parseFieldFrom(input)) { + } + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (code != 0) { + size += WireFormat.getInt32Size(1, code) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (code != 0) { + size += WireFormat.getInt32Size(1, code) + } + return size + } + + } + +} + +class RouteRequest private constructor(var distances: IntArray, var angles: IntArray) { + //========== Properties =========== + //repeated int32 distances = 1 + + //repeated int32 angles = 2 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo(output: CodedOutputStream) { + //repeated int32 distances = 1 + if (distances.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (distances.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + arrayByteSize += arraySize + } while (false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < distances.size) { + output.writeInt32NoTag(distances[i]) + i += 1 + } + } while (false) + } + + //repeated int32 angles = 2 + if (angles.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (angles.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + arrayByteSize += arraySize + } while (false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < angles.size) { + output.writeInt32NoTag(angles[i]) + i += 1 + } + } while (false) + } + + } + + fun mergeWith(other: RouteRequest) { + distances = distances.plus((other.distances)) + angles = angles.plus((other.angles)) + this.errorCode = other.errorCode + } + + fun mergeFromWithSize(input: CodedInputStream, expectedSize: Int) { + val builder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom(input: CodedInputStream) { + val builder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + return size + } + + //========== Builder =========== + class BuilderRouteRequest constructor(var distances: IntArray, var angles: IntArray) { + //========== Properties =========== + //repeated int32 distances = 1 + fun setDistances(value: IntArray): RouteRequest.BuilderRouteRequest { + distances = value + return this + } + + fun setdistancesByIndex(index: Int, value: Int): RouteRequest.BuilderRouteRequest { + distances[index] = value + return this + } + + //repeated int32 angles = 2 + fun setAngles(value: IntArray): RouteRequest.BuilderRouteRequest { + angles = value + return this + } + + fun setanglesByIndex(index: Int, value: Int): RouteRequest.BuilderRouteRequest { + angles[index] = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo(output: CodedOutputStream) { + //repeated int32 distances = 1 + if (distances.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (distances.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + arrayByteSize += arraySize + } while (false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < distances.size) { + output.writeInt32NoTag(distances[i]) + i += 1 + } + } while (false) + } + + //repeated int32 angles = 2 + if (angles.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (angles.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + arrayByteSize += arraySize + } while (false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < angles.size) { + output.writeInt32NoTag(angles[i]) + i += 1 + } + } while (false) + } + + } + + //========== Mutating methods =========== + fun build(): RouteRequest { + val res = RouteRequest(distances, angles) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { + return false + } + val tag = input.readInt32NoTag() + if (tag == 0) { + return false + } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when (fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = IntArray(0) + var readSize = 0 + do { + var i = 0 + while (readSize < expectedByteSize) { + val tmp = IntArray(1) + tmp[0] = input.readInt32NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getInt32SizeNoTag(tmp[0]) + } + distances = newArray + } while (false) + } + 2 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = IntArray(0) + var readSize = 0 + do { + var i = 0 + while (readSize < expectedByteSize) { + val tmp = IntArray(1) + tmp[0] = input.readInt32NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getInt32SizeNoTag(tmp[0]) + } + angles = newArray + } while (false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): RouteRequest.BuilderRouteRequest { + while (getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { + errorCode = 2 + } + return this + } + + fun parseFrom(input: CodedInputStream): RouteRequest.BuilderRouteRequest { + while (parseFieldFrom(input)) { + } + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while (false) + } + return size + } + + } + +} + +fun serialization_test1(i: Int): Int { + val msg = DirectionResponse.BuilderDirectionResponse(i).build() + val buffer = ByteArray(msg.getSizeNoTag()) + val output = CodedOutputStream(buffer) + msg.writeTo(output) + + val input = CodedInputStream(buffer) + val msg2 = DirectionResponse.BuilderDirectionResponse(1).parseFrom(input) + + return msg2.code +} + +fun serialization_test2(size: Int) { + val arr = IntArray(size) + + var i = 0 + while (i < size) { + arr[i] = i + i++ + } + + val message = RouteRequest.BuilderRouteRequest(arr, arr).build() + val buffer = ByteArray(message.getSizeNoTag()) + + i = 0 + while (i < buffer.size) { + buffer[i] = 0 + i++ + } + + + val outputStream = CodedOutputStream(buffer) + message.writeTo(outputStream) + + val inputStream = CodedInputStream(buffer) + val receivedMessage = RouteRequest.BuilderRouteRequest(IntArray(1), IntArray(1)).parseFrom(inputStream).build() + + i = 0 + while (i < size) { + assert(message.distances[i] == receivedMessage.distances[i]) + i++ + } +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.txt b/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.txt new file mode 100644 index 00000000000..26a1fd0a657 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/serialization_test/serialization_test.txt @@ -0,0 +1,2 @@ +serialization_test1_Int(1442) == 1442 +serialization_test2_Int(5) diff --git a/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.kt b/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.kt new file mode 100644 index 00000000000..41b23a122ba --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.kt @@ -0,0 +1,20 @@ +class simple_class_2_MyClass(val b: Int, var c: Int) + +fun simple_class_2_genMyClass(i: Int): simple_class_2_MyClass { + return simple_class_2_MyClass(i, i) +} + +fun simple_class_2_change(x: Int): Int { + val y = simple_class_2_MyClass(x, x) + y.c = x + y.c = x + y.c = 1 + y.c = x + 1 + + return y.c +} + +fun simple_class_2_testGen(i: Int): Int { + val j = simple_class_2_genMyClass(i) + return j.b +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.txt b/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.txt new file mode 100644 index 00000000000..25648e5b636 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simple_class_2/simple_class_2.txt @@ -0,0 +1,3 @@ +simple_class_2_change_Int(0) == 1 +simple_class_2_change_Int(1) == 2 +simple_class_2_testGen_Int(10) == 10 diff --git a/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.kt b/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.kt new file mode 100644 index 00000000000..128b2cf90bc --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.kt @@ -0,0 +1,296 @@ +class simple_test private constructor (var field1: Int, var field2: Long, var field3: Int, var field4: Long, var field5: Boolean) { + //========== Properties =========== + //int32 field1 = 1 + + //int64 field2 = 2 + + //sint32 field3 = 3 + + //sint64 field4 = 4 + + //bool field5 = 5 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 field1 = 1 + if (field1 != 0) { + output.writeInt32 (1, field1) + } + + //int64 field2 = 2 + if (field2 != 0L) { + output.writeInt64 (2, field2) + } + + //sint32 field3 = 3 + if (field3 != 0) { + output.writeSInt32 (3, field3) + } + + //sint64 field4 = 4 + if (field4 != 0L) { + output.writeSInt64 (4, field4) + } + + //bool field5 = 5 + if (field5 != false) { + output.writeBool (5, field5) + } + + } + + fun mergeWith (other: simple_test) { + field1 = other.field1 + field2 = other.field2 + field3 = other.field3 + field4 = other.field4 + field5 = other.field5 + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = simple_test.Buildersimple_test(0, 0L, 0, 0L, false) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = simple_test.Buildersimple_test(0, 0L, 0, 0L, false) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (field1 != 0) { + size += WireFormat.getInt32Size(1, field1) + } + if (field2 != 0L) { + size += WireFormat.getInt64Size(2, field2) + } + if (field3 != 0) { + size += WireFormat.getSInt32Size(3, field3) + } + if (field4 != 0L) { + size += WireFormat.getSInt64Size(4, field4) + } + if (field5 != false) { + size += WireFormat.getBoolSize(5, field5) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (field1 != 0) { + size += WireFormat.getInt32Size(1, field1) + } + if (field2 != 0L) { + size += WireFormat.getInt64Size(2, field2) + } + if (field3 != 0) { + size += WireFormat.getSInt32Size(3, field3) + } + if (field4 != 0L) { + size += WireFormat.getSInt64Size(4, field4) + } + if (field5 != false) { + size += WireFormat.getBoolSize(5, field5) + } + return size + } + + //========== Builder =========== + class Buildersimple_test constructor (var field1: Int, var field2: Long, var field3: Int, var field4: Long, var field5: Boolean) { + //========== Properties =========== + //int32 field1 = 1 + fun setField1(value: Int): simple_test.Buildersimple_test { + field1 = value + return this + } + + //int64 field2 = 2 + fun setField2(value: Long): simple_test.Buildersimple_test { + field2 = value + return this + } + + //sint32 field3 = 3 + fun setField3(value: Int): simple_test.Buildersimple_test { + field3 = value + return this + } + + //sint64 field4 = 4 + fun setField4(value: Long): simple_test.Buildersimple_test { + field4 = value + return this + } + + //bool field5 = 5 + fun setField5(value: Boolean): simple_test.Buildersimple_test { + field5 = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //int32 field1 = 1 + if (field1 != 0) { + output.writeInt32 (1, field1) + } + + //int64 field2 = 2 + if (field2 != 0L) { + output.writeInt64 (2, field2) + } + + //sint32 field3 = 3 + if (field3 != 0) { + output.writeSInt32 (3, field3) + } + + //sint64 field4 = 4 + if (field4 != 0L) { + output.writeSInt64 (4, field4) + } + + //bool field5 = 5 + if (field5 != false) { + output.writeBool (5, field5) + } + + } + + //========== Mutating methods =========== + fun build(): simple_test { + val res = simple_test(field1, field2, field3, field4, field5) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + field1 = input.readInt32NoTag() + } + 2 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + field2 = input.readInt64NoTag() + } + 3 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + field3 = input.readSInt32NoTag() + } + 4 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + field4 = input.readSInt64NoTag() + } + 5 -> { + if (wireType.id != WireType.VARINT.id) { + errorCode = 1 + return false + } + field5 = input.readBoolNoTag() + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): simple_test.Buildersimple_test { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): simple_test.Buildersimple_test { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (field1 != 0) { + size += WireFormat.getInt32Size(1, field1) + } + if (field2 != 0L) { + size += WireFormat.getInt64Size(2, field2) + } + if (field3 != 0) { + size += WireFormat.getSInt32Size(3, field3) + } + if (field4 != 0L) { + size += WireFormat.getSInt64Size(4, field4) + } + if (field5 != false) { + size += WireFormat.getBoolSize(5, field5) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (field1 != 0) { + size += WireFormat.getInt32Size(1, field1) + } + if (field2 != 0L) { + size += WireFormat.getInt64Size(2, field2) + } + if (field3 != 0) { + size += WireFormat.getSInt32Size(3, field3) + } + if (field4 != 0L) { + size += WireFormat.getSInt64Size(4, field4) + } + if (field5 != false) { + size += WireFormat.getBoolSize(5, field5) + } + return size + } + + } + +} + +fun simple_proto_test(): Int{ + val instance = simple_test.Buildersimple_test(100, 200, 300, 400, true).build() + val buffer = ByteArray(instance.getSizeNoTag()) + val outputStream = CodedOutputStream(buffer) + instance.writeTo(outputStream) + val inputStream = CodedInputStream(buffer) + val receivedMesssage = simple_test.Buildersimple_test(112, 222, 333, 444, false).parseFrom(inputStream).build() + + assert(receivedMesssage.field1 == 100) + assert(receivedMesssage.field2 == 200L) + assert(receivedMesssage.field3 == 300) + assert(receivedMesssage.field4 == 400L) + assert(receivedMesssage.field5 == true) + return 1 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.txt b/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.txt new file mode 100644 index 00000000000..eaa33bf8d8c --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simple_proto_test_1/simple_proto_test_1.txt @@ -0,0 +1 @@ +simple_proto_test() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.kt b/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.kt new file mode 100644 index 00000000000..b0bc005f92b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.kt @@ -0,0 +1,10 @@ +class classname_A(val x: Int) { + fun method(): Int { + return this.x + 5 + } +} + +fun simply_class_1(zz: Int): Int { + val x = classname_A(zz) + return x.method() +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.txt b/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.txt new file mode 100644 index 00000000000..2ca18d2e3ff --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/simply_class_1/simply_class_1.txt @@ -0,0 +1 @@ +simply_class_1_Int(6789) == 6794 diff --git a/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.kt b/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.kt new file mode 100644 index 00000000000..1ba463a1ae2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.kt @@ -0,0 +1,11 @@ +fun smartcast_1_CastCheck(x: Int): Int { + return x + 1 +} + +fun smartcast_1(): Int { + var x: Int? = null + x = 3 + val y = x + val uio = smartcast_1_CastCheck(y) + return uio +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.txt b/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.txt new file mode 100644 index 00000000000..5343a057e00 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/smartcast_1/smartcast_1.txt @@ -0,0 +1 @@ +smartcast_1() == 4 diff --git a/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.kt b/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.kt new file mode 100644 index 00000000000..551b6889a6d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.kt @@ -0,0 +1,414 @@ +class RouteRequest private constructor (var distances: IntArray, var angles: IntArray) { + //========== Properties =========== + //repeated int32 distances = 1 + + //repeated int32 angles = 2 + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated int32 distances = 1 + if (distances.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (distances.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < distances.size) { + output.writeInt32NoTag (distances[i]) + i += 1 + } + } while(false) + } + + //repeated int32 angles = 2 + if (angles.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (angles.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < angles.size) { + output.writeInt32NoTag (angles[i]) + i += 1 + } + } while(false) + } + + } + + fun mergeWith (other: RouteRequest) { + distances = distances.plus((other.distances)) + angles = angles.plus((other.angles)) + this.errorCode = other.errorCode + } + + fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) { + val builder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)) + mergeWith(builder.parseFromWithSize(input, expectedSize).build()) + } + + fun mergeFrom (input: CodedInputStream) { + val builder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)) + mergeWith(builder.parseFrom(input).build()) + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + //========== Builder =========== + class BuilderRouteRequest constructor (var distances: IntArray, var angles: IntArray) { + //========== Properties =========== + //repeated int32 distances = 1 + fun setDistances(value: IntArray): RouteRequest.BuilderRouteRequest { + distances = value + return this + } + fun setdistancesByIndex(index: Int, value: Int): RouteRequest.BuilderRouteRequest { + distances[index] = value + return this + } + + //repeated int32 angles = 2 + fun setAngles(value: IntArray): RouteRequest.BuilderRouteRequest { + angles = value + return this + } + fun setanglesByIndex(index: Int, value: Int): RouteRequest.BuilderRouteRequest { + angles[index] = value + return this + } + + var errorCode: Int = 0 + + //========== Serialization methods =========== + fun writeTo (output: CodedOutputStream) { + //repeated int32 distances = 1 + if (distances.size > 0) { + output.writeTag(1, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (distances.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < distances.size) { + output.writeInt32NoTag (distances[i]) + i += 1 + } + } while(false) + } + + //repeated int32 angles = 2 + if (angles.size > 0) { + output.writeTag(2, WireType.LENGTH_DELIMITED) + var arrayByteSize = 0 + + if (angles.size != 0) { + do { + var arraySize = 0 + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + arrayByteSize += arraySize + } while(false) + } + output.writeInt32NoTag(arrayByteSize) + + do { + var i = 0 + while (i < angles.size) { + output.writeInt32NoTag (angles[i]) + i += 1 + } + } while(false) + } + + } + + //========== Mutating methods =========== + fun build(): RouteRequest { + val res = RouteRequest(distances, angles) + res.errorCode = errorCode + return res + } + + fun parseFieldFrom(input: CodedInputStream): Boolean { + if (input.isAtEnd()) { return false } + val tag = input.readInt32NoTag() + if (tag == 0) { return false } + val fieldNumber = WireFormat.getTagFieldNumber(tag) + val wireType = WireFormat.getTagWireType(tag) + when(fieldNumber) { + 1 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = IntArray(0) + var readSize = 0 + do { + var i = 0 + while(readSize < expectedByteSize) { + val tmp = IntArray(1) + tmp[0] = input.readInt32NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getInt32SizeNoTag(tmp[0]) + } + distances = newArray + } while (false) + } + 2 -> { + if (wireType.id != WireType.LENGTH_DELIMITED.id) { + errorCode = 1 + return false + } + val expectedByteSize = input.readInt32NoTag() + var newArray = IntArray(0) + var readSize = 0 + do { + var i = 0 + while(readSize < expectedByteSize) { + val tmp = IntArray(1) + tmp[0] = input.readInt32NoTag() + newArray = newArray.plus(tmp) + readSize += WireFormat.getInt32SizeNoTag(tmp[0]) + } + angles = newArray + } while (false) + } + else -> errorCode = 4 + } + return true + } + + fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): RouteRequest.BuilderRouteRequest { + while(getSizeNoTag() < expectedSize) { + parseFieldFrom(input) + } + if (getSizeNoTag() > expectedSize) { errorCode = 2 } + return this + } + + fun parseFrom(input: CodedInputStream): RouteRequest.BuilderRouteRequest { + while(parseFieldFrom(input)) {} + return this + } + + //========== Size-related methods =========== + fun getSize(fieldNumber: Int): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + size += WireFormat.getVarint32Size(size) + WireFormat.getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + return size + } + + fun getSizeNoTag(): Int { + var size = 0 + if (distances.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < distances.size) { + arraySize += WireFormat.getInt32SizeNoTag(distances[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + if (angles.size != 0) { + do { + var arraySize = 0 + size += WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + var i = 0 + while (i < angles.size) { + arraySize += WireFormat.getInt32SizeNoTag(angles[i]) + i += 1 + } + size += arraySize + size += WireFormat.getInt32SizeNoTag(arraySize) + } while(false) + } + return size + } + + } + +} + +fun echoProto() { + var i = 0 + while (i < 100) { + val route = readRoute() + go(route) + i++ + } +} + +fun receiveByteArray(): ByteArray { + val result = ByteArray(10) + result[0] = 10 + result[1] = 4 + result[2] = 232.toByte() + result[3] = 7 + result[4] = 232.toByte() + result[5] = 7 + result[6] = 18 + result[7] = 2 + result[8] = 0 + result[9] = 0 + + return result +} + +fun readRoute(): RouteRequest { + val buffer = receiveByteArray() + val stream = CodedInputStream(buffer) + val result = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)).parseFrom(stream).build() + + return result +} + +fun wait(i: Int) { +} + +fun go(request: RouteRequest) { + val times = request.distances + var j = 0 + + while (j < times.size) { + val time = times[j] + wait(time) + j++ + } + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.txt b/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.txt new file mode 100644 index 00000000000..477ef1303c2 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/stress_test_1/stress_test_1.txt @@ -0,0 +1 @@ +echoProto() diff --git a/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.kt b/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.kt new file mode 100644 index 00000000000..e553c80f108 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.kt @@ -0,0 +1,11 @@ +fun string_print_test_1_inline(): Int { + println("STRING INLINE PRINT WORKS") + return 23 +} + +fun string_print_test_1_variable(): Int { + val x = "STRING VARIABLE WORKS" + val y = x + println(y) + return 1 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.txt b/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.txt new file mode 100644 index 00000000000..11a3bfdf37d --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/string_print_test_1/string_print_test_1.txt @@ -0,0 +1,2 @@ +string_print_test_1_inline() == 23 +string_print_test_1_variable() == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.kt b/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.kt new file mode 100644 index 00000000000..6471202d711 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.kt @@ -0,0 +1,12 @@ +class this_test_1_class { + var data: Int = 5 + fun f(x: Int) { + data = x + 5 + } +} + +fun this_test_1(arg: Int): Int { + val instance = this_test_1_class() + instance.f(arg) + return instance.data +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.txt b/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.txt new file mode 100644 index 00000000000..dd4d81be586 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/this_test_1/this_test_1.txt @@ -0,0 +1 @@ +this_test_1_Int(48) == 53 diff --git a/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.kt b/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.kt new file mode 100644 index 00000000000..c45d721e185 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.kt @@ -0,0 +1,11 @@ +fun unary_operator_1_minus(x : Int): Int { + return -x +} + +fun unary_operator_1_plus(x : Int): Int { + return x +} + +fun unary_operator_1_not(x : Boolean): Boolean { + return !x +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.txt b/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.txt new file mode 100644 index 00000000000..752ab97e7db --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/unary_operators_1/unary_operators_1.txt @@ -0,0 +1,6 @@ +unary_operator_1_minus_Int(-5) == 5 +unary_operator_1_minus_Int(5) == -5 +unary_operator_1_plus_Int(-5) == -5 +unary_operator_1_plus_Int(5) == 5 +unary_operator_1_not_Boolean(1) == 0 +unary_operator_1_not_Boolean(0) == 1 diff --git a/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.kt b/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.kt new file mode 100644 index 00000000000..2306ec0805c --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.kt @@ -0,0 +1,6 @@ +fun variables_assigment_1(x: Int): Int { + var z = x + z++ + return x +} + diff --git a/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.txt b/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.txt new file mode 100644 index 00000000000..065f58fb725 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/variables_assigment_1/variables_assigment_1.txt @@ -0,0 +1 @@ +variables_assigment_1_Int(56789) == 56789 diff --git a/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.kt b/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.kt new file mode 100644 index 00000000000..22a1a996c4a --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.kt @@ -0,0 +1,9 @@ + +fun when_block_test1(i: Int): Boolean { + when (i) { + 0 -> return true + 1 -> return false + } + + return false +} diff --git a/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.txt b/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.txt new file mode 100644 index 00000000000..59450fdc4d8 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/when_block/when_block.txt @@ -0,0 +1,3 @@ +when_block_test1_Int(0) == 1 +when_block_test1_Int(1) == 0 +when_block_test1_Int(2) == 0 diff --git a/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.kt b/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.kt new file mode 100644 index 00000000000..ebd1fe4f40b --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.kt @@ -0,0 +1,22 @@ +fun when_expression_1(x: Int): Int { + val z = when (x) { + 21234 -> 20 + 55555 -> 50 + else -> 100 + } + return z +} + +fun when_expression_2 (value: Byte): Int { + val result = when (value) { + 0.toByte() -> 100 + 1.toByte() -> 101 + 2.toByte() -> 102 + 3.toByte() -> 103 + 4.toByte() -> 104 + 5.toByte() -> 105 + else -> 199 + } + + return result +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.txt b/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.txt new file mode 100644 index 00000000000..9e1a1287947 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/when_expression_1/when_expression_1.txt @@ -0,0 +1,7 @@ +when_expression_1_Int(21234) == 20 +when_expression_1_Int(55555) == 50 +when_expression_1_Int(345626) == 100 +when_expression_1_Int(756754) == 100 +when_expression_2_Byte(0) == 100 +when_expression_2_Byte(5) == 105 +when_expression_2_Byte(155) == 199 diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.kt b/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.kt new file mode 100644 index 00000000000..7a5836cf05c --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.kt @@ -0,0 +1,8 @@ +fun while_test_1(x: Int): Int { + var a = 5 + while (2 < 3) { + a = 10 + return a + } + return 5 +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.txt b/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.txt new file mode 100644 index 00000000000..02f167597f8 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_1/while_1.txt @@ -0,0 +1 @@ +while_test_1_Int(6) == 10 diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.c b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.c new file mode 100644 index 00000000000..23987f1e9a9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.c @@ -0,0 +1,3 @@ +int link_example(){ + return 5; +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.kt b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.kt new file mode 100644 index 00000000000..41441e899a9 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.kt @@ -0,0 +1,7 @@ +fun while_test_2(x: Int): Int { + var a = x + while (2 < 3) { + a = x + 1 + return a + } +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.txt b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.txt new file mode 100644 index 00000000000..d0b8a70ce30 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_2/while_2.txt @@ -0,0 +1 @@ +while_test_2_Int(77) == 78 diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.kt b/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.kt new file mode 100644 index 00000000000..85599858a3c --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.kt @@ -0,0 +1,15 @@ +object while_argument_side_effects_1_Counter{ + var cnt = 0 + fun isEnd():Boolean{ + cnt += 1 + return cnt < 10 + } +} + +fun while_argument_side_effects_1():Int{ + var iter = 0 + while(while_argument_side_effects_1_Counter.isEnd()){ + iter += 1 + } + return iter+ 1009*while_argument_side_effects_1_Counter.cnt +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.txt b/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.txt new file mode 100644 index 00000000000..aab348e4066 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_argument_side_effects_1/while_argument_side_effects_1.txt @@ -0,0 +1 @@ +while_argument_side_effects_1() == 10099 diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.kt b/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.kt new file mode 100644 index 00000000000..07a4acd4d09 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.kt @@ -0,0 +1,9 @@ +fun while_break_1(): Int { + var i = 1 + while (true) { + i = i + 1 + break + i = -100 + } + return i +} \ No newline at end of file diff --git a/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.txt b/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.txt new file mode 100644 index 00000000000..7fde1413cc1 --- /dev/null +++ b/experiments/translator-bc/src/test/kotlin/tests/while_break_1/while_break_1.txt @@ -0,0 +1 @@ +while_break_1() == 2 diff --git a/experiments/translator-bc/translate.sh b/experiments/translator-bc/translate.sh new file mode 100755 index 00000000000..2eb68f20216 --- /dev/null +++ b/experiments/translator-bc/translate.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +java -jar $DIR/build/libs/translator-1.0.jar -I $DIR/kotstd/include $@