+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/translator/README.md b/experiments/translator/README.md
index c18661729e9..5778ef83e0e 100644
--- a/experiments/translator/README.md
+++ b/experiments/translator/README.md
@@ -28,7 +28,7 @@ Assembled the translator can be found in the following folder
$ 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 standart kotlin lib, by default it `../kotstd/kt`
+ - $(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
diff --git a/experiments/translator/kotstd/Makefile b/experiments/translator/kotstd/Makefile
new file mode 100644
index 00000000000..fdd6cf55107
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Assert.kt b/experiments/translator/kotstd/include/Assert.kt
new file mode 100644
index 00000000000..fc253e0f13e
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/BooleanArray.kt b/experiments/translator/kotstd/include/BooleanArray.kt
new file mode 100644
index 00000000000..7df7eb81e46
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/ByteArray.kt b/experiments/translator/kotstd/include/ByteArray.kt
new file mode 100644
index 00000000000..8952a07eb1f
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/CodedInputStream.kt b/experiments/translator/kotstd/include/CodedInputStream.kt
new file mode 100644
index 00000000000..bb5b6e47cae
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/CodedOutputStream.kt b/experiments/translator/kotstd/include/CodedOutputStream.kt
new file mode 100644
index 00000000000..9c40747b99c
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Console.kt b/experiments/translator/kotstd/include/Console.kt
new file mode 100644
index 00000000000..c4077be14d4
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/IntArray.kt b/experiments/translator/kotstd/include/IntArray.kt
new file mode 100644
index 00000000000..09767b162b9
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Iterators.kt b/experiments/translator/kotstd/include/Iterators.kt
new file mode 100644
index 00000000000..836b06babe9
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/KotlinInputStream.kt b/experiments/translator/kotstd/include/KotlinInputStream.kt
new file mode 100644
index 00000000000..ee2c40aa387
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/KotlinOutputStream.kt b/experiments/translator/kotstd/include/KotlinOutputStream.kt
new file mode 100644
index 00000000000..51f80aaf766
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/LongArray.kt b/experiments/translator/kotstd/include/LongArray.kt
new file mode 100644
index 00000000000..f8ae4fe7d03
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Primitives.kt b/experiments/translator/kotstd/include/Primitives.kt
new file mode 100644
index 00000000000..3da2e500545
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Progressions.kt b/experiments/translator/kotstd/include/Progressions.kt
new file mode 100644
index 00000000000..ec9bbb3ec09
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/Ranges.kt b/experiments/translator/kotstd/include/Ranges.kt
new file mode 100644
index 00000000000..4c12faa5e3d
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/ShortArray.kt b/experiments/translator/kotstd/include/ShortArray.kt
new file mode 100644
index 00000000000..3d1cf82a40e
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/WireFormat.kt b/experiments/translator/kotstd/include/WireFormat.kt
new file mode 100644
index 00000000000..d43c6e37003
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/WireType.kt b/experiments/translator/kotstd/include/WireType.kt
new file mode 100644
index 00000000000..4ffc150fa68
--- /dev/null
+++ b/experiments/translator/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/kotstd/include/progressionUtil.kt b/experiments/translator/kotstd/include/progressionUtil.kt
new file mode 100644
index 00000000000..a03312f71e4
--- /dev/null
+++ b/experiments/translator/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/kotstd/libc/array_c.c b/experiments/translator/kotstd/libc/array_c.c
new file mode 100644
index 00000000000..8b80a3534cc
--- /dev/null
+++ b/experiments/translator/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/kotstd/libc/assert_c.c b/experiments/translator/kotstd/libc/assert_c.c
new file mode 100644
index 00000000000..e526eaaca41
--- /dev/null
+++ b/experiments/translator/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/kotstd/libc/memory.c b/experiments/translator/kotstd/libc/memory.c
new file mode 100644
index 00000000000..18844c7c0ef
--- /dev/null
+++ b/experiments/translator/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/kotstd/libc/primitives_c.c b/experiments/translator/kotstd/libc/primitives_c.c
new file mode 100644
index 00000000000..5f1eb3c2f52
--- /dev/null
+++ b/experiments/translator/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/translate.sh b/experiments/translator/translate.sh
new file mode 100755
index 00000000000..2eb68f20216
--- /dev/null
+++ b/experiments/translator/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 $@