diff --git a/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/Math.kt b/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/Math.kt index cbbfb3a2..f19604cf 100644 --- a/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/Math.kt +++ b/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/Math.kt @@ -1,12 +1,12 @@ package com.strumenta.kotlinmultiplatform object Math { - fun min(a: Int, b: Int): Int = + inline fun min(a: Int, b: Int): Int = kotlin.math.min(a, b) - fun max(a: Int, b: Int): Int = + inline fun max(a: Int, b: Int): Int = kotlin.math.max(a, b) - fun floor(d: Double): Double = + inline fun floor(d: Double): Double = kotlin.math.floor(d) } diff --git a/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/ext/String.ext.kt b/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/ext/String.ext.kt new file mode 100644 index 00000000..7a8fa960 --- /dev/null +++ b/antlr-kotlin-runtime/src/commonMain/kotlin/com/strumenta/kotlinmultiplatform/ext/String.ext.kt @@ -0,0 +1,14 @@ +package com.strumenta.kotlinmultiplatform.ext + +fun String.codePointIndices(): IntArray { + val intArray = IntArray(length) + var p = 0 + + for (i in indices) { + if (!hasSurrogatePairAt(i - 1)) { + intArray[p++] = i + } + } + + return intArray.copyOfRange(0, p) +} diff --git a/antlr-kotlin-runtime/src/commonMain/kotlin/org/antlr/v4/kotlinruntime/StringCharStream.kt b/antlr-kotlin-runtime/src/commonMain/kotlin/org/antlr/v4/kotlinruntime/StringCharStream.kt index 46819b37..be7a9106 100644 --- a/antlr-kotlin-runtime/src/commonMain/kotlin/org/antlr/v4/kotlinruntime/StringCharStream.kt +++ b/antlr-kotlin-runtime/src/commonMain/kotlin/org/antlr/v4/kotlinruntime/StringCharStream.kt @@ -2,76 +2,48 @@ package org.antlr.v4.kotlinruntime import com.strumenta.kotlinmultiplatform.Math import com.strumenta.kotlinmultiplatform.assert +import com.strumenta.kotlinmultiplatform.ext.codePointIndices import org.antlr.v4.kotlinruntime.misc.Interval -internal fun String.codePointIndices(): IntArray { - return (0 until length).mapNotNull { index -> - if (hasSurrogatePairAt(index - 1)) { - null - } else { - index - } - }.toIntArray() -} - -private fun toCodePoint(high: Char, low: Char): Int { - return high.toInt().shl(10) + low.toInt() + -56613888 -} - class StringCharStream(private val source: String, override val sourceName: String) : CharStream { private val codePointIndices = source.codePointIndices() private val size = codePointIndices.size - private var position: Int = 0 - - private fun codePoint(index: Int): Int { - return if (index in 0 until size) { - val char = source[codePointIndices[index]] - if (char.isHighSurrogate()) { - if (index + 1 in 0 until size) { - val low = source[codePointIndices[index] + 1] - toCodePoint(char, low) - } else { - IntStream.EOF - } - } else { - char.toInt() - } - } else { - IntStream.EOF - } - } + private var position = 0 override fun consume() { if (size - position == 0) { assert(LA(1) == IntStream.EOF) throw IllegalStateException("cannot consume EOF") } - position += 1 - } - override fun index(): Int { - return position + position++ } - override fun size(): Int { - return size - } + override fun index(): Int = + position - /** mark/release do nothing; we have entire buffer */ - override fun mark(): Int { - return -1 - } + override fun size(): Int = + size + /** + * Does nothing, as we have the entire buffer. + */ + override fun mark(): Int = + -1 + + /** + * Does nothing, as we have the entire buffer. + */ override fun release(marker: Int) { + // Noop } override fun seek(index: Int) { position = index } - override fun toString(): String { - return getText(Interval.of(0, size - 1)) - } + override fun toString(): String = + getText(Interval.of(0, size - 1)) override fun getText(interval: Interval): String { val startIndex = Math.min(interval.a, size) @@ -79,13 +51,33 @@ class StringCharStream(private val source: String, override val sourceName: Stri return source.substring(codePointIndices[startIndex], codePointIndices[endIndex] + 1) } - override fun LA(i: Int): Int { - return when { + override fun LA(i: Int): Int = + when { i < 0 -> codePoint(position + i) i > 0 -> codePoint(position + i - 1) - else -> - // Undefined - return 0 + // Undefined + else -> 0 + } + + private fun codePoint(index: Int): Int { + if (index !in 0..