Generate unsigned integers declarations, mostly without implementations

Generate and/or/xor/inv for UByte/UShort using experimental signed counterparts
This commit is contained in:
Ilya Gorbunov
2018-04-27 23:24:10 +03:00
parent e57e3971b6
commit 188d8ab8dd
8 changed files with 716 additions and 5 deletions
+11
View File
@@ -36,6 +36,16 @@ enum class PrimitiveType {
}
}
enum class UnsignedType {
UBYTE,
USHORT,
UINT,
ULONG;
val capitalized: String get() = name.substring(0, 2) + name.substring(2).toLowerCase()
val asSigned: PrimitiveType = PrimitiveType.valueOf(name.substring(1))
}
enum class ProgressionKind {
CHAR,
INT,
@@ -53,3 +63,4 @@ fun areEqualNumbers(v: String) = "$v == other.$v"
fun hashLong(v: String) = "($v xor ($v ushr 32))"
fun convert(v: String, from: UnsignedType, to: UnsignedType) = if (from == to) v else "$v.to${to.capitalized}()"
+5
View File
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.generators.builtins.progressionIterators.GeneratePro
import org.jetbrains.kotlin.generators.builtins.progressions.GenerateProgressions
import org.jetbrains.kotlin.generators.builtins.ranges.GeneratePrimitives
import org.jetbrains.kotlin.generators.builtins.ranges.GenerateRanges
import org.jetbrains.kotlin.generators.builtins.unsigned.generateUnsignedTypes
import org.xml.sax.InputSource
import java.io.File
import java.io.PrintWriter
@@ -25,6 +26,7 @@ fun assertExists(file: File) {
val BUILT_INS_NATIVE_DIR = File("core/builtins/native/")
val BUILT_INS_SRC_DIR = File("core/builtins/src/")
val RUNTIME_JVM_DIR = File("libraries/stdlib/jvm/runtime/")
val UNSIGNED_TYPES_DIR = File("libraries/stdlib/unsigned/src")
abstract class BuiltInsSourceGenerator(val out: PrintWriter) {
protected abstract fun generateBody(): Unit
@@ -65,6 +67,7 @@ fun generateBuiltIns(generate: (File, (PrintWriter) -> BuiltInsSourceGenerator)
assertExists(BUILT_INS_NATIVE_DIR)
assertExists(BUILT_INS_SRC_DIR)
assertExists(RUNTIME_JVM_DIR)
assertExists(UNSIGNED_TYPES_DIR)
generate(File(RUNTIME_JVM_DIR, "kotlin/jvm/functions/Functions.kt")) { GenerateFunctions(it) }
generate(File(BUILT_INS_NATIVE_DIR, "kotlin/Arrays.kt")) { GenerateArrays(it) }
@@ -74,6 +77,8 @@ fun generateBuiltIns(generate: (File, (PrintWriter) -> BuiltInsSourceGenerator)
generate(File(BUILT_INS_SRC_DIR, "kotlin/ProgressionIterators.kt")) { GenerateProgressionIterators(it) }
generate(File(BUILT_INS_SRC_DIR, "kotlin/Progressions.kt")) { GenerateProgressions(it) }
generate(File(BUILT_INS_SRC_DIR, "kotlin/Ranges.kt")) { GenerateRanges(it) }
generateUnsignedTypes(UNSIGNED_TYPES_DIR, generate)
}
fun main(args: Array<String>) {
+7 -5
View File
@@ -10,27 +10,29 @@ import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsSourceG
import java.io.PrintWriter
class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) {
private val binaryOperators: Map<String, String> = mapOf(
companion object {
internal val binaryOperators: Map<String, String> = mapOf(
"plus" to "Adds the other value to this value.",
"minus" to "Subtracts the other value from this value.",
"times" to "Multiplies this value by the other value.",
"div" to "Divides this value by the other value.",
"mod" to "Calculates the remainder of dividing this value by the other value.",
"rem" to "Calculates the remainder of dividing this value by the other value."
)
private val unaryOperators: Map<String, String> = mapOf(
)
internal val unaryOperators: Map<String, String> = mapOf(
"inc" to "Increments this value.",
"dec" to "Decrements this value.",
"unaryPlus" to "Returns this value.",
"unaryMinus" to "Returns the negative of this value.")
private val shiftOperators: Map<String, String> = mapOf(
internal val shiftOperators: Map<String, String> = mapOf(
"shl" to "Shifts this value left by the [bitCount] number of bits.",
"shr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.",
"ushr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.")
private val bitwiseOperators: Map<String, String> = mapOf(
internal val bitwiseOperators: Map<String, String> = mapOf(
"and" to "Performs a bitwise AND operation between the two values.",
"or" to "Performs a bitwise OR operation between the two values.",
"xor" to "Performs a bitwise XOR operation between the two values.")
}
private val typeDescriptions: Map<PrimitiveType, String> = mapOf(
PrimitiveType.DOUBLE to "double-precision 64-bit IEEE 754 floating point number",
PrimitiveType.FLOAT to "single-precision 32-bit IEEE 754 floating point number",
+173
View File
@@ -0,0 +1,173 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.generators.builtins.unsigned
import org.jetbrains.kotlin.generators.builtins.UnsignedType
import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsSourceGenerator
import org.jetbrains.kotlin.generators.builtins.ranges.GeneratePrimitives
import java.io.File
import java.io.PrintWriter
fun generateUnsignedTypes(
targetDir: File,
generate: (File, (PrintWriter) -> BuiltInsSourceGenerator) -> Unit
) {
for (type in UnsignedType.values()) {
generate(File(targetDir, "kotlin/${type.capitalized}.kt")) { UnsignedTypeGenerator(type, it) }
}
}
class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltInsSourceGenerator(out) {
val className = type.capitalized
val storageType = type.asSigned.capitalized
override fun generateBody() {
out.println("import kotlin.experimental.*")
out.println()
out.println("public inline class $className internal constructor(private val data: $storageType) : Comparable<$className> {")
out.println()
out.println(""" companion object {
/**
* A constant holding the minimum value an instance of $className can have.
*/
public /*const*/ val MIN_VALUE: $className = $className(0)
/**
* A constant holding the maximum value an instance of $className can have.
*/
public /*const*/ val MAX_VALUE: $className = $className(-1)
}""")
generateCompareTo()
generateBinaryOperators()
generateUnaryOperators()
generateRangeTo()
if (type == UnsignedType.UINT || type == UnsignedType.ULONG) {
generateBitShiftOperators()
}
generateBitwiseOperators()
generateMemberConversions()
out.println("}")
out.println()
generateExtensionConversions()
}
private fun generateCompareTo() {
for (otherType in UnsignedType.values()) {
out.println("""
/**
* Compares this value with the specified value for order.
* Returns zero if this value is equal to the specified other value, a negative number if it's less than other,
* or a positive number if it's greater than other.
*/""")
out.print(" public ")
if (otherType == type) out.print("override ")
out.println("operator fun compareTo(other: ${otherType.capitalized}): Int = TODO()")
}
out.println()
}
private fun generateBinaryOperators() {
for ((name, doc) in GeneratePrimitives.binaryOperators) {
if (name != "mod") {
generateOperator(name, doc)
}
}
}
private fun generateOperator(name: String, doc: String) {
for (otherType in UnsignedType.values()) {
val returnType = getOperatorReturnType(type, otherType)
out.println(" /** $doc */")
out.println(" public operator fun $name(other: ${otherType.capitalized}): ${returnType.capitalized} = TODO()")
}
out.println()
}
private fun generateUnaryOperators() {
for ((name, doc) in GeneratePrimitives.unaryOperators) {
if (name in listOf("unaryPlus", "unaryMinus")) continue // TODO: Decide if unaryPlus and unaryMinus are needed
out.println(" /** $doc */")
out.println(" public operator fun $name(): $className = TODO()")
}
out.println()
}
private fun generateRangeTo() {
// TODO("not implemented")
}
private fun generateBitShiftOperators() {
fun generateShiftOperator(name: String, implementation: String = name) {
val doc = GeneratePrimitives.shiftOperators[implementation]!!
out.println(" /** $doc */")
out.println(" public infix fun $name(bitCount: Int): $className = $className(data $implementation bitCount)")
}
generateShiftOperator("shl")
generateShiftOperator("shr", "ushr")
}
private fun generateBitwiseOperators() {
for ((name, doc) in GeneratePrimitives.bitwiseOperators) {
out.println(" /** $doc */")
out.println(" public infix fun $name(other: $className): $className = $className(this.data $name other.data)")
}
out.println(" /** Inverts the bits in this value. */")
out.println(" public fun inv(): $className = $className(data.inv())")
out.println()
}
private fun generateMemberConversions() {
for (otherType in UnsignedType.values()) {
val signed = otherType.asSigned.capitalized
out.println(" public fun to$signed(): $signed = TODO()")
}
out.println()
for (otherType in UnsignedType.values()) {
val name = otherType.capitalized
out.println(" public fun to$name(): $name = TODO()")
}
out.println()
}
private fun generateExtensionConversions() {
for (otherType in UnsignedType.values()) {
val otherSigned = otherType.asSigned.capitalized
val thisSigned = type.asSigned.capitalized
out.println("public fun $otherSigned.to$className(): $className = $className(this.to$thisSigned())")
}
}
private fun maxByDomainCapacity(type1: UnsignedType, type2: UnsignedType): UnsignedType =
if (type1.ordinal > type2.ordinal) type1 else type2
private fun getOperatorReturnType(type1: UnsignedType, type2: UnsignedType): UnsignedType {
return maxByDomainCapacity(maxByDomainCapacity(type1, type2), UnsignedType.UINT)
}
}