Add short-circuit ops in bytecode compiler and VM

This commit is contained in:
sergeych committed 2026-01-25 19:59:22 +03:00
1 parent 3d9170d677
commit 8ae6eb8d69
3 files changed
+77 -1

No files matched your search

@@ -25,8 +25,12 @@ import net.sergeych.lyng.bytecode.Opcode
import net.sergeych.lyng.obj.BinaryOpRef
import net.sergeych.lyng.obj.BinOp
import net.sergeych.lyng.obj.ConstRef
import net.sergeych.lyng.obj.ObjFalse
import net.sergeych.lyng.obj.ObjInt
import net.sergeych.lyng.obj.ObjTrue
import net.sergeych.lyng.obj.ValueFnRef
import net.sergeych.lyng.obj.ObjVoid
import net.sergeych.lyng.obj.toBool
import net.sergeych.lyng.obj.toInt
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -93,4 +97,36 @@ class BytecodeVmTest {
val result = BytecodeVm().execute(fn, Scope(), emptyList())
assertEquals(ObjVoid, result)
}
@Test
fun andIsShortCircuit() = kotlinx.coroutines.test.runTest {
val throwingRef = ValueFnRef { error("should not execute") }
val expr = ExpressionStatement(
BinaryOpRef(
BinOp.AND,
ConstRef(ObjFalse.asReadonly),
throwingRef
),
net.sergeych.lyng.Pos.builtIn
)
val fn = BytecodeCompiler().compileExpression("andShort", expr) ?: error("bytecode compile failed")
val result = BytecodeVm().execute(fn, Scope(), emptyList())
assertEquals(false, result.toBool())
}
@Test
fun orIsShortCircuit() = kotlinx.coroutines.test.runTest {
val throwingRef = ValueFnRef { error("should not execute") }
val expr = ExpressionStatement(
BinaryOpRef(
BinOp.OR,
ConstRef(ObjTrue.asReadonly),
throwingRef
),
net.sergeych.lyng.Pos.builtIn
)
val fn = BytecodeCompiler().compileExpression("orShort", expr) ?: error("bytecode compile failed")
val result = BytecodeVm().execute(fn, Scope(), emptyList())
assertEquals(true, result.toBool())
}
}