blob: 3fdffcbaafeab5d270a582d118ccf0e40e816ad3 [file]
/*
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.wasm.internal
internal actual fun parseDouble(string: String): Double {
if (string.isEmpty()) numberFormatError(string)
var index = 0
fun parseUnsignificants() {
while (index <= string.lastIndex) {
if (string[index] != ' ' && string[index] != '\n' && string[index] != '\t') break
index++
}
}
fun parseNumber(sb: StringBuilder) {
while (index <= string.lastIndex) {
val ch = string[index]
if (ch !in '0'..'9') break
sb.append(string[index])
index++
}
}
fun parseSign(): Boolean {
if (index > string.lastIndex) return false
val ch = string[index]
if (ch == '+' || ch == '-') {
index++
return ch == '-'
}
return false
}
fun parseE(): Boolean {
if (index > string.lastIndex) return false
val ch = string[index]
if (ch == 'e' || ch == 'E') {
index++
return true
}
return false
}
fun parseDot(): Boolean {
if (index > string.lastIndex) return false
val ch = string[index]
if (ch == '.') {
index++
return true
}
return false
}
fun tryParseWord(word: String): Boolean {
if (string.length - index < word.length) return false
val originalIndex = index
var wordIndex = 0
while (wordIndex < word.length) {
if (string[index] != word[wordIndex]) {
index = originalIndex
return false
}
wordIndex++
index++
}
return true
}
parseUnsignificants()
val isNegative = parseSign()
if (tryParseWord("NaN")) {
parseUnsignificants()
if (index != string.length) numberFormatError(string)
return if (!isNegative) Double.NaN else -Double.NaN
}
if (tryParseWord("Infinity")) {
parseUnsignificants()
if (index != string.length) numberFormatError(string)
return if (!isNegative) Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY
}
val numberBuilder = StringBuilder()
parseNumber(numberBuilder)
var scale = numberBuilder.length
if (parseDot()) parseNumber(numberBuilder)
if (numberBuilder.isEmpty()) numberFormatError(string)
val numberString = numberBuilder.toString()
if (parseE()) {
numberBuilder.clear()
val isExponentNegative = parseSign()
parseNumber(numberBuilder)
if (numberBuilder.isEmpty()) numberFormatError(string)
parseUnsignificants()
if (index != string.length) numberFormatError(string)
if (numberString.all { it == '0' }) {
return if (isNegative) -0.0 else 0.0
}
val exponentScale = numberBuilder.toString().toIntOrNull() ?: run {
return if (isExponentNegative) {
if (isNegative) -0.0 else 0.0
} else {
if (isNegative) Double.NEGATIVE_INFINITY else Double.POSITIVE_INFINITY
}
}
if (isExponentNegative) {
scale -= exponentScale
} else {
scale += exponentScale
}
} else {
parseUnsignificants()
if (index != string.length) numberFormatError(string)
}
return numberToDouble(isNegative, scale, numberString)
}