Add bytecode MAKE_RANGE and re-enable open range tests
This commit is contained in:
parent
eaee738dee
commit
a73c118c77
@ -217,6 +217,7 @@ class BytecodeCompiler(
|
|||||||
is AssignOpRef -> compileAssignOp(ref) ?: compileEvalRef(ref)
|
is AssignOpRef -> compileAssignOp(ref) ?: compileEvalRef(ref)
|
||||||
is AssignIfNullRef -> compileAssignIfNull(ref)
|
is AssignIfNullRef -> compileAssignIfNull(ref)
|
||||||
is IncDecRef -> compileIncDec(ref, true)
|
is IncDecRef -> compileIncDec(ref, true)
|
||||||
|
is RangeRef -> compileRangeRef(ref)
|
||||||
is ConditionalRef -> compileConditional(ref)
|
is ConditionalRef -> compileConditional(ref)
|
||||||
is ElvisRef -> compileElvis(ref)
|
is ElvisRef -> compileElvis(ref)
|
||||||
is CallRef -> compileCall(ref)
|
is CallRef -> compileCall(ref)
|
||||||
@ -1216,6 +1217,34 @@ class BytecodeCompiler(
|
|||||||
return CompiledValue(dst, SlotType.OBJ)
|
return CompiledValue(dst, SlotType.OBJ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun compileRangeRef(ref: RangeRef): CompiledValue? {
|
||||||
|
val startSlot = if (ref.left != null) {
|
||||||
|
val start = compileRefWithFallback(ref.left, null, Pos.builtIn) ?: return null
|
||||||
|
ensureObjSlot(start).slot
|
||||||
|
} else {
|
||||||
|
val slot = allocSlot()
|
||||||
|
builder.emit(Opcode.CONST_NULL, slot)
|
||||||
|
updateSlotType(slot, SlotType.OBJ)
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
val endSlot = if (ref.right != null) {
|
||||||
|
val end = compileRefWithFallback(ref.right, null, Pos.builtIn) ?: return null
|
||||||
|
ensureObjSlot(end).slot
|
||||||
|
} else {
|
||||||
|
val slot = allocSlot()
|
||||||
|
builder.emit(Opcode.CONST_NULL, slot)
|
||||||
|
updateSlotType(slot, SlotType.OBJ)
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
val inclusiveSlot = allocSlot()
|
||||||
|
val inclusiveId = builder.addConst(BytecodeConst.Bool(ref.isEndInclusive))
|
||||||
|
builder.emit(Opcode.CONST_BOOL, inclusiveId, inclusiveSlot)
|
||||||
|
val dst = allocSlot()
|
||||||
|
builder.emit(Opcode.MAKE_RANGE, startSlot, endSlot, inclusiveSlot, dst)
|
||||||
|
updateSlotType(dst, SlotType.OBJ)
|
||||||
|
return CompiledValue(dst, SlotType.OBJ)
|
||||||
|
}
|
||||||
|
|
||||||
private fun compileAssignOpBinary(
|
private fun compileAssignOpBinary(
|
||||||
targetType: SlotType,
|
targetType: SlotType,
|
||||||
rhs: CompiledValue,
|
rhs: CompiledValue,
|
||||||
|
|||||||
@ -182,6 +182,8 @@ class CmdBuilder {
|
|||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.SET_INDEX ->
|
Opcode.SET_INDEX ->
|
||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
|
Opcode.MAKE_RANGE ->
|
||||||
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.LIST_LITERAL ->
|
Opcode.LIST_LITERAL ->
|
||||||
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
listOf(OperandKind.CONST, OperandKind.SLOT, OperandKind.COUNT, OperandKind.SLOT)
|
||||||
Opcode.GET_THIS_MEMBER ->
|
Opcode.GET_THIS_MEMBER ->
|
||||||
@ -225,6 +227,7 @@ class CmdBuilder {
|
|||||||
Opcode.BOX_OBJ -> CmdBoxObj(operands[0], operands[1])
|
Opcode.BOX_OBJ -> CmdBoxObj(operands[0], operands[1])
|
||||||
Opcode.OBJ_TO_BOOL -> CmdObjToBool(operands[0], operands[1])
|
Opcode.OBJ_TO_BOOL -> CmdObjToBool(operands[0], operands[1])
|
||||||
Opcode.RANGE_INT_BOUNDS -> CmdRangeIntBounds(operands[0], operands[1], operands[2], operands[3])
|
Opcode.RANGE_INT_BOUNDS -> CmdRangeIntBounds(operands[0], operands[1], operands[2], operands[3])
|
||||||
|
Opcode.MAKE_RANGE -> CmdMakeRange(operands[0], operands[1], operands[2], operands[3])
|
||||||
Opcode.CHECK_IS -> CmdCheckIs(operands[0], operands[1], operands[2])
|
Opcode.CHECK_IS -> CmdCheckIs(operands[0], operands[1], operands[2])
|
||||||
Opcode.ASSERT_IS -> CmdAssertIs(operands[0], operands[1])
|
Opcode.ASSERT_IS -> CmdAssertIs(operands[0], operands[1])
|
||||||
Opcode.RET_LABEL -> CmdRetLabel(operands[0], operands[1])
|
Opcode.RET_LABEL -> CmdRetLabel(operands[0], operands[1])
|
||||||
|
|||||||
@ -72,6 +72,7 @@ object CmdDisassembler {
|
|||||||
is CmdCheckIs -> Opcode.CHECK_IS to intArrayOf(cmd.objSlot, cmd.typeSlot, cmd.dst)
|
is CmdCheckIs -> Opcode.CHECK_IS to intArrayOf(cmd.objSlot, cmd.typeSlot, cmd.dst)
|
||||||
is CmdAssertIs -> Opcode.ASSERT_IS to intArrayOf(cmd.objSlot, cmd.typeSlot)
|
is CmdAssertIs -> Opcode.ASSERT_IS to intArrayOf(cmd.objSlot, cmd.typeSlot)
|
||||||
is CmdRangeIntBounds -> Opcode.RANGE_INT_BOUNDS to intArrayOf(cmd.src, cmd.startSlot, cmd.endSlot, cmd.okSlot)
|
is CmdRangeIntBounds -> Opcode.RANGE_INT_BOUNDS to intArrayOf(cmd.src, cmd.startSlot, cmd.endSlot, cmd.okSlot)
|
||||||
|
is CmdMakeRange -> Opcode.MAKE_RANGE to intArrayOf(cmd.startSlot, cmd.endSlot, cmd.inclusiveSlot, cmd.dst)
|
||||||
is CmdResolveScopeSlot -> Opcode.RESOLVE_SCOPE_SLOT to intArrayOf(cmd.scopeSlot, cmd.addrSlot)
|
is CmdResolveScopeSlot -> Opcode.RESOLVE_SCOPE_SLOT to intArrayOf(cmd.scopeSlot, cmd.addrSlot)
|
||||||
is CmdLoadObjAddr -> Opcode.LOAD_OBJ_ADDR to intArrayOf(cmd.addrSlot, cmd.dst)
|
is CmdLoadObjAddr -> Opcode.LOAD_OBJ_ADDR to intArrayOf(cmd.addrSlot, cmd.dst)
|
||||||
is CmdStoreObjAddr -> Opcode.STORE_OBJ_ADDR to intArrayOf(cmd.src, cmd.addrSlot)
|
is CmdStoreObjAddr -> Opcode.STORE_OBJ_ADDR to intArrayOf(cmd.src, cmd.addrSlot)
|
||||||
@ -213,7 +214,7 @@ object CmdDisassembler {
|
|||||||
listOf(OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.CHECK_IS ->
|
Opcode.CHECK_IS ->
|
||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.RANGE_INT_BOUNDS ->
|
Opcode.RANGE_INT_BOUNDS, Opcode.MAKE_RANGE ->
|
||||||
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
listOf(OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT, OperandKind.SLOT)
|
||||||
Opcode.RET_LABEL, Opcode.THROW ->
|
Opcode.RET_LABEL, Opcode.THROW ->
|
||||||
listOf(OperandKind.CONST, OperandKind.SLOT)
|
listOf(OperandKind.CONST, OperandKind.SLOT)
|
||||||
|
|||||||
@ -141,6 +141,21 @@ class CmdConstBool(internal val constId: Int, internal val dst: Int) : Cmd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CmdMakeRange(
|
||||||
|
internal val startSlot: Int,
|
||||||
|
internal val endSlot: Int,
|
||||||
|
internal val inclusiveSlot: Int,
|
||||||
|
internal val dst: Int,
|
||||||
|
) : Cmd() {
|
||||||
|
override suspend fun perform(frame: CmdFrame) {
|
||||||
|
val start = frame.slotToObj(startSlot)
|
||||||
|
val end = frame.slotToObj(endSlot)
|
||||||
|
val inclusive = frame.slotToObj(inclusiveSlot).toBool()
|
||||||
|
frame.storeObjResult(dst, ObjRange(start, end, isEndInclusive = inclusive))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CmdConstNull(internal val dst: Int) : Cmd() {
|
class CmdConstNull(internal val dst: Int) : Cmd() {
|
||||||
override suspend fun perform(frame: CmdFrame) {
|
override suspend fun perform(frame: CmdFrame) {
|
||||||
frame.setObj(dst, ObjNull)
|
frame.setObj(dst, ObjNull)
|
||||||
|
|||||||
@ -29,6 +29,7 @@ enum class Opcode(val code: Int) {
|
|||||||
CONST_NULL(0x09),
|
CONST_NULL(0x09),
|
||||||
BOX_OBJ(0x0A),
|
BOX_OBJ(0x0A),
|
||||||
RANGE_INT_BOUNDS(0x0B),
|
RANGE_INT_BOUNDS(0x0B),
|
||||||
|
MAKE_RANGE(0x0C),
|
||||||
|
|
||||||
INT_TO_REAL(0x10),
|
INT_TO_REAL(0x10),
|
||||||
REAL_TO_INT(0x11),
|
REAL_TO_INT(0x11),
|
||||||
|
|||||||
@ -1217,7 +1217,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Bytecode: unsupported or incorrect behavior")
|
|
||||||
@Test
|
@Test
|
||||||
fun forLoop1() = runTest {
|
fun forLoop1() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -1245,7 +1244,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Bytecode: unsupported or incorrect behavior")
|
|
||||||
@Test
|
@Test
|
||||||
fun forLoop2() = runTest {
|
fun forLoop2() = runTest {
|
||||||
println(
|
println(
|
||||||
@ -1371,7 +1369,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Bytecode: unsupported or incorrect behavior")
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenEndRanges() = runTest {
|
fun testOpenEndRanges() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -1384,7 +1381,6 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Bytecode: unsupported or incorrect behavior")
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenEndRanges2() = runTest {
|
fun testOpenEndRanges2() = runTest {
|
||||||
eval(
|
eval(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user