From 70d05f7987970f51be14a29ea148edfd47a127f5 Mon Sep 17 00:00:00 2001 From: sergeych Date: Thu, 29 Jan 2026 02:44:20 +0300 Subject: [PATCH] Enable props/ops/object tests and improve unary/incdec --- .../lyng/bytecode/BytecodeCompiler.kt | 52 +++++++++++++------ .../commonTest/kotlin/ObjectExpressionTest.kt | 1 - .../sergeych/lyng/OperatorOverloadingTest.kt | 1 - .../kotlin/net/sergeych/lyng/PropsTest.kt | 1 - .../kotlin/net/sergeych/lyng/TransientTest.kt | 1 - lynglib/src/jvmTest/kotlin/LynonTests.kt | 4 +- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt index 017e0d6..30577b9 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt @@ -194,6 +194,8 @@ class BytecodeCompiler( } is BinaryOpRef -> compileBinary(ref) ?: compileEvalRef(ref) is UnaryOpRef -> compileUnary(ref) + is LogicalAndRef -> compileEvalRef(ref) + is LogicalOrRef -> compileEvalRef(ref) is AssignRef -> compileAssign(ref) ?: compileEvalRef(ref) is AssignOpRef -> compileAssignOp(ref) ?: compileEvalRef(ref) is AssignIfNullRef -> compileAssignIfNull(ref) @@ -295,7 +297,12 @@ class BytecodeCompiler( builder.emit(Opcode.NEG_REAL, a.slot, out) CompiledValue(out, SlotType.REAL) } - else -> null + else -> { + val obj = ensureObjSlot(a) + val methodId = builder.addConst(BytecodeConst.StringVal("negate")) + builder.emit(Opcode.CALL_VIRTUAL, obj.slot, methodId, 0, 0, out) + CompiledValue(out, SlotType.OBJ) + } } UnaryOp.NOT -> { when (a.type) { @@ -307,18 +314,24 @@ class BytecodeCompiler( } SlotType.OBJ, SlotType.UNKNOWN -> { val obj = ensureObjSlot(a) - val tmp = allocSlot() - builder.emit(Opcode.OBJ_TO_BOOL, obj.slot, tmp) - builder.emit(Opcode.NOT_BOOL, tmp, out) + val methodId = builder.addConst(BytecodeConst.StringVal("logicalNot")) + val tmpObj = allocSlot() + builder.emit(Opcode.CALL_VIRTUAL, obj.slot, methodId, 0, 0, tmpObj) + builder.emit(Opcode.OBJ_TO_BOOL, tmpObj, out) } else -> return null } CompiledValue(out, SlotType.BOOL) } UnaryOp.BITNOT -> { - if (a.type != SlotType.INT) return null - builder.emit(Opcode.INV_INT, a.slot, out) - CompiledValue(out, SlotType.INT) + if (a.type == SlotType.INT) { + builder.emit(Opcode.INV_INT, a.slot, out) + return CompiledValue(out, SlotType.INT) + } + val obj = ensureObjSlot(a) + val methodId = builder.addConst(BytecodeConst.StringVal("bitNot")) + builder.emit(Opcode.CALL_VIRTUAL, obj.slot, methodId, 0, 0, out) + CompiledValue(out, SlotType.OBJ) } } } @@ -1372,16 +1385,25 @@ class BytecodeCompiler( } } SlotType.UNKNOWN -> { + val oneSlot = allocSlot() + val oneId = builder.addConst(BytecodeConst.ObjRef(ObjInt.One)) + builder.emit(Opcode.CONST_OBJ, oneId, oneSlot) + val current = allocSlot() + builder.emit(Opcode.BOX_OBJ, slot, current) if (wantResult && ref.isPost) { - val old = allocSlot() - builder.emit(Opcode.MOVE_INT, slot, old) - builder.emit(if (ref.isIncrement) Opcode.INC_INT else Opcode.DEC_INT, slot) - updateSlotType(slot, SlotType.INT) - CompiledValue(old, SlotType.INT) + val result = allocSlot() + val op = if (ref.isIncrement) Opcode.ADD_OBJ else Opcode.SUB_OBJ + builder.emit(op, current, oneSlot, result) + builder.emit(Opcode.MOVE_OBJ, result, slot) + updateSlotType(slot, SlotType.OBJ) + CompiledValue(current, SlotType.OBJ) } else { - builder.emit(if (ref.isIncrement) Opcode.INC_INT else Opcode.DEC_INT, slot) - updateSlotType(slot, SlotType.INT) - CompiledValue(slot, SlotType.INT) + val result = allocSlot() + val op = if (ref.isIncrement) Opcode.ADD_OBJ else Opcode.SUB_OBJ + builder.emit(op, current, oneSlot, result) + builder.emit(Opcode.MOVE_OBJ, result, slot) + updateSlotType(slot, SlotType.OBJ) + CompiledValue(result, SlotType.OBJ) } } else -> null diff --git a/lynglib/src/commonTest/kotlin/ObjectExpressionTest.kt b/lynglib/src/commonTest/kotlin/ObjectExpressionTest.kt index 8906d3d..57e5746 100644 --- a/lynglib/src/commonTest/kotlin/ObjectExpressionTest.kt +++ b/lynglib/src/commonTest/kotlin/ObjectExpressionTest.kt @@ -6,7 +6,6 @@ import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertFailsWith -@Ignore("TODO(bytecode-only): uses fallback") class ObjectExpressionTest { @Test diff --git a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt index 2b5ff6a..b0bdbfd 100644 --- a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt +++ b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/OperatorOverloadingTest.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.test.runTest import kotlin.test.Ignore import kotlin.test.Test -@Ignore("TODO(bytecode-only): uses fallback") class OperatorOverloadingTest { @Test fun testBinaryOverloading() = runTest { diff --git a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/PropsTest.kt b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/PropsTest.kt index 7de558b..b58d501 100644 --- a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/PropsTest.kt +++ b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/PropsTest.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.test.runTest import kotlin.test.Ignore import kotlin.test.Test -@Ignore("TODO(bytecode-only): uses fallback") class PropsTest { @Test diff --git a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/TransientTest.kt b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/TransientTest.kt index bd6b1f8..cc26492 100644 --- a/lynglib/src/commonTest/kotlin/net/sergeych/lyng/TransientTest.kt +++ b/lynglib/src/commonTest/kotlin/net/sergeych/lyng/TransientTest.kt @@ -30,7 +30,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotNull -@Ignore("TODO(bytecode-only): uses fallback") class TransientTest { @Test diff --git a/lynglib/src/jvmTest/kotlin/LynonTests.kt b/lynglib/src/jvmTest/kotlin/LynonTests.kt index c9f1e69..4314f60 100644 --- a/lynglib/src/jvmTest/kotlin/LynonTests.kt +++ b/lynglib/src/jvmTest/kotlin/LynonTests.kt @@ -31,7 +31,7 @@ import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertTrue -@Ignore("TODO(bytecode-only): uses fallback") +@Ignore("TODO(bytecode-only): uses fallback (unary minus, MI, simple types)") class LynonTests { @Test @@ -794,5 +794,3 @@ class Wallet( id, ownerKey, balance=0, createdAt=Instant.now().truncateToSecond( } - -