diff --git a/package/PikaStdLib/PikaStdData.pyi b/package/PikaStdLib/PikaStdData.pyi index 58ce438d1..1240d7278 100644 --- a/package/PikaStdLib/PikaStdData.pyi +++ b/package/PikaStdLib/PikaStdData.pyi @@ -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: ... diff --git a/package/PikaStdLib/PikaStdData_List.c b/package/PikaStdLib/PikaStdData_List.c index 5c2adf1ea..ebcab8a26 100644 --- a/package/PikaStdLib/PikaStdData_List.c +++ b/package/PikaStdLib/PikaStdData_List.c @@ -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); +} diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 4d99032d8..d4eadda84 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -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}", diff --git a/port/linux/.vscode/settings.json b/port/linux/.vscode/settings.json index 349ac6e0c..7e53a47f5 100644 --- a/port/linux/.vscode/settings.json +++ b/port/linux/.vscode/settings.json @@ -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" } } \ No newline at end of file diff --git a/port/linux/package/pikascript/PikaStdData.pyi b/port/linux/package/pikascript/PikaStdData.pyi index 58ce438d1..1240d7278 100644 --- a/port/linux/package/pikascript/PikaStdData.pyi +++ b/port/linux/package/pikascript/PikaStdData.pyi @@ -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: ... diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_List.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_List.c index 5c2adf1ea..ebcab8a26 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_List.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_List.c @@ -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); +} diff --git a/port/linux/test/VM-test.cpp b/port/linux/test/VM-test.cpp index fc3a4ec64..5d817a555 100644 --- a/port/linux/test/VM-test.cpp +++ b/port/linux/test/VM-test.cpp @@ -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); +} diff --git a/port/linux/test/parse-test.cpp b/port/linux/test/parse-test.cpp index e6830febe..984015bc5 100644 --- a/port/linux/test/parse-test.cpp +++ b/port/linux/test/parse-test.cpp @@ -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); +} diff --git a/src/PikaVM.c b/src/PikaVM.c index 8ef732815..e0ca572dd 100644 --- a/src/PikaVM.c +++ b/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 { - /* 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 */ diff --git a/src/dataArg.c b/src/dataArg.c index decda490c..9e4a0070c 100644 --- a/src/dataArg.c +++ b/src/dataArg.c @@ -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"); +} diff --git a/src/dataArgs.c b/src/dataArgs.c index b7de18ffe..976357456 100644 --- a/src/dataArgs.c +++ b/src/dataArgs.c @@ -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; diff --git a/src/dataArgs.h b/src/dataArgs.h index 96e830f4a..ff0d4b44f 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -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); diff --git a/tools/pikaCompiler/src/py_type.rs b/tools/pikaCompiler/src/py_type.rs index f64ccb4b4..b96f040b9 100644 --- a/tools/pikaCompiler/src/py_type.rs +++ b/tools/pikaCompiler/src/py_type.rs @@ -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(); }