support *var in py function

This commit is contained in:
pikastech 2022-08-16 12:21:11 +08:00
parent 77e291101f
commit d01ca77a51
13 changed files with 190 additions and 57 deletions

View File

@ -1,29 +1,42 @@
class Tuple:
def __init__(self): ...
# get an arg by the index
def get(self, i: int) -> any: ...
# get the length of list
def len(self) -> int: ...
# support for loop
def __iter__(self) -> any: ...
# support for loop
def __next__(self) -> any: ...
# support val = list[]
def __init__(self):
"""get an arg by the index"""
def get(self, i: int) -> any:
"""get the length of list"""
def len(self) -> int:
"""support for loop"""
def __iter__(self) -> any:
"""support for loop"""
def __next__(self) -> any:
"""support val = list[]"""
def __getitem__(self, __key: any) -> any: ...
def __del__(self): ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class List(Tuple):
def __init__(self): ...
# add an arg after the end of list
def append(self, arg: any): ...
# set an arg by the index
def set(self, i: int, arg: any): ...
# support list[] = val
def __init__(self):
"""add an arg after the end of list"""
def append(self, arg: any):
"""set an arg by the index"""
def set(self, i: int, arg: any):
"""support list[] = val"""
def reverse(self):
"""reverse the list"""
def __setitem__(self, __key: any, __val: any): ...
def __str__(self) -> str: ...
class Dict:
def __init__(self): ...
# get an arg by the key
@ -43,12 +56,14 @@ class Dict:
def keys(self) -> dict_keys: ...
def __len__(self) -> int: ...
class dict_keys:
def __iter__(self) -> any: ...
def __next__(self) -> any: ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class String:
def __init__(self, s: str): ...
def set(self, s: str): ...
@ -74,6 +89,7 @@ class String:
def replace(self, old: str, new: str) -> str: ...
def strip(self) -> str: ...
class ByteArray:
# convert a string to ByteArray
def __init__(self, bytes: any): ...
@ -87,6 +103,7 @@ class ByteArray:
def __str__(self) -> str: ...
def decode(self) -> str: ...
class FILEIO:
def init(self, path: str, mode: str) -> int: ...
def read(self, size: int) -> any: ...
@ -98,6 +115,7 @@ class FILEIO:
def readlines(self) -> List: ...
def writelines(self, lines: List): ...
class Utils:
# convert a int to bytes
def int_to_bytes(self, val: int) -> bytes: ...

View File

@ -55,3 +55,8 @@ char* PikaStdData_List___str__(PikaObj* self) {
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
void PikaStdData_List_reverse(PikaObj* self) {
PikaList* list = obj_getPtr(self, "list");
list_reverse(list);
}

View File

@ -11,7 +11,8 @@
"program": "${workspaceFolder}/build/test/pikascript_test",
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [
// "--gtest_filter=pikaMain.synac_err_1"
"--gtest_filter=VM.vars_runtime"
// "--gtest_filter=parser.*"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -1,6 +1,7 @@
{
"C_Cpp.clang_format_style": "{ BasedOnStyle: Chromium, IndentWidth: 4}",
"files.associations": {
"pikastdlib_sysobj.h": "c"
"pikastdlib_sysobj.h": "c",
"pikastddata_list.h": "c"
}
}

View File

@ -1,29 +1,42 @@
class Tuple:
def __init__(self): ...
# get an arg by the index
def get(self, i: int) -> any: ...
# get the length of list
def len(self) -> int: ...
# support for loop
def __iter__(self) -> any: ...
# support for loop
def __next__(self) -> any: ...
# support val = list[]
def __init__(self):
"""get an arg by the index"""
def get(self, i: int) -> any:
"""get the length of list"""
def len(self) -> int:
"""support for loop"""
def __iter__(self) -> any:
"""support for loop"""
def __next__(self) -> any:
"""support val = list[]"""
def __getitem__(self, __key: any) -> any: ...
def __del__(self): ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class List(Tuple):
def __init__(self): ...
# add an arg after the end of list
def append(self, arg: any): ...
# set an arg by the index
def set(self, i: int, arg: any): ...
# support list[] = val
def __init__(self):
"""add an arg after the end of list"""
def append(self, arg: any):
"""set an arg by the index"""
def set(self, i: int, arg: any):
"""support list[] = val"""
def reverse(self):
"""reverse the list"""
def __setitem__(self, __key: any, __val: any): ...
def __str__(self) -> str: ...
class Dict:
def __init__(self): ...
# get an arg by the key
@ -43,12 +56,14 @@ class Dict:
def keys(self) -> dict_keys: ...
def __len__(self) -> int: ...
class dict_keys:
def __iter__(self) -> any: ...
def __next__(self) -> any: ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class String:
def __init__(self, s: str): ...
def set(self, s: str): ...
@ -74,6 +89,7 @@ class String:
def replace(self, old: str, new: str) -> str: ...
def strip(self) -> str: ...
class ByteArray:
# convert a string to ByteArray
def __init__(self, bytes: any): ...
@ -87,6 +103,7 @@ class ByteArray:
def __str__(self) -> str: ...
def decode(self) -> str: ...
class FILEIO:
def init(self, path: str, mode: str) -> int: ...
def read(self, size: int) -> any: ...
@ -98,6 +115,7 @@ class FILEIO:
def readlines(self) -> List: ...
def writelines(self, lines: List): ...
class Utils:
# convert a int to bytes
def int_to_bytes(self, val: int) -> bytes: ...

View File

@ -55,3 +55,8 @@ char* PikaStdData_List___str__(PikaObj* self) {
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
void PikaStdData_List_reverse(PikaObj* self) {
PikaList* list = obj_getPtr(self, "list");
list_reverse(list);
}

View File

@ -1141,3 +1141,22 @@ TEST(VM, issue_I5LHJG) {
obj_deinit(self);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(VM, vars_runtime) {
char* line =
"def testvars(a, *b):\n"
" sum = 0\n"
" for i in b:\n"
" sum += i\n"
" return a * sum\n"
"res = testvars(6, 2, 3, 4, 5)\n";
PikaObj* self = newRootObj("root", New_PikaStdLib_SysObj);
obj_run(self, line);
/* collect */
int res = obj_getInt(self, "res");
/* assert */
EXPECT_EQ(res, 84);
/* deinit */
obj_deinit(self);
EXPECT_EQ(pikaMemNow(), 0);
}

View File

@ -3871,3 +3871,53 @@ TEST(lexser, connet_part1) {
args_deinit(buffs);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(parser, vars_runtime) {
pikaMemInfo.heapUsedMax = 0;
Args* buffs = New_strBuff();
char* lines =
"def testvars(a, *b):\n"
" sum = 0\n"
" for i in b:\n"
" sum += i\n"
" return a * sum";
__platform_printf("%s\n", lines);
char* pikaAsm = Parser_linesToAsm(buffs, lines);
__platform_printf("%s", pikaAsm);
EXPECT_STREQ(pikaAsm,
"B0\n"
"0 DEF testvars(a,*b)\n"
"0 JMP 1\n"
"B1\n"
"0 NUM 0\n"
"0 OUT sum\n"
"B1\n"
"1 REF b\n"
"0 RUN iter\n"
"0 OUT _l1\n"
"B1\n"
"0 RUN _l1.__next__\n"
"0 OUT i\n"
"0 EST i\n"
"0 JEZ 2\n"
"B2\n"
"1 REF sum\n"
"2 REF i\n"
"1 RUN \n"
"0 OPT +\n"
"0 OUT sum\n"
"B1\n"
"0 JMP -1\n"
"B1\n"
"0 DEL _l1\n"
"B1\n"
"1 REF a\n"
"1 REF sum\n"
"0 OPT *\n"
"0 RET \n"
"B1\n"
"0 RET \n"
"B0\n");
args_deinit(buffs);
EXPECT_EQ(pikaMemNow(), 0);
}

View File

@ -438,6 +438,7 @@ static Arg* VM_instruction_handler_REF(PikaObj* self,
if (strEqu(data, (char*)"RuntimeError")) {
return arg_setInt(arg_ret_reg, "", PIKA_RES_ERR_RUNTIME_ERROR);
}
Arg* arg = NULL;
if (data[0] == '.') {
/* find host from stack */
@ -447,15 +448,17 @@ static Arg* VM_instruction_handler_REF(PikaObj* self,
arg_ret_reg);
}
arg_deinit(host_obj);
} else {
/* find in local list first */
arg = arg_copy_noalloc(obj_getArg(vm->locals, data), arg_ret_reg);
if (NULL == arg) {
/* find in global list second */
arg = arg_copy_noalloc(obj_getArg(vm->globals, data), arg_ret_reg);
}
goto exit;
}
/* find in local list first */
arg = arg_copy_noalloc(obj_getArg(vm->locals, data), arg_ret_reg);
if (NULL == arg) {
/* find in global list second */
arg = arg_copy_noalloc(obj_getArg(vm->globals, data), arg_ret_reg);
}
exit:
if (NULL == arg) {
VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND);
__platform_printf("NameError: name '%s' is not defined\r\n", data);
@ -632,7 +635,7 @@ static int VMState_loadArgsFromMethodArg(VMState* vm,
arg_num = arg_num_dec;
}
if (strIsContain(type_list, '*')) {
if (is_variable) {
/* get variable tuple name */
type_list_buff = strCopy(buffs2, type_list);
variable_arg_start = 0;
@ -682,19 +685,13 @@ static int VMState_loadArgsFromMethodArg(VMState* vm,
}
if (PIKA_TRUE == is_variable) {
/* resort the tuple */
PikaTuple* tuple_sorted = New_tuple();
if (NULL != tuple) {
int tuple_size = tuple_getSize(tuple);
for (int i = 0; i < tuple_size; i++) {
Arg* arg = tuple_getArg(tuple, tuple_size - 1 - i);
list_append(&(tuple_sorted->super), arg);
}
tuple_deinit(tuple);
}
list_reverse(&tuple->super);
/* load variable tuple */
args_setPtrWithType(args, variable_tuple_name, ARG_TYPE_TUPLE,
tuple_sorted);
PikaObj* New_PikaStdData_Tuple(Args * args);
PikaObj* tuple_obj = newNormalObj(New_PikaStdData_Tuple);
obj_setPtr(tuple_obj, "list", tuple);
args_setPtrWithType(args, variable_tuple_name, ARG_TYPE_OBJECT,
tuple_obj);
}
/* load 'self' as the first arg when call object method */

View File

@ -269,7 +269,7 @@ Arg* arg_setStr(Arg* self, char* name, char* string) {
}
int64_t arg_getInt(Arg* self) {
pika_assert(NULL!=self);
pika_assert(NULL != self);
if (NULL == arg_getContent(self)) {
return -999999;
}
@ -328,7 +328,7 @@ Arg* arg_copy_noalloc(Arg* arg_src, Arg* arg_dict) {
if (NULL == arg_src) {
return NULL;
}
if (NULL == arg_dict){
if (NULL == arg_dict) {
return arg_copy(arg_src);
}
/* size is too big to be copied by noalloc */
@ -429,3 +429,8 @@ void arg_deinit(Arg* self) {
/* free the ref */
arg_freeContent(self);
}
PikaTuple* args_getTuple(Args* self, char* name) {
PikaObj* tuple_obj = args_getPtr(self, name);
return obj_getPtr(tuple_obj, "list");
}

View File

@ -596,6 +596,18 @@ size_t list_getSize(PikaList* self) {
return args_getInt(&self->super, "top");
}
void list_reverse(PikaList* self) {
int top = list_getSize(self);
for (int i = 0; i < top / 2; i++) {
Arg* arg_i = arg_copy(list_getArg(self, i));
Arg* arg_top = arg_copy(list_getArg(self, top - i - 1));
list_setArg(self, i, arg_top);
list_setArg(self, top - i - 1, arg_i);
arg_deinit(arg_i);
arg_deinit(arg_top);
}
}
PikaTuple* New_tuple(void) {
PikaTuple* self = (PikaTuple*)New_list();
return self;

View File

@ -168,6 +168,7 @@ char* list_getStr(PikaList* self, int index);
void* list_getPtr(PikaList* self, int index);
Arg* list_getArg(PikaList* self, int index);
size_t list_getSize(PikaList* self);
void list_reverse(PikaList* self);
char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg);
/* tuple api */
@ -183,6 +184,7 @@ char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg);
PikaList* New_list(void);
PikaTuple* New_tuple(void);
PikaTuple* args_getTuple(Args* self, char* name);
char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list);

View File

@ -124,7 +124,7 @@ impl PyType {
return "args_getArg".to_string();
}
if self.type_name == "@tupleVarPar" {
return "args_getPtr".to_string();
return "args_getTuple".to_string();
}
return "args_getPtr".to_string();
}