mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
!49 fix for loop continue position err
* fix for loop continue bug * adding jmp_deepth in VM
This commit is contained in:
parent
541dcc3cea
commit
f69dcf4d6d
@ -2475,3 +2475,38 @@ TEST(pikaMain, returnNullString) {
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(pikaMain, for_loop_issue_1b2a3f1bdf) {
|
||||
char* lines =
|
||||
"res = 0\n"
|
||||
"for i in range(0, 10):\n"
|
||||
" if i < 3:\n"
|
||||
" continue\n"
|
||||
" if i > 7:\n"
|
||||
" continue\n"
|
||||
" for i in range(i, i+3):\n"
|
||||
" res += i\n"
|
||||
"\n";
|
||||
|
||||
Args* buffs = New_strBuff();
|
||||
__platform_printf("%s\n", lines);
|
||||
char* pikaAsm = Parser_multiLineToAsm(buffs, lines);
|
||||
__platform_printf("%s", pikaAsm);
|
||||
args_deinit(buffs);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
|
||||
/* init */
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
/* run */
|
||||
__platform_printf("BEGIN\r\n");
|
||||
|
||||
obj_run(pikaMain, lines);
|
||||
/* collect */
|
||||
int res = obj_getInt(pikaMain, "res");
|
||||
/* assert */
|
||||
EXPECT_EQ(res, 90);
|
||||
/* deinit */
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
38
src/PikaVM.c
38
src/PikaVM.c
@ -74,14 +74,30 @@ static char* VMState_getConstWithInstructUnit(VMState* vs,
|
||||
|
||||
static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vs) {
|
||||
int offset = 0;
|
||||
InstructUnit* ins_unit_now = VMState_getInstructNow(vs);
|
||||
int loop_deepth = -1;
|
||||
|
||||
/* find loop deepth */
|
||||
while (1) {
|
||||
offset += instructUnit_getSize(ins_unit_now);
|
||||
ins_unit_now = VMState_getInstructWithOffset(vs, offset);
|
||||
offset -= instructUnit_getSize(ins_unit_now);
|
||||
InstructUnit* ins_unit_now = VMState_getInstructWithOffset(vs, offset);
|
||||
uint16_t invoke_deepth = instructUnit_getInvokeDeepth(ins_unit_now);
|
||||
enum Instruct ins = instructUnit_getInstruct(ins_unit_now);
|
||||
char* data = VMState_getConstWithInstructUnit(vs, ins_unit_now);
|
||||
if ((0 == invoke_deepth) && (JMP == ins) && strEqu(data, "-1")) {
|
||||
if ((0 == invoke_deepth) && (JEZ == ins) && strEqu(data, "2")) {
|
||||
loop_deepth = instructUnit_getBlockDeepth(ins_unit_now);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
while (1) {
|
||||
offset += instructUnit_getSize(ins_unit_now);
|
||||
InstructUnit* ins_unit_now = VMState_getInstructWithOffset(vs, offset);
|
||||
enum Instruct ins = instructUnit_getInstruct(ins_unit_now);
|
||||
char* data = VMState_getConstWithInstructUnit(vs, ins_unit_now);
|
||||
int block_deepth_now = instructUnit_getBlockDeepth(ins_unit_now);
|
||||
if ((block_deepth_now == loop_deepth) && (JMP == ins) &&
|
||||
strEqu(data, "-1")) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
@ -972,16 +988,25 @@ static Arg* VM_instruction_handler_SER(PikaObj* self, VMState* vs, char* data) {
|
||||
static Arg* VM_instruction_handler_JEZ(PikaObj* self, VMState* vs, char* data) {
|
||||
int thisBlockDeepth;
|
||||
thisBlockDeepth = VMState_getBlockDeepthNow(vs);
|
||||
int jmp_expect = fast_atoi(data);
|
||||
Arg* pika_assertArg = stack_popArg(&(vs->stack));
|
||||
int pika_assert = arg_getInt(pika_assertArg);
|
||||
arg_deinit(pika_assertArg);
|
||||
char __else[] = "__else0";
|
||||
__else[6] = '0' + thisBlockDeepth;
|
||||
args_setInt(self->list, __else, !pika_assert);
|
||||
|
||||
if (0 == pika_assert) {
|
||||
/* set __else flag */
|
||||
vs->jmp = fast_atoi(data);
|
||||
/* jump */
|
||||
vs->jmp = jmp_expect;
|
||||
}
|
||||
|
||||
/* restore loop deepth */
|
||||
if (2 == jmp_expect && 0 == pika_assert) {
|
||||
int block_deepth_now = VMState_getBlockDeepthNow(vs);
|
||||
vs->loop_deepth = block_deepth_now;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1885,6 +1910,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
|
||||
.globals = globals,
|
||||
.jmp = 0,
|
||||
.pc = pc,
|
||||
.loop_deepth = 0,
|
||||
.error_code = PIKA_RES_OK,
|
||||
.line_error_code = PIKA_RES_OK,
|
||||
.try_error_code = PIKA_RES_OK,
|
||||
|
@ -72,6 +72,7 @@ struct VMState {
|
||||
int32_t jmp;
|
||||
int32_t pc;
|
||||
ByteCodeFrame* bytecode_frame;
|
||||
uint8_t loop_deepth;
|
||||
uint8_t error_code;
|
||||
uint8_t line_error_code;
|
||||
uint8_t try_error_code;
|
||||
|
Loading…
x
Reference in New Issue
Block a user