!37 support <try> <except> <raise> keywords, not support parameter yet

* restore __pika_ooc.h
* raise in cmodule and py function is ok
* add trydef1.py
* add PIKA_ASSERT_ENABLE config, add try_info
This commit is contained in:
李昂 2022-06-26 07:30:52 +00:00
parent 52afe58605
commit b20b5f1bb5
13 changed files with 109 additions and 42 deletions

View File

@ -0,0 +1,6 @@
try:
print('before raise')
raise
print('after raise')
except:
print('in except')

View File

@ -0,0 +1,14 @@
def tryfn(a):
if a == 1:
print('a:1')
raise
print('a:1,after raise')
return
if a == 0:
print('a:0')
return
try:
tryfn(1)
tryfn(0)
except:
print('in except')

View File

@ -11,7 +11,7 @@
"program": "${workspaceFolder}/build/test/pikascript_test",
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [
// "--gtest_filter=parser.__set__"
// "--gtest_filter=except.trydef1"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -1 +1,2 @@
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_ASSERT_ENABLE 1

View File

@ -1,2 +1,3 @@
#define PIKA_OPTIMIZE PIKA_OPTIMIZE_SPEED
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_ASSERT_ENABLE 1

View File

@ -1,3 +1,4 @@
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_POOL_ENABLE 1
#define PIKA_POOL_SIZE 0x40000
#define PIKA_POOL_SIZE 0x40000
#define PIKA_ASSERT_ENABLE 1

View File

@ -1,2 +1,3 @@
#define PIKA_SYNTAX_LEVEL PIKA_SYNTAX_LEVEL_MINIMAL
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_STACK_BUFF_SIZE 2048
#define PIKA_ASSERT_ENABLE 1

View File

@ -51,25 +51,30 @@ TEST(except, trydef1) {
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
__platform_printf("BEGIN\r\n");
/* run */
obj_run(pikaMain,
"def tryfn(a):\n"
" if a == 1:\n"
" print('a:1')\n"
" raise\n"
" print('a:1,after raise')\n"
" return\n"
" if a == 0:\n"
" print('a:0')\n"
" return\n"
"try:\n"
" tryfn(1)\n"
" tryfn(0)\n"
"except:\n"
" print('in except')\n"
"\n");
pikaVM_runSingleFile(pikaMain, "../../examples/Exception/trydef1.py");
/* collect */
/* assert */
EXPECT_STREQ("BEGIN\r\n", log_buff[2]);
EXPECT_STREQ("a:1\r\n", log_buff[1]);
EXPECT_STREQ("in except\r\n", log_buff[0]);
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(except, try1file) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
__platform_printf("BEGIN\r\n");
/* run */
pikaVM_runSingleFile(pikaMain, "../../examples/Exception/try1.py");
/* collect */
EXPECT_STREQ("BEGIN\r\n", log_buff[2]);
EXPECT_STREQ("before raise\r\n", log_buff[1]);
EXPECT_STREQ("in except\r\n", log_buff[0]);
/* assert */
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}

View File

@ -35,6 +35,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if PIKA_ASSERT_ENABLE
#include <assert.h>
#else
#define assert(...)
#endif
/* Compiler */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5000000) /* ARM Compiler \

View File

@ -41,7 +41,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* globals,
ByteCodeFrame* bytecode_frame,
uint16_t pc,
TRY_STATE is_in_try);
TryInfo* try_info);
/* head declear end */
@ -173,12 +173,13 @@ static Arg* VM_instruction_handler_NON(PikaObj* self, VMState* vs, char* data) {
}
static Arg* VM_instruction_handler_TRY(PikaObj* self, VMState* vs, char* data) {
vs->try_state = TRY_STATE_TOP;
assert(NULL != vs->try_info);
vs->try_info->try_state = TRY_STATE_TOP;
return NULL;
}
static Arg* VM_instruction_handler_NTR(PikaObj* self, VMState* vs, char* data) {
vs->try_state = TRY_STATE_NONE;
vs->try_info->try_state = TRY_STATE_NONE;
return NULL;
}
@ -233,7 +234,8 @@ static int32_t __foreach_handler_deinitTuple(Arg* argEach, Args* context) {
Arg* __obj_runMethodArgWithState(PikaObj* self,
PikaObj* method_args_obj,
Arg* method_arg,
TRY_STATE try_state) {
TryInfo* try_state) {
assert(NULL != try_state);
Arg* return_arg = NULL;
/* get method Ptr */
Method method_ptr = methodArg_getPtr(method_arg);
@ -284,8 +286,9 @@ Arg* __obj_runMethodArgWithState(PikaObj* self,
Arg* obj_runMethodArg(PikaObj* self,
PikaObj* method_args_obj,
Arg* method_arg) {
TryInfo try_info = {0};
return __obj_runMethodArgWithState(self, method_args_obj, method_arg,
TRY_STATE_NONE);
&try_info);
}
static int VMState_loadArgsFromMethodArg(VMState* vs,
@ -462,10 +465,11 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
Arg* method_arg = NULL;
char* sys_out;
int arg_num_used = 0;
TRY_STATE sub_try_state = TRY_STATE_NONE;
if (vs->try_state == TRY_STATE_TOP ||
TryInfo sub_try_info = {0};
assert(NULL != vs->try_info);
if (vs->try_info->try_state == TRY_STATE_TOP ||
vs->try_error_code == TRY_STATE_INNER) {
sub_try_state = TRY_STATE_INNER;
sub_try_info.try_state = TRY_STATE_INNER;
}
/* return arg directly */
if (strEqu(data, "")) {
@ -516,7 +520,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
/* run method arg */
return_arg = __obj_runMethodArgWithState(method_host_obj, sub_locals,
method_arg, sub_try_state);
method_arg, &sub_try_info);
/* __init__() */
if (ARG_TYPE_OBJECT_NEW == arg_getType(return_arg)) {
@ -536,7 +540,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
goto init_exit;
}
return_arg_init = __obj_runMethodArgWithState(
new_obj, sub_locals, method_arg, sub_try_state);
new_obj, sub_locals, method_arg, &sub_try_info);
init_exit:
if (NULL != return_arg_init) {
arg_deinit(return_arg_init);
@ -556,6 +560,13 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
VMState_setErrorCode(vs, PIKA_RES_ERR_RUNTIME_ERROR);
}
/* check try result */
if (sub_try_info.try_result == TRY_RESULT_RAISE) {
/* try error */
VMState_setErrorCode(vs, PIKA_RES_ERR_RUNTIME_ERROR);
vs->jmp = VM_JMP_RAISE;
}
goto exit;
exit:
if (NULL != method_arg) {
@ -1029,9 +1040,10 @@ static Arg* VM_instruction_handler_RIS(PikaObj* self, VMState* vs, char* data) {
VMState_setErrorCode(vs, err);
arg_deinit(err_arg);
/* raise jmp */
if (vs->try_state == TRY_STATE_TOP) {
if (vs->try_info->try_state == TRY_STATE_TOP) {
vs->jmp = VM_JMP_RAISE;
} else if (vs->try_state == TRY_STATE_INNER) {
} else if (vs->try_info->try_state == TRY_STATE_INNER) {
vs->try_info->try_result = TRY_RESULT_RAISE;
return VM_instruction_handler_RET(self, vs, data);
}
return NULL;
@ -1137,6 +1149,7 @@ static int pikaVM_runInstructUnit(PikaObj* self,
int32_t pc_next = vs->pc + instructUnit_getSize();
char* data = VMState_getConstWithInstructUnit(vs, ins_unit);
/* run instruct */
assert(NULL != vs->try_info);
return_arg = VM_instruct_handler_table[instruct](self, vs, data);
if (NULL != return_arg) {
stack_pushArg(&(vs->stack), return_arg);
@ -1145,7 +1158,7 @@ static int pikaVM_runInstructUnit(PikaObj* self,
nextLine:
/* exit */
if (VM_JMP_EXIT == vs->jmp) {
pc_next = -99999;
pc_next = VM_PC_EXIT;
goto exit;
}
/* break */
@ -1175,7 +1188,7 @@ exit:
vs->jmp = 0;
/* reach the end */
if (pc_next >= (int)VMState_getInstructArraySize(vs)) {
return -99999;
return VM_PC_EXIT;
}
return pc_next;
}
@ -1595,7 +1608,8 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* globals,
ByteCodeFrame* bytecode_frame,
uint16_t pc,
TRY_STATE try_state) {
TryInfo* try_info) {
assert(NULL != try_info);
int size = bytecode_frame->instruct_array.size;
/* locals is the local scope */
VMState vs = {
@ -1607,11 +1621,11 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
.error_code = PIKA_RES_OK,
.line_error_code = PIKA_RES_OK,
.try_error_code = PIKA_RES_OK,
.try_state = try_state,
.try_info = try_info,
};
stack_init(&(vs.stack));
while (vs.pc < size) {
if (vs.pc == -99999) {
if (vs.pc == VM_PC_EXIT) {
break;
}
InstructUnit* this_ins_unit = VMState_getInstructNow(&vs);
@ -1632,11 +1646,11 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
}
head_ins_unit--;
}
if (vs.try_state) {
if (vs.try_info->try_state) {
vs.try_error_code = vs.error_code;
}
/* print inses of a line */
if (!vs.try_state) {
if (!vs.try_info->try_state) {
while (1) {
if (head_ins_unit != this_ins_unit) {
__platform_printf(" ");
@ -1662,8 +1676,10 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame) {
TryInfo try_info = {0};
try_info.try_state = TRY_STATE_NONE;
return __pikaVM_runByteCodeFrameWithState(self, self, self, byteCode_frame,
0, TRY_STATE_NONE);
0, &try_info);
}
char* constPool_getByOffset(ConstPool* self, uint16_t offset) {

View File

@ -45,12 +45,25 @@ typedef enum {
VM_JMP_RAISE = -996,
} VM_JMP;
typedef enum { VM_PC_EXIT = -99999 } VM_PC;
typedef enum {
TRY_STATE_NONE = 0,
TRY_STATE_TOP,
TRY_STATE_INNER,
} TRY_STATE;
typedef enum {
TRY_RESULT_NONE = 0,
TRY_RESULT_RAISE,
} TRY_RESULT;
typedef struct TryInfo TryInfo;
struct TryInfo {
TRY_STATE try_state;
TRY_RESULT try_result;
};
typedef struct VMState VMState;
struct VMState {
VMParameters* locals;
@ -62,7 +75,7 @@ struct VMState {
uint8_t error_code;
uint8_t line_error_code;
uint8_t try_error_code;
TRY_STATE try_state;
TryInfo* try_info;
};
VMParameters* pikaVM_run(PikaObj* self, char* pyLine);

View File

@ -192,6 +192,10 @@
#ifndef PIKA_POOL_ALIGN
#define PIKA_POOL_ALIGN 8
#endif
#ifndef PIKA_ASSERT_ENABLE
#define PIKA_ASSERT_ENABLE 0
#endif
/* configuration validation */