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 =
|
||||
call(
|
||||
complexClass,
|
||||
Arguments(ObjReal.of(real), ObjReal.of(imag))
|
||||
) as? ObjInstance ?: raiseIllegalState("Complex() did not return an object instance")
|
||||
instantiateComplex(this, complexClass, real, imag)
|
||||
|
||||
private suspend fun instantiateComplex(scope: ScopeFacade, complexClass: ObjClass, real: Double, imag: Double): ObjInstance {
|
||||
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 =
|
||||
ObjDecimalSupport.toDoubleOrNull(value)
|
||||
|
||||
@ -54,19 +54,23 @@ object ObjDecimalSupport {
|
||||
instance.kotlinInstanceData = zero
|
||||
}
|
||||
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())))
|
||||
}
|
||||
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())))
|
||||
}
|
||||
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())))
|
||||
}
|
||||
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())))
|
||||
}
|
||||
decimalClass.addFn("mod") {
|
||||
|
||||
@ -97,6 +97,15 @@ class ComplexModuleTest {
|
||||
assert( 5 + 1.d.i is Complex )
|
||||
assert( 5.d + 1.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()
|
||||
)
|
||||
}
|
||||
|
||||
@ -308,4 +308,5 @@ class DecimalModuleTest {
|
||||
assertEquals(10,t)
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user