From f2e184aa81bf75b0ba333e3fca0b383f9486d4ae Mon Sep 17 00:00:00 2001 From: pikastech Date: Mon, 19 Sep 2022 09:53:27 +0800 Subject: [PATCH] support list(str) --- package/PikaStdLib/PikaStdLib.pyi | 2 +- package/PikaStdLib/PikaStdLib_SysObj.c | 93 ++++++++++++------- port/linux/.vscode/launch.json | 2 +- port/linux/.vscode/settings.json | 3 +- port/linux/package/pikascript/PikaStdLib.pyi | 2 +- port/linux/package/pikascript/modbus.py | 4 +- .../PikaStdLib/PikaStdLib_SysObj.c | 93 ++++++++++++------- port/linux/test/compile-test.cpp | 12 ++- port/linux/test/stddata-test.cpp | 30 ++++++ src/PikaObj.c | 8 +- 10 files changed, 172 insertions(+), 77 deletions(-) diff --git a/package/PikaStdLib/PikaStdLib.pyi b/package/PikaStdLib/PikaStdLib.pyi index 22b5bcb69..41cd3279a 100644 --- a/package/PikaStdLib/PikaStdLib.pyi +++ b/package/PikaStdLib/PikaStdLib.pyi @@ -53,7 +53,7 @@ class SysObj: @staticmethod @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") - def list() -> any: ... + def list(*val) -> any: ... @staticmethod @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") diff --git a/package/PikaStdLib/PikaStdLib_SysObj.c b/package/PikaStdLib/PikaStdLib_SysObj.c index 0649c2df6..8a56562d5 100644 --- a/package/PikaStdLib/PikaStdLib_SysObj.c +++ b/package/PikaStdLib/PikaStdLib_SysObj.c @@ -148,40 +148,32 @@ exit: } Arg* PikaStdLib_SysObj_iter(PikaObj* self, Arg* arg) { - /* a String, return a StringObj */ - if (ARG_TYPE_STRING == arg_getType(arg)) { - obj_setStr(self, "_sobj", arg_getStr(arg)); - return arg_newMetaObj(New_PikaStdLib_StringObj); - } - /* a MATE object, return itself */ - if (ARG_TYPE_OBJECT_META == arg_getType(arg)) { + /* object */ + PIKA_BOOL is_temp = 0; + PikaObj* arg_obj = _arg_to_obj(arg, &is_temp); + NewFun _clsptr = (NewFun)arg_obj->constructor; + if (_clsptr == New_PikaStdLib_RangeObj) { + /* found RangeObj, return directly */ return arg_copy(arg); } - /* object */ - if (argType_isObject(arg_getType(arg))) { - PikaObj* arg_obj = arg_getPtr(arg); - NewFun _clsptr = (NewFun)arg_obj->constructor; - if (_clsptr == New_PikaStdLib_RangeObj) { - /* found RangeObj, return directly */ - return arg_copy(arg); - } - // pikaVM_runAsm(arg_obj, - // "B0\n" - // "0 RUN __iter__\n" - // "0 OUT __res\n"); - const uint8_t bytes[] = { - 0x08, 0x00, /* instruct array size */ - 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x00, /* instruct array */ - 0x10, 0x00, /* const pool size */ - 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x5f, - 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ - }; - pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); - Arg* res = arg_copy(args_getArg(arg_obj->list, "__res")); - obj_removeArg(arg_obj, "__res"); - return res; + // pikaVM_runAsm(arg_obj, + // "B0\n" + // "0 RUN __iter__\n" + // "0 OUT __res\n"); + const uint8_t bytes[] = { + 0x08, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x00, /* instruct array */ + 0x10, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x5f, + 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + Arg* res = arg_copy(args_getArg(arg_obj->list, "__res")); + obj_removeArg(arg_obj, "__res"); + if (is_temp) { + obj_refcntDec(arg_obj); } - return arg_newNull(); + return res; } Arg* PikaStdLib_SysObj_range(PikaObj* self, PikaTuple* ax) { @@ -305,15 +297,48 @@ int PikaStdLib_SysObj_len(PikaObj* self, Arg* arg) { return -1; } -Arg* PikaStdLib_SysObj_list(PikaObj* self) { +Arg* PikaStdLib_SysObj_list(PikaObj* self, PikaTuple* val) { #if PIKA_BUILTIN_STRUCT_ENABLE + if (1 == tuple_getSize(val)) { + Arg* in = tuple_getArg(val, 0); + obj_setArg(self, "__list", in); + /* clang-format off */ + PIKA_PYTHON( + __res = [] + for __item in __list: + __res.append(__item) + del __item + del __list + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x3c, 0x00, /* instruct array size */ + 0x00, 0x95, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x10, 0x81, 0x07, + 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x04, 0x13, 0x00, 0x00, 0x82, + 0x17, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x0d, 0x24, 0x00, 0x00, + 0x07, 0x2b, 0x00, 0x11, 0x81, 0x24, 0x00, 0x01, 0x02, 0x2d, 0x00, + 0x00, 0x86, 0x3a, 0x00, 0x00, 0x8c, 0x13, 0x00, 0x00, 0x8c, 0x24, + 0x00, 0x00, 0x8c, 0x07, 0x00, + /* instruct array */ + 0x3d, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, 0x5f, 0x5f, 0x6c, 0x69, + 0x73, 0x74, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, 0x6c, 0x30, + 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x00, 0x2d, 0x31, 0x00, + /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + return arg_copy(obj_getArg(self, "__res")); + } PikaObj* New_PikaStdData_List(Args * args); return arg_newDirectObj(New_PikaStdData_List); #else obj_setErrorCode(self, 1); __platform_printf("[Error] built-in list is not enabled.\r\n"); - return arg_newNull(); #endif + return arg_newNull(); } Arg* PikaStdLib_SysObj_dict(PikaObj* self) { @@ -539,6 +564,6 @@ exit: return; } -void PikaStdLib_SysObj_exit(PikaObj *self){ +void PikaStdLib_SysObj_exit(PikaObj* self) { pks_vm_exit(); } diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index fb3460957..37e32d0db 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=parser.modbus_1" + // "--gtest_filter=stddata.list_str" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/.vscode/settings.json b/port/linux/.vscode/settings.json index 599788e7a..1445cea93 100644 --- a/port/linux/.vscode/settings.json +++ b/port/linux/.vscode/settings.json @@ -64,6 +64,7 @@ "_modbus__modbus.h": "c", "agile_modbus.h": "c", "_modbus__modbusrtu.h": "c", - "_modbus__modbustcp.h": "c" + "_modbus__modbustcp.h": "c", + "pikastddata_string.h": "c" } } \ No newline at end of file diff --git a/port/linux/package/pikascript/PikaStdLib.pyi b/port/linux/package/pikascript/PikaStdLib.pyi index 22b5bcb69..41cd3279a 100644 --- a/port/linux/package/pikascript/PikaStdLib.pyi +++ b/port/linux/package/pikascript/PikaStdLib.pyi @@ -53,7 +53,7 @@ class SysObj: @staticmethod @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") - def list() -> any: ... + def list(*val) -> any: ... @staticmethod @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") diff --git a/port/linux/package/pikascript/modbus.py b/port/linux/package/pikascript/modbus.py index 5b436d1f3..d98ef82cf 100644 --- a/port/linux/package/pikascript/modbus.py +++ b/port/linux/package/pikascript/modbus.py @@ -2,12 +2,12 @@ import _modbus class ModBus(_modbus._ModBus): - def deserializeReadBits(self, msgLength: int): + def deserializeReadBits(self, msgLength: int) -> list: dest = bytes(msgLength) super().deserializeReadBits(msgLength, dest) return list(dest) - def deserializeReadInputBits(self, msgLength: int): + def deserializeReadInputBits(self, msgLength: int) -> list: dest = bytes(msgLength) super().deserializeReadInputBits(msgLength, dest) return list(dest) diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c index 0649c2df6..8a56562d5 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -148,40 +148,32 @@ exit: } Arg* PikaStdLib_SysObj_iter(PikaObj* self, Arg* arg) { - /* a String, return a StringObj */ - if (ARG_TYPE_STRING == arg_getType(arg)) { - obj_setStr(self, "_sobj", arg_getStr(arg)); - return arg_newMetaObj(New_PikaStdLib_StringObj); - } - /* a MATE object, return itself */ - if (ARG_TYPE_OBJECT_META == arg_getType(arg)) { + /* object */ + PIKA_BOOL is_temp = 0; + PikaObj* arg_obj = _arg_to_obj(arg, &is_temp); + NewFun _clsptr = (NewFun)arg_obj->constructor; + if (_clsptr == New_PikaStdLib_RangeObj) { + /* found RangeObj, return directly */ return arg_copy(arg); } - /* object */ - if (argType_isObject(arg_getType(arg))) { - PikaObj* arg_obj = arg_getPtr(arg); - NewFun _clsptr = (NewFun)arg_obj->constructor; - if (_clsptr == New_PikaStdLib_RangeObj) { - /* found RangeObj, return directly */ - return arg_copy(arg); - } - // pikaVM_runAsm(arg_obj, - // "B0\n" - // "0 RUN __iter__\n" - // "0 OUT __res\n"); - const uint8_t bytes[] = { - 0x08, 0x00, /* instruct array size */ - 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x00, /* instruct array */ - 0x10, 0x00, /* const pool size */ - 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x5f, - 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ - }; - pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); - Arg* res = arg_copy(args_getArg(arg_obj->list, "__res")); - obj_removeArg(arg_obj, "__res"); - return res; + // pikaVM_runAsm(arg_obj, + // "B0\n" + // "0 RUN __iter__\n" + // "0 OUT __res\n"); + const uint8_t bytes[] = { + 0x08, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x00, /* instruct array */ + 0x10, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x5f, + 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + Arg* res = arg_copy(args_getArg(arg_obj->list, "__res")); + obj_removeArg(arg_obj, "__res"); + if (is_temp) { + obj_refcntDec(arg_obj); } - return arg_newNull(); + return res; } Arg* PikaStdLib_SysObj_range(PikaObj* self, PikaTuple* ax) { @@ -305,15 +297,48 @@ int PikaStdLib_SysObj_len(PikaObj* self, Arg* arg) { return -1; } -Arg* PikaStdLib_SysObj_list(PikaObj* self) { +Arg* PikaStdLib_SysObj_list(PikaObj* self, PikaTuple* val) { #if PIKA_BUILTIN_STRUCT_ENABLE + if (1 == tuple_getSize(val)) { + Arg* in = tuple_getArg(val, 0); + obj_setArg(self, "__list", in); + /* clang-format off */ + PIKA_PYTHON( + __res = [] + for __item in __list: + __res.append(__item) + del __item + del __list + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x3c, 0x00, /* instruct array size */ + 0x00, 0x95, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x10, 0x81, 0x07, + 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x04, 0x13, 0x00, 0x00, 0x82, + 0x17, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x0d, 0x24, 0x00, 0x00, + 0x07, 0x2b, 0x00, 0x11, 0x81, 0x24, 0x00, 0x01, 0x02, 0x2d, 0x00, + 0x00, 0x86, 0x3a, 0x00, 0x00, 0x8c, 0x13, 0x00, 0x00, 0x8c, 0x24, + 0x00, 0x00, 0x8c, 0x07, 0x00, + /* instruct array */ + 0x3d, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, 0x5f, 0x5f, 0x6c, 0x69, + 0x73, 0x74, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, 0x6c, 0x30, + 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x00, 0x2d, 0x31, 0x00, + /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + return arg_copy(obj_getArg(self, "__res")); + } PikaObj* New_PikaStdData_List(Args * args); return arg_newDirectObj(New_PikaStdData_List); #else obj_setErrorCode(self, 1); __platform_printf("[Error] built-in list is not enabled.\r\n"); - return arg_newNull(); #endif + return arg_newNull(); } Arg* PikaStdLib_SysObj_dict(PikaObj* self) { @@ -539,6 +564,6 @@ exit: return; } -void PikaStdLib_SysObj_exit(PikaObj *self){ +void PikaStdLib_SysObj_exit(PikaObj* self) { pks_vm_exit(); } diff --git a/port/linux/test/compile-test.cpp b/port/linux/test/compile-test.cpp index c6389d741..176f932a9 100644 --- a/port/linux/test/compile-test.cpp +++ b/port/linux/test/compile-test.cpp @@ -98,7 +98,6 @@ TEST(compiler, task) { byteCodeFrame_deinit(&bytecode_frame); strsDeinit(&buffs); EXPECT_EQ(pikaMemNow(), 0); - } TEST(compiler, demo1) { @@ -612,3 +611,14 @@ TEST(compiler, __callback) { Parser_linesToArray(lines); EXPECT_EQ(pikaMemNow(), 0); } + +TEST(compiler, __list) { + char* lines = + "__res = []\n" + "for __item in __list:\n" + " __res.append(__item)\n" + "del __item\n" + "del __list\n"; + Parser_linesToArray(lines); + EXPECT_EQ(pikaMemNow(), 0); +} diff --git a/port/linux/test/stddata-test.cpp b/port/linux/test/stddata-test.cpp index 8de54a2f1..096cd53b9 100644 --- a/port/linux/test/stddata-test.cpp +++ b/port/linux/test/stddata-test.cpp @@ -266,4 +266,34 @@ TEST(dict, items_kv) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(stddata, list_str) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + obj_run(pikaMain, "list('test')"); + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[0], "['t', 'e', 's', 't']\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(stddata, list_bytes) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + obj_run(pikaMain, "list(b'test')"); + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[0], "[116, 101, 115, 116]\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif diff --git a/src/PikaObj.c b/src/PikaObj.c index 7848cbbce..57ca859eb 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -443,14 +443,18 @@ PikaObj* _arg_to_obj(Arg* self, PIKA_BOOL* pIsTemp) { PikaObj* New_PikaStdData_String(Args * args); PikaObj* obj = newNormalObj(New_PikaStdData_String); obj_setStr(obj, "str", arg_getStr(self)); - *pIsTemp = PIKA_TRUE; + if (NULL != pIsTemp) { + *pIsTemp = PIKA_TRUE; + } return obj; } if (arg_getType(self) == ARG_TYPE_BYTES) { PikaObj* New_PikaStdData_ByteArray(Args * args); PikaObj* obj = newNormalObj(New_PikaStdData_ByteArray); obj_setArg(obj, "raw", self); - *pIsTemp = PIKA_TRUE; + if (NULL != pIsTemp) { + *pIsTemp = PIKA_TRUE; + } return obj; } #endif