mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
support *var in py function
This commit is contained in:
parent
77e291101f
commit
d01ca77a51
@ -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: ...
|
||||
|
@ -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);
|
||||
}
|
||||
|
3
port/linux/.vscode/launch.json
vendored
3
port/linux/.vscode/launch.json
vendored
@ -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}",
|
||||
|
3
port/linux/.vscode/settings.json
vendored
3
port/linux/.vscode/settings.json
vendored
@ -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"
|
||||
}
|
||||
}
|
@ -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: ...
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
27
src/PikaVM.c
27
src/PikaVM.c
@ -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 {
|
||||
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 */
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user