mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
support navite constructor method
This commit is contained in:
parent
2c29722f69
commit
f438446313
@ -2059,7 +2059,7 @@ TEST(parser, class_) {
|
||||
printf("%s", pikaAsm);
|
||||
EXPECT_STREQ(pikaAsm, (char* )
|
||||
"B0\n"
|
||||
"0 DEF Test()\n"
|
||||
"0 CLS Test()\n"
|
||||
"0 JMP 1\n"
|
||||
"B1\n"
|
||||
"0 RUN PikaStdLib.PikaObj\n"
|
||||
@ -2096,7 +2096,7 @@ TEST(parser, class_def) {
|
||||
|
||||
EXPECT_STREQ(pikaAsm, (char*)
|
||||
"B0\n"
|
||||
"0 DEF Test()\n"
|
||||
"0 CLS Test()\n"
|
||||
"0 JMP 1\n"
|
||||
"B1\n"
|
||||
"0 RUN PikaStdLib.PikaObj\n"
|
||||
@ -2510,7 +2510,7 @@ TEST(parser, class_def_void_line) {
|
||||
|
||||
EXPECT_STREQ(pikaAsm, (char*)
|
||||
"B0\n"
|
||||
"0 DEF Test()\n"
|
||||
"0 CLS Test()\n"
|
||||
"0 JMP 1\n"
|
||||
"B1\n"
|
||||
"0 RUN PikaStdLib.PikaObj\n"
|
||||
|
@ -1135,29 +1135,29 @@ TEST(pikaMain, class_demo_1) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
// TEST(pikaMain, class_demo_2) {
|
||||
// /* init */
|
||||
// pikaMemInfo.heapUsedMax = 0;
|
||||
// /* run */
|
||||
// PikaObj* self = newRootObj((char*)"pikaMain", New_PikaMain);
|
||||
// __platform_printf((char*)"BEGIN\r\n");
|
||||
// obj_run(self, (char*)
|
||||
// "class Complex:\n"
|
||||
// " def __init__(self):\n"
|
||||
// " self.r = 3.0\n"
|
||||
// " self.i = -4.5\n"
|
||||
// "x = Complex()\n"
|
||||
// "print(x.r)\n"
|
||||
// "print(x.i)\n"
|
||||
// );
|
||||
// /* assert */
|
||||
// EXPECT_STREQ(log_buff[0], (char*)"-4.500000\r\n");
|
||||
// EXPECT_STREQ(log_buff[1], (char*)"3.000000\r\n");
|
||||
// EXPECT_STREQ(log_buff[2], (char*)"BEGIN\r\n");
|
||||
// /* deinit */
|
||||
// obj_deinit(self);
|
||||
// EXPECT_EQ(pikaMemNow(), 0);
|
||||
// }
|
||||
TEST(pikaMain, class_demo_2) {
|
||||
/* init */
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
/* run */
|
||||
PikaObj* self = newRootObj((char*)"pikaMain", New_PikaMain);
|
||||
__platform_printf((char*)"BEGIN\r\n");
|
||||
obj_run(self, (char*)
|
||||
"class Complex:\n"
|
||||
" def __init__(self):\n"
|
||||
" self.r = 3.0\n"
|
||||
" self.i = -4.5\n"
|
||||
"x = Complex()\n"
|
||||
"print(x.r)\n"
|
||||
"print(x.i)\n"
|
||||
);
|
||||
/* assert */
|
||||
EXPECT_STREQ(log_buff[0], (char*)"-4.500000\r\n");
|
||||
EXPECT_STREQ(log_buff[1], (char*)"3.000000\r\n");
|
||||
EXPECT_STREQ(log_buff[2], (char*)"BEGIN\r\n");
|
||||
/* deinit */
|
||||
obj_deinit(self);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(pikaMain, class_demo_3) {
|
||||
/* init */
|
||||
@ -1411,3 +1411,27 @@ TEST(pikaMain, self_operator) {
|
||||
/* mem check */
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(pikaMain, class_demo_2_initwitharg) {
|
||||
/* init */
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
/* run */
|
||||
PikaObj* self = newRootObj((char*)"pikaMain", New_PikaMain);
|
||||
__platform_printf((char*)"BEGIN\r\n");
|
||||
obj_run(self, (char*)
|
||||
"class Complex:\n"
|
||||
" def __init__(self, r, i):\n"
|
||||
" self.r = r\n"
|
||||
" self.i = i\n"
|
||||
"x = Complex(3.0, -4.5)\n"
|
||||
"print(x.r)\n"
|
||||
"print(x.i)\n"
|
||||
);
|
||||
/* assert */
|
||||
EXPECT_STREQ(log_buff[0], (char*)"-4.500000\r\n");
|
||||
EXPECT_STREQ(log_buff[1], (char*)"3.000000\r\n");
|
||||
EXPECT_STREQ(log_buff[2], (char*)"BEGIN\r\n");
|
||||
/* deinit */
|
||||
obj_deinit(self);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ int32_t class_defineConstructor(PikaObj* self,
|
||||
char* declearation,
|
||||
Method methodPtr) {
|
||||
return __class_defineMethodWithType(self, declearation, methodPtr,
|
||||
ARG_TYPE_CONSTRUCTOR_METHOD, NULL);
|
||||
ARG_TYPE_NATIVE_CONSTRUCTOR_METHOD, NULL);
|
||||
}
|
||||
|
||||
/* define a native method as default */
|
||||
@ -519,6 +519,16 @@ int32_t class_defineMethod(PikaObj* self,
|
||||
ARG_TYPE_NATIVE_METHOD, NULL);
|
||||
}
|
||||
|
||||
/* define object method, object method is which startwith (self) */
|
||||
int32_t class_defineRunTimeConstructor(PikaObj* self,
|
||||
char* declearation,
|
||||
Method methodPtr,
|
||||
ByteCodeFrame* bytecode_frame) {
|
||||
return __class_defineMethodWithType(self, declearation, methodPtr,
|
||||
ARG_TYPE_CONSTRUCTOR_METHOD,
|
||||
bytecode_frame);
|
||||
}
|
||||
|
||||
/* define object method, object method is which startwith (self) */
|
||||
int32_t class_defineObjectMethod(PikaObj* self,
|
||||
char* declearation,
|
||||
|
@ -156,6 +156,11 @@ int32_t class_defineConstructor(PikaObj* self,
|
||||
char* declearation,
|
||||
Method methodPtr);
|
||||
|
||||
int32_t class_defineRunTimeConstructor(PikaObj* self,
|
||||
char* declearation,
|
||||
Method methodPtr,
|
||||
ByteCodeFrame* bytecode_frame);
|
||||
|
||||
int32_t obj_removeArg(PikaObj* self, char* argPath);
|
||||
int32_t obj_isArgExist(PikaObj* self, char* argPath);
|
||||
PikaObj* obj_getClassObjByNewFun(PikaObj* self, char* name, NewFun newClassFun);
|
||||
|
@ -1576,7 +1576,7 @@ char* AST_toPikaASM(AST* ast, Args* outBuffs) {
|
||||
/* default superClass */
|
||||
superClass = "PikaStdLib.PikaObj";
|
||||
}
|
||||
pikaAsm = strsAppend(&buffs, pikaAsm, "0 DEF ");
|
||||
pikaAsm = strsAppend(&buffs, pikaAsm, "0 CLS ");
|
||||
pikaAsm = strsAppend(&buffs, pikaAsm,
|
||||
strsAppend(&buffs, thisClass,
|
||||
"()\n"
|
||||
|
124
src/PikaVM.c
124
src/PikaVM.c
@ -182,10 +182,50 @@ static Arg* VM_instruction_handler_REF(PikaObj* self, VMState* vs, char* data) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
static Arg* VMState_runMethodArg(VMState* vs,
|
||||
PikaObj* method_host_obj,
|
||||
PikaObj* sub_locals,
|
||||
Arg* method_arg) {
|
||||
Arg* return_arg = NULL;
|
||||
/* get method Ptr */
|
||||
Method method_ptr = methodArg_getPtr(method_arg);
|
||||
/* get method type list */
|
||||
ArgType method_type = arg_getType(method_arg);
|
||||
ByteCodeFrame* method_bytecodeFrame =
|
||||
methodArg_getBytecodeFrame(method_arg);
|
||||
obj_setErrorCode(method_host_obj, 0);
|
||||
|
||||
/* run method */
|
||||
if (method_type == ARG_TYPE_NATIVE_METHOD) {
|
||||
/* native method */
|
||||
method_ptr(method_host_obj, sub_locals->list);
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
} else if (method_type == ARG_TYPE_NATIVE_CONSTRUCTOR_METHOD) {
|
||||
/* native method */
|
||||
method_ptr(method_host_obj, sub_locals->list);
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
} else {
|
||||
/* static method and object method */
|
||||
/* byteCode */
|
||||
uint16_t pc = (uintptr_t)method_ptr -
|
||||
(uintptr_t)instructArray_getByOffset(
|
||||
&(method_bytecodeFrame->instruct_array), 0);
|
||||
sub_locals = pikaVM_runByteCodeWithState(
|
||||
method_host_obj, sub_locals, vs->globals, method_bytecodeFrame, pc);
|
||||
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
}
|
||||
return return_arg;
|
||||
}
|
||||
|
||||
static void VMState_loadArgsFromMethodArg(VMState* vs,
|
||||
PikaObj* method_host_obj,
|
||||
Args* args,
|
||||
Arg* method_arg) {
|
||||
Arg* method_arg,
|
||||
char* method_name) {
|
||||
Args buffs = {0};
|
||||
/* get method type list */
|
||||
char* type_list = methodArg_getTypeList(method_arg, &buffs);
|
||||
@ -203,16 +243,17 @@ static void VMState_loadArgsFromMethodArg(VMState* vs,
|
||||
uint8_t arg_num_input = VMState_getInputArgNum(vs);
|
||||
|
||||
/* check arg num */
|
||||
if (method_type == ARG_TYPE_CONSTRUCTOR_METHOD) {
|
||||
if (method_type == ARG_TYPE_NATIVE_CONSTRUCTOR_METHOD ||
|
||||
method_type == ARG_TYPE_CONSTRUCTOR_METHOD) {
|
||||
/* not check decleard arg num for constrctor */
|
||||
} else {
|
||||
/* check arg num decleard and input */
|
||||
if (arg_num_dec != arg_num_input) {
|
||||
VMState_setErrorCode(vs, 3);
|
||||
__platform_printf(
|
||||
"TypeError: method takes %d positional argument but %d were "
|
||||
"TypeError: %s() takes %d positional argument but %d were "
|
||||
"given\r\n",
|
||||
arg_num_dec, arg_num_input);
|
||||
method_name, arg_num_dec, arg_num_input);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
@ -244,10 +285,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
|
||||
char* methodPath = data;
|
||||
PikaObj* method_host_obj;
|
||||
Arg* method_arg = NULL;
|
||||
Method method_ptr;
|
||||
ArgType method_type = ARG_TYPE_NULL;
|
||||
char* sys_out;
|
||||
ByteCodeFrame* method_bytecodeFrame;
|
||||
/* return arg directly */
|
||||
if (strEqu(data, "")) {
|
||||
return_arg = stack_popArg(&(vs->stack));
|
||||
@ -278,42 +316,15 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
|
||||
|
||||
goto exit;
|
||||
}
|
||||
/* get method Ptr */
|
||||
method_ptr = methodArg_getPtr(method_arg);
|
||||
/* get method type list */
|
||||
method_type = arg_getType(method_arg);
|
||||
method_bytecodeFrame = methodArg_getBytecodeFrame(method_arg);
|
||||
|
||||
sub_locals = New_PikaObj();
|
||||
/* load args from vmState to sub_local->list */
|
||||
VMState_loadArgsFromMethodArg(vs, method_host_obj, sub_locals->list,
|
||||
method_arg);
|
||||
method_arg, data);
|
||||
|
||||
obj_setErrorCode(method_host_obj, 0);
|
||||
|
||||
/* run method */
|
||||
if (method_type == ARG_TYPE_NATIVE_METHOD) {
|
||||
/* native method */
|
||||
method_ptr(method_host_obj, sub_locals->list);
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
} else if (method_type == ARG_TYPE_CONSTRUCTOR_METHOD) {
|
||||
/* native method */
|
||||
method_ptr(method_host_obj, sub_locals->list);
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
} else {
|
||||
/* static method and object method */
|
||||
/* byteCode */
|
||||
uint16_t pc = (uintptr_t)method_ptr -
|
||||
(uintptr_t)instructArray_getByOffset(
|
||||
&(method_bytecodeFrame->instruct_array), 0);
|
||||
sub_locals = pikaVM_runByteCodeWithState(
|
||||
method_host_obj, sub_locals, vs->globals, method_bytecodeFrame, pc);
|
||||
|
||||
/* get method return */
|
||||
return_arg = arg_copy(args_getArg(sub_locals->list, (char*)"return"));
|
||||
}
|
||||
/* run method arg */
|
||||
return_arg =
|
||||
VMState_runMethodArg(vs, method_host_obj, sub_locals, method_arg);
|
||||
|
||||
/* __init__() */
|
||||
if (arg_getType(return_arg) == ARG_TYPE_FREE_OBJECT) {
|
||||
@ -321,12 +332,13 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, VMState* vs, char* data) {
|
||||
PikaObj* new_obj = arg_getPtr(return_arg);
|
||||
Arg* method_arg = obj_getMethodArg(new_obj, "__init__");
|
||||
if (NULL != method_arg) {
|
||||
Args method_args = {0};
|
||||
VMState_loadArgsFromMethodArg(vs, new_obj, &method_args,
|
||||
method_arg);
|
||||
Method method_ptr = methodArg_getPtr(method_arg);
|
||||
method_ptr(new_obj, &method_args);
|
||||
args_deinit_stack(&method_args);
|
||||
PikaObj* sub_locals = New_PikaObj();
|
||||
VMState_loadArgsFromMethodArg(vs, new_obj, sub_locals->list,
|
||||
method_arg, "__init__");
|
||||
Arg* return_arg =
|
||||
VMState_runMethodArg(vs, new_obj, sub_locals, method_arg);
|
||||
arg_deinit(return_arg);
|
||||
obj_deinit(sub_locals);
|
||||
arg_deinit(method_arg);
|
||||
}
|
||||
}
|
||||
@ -676,7 +688,10 @@ OPT_exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Arg* VM_instruction_handler_DEF(PikaObj* self, VMState* vs, char* data) {
|
||||
static Arg* __VM_instruction_handler_DEF(PikaObj* self,
|
||||
VMState* vs,
|
||||
char* data,
|
||||
uint8_t is_class) {
|
||||
int thisBlockDeepth = VMState_getBlockDeepthNow(vs);
|
||||
|
||||
PikaObj* hostObj = vs->locals;
|
||||
@ -699,8 +714,15 @@ static Arg* VM_instruction_handler_DEF(PikaObj* self, VMState* vs, char* data) {
|
||||
class_defineObjectMethod(hostObj, data, (Method)ins_unit_now,
|
||||
vs->bytecode_frame);
|
||||
} else {
|
||||
class_defineStaticMethod(hostObj, data, (Method)ins_unit_now,
|
||||
vs->bytecode_frame);
|
||||
if (is_class) {
|
||||
class_defineRunTimeConstructor(hostObj, data,
|
||||
(Method)ins_unit_now,
|
||||
vs->bytecode_frame);
|
||||
} else {
|
||||
class_defineStaticMethod(hostObj, data,
|
||||
(Method)ins_unit_now,
|
||||
vs->bytecode_frame);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -710,6 +732,14 @@ static Arg* VM_instruction_handler_DEF(PikaObj* self, VMState* vs, char* data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Arg* VM_instruction_handler_DEF(PikaObj* self, VMState* vs, char* data) {
|
||||
return __VM_instruction_handler_DEF(self, vs, data, 0);
|
||||
}
|
||||
|
||||
static Arg* VM_instruction_handler_CLS(PikaObj* self, VMState* vs, char* data) {
|
||||
return __VM_instruction_handler_DEF(self, vs, data, 1);
|
||||
}
|
||||
|
||||
static Arg* VM_instruction_handler_RET(PikaObj* self, VMState* vs, char* data) {
|
||||
/* exit jmp signal */
|
||||
vs->jmp = -999;
|
||||
|
@ -46,3 +46,4 @@ def_ins(CTN)
|
||||
def_ins(GLB)
|
||||
def_ins(RAS)
|
||||
def_ins(NEW)
|
||||
def_ins(CLS)
|
||||
|
@ -44,6 +44,7 @@ typedef enum {
|
||||
ARG_TYPE_MATE_OBJECT,
|
||||
ARG_TYPE_FREE_OBJECT,
|
||||
ARG_TYPE_NATIVE_METHOD,
|
||||
ARG_TYPE_NATIVE_CONSTRUCTOR_METHOD,
|
||||
ARG_TYPE_CONSTRUCTOR_METHOD,
|
||||
ARG_TYPE_OBJECT_METHOD,
|
||||
ARG_TYPE_STATIC_METHOD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user