fixed Decima/Complex interop bug
This commit is contained in:
parent
cdd48ec871
commit
f845213332
@ -87,11 +87,37 @@ object ObjComplexSupport {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal suspend fun decimalBinary(scope: ScopeFacade, decimal: Obj, other: Obj, operator: InteropOperator): Obj? {
|
||||||
|
val left = ObjDecimalSupport.toDoubleOrNull(decimal) ?: return null
|
||||||
|
val complex = other as? ObjInstance ?: return null
|
||||||
|
if (complex.objClass.className != "Complex") return null
|
||||||
|
val otherReal = complex.readField(scope.requireScope(), "real").value.toDouble()
|
||||||
|
val otherImag = complex.readField(scope.requireScope(), "imag").value.toDouble()
|
||||||
|
return when (operator) {
|
||||||
|
InteropOperator.Plus -> instantiateComplex(scope, complex.objClass, left + otherReal, otherImag)
|
||||||
|
InteropOperator.Minus -> instantiateComplex(scope, complex.objClass, left - otherReal, -otherImag)
|
||||||
|
InteropOperator.Mul -> instantiateComplex(scope, complex.objClass, left * otherReal, left * otherImag)
|
||||||
|
InteropOperator.Div -> {
|
||||||
|
val denominator = otherReal * otherReal + otherImag * otherImag
|
||||||
|
instantiateComplex(scope, complex.objClass, left * otherReal / denominator, -left * otherImag / denominator)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun ScopeFacade.newComplex(complexClass: ObjClass, real: Double, imag: Double): ObjInstance =
|
private suspend fun ScopeFacade.newComplex(complexClass: ObjClass, real: Double, imag: Double): ObjInstance =
|
||||||
call(
|
instantiateComplex(this, complexClass, real, imag)
|
||||||
complexClass,
|
|
||||||
Arguments(ObjReal.of(real), ObjReal.of(imag))
|
private suspend fun instantiateComplex(scope: ScopeFacade, complexClass: ObjClass, real: Double, imag: Double): ObjInstance {
|
||||||
) as? ObjInstance ?: raiseIllegalState("Complex() did not return an object instance")
|
val runtimeScope = scope.requireScope()
|
||||||
|
val instance = complexClass.createInstance(runtimeScope)
|
||||||
|
complexClass.initializeInstance(
|
||||||
|
instance,
|
||||||
|
Arguments(ObjReal.of(real), ObjReal.of(imag)),
|
||||||
|
runConstructors = false
|
||||||
|
)
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
private fun ScopeFacade.decimalToReal(value: Obj): Double =
|
private fun ScopeFacade.decimalToReal(value: Obj): Double =
|
||||||
ObjDecimalSupport.toDoubleOrNull(value)
|
ObjDecimalSupport.toDoubleOrNull(value)
|
||||||
|
|||||||
@ -54,19 +54,23 @@ object ObjDecimalSupport {
|
|||||||
instance.kotlinInstanceData = zero
|
instance.kotlinInstanceData = zero
|
||||||
}
|
}
|
||||||
decimalClass.addFn("plus") {
|
decimalClass.addFn("plus") {
|
||||||
OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Plus)
|
ObjComplexSupport.decimalBinary(this, thisObj, args.firstAndOnly(), InteropOperator.Plus)
|
||||||
|
?: OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Plus)
|
||||||
?: newInstance(decimalClass, valueOf(thisObj).plus(coerceArg(requireScope(), args.firstAndOnly())))
|
?: newInstance(decimalClass, valueOf(thisObj).plus(coerceArg(requireScope(), args.firstAndOnly())))
|
||||||
}
|
}
|
||||||
decimalClass.addFn("minus") {
|
decimalClass.addFn("minus") {
|
||||||
OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Minus)
|
ObjComplexSupport.decimalBinary(this, thisObj, args.firstAndOnly(), InteropOperator.Minus)
|
||||||
|
?: OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Minus)
|
||||||
?: newInstance(decimalClass, valueOf(thisObj).minus(coerceArg(requireScope(), args.firstAndOnly())))
|
?: newInstance(decimalClass, valueOf(thisObj).minus(coerceArg(requireScope(), args.firstAndOnly())))
|
||||||
}
|
}
|
||||||
decimalClass.addFn("mul") {
|
decimalClass.addFn("mul") {
|
||||||
OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Mul)
|
ObjComplexSupport.decimalBinary(this, thisObj, args.firstAndOnly(), InteropOperator.Mul)
|
||||||
|
?: OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Mul)
|
||||||
?: newInstance(decimalClass, valueOf(thisObj).times(coerceArg(requireScope(), args.firstAndOnly())))
|
?: newInstance(decimalClass, valueOf(thisObj).times(coerceArg(requireScope(), args.firstAndOnly())))
|
||||||
}
|
}
|
||||||
decimalClass.addFn("div") {
|
decimalClass.addFn("div") {
|
||||||
OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Div)
|
ObjComplexSupport.decimalBinary(this, thisObj, args.firstAndOnly(), InteropOperator.Div)
|
||||||
|
?: OperatorInteropRegistry.invokeBinary(requireScope(), thisObj, args.firstAndOnly(), InteropOperator.Div)
|
||||||
?: newInstance(decimalClass, divideWithContext(valueOf(thisObj), coerceArg(requireScope(), args.firstAndOnly()), currentDivisionMode(requireScope())))
|
?: newInstance(decimalClass, divideWithContext(valueOf(thisObj), coerceArg(requireScope(), args.firstAndOnly()), currentDivisionMode(requireScope())))
|
||||||
}
|
}
|
||||||
decimalClass.addFn("mod") {
|
decimalClass.addFn("mod") {
|
||||||
|
|||||||
@ -97,6 +97,15 @@ class ComplexModuleTest {
|
|||||||
assert( 5 + 1.d.i is Complex )
|
assert( 5 + 1.d.i is Complex )
|
||||||
assert( 5.d + 1.i is Complex )
|
assert( 5.d + 1.i is Complex )
|
||||||
assert( 5.d + 2.d.i is Complex )
|
assert( 5.d + 2.d.i is Complex )
|
||||||
|
assertEquals("0.0+1.0i", 1.d.i.toString())
|
||||||
|
assertEquals("1.0+0.0i", 1.d.re.toString())
|
||||||
|
|
||||||
|
var c = 1 + 2.i
|
||||||
|
assert(c is Complex)
|
||||||
|
assertEquals("1.0+2.0i", c.toString())
|
||||||
|
|
||||||
|
c = 1.d + 2.i
|
||||||
|
assertEquals("1.0+2.0i", c.toString())
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -308,4 +308,5 @@ class DecimalModuleTest {
|
|||||||
assertEquals(10,t)
|
assertEquals(10,t)
|
||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user