fixed Decimal conversion bug
This commit is contained in:
parent
aa9565b40b
commit
c3c0a3292b
@ -88,7 +88,7 @@ object ObjDecimalSupport {
|
||||
}
|
||||
decimalClass.addClassFn("fromInt") {
|
||||
val value = requiredArg<ObjInt>(0).value
|
||||
newInstance(decimalClass, IonBigDecimal.fromLongAsSignificand(value))
|
||||
newInstance(decimalClass, IonBigDecimal.fromLong(value))
|
||||
}
|
||||
decimalClass.addClassFn("fromReal") {
|
||||
val value = requiredArg<ObjReal>(0).value
|
||||
@ -204,7 +204,7 @@ object ObjDecimalSupport {
|
||||
}
|
||||
|
||||
private fun coerceArg(scope: Scope, value: Obj): IonBigDecimal = when (value) {
|
||||
is ObjInt -> IonBigDecimal.fromLongAsSignificand(value.value)
|
||||
is ObjInt -> IonBigDecimal.fromLong(value.value)
|
||||
is ObjReal -> IonBigDecimal.fromDouble(value.value, realConversionMode)
|
||||
is ObjInstance -> {
|
||||
if (value.objClass.className != "Decimal") {
|
||||
@ -303,7 +303,7 @@ object ObjDecimalSupport {
|
||||
doc = "Convert this integer to a Decimal.",
|
||||
type = type("lyng.decimal.Decimal"),
|
||||
moduleName = "lyng.decimal",
|
||||
getter = { newInstance(decimalClass, IonBigDecimal.fromLongAsSignificand(thisAs<ObjInt>().value)) }
|
||||
getter = { newInstance(decimalClass, IonBigDecimal.fromLong(thisAs<ObjInt>().value)) }
|
||||
)
|
||||
ObjInt.type.members["d"] = ObjInt.type.members.getValue("d").copy(typeDecl = decimalTypeDecl)
|
||||
ObjReal.type.addPropertyDoc(
|
||||
@ -347,7 +347,7 @@ object ObjDecimalSupport {
|
||||
),
|
||||
leftToCommon = ObjExternCallable.fromBridge {
|
||||
val value = requiredArg<ObjInt>(0).value
|
||||
newInstance(decimalClass, IonBigDecimal.fromLongAsSignificand(value))
|
||||
newInstance(decimalClass, IonBigDecimal.fromLong(value))
|
||||
},
|
||||
rightToCommon = ObjExternCallable.fromBridge {
|
||||
requiredArg<Obj>(0)
|
||||
|
||||
@ -17,14 +17,15 @@
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import net.sergeych.lyng.bridge.bindGlobalFun1
|
||||
import net.sergeych.lyng.bridge.bindGlobalFun3
|
||||
import net.sergeych.lyng.bridge.bindGlobalVar
|
||||
import net.sergeych.lyng.bridge.globalBinder
|
||||
import net.sergeych.lyng.bridge.*
|
||||
import net.sergeych.lyng.obj.ObjInstance
|
||||
import net.sergeych.lyng.obj.ObjInt
|
||||
import net.sergeych.lyng.obj.ObjReal
|
||||
import net.sergeych.lyng.obj.ObjString
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class GlobalBindingTest {
|
||||
@ -136,4 +137,87 @@ class GlobalBindingTest {
|
||||
assertTrue(readonlySetter)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rawDecimalExternBindingDoesNotBreakDecimalLiteralRendering() = runTest {
|
||||
val scope = Script.newScope()
|
||||
var x = BigDecimal.ZERO
|
||||
|
||||
scope.eval(
|
||||
"""
|
||||
import lyng.decimal
|
||||
extern var X: Decimal
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
scope.globalBinder().bindGlobalVarRaw(
|
||||
name = "X",
|
||||
get = { it.newDecimal(x) },
|
||||
set = { _, value ->
|
||||
x = when (value) {
|
||||
is ObjInt -> BigDecimal.fromLong(value.value)
|
||||
is ObjReal -> BigDecimal.fromDouble(value.value)
|
||||
is ObjInstance -> value.data as BigDecimal
|
||||
else -> error("unexpected value: $value")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
scope.eval(
|
||||
"""
|
||||
fun main() {
|
||||
assertEquals("42", 42.d.toStringExpanded())
|
||||
}
|
||||
|
||||
main()
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
assertEquals(BigDecimal.ZERO, x)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun externDecimalDeclarationAloneDoesNotBreakDecimalLiteralRendering() = runTest {
|
||||
val scope = Script.newScope()
|
||||
|
||||
scope.eval(
|
||||
"""
|
||||
import lyng.decimal
|
||||
extern var X: Decimal
|
||||
|
||||
fun main() {
|
||||
assertEquals("42", 42.d.toStringExpanded())
|
||||
}
|
||||
|
||||
main()
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parserKeeps42DotDAsIntDotIdentifierAfterExternDecimalDeclaration() = runTest {
|
||||
val tokens = parseLyng(
|
||||
Source(
|
||||
"test",
|
||||
"""
|
||||
import lyng.decimal
|
||||
extern var X: Decimal
|
||||
|
||||
fun main() {
|
||||
42.d.toStringExpanded()
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
)
|
||||
val tokenTexts = tokens.map { it.type to it.value }
|
||||
val needle = listOf(
|
||||
Token.Type.INT to "42",
|
||||
Token.Type.DOT to ".",
|
||||
Token.Type.ID to "d",
|
||||
Token.Type.DOT to ".",
|
||||
Token.Type.ID to "toStringExpanded",
|
||||
)
|
||||
val found = tokenTexts.windowed(needle.size).any { it == needle }
|
||||
assertTrue(found, tokenTexts.joinToString())
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +32,10 @@ class DecimalModuleTest {
|
||||
|
||||
assertEquals("12.34", Decimal.fromString("12.34").toStringExpanded())
|
||||
assertEquals("1", Decimal.fromInt(1).toStringExpanded())
|
||||
assertEquals("42", Decimal.fromInt(42).toStringExpanded())
|
||||
assertEquals("2.5", "2.5".d.toStringExpanded())
|
||||
assertEquals("1", 1.d.toStringExpanded())
|
||||
assertEquals("42", 42.d.toStringExpanded())
|
||||
assertEquals("2.2", 2.2.d.toStringExpanded())
|
||||
assertEquals("3", (1 + 2).d.toStringExpanded())
|
||||
assertEquals("1.5", (1 + 0.5).d.toStringExpanded())
|
||||
@ -229,6 +231,21 @@ class DecimalModuleTest {
|
||||
""")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decimalPropertyWorksInsideFunctionBody() = runTest {
|
||||
eval("""
|
||||
import lyng.decimal
|
||||
|
||||
fun main() {
|
||||
val x = 42.d
|
||||
assertEquals(42.d, x)
|
||||
assertEquals(53.d, x + 11)
|
||||
}
|
||||
|
||||
main()
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun kotlinHelperCanWrapIonBigDecimal() = runTest {
|
||||
val scope = Script.newScope()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user