From 660a97110f19d5f1cb526c04e2194af420bafa84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Mon, 11 Jul 2022 06:42:12 +0000 Subject: [PATCH] !47 not use suger to parse slice * use __vm_[get/slice] for sysobj * not use suger in slice * parser for new slice is ok * add SLC ins --- package/PikaStdLib/PikaStdLib_SysObj.c | 113 +------ port/linux/.vscode/launch.json | 2 +- .../PikaStdLib/PikaStdLib_SysObj.c | 113 +------ port/linux/test/parse-test.cpp | 75 ++--- src/PikaParser.c | 275 ++++++------------ src/PikaVM.c | 141 +++++++++ src/PikaVM.h | 2 + src/__instruction_table.cfg | 2 + src/dataStrs.c | 9 +- src/dataStrs.h | 1 + 10 files changed, 281 insertions(+), 452 deletions(-) diff --git a/package/PikaStdLib/PikaStdLib_SysObj.c b/package/PikaStdLib/PikaStdLib_SysObj.c index 9e1cedbe4..5fc9fd847 100644 --- a/package/PikaStdLib/PikaStdLib_SysObj.c +++ b/package/PikaStdLib/PikaStdLib_SysObj.c @@ -192,51 +192,7 @@ Arg* PikaStdLib_SysObj_range(PikaObj* self, int a1, int a2) { } Arg* PikaStdLib_SysObj___get__(PikaObj* self, Arg* key, Arg* obj) { - ArgType obj_type = arg_getType(obj); - int index = 0; - if (ARG_TYPE_INT == arg_getType(key)) { - index = arg_getInt(key); - } - if (ARG_TYPE_STRING == obj_type) { - char* str_pyload = arg_getStr(obj); - char char_buff[] = " "; - if (index < 0) { - index = strGetSize(str_pyload) + index; - } - char_buff[0] = str_pyload[index]; - return arg_setStr(NULL, "", char_buff); - } - if (ARG_TYPE_BYTES == obj_type) { - uint8_t* bytes_pyload = arg_getBytes(obj); - uint8_t byte_buff[] = " "; - if (index < 0) { - index = arg_getBytesSize(obj) + index; - } - byte_buff[0] = bytes_pyload[index]; - return arg_setBytes(NULL, "", byte_buff, 1); - } - if (argType_isObject(obj_type)) { - PikaObj* arg_obj = arg_getPtr(obj); - obj_setArg(arg_obj, "__key", key); - // pikaVM_runAsm(arg_obj, - // "B0\n" - // "1 REF __key\n" - // "0 RUN __get__\n" - // "0 OUT __res\n"); - const uint8_t bytes[] = { - 0x0c, 0x00, /* instruct array size */ - 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x0f, - 0x00, - /* instruct array */ - 0x15, 0x00, /* const pool size */ - 0x00, 0x5f, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x5f, 0x5f, 0x67, 0x65, - 0x74, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, - 0x00, /* const pool */ - }; - pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); - return arg_copy(args_getArg(arg_obj->list, "__res")); - } - return arg_setNull(NULL); + return __vm_get(self, key, obj); } Arg* PikaStdLib_SysObj___set__(PikaObj* self, Arg* key, Arg* obj, Arg* val) { @@ -399,70 +355,7 @@ Arg* PikaStdLib_SysObj___slice__(PikaObj* self, Arg* obj, Arg* start, int step) { -#if PIKA_SYNTAX_SLICE_ENABLE - /* No interger index only support __get__ */ - if (!(arg_getType(start) == ARG_TYPE_INT && - arg_getType(end) == ARG_TYPE_INT)) { - return PikaStdLib_SysObj___get__(self, start, obj); - } - - int start_i = arg_getInt(start); - int end_i = arg_getInt(end); - - /* __slice__ is equal to __get__ */ - if (end_i - start_i == 1) { - return PikaStdLib_SysObj___get__(self, start, obj); - } - - if (ARG_TYPE_STRING == arg_getType(obj)) { - size_t len = strGetSize(arg_getStr(obj)); - if (start_i < 0) { - start_i += len; - } - if (end_i < 0) { - end_i += len + 1; - } - Arg* sliced_arg = arg_setStr(NULL, "", ""); - for (int i = start_i; i < end_i; i++) { - Arg* i_arg = arg_setInt(NULL, "", i); - Arg* item_arg = PikaStdLib_SysObj___get__(self, i_arg, obj); - sliced_arg = arg_strAppend(sliced_arg, arg_getStr(item_arg)); - arg_deinit(item_arg); - arg_deinit(i_arg); - } - return sliced_arg; - } - - if (ARG_TYPE_BYTES == arg_getType(obj)) { - size_t len = arg_getBytesSize(obj); - if (start_i < 0) { - start_i += len; - } - if (end_i < 0) { - end_i += len + 1; - } - Arg* sliced_arg = arg_setBytes(NULL, "", NULL, 0); - for (int i = start_i; i < end_i; i++) { - Arg* i_arg = arg_setInt(NULL, "", i); - Arg* item_arg = PikaStdLib_SysObj___get__(self, i_arg, obj); - uint8_t* bytes_origin = arg_getBytes(sliced_arg); - size_t size_origin = arg_getBytesSize(sliced_arg); - Arg* sliced_arg_new = arg_setBytes(NULL, "", NULL, size_origin + 1); - __platform_memcpy(arg_getBytes(sliced_arg_new), bytes_origin, - size_origin); - __platform_memcpy(arg_getBytes(sliced_arg_new) + size_origin, - arg_getBytes(item_arg), 1); - arg_deinit(sliced_arg); - sliced_arg = sliced_arg_new; - arg_deinit(item_arg); - arg_deinit(i_arg); - } - return sliced_arg; - } - return arg_setNull(NULL); -#else - return PikaStdLib_SysObj___get__(self, start, obj); -#endif + return __vm_slice(self, end, obj, start, step); } static void __print_arg(PikaObj* self, Arg* val) { @@ -535,7 +428,7 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) { } char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { - #if PIKA_SYNTAX_FORMAT_ENABLE +#if PIKA_SYNTAX_FORMAT_ENABLE Args buffs = {0}; pikaMemMaxReset(); char* res = strsFormatList(&buffs, fmt, &var->super); diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 21562e37b..75595a18e 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.__get__" + // "--gtest_filter=parser.*" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", 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 9e1cedbe4..5fc9fd847 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -192,51 +192,7 @@ Arg* PikaStdLib_SysObj_range(PikaObj* self, int a1, int a2) { } Arg* PikaStdLib_SysObj___get__(PikaObj* self, Arg* key, Arg* obj) { - ArgType obj_type = arg_getType(obj); - int index = 0; - if (ARG_TYPE_INT == arg_getType(key)) { - index = arg_getInt(key); - } - if (ARG_TYPE_STRING == obj_type) { - char* str_pyload = arg_getStr(obj); - char char_buff[] = " "; - if (index < 0) { - index = strGetSize(str_pyload) + index; - } - char_buff[0] = str_pyload[index]; - return arg_setStr(NULL, "", char_buff); - } - if (ARG_TYPE_BYTES == obj_type) { - uint8_t* bytes_pyload = arg_getBytes(obj); - uint8_t byte_buff[] = " "; - if (index < 0) { - index = arg_getBytesSize(obj) + index; - } - byte_buff[0] = bytes_pyload[index]; - return arg_setBytes(NULL, "", byte_buff, 1); - } - if (argType_isObject(obj_type)) { - PikaObj* arg_obj = arg_getPtr(obj); - obj_setArg(arg_obj, "__key", key); - // pikaVM_runAsm(arg_obj, - // "B0\n" - // "1 REF __key\n" - // "0 RUN __get__\n" - // "0 OUT __res\n"); - const uint8_t bytes[] = { - 0x0c, 0x00, /* instruct array size */ - 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x0f, - 0x00, - /* instruct array */ - 0x15, 0x00, /* const pool size */ - 0x00, 0x5f, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x5f, 0x5f, 0x67, 0x65, - 0x74, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, - 0x00, /* const pool */ - }; - pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); - return arg_copy(args_getArg(arg_obj->list, "__res")); - } - return arg_setNull(NULL); + return __vm_get(self, key, obj); } Arg* PikaStdLib_SysObj___set__(PikaObj* self, Arg* key, Arg* obj, Arg* val) { @@ -399,70 +355,7 @@ Arg* PikaStdLib_SysObj___slice__(PikaObj* self, Arg* obj, Arg* start, int step) { -#if PIKA_SYNTAX_SLICE_ENABLE - /* No interger index only support __get__ */ - if (!(arg_getType(start) == ARG_TYPE_INT && - arg_getType(end) == ARG_TYPE_INT)) { - return PikaStdLib_SysObj___get__(self, start, obj); - } - - int start_i = arg_getInt(start); - int end_i = arg_getInt(end); - - /* __slice__ is equal to __get__ */ - if (end_i - start_i == 1) { - return PikaStdLib_SysObj___get__(self, start, obj); - } - - if (ARG_TYPE_STRING == arg_getType(obj)) { - size_t len = strGetSize(arg_getStr(obj)); - if (start_i < 0) { - start_i += len; - } - if (end_i < 0) { - end_i += len + 1; - } - Arg* sliced_arg = arg_setStr(NULL, "", ""); - for (int i = start_i; i < end_i; i++) { - Arg* i_arg = arg_setInt(NULL, "", i); - Arg* item_arg = PikaStdLib_SysObj___get__(self, i_arg, obj); - sliced_arg = arg_strAppend(sliced_arg, arg_getStr(item_arg)); - arg_deinit(item_arg); - arg_deinit(i_arg); - } - return sliced_arg; - } - - if (ARG_TYPE_BYTES == arg_getType(obj)) { - size_t len = arg_getBytesSize(obj); - if (start_i < 0) { - start_i += len; - } - if (end_i < 0) { - end_i += len + 1; - } - Arg* sliced_arg = arg_setBytes(NULL, "", NULL, 0); - for (int i = start_i; i < end_i; i++) { - Arg* i_arg = arg_setInt(NULL, "", i); - Arg* item_arg = PikaStdLib_SysObj___get__(self, i_arg, obj); - uint8_t* bytes_origin = arg_getBytes(sliced_arg); - size_t size_origin = arg_getBytesSize(sliced_arg); - Arg* sliced_arg_new = arg_setBytes(NULL, "", NULL, size_origin + 1); - __platform_memcpy(arg_getBytes(sliced_arg_new), bytes_origin, - size_origin); - __platform_memcpy(arg_getBytes(sliced_arg_new) + size_origin, - arg_getBytes(item_arg), 1); - arg_deinit(sliced_arg); - sliced_arg = sliced_arg_new; - arg_deinit(item_arg); - arg_deinit(i_arg); - } - return sliced_arg; - } - return arg_setNull(NULL); -#else - return PikaStdLib_SysObj___get__(self, start, obj); -#endif + return __vm_slice(self, end, obj, start, step); } static void __print_arg(PikaObj* self, Arg* val) { @@ -535,7 +428,7 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) { } char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { - #if PIKA_SYNTAX_FORMAT_ENABLE +#if PIKA_SYNTAX_FORMAT_ENABLE Args buffs = {0}; pikaMemMaxReset(); char* res = strsFormatList(&buffs, fmt, &var->super); diff --git a/port/linux/test/parse-test.cpp b/port/linux/test/parse-test.cpp index a797ec108..857c4e9ce 100644 --- a/port/linux/test/parse-test.cpp +++ b/port/linux/test/parse-test.cpp @@ -1814,24 +1814,12 @@ TEST(parser, __get__3) { "3 REF c\n" "3 REF d\n" "2 OPT +\n" - "4 REF c\n" - "4 REF d\n" - "3 OPT +\n" - "3 NUM 1\n" - "2 OPT +\n" - "2 NUM 1\n" - "1 RUN __slice__\n" + "1 SLC \n" "2 REF e\n" "3 REF f\n" "3 REF j\n" "2 OPT *\n" - "4 REF f\n" - "4 REF j\n" - "3 OPT *\n" - "3 NUM 1\n" - "2 OPT +\n" - "2 NUM 1\n" - "1 RUN __slice__\n" + "1 SLC \n" "0 OPT +\n" "0 OUT a\n"); args_deinit(buffs); @@ -1851,11 +1839,7 @@ TEST(parser, __get__) { "B0\n" "1 REF b\n" "1 REF c\n" - "2 REF c\n" - "2 NUM 1\n" - "1 OPT +\n" - "1 NUM 1\n" - "0 RUN __slice__\n" + "0 SLC \n" "0 OUT a\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); @@ -1876,13 +1860,7 @@ TEST(parser, __get__2) { "2 REF c\n" "2 REF d\n" "1 OPT +\n" - "3 REF c\n" - "3 REF d\n" - "2 OPT +\n" - "2 NUM 1\n" - "1 OPT +\n" - "1 NUM 1\n" - "0 RUN __slice__\n" + "0 SLC \n" "0 OUT a\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); @@ -2210,18 +2188,10 @@ TEST(parser, list_1_2) { "B0\n" "3 REF list\n" "3 NUM 0\n" - "4 NUM 0\n" - "4 NUM 1\n" - "3 OPT +\n" - "3 NUM 1\n" - "2 RUN __slice__\n" + "2 SLC \n" "3 REF list\n" "3 NUM 1\n" - "4 NUM 1\n" - "4 NUM 1\n" - "3 OPT +\n" - "3 NUM 1\n" - "2 RUN __slice__\n" + "2 SLC \n" "1 OPT +\n" "0 RUN print\n"); args_deinit(buffs); @@ -2629,11 +2599,7 @@ TEST(parser, bytes_index) { "B0\n" "1 BYT eqrt\n" "1 NUM 2\n" - "2 NUM 2\n" - "2 NUM 1\n" - "1 OPT +\n" - "1 NUM 1\n" - "0 RUN __slice__\n" + "0 SLC \n" "0 OUT res2\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); @@ -2741,8 +2707,7 @@ TEST(parser, slice1) { "1 REF recv_buf\n" "1 NUM 1\n" "1 NUM 4\n" - "1 NUM 1\n" - "0 RUN __slice__\n" + "0 SLC \n" "0 OUT a\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); @@ -2763,7 +2728,7 @@ TEST(parser, slice2) { "1 NUM 1\n" "1 NUM 4\n" "1 NUM 2\n" - "0 RUN __slice__\n" + "0 SLC \n" "0 OUT a\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); @@ -2932,8 +2897,26 @@ TEST(parser, slice_12lkj) { "1 REF b\n" "1 NUM 0\n" "1 NUM 6\n" - "1 NUM 1\n" - "0 RUN __slice__\n" + "0 SLC \n" + "0 OUT a\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(parser, slice_oifjlk) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = "a = b[6:]\n"; + printf("%s", lines); + char* pikaAsm = Parser_multiLineToAsm(buffs, lines); + printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "1 REF b\n" + "1 NUM 6\n" + "2 NUM 1\n" + "1 OPT -\n" + "0 SLC \n" "0 OUT a\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); diff --git a/src/PikaParser.c b/src/PikaParser.c index 0fcc18c8a..0dd3ea1aa 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -937,106 +937,11 @@ static void Slice_getPars(Args* outBuffs, #endif #if PIKA_SYNTAX_SLICE_ENABLE -char* Suger_solveRightBranckets(Args* outBuffs, char* right) { - /* init objects */ - Args buffs = {0}; - Arg* right_arg = arg_setStr(NULL, "", ""); - uint8_t is_in_brancket = 0; - args_setStr(&buffs, "inner", ""); - uint8_t matched = 0; - char* right_res = NULL; - /* exit when not match - (symble | iteral | <]> | <)>) + <[> - */ - ParserState_forEachToken(ps, right) { - ParserState_iterStart(&ps); - if (strEqu(ps.token2.pyload, "[")) { - if (TOKEN_symbol == ps.token1.type || - TOKEN_literal == ps.token1.type || - strEqu(ps.token1.pyload, "]") || - strEqu(ps.token1.pyload, ")")) { - matched = 1; - ParserState_iterEnd(&ps); - break; - } - } - ParserState_iterEnd(&ps); - } - ParserState_deinit(&ps); - if (!matched) { - /* not contain '[', return origin */ - arg_deinit(right_arg); - right_arg = arg_setStr(right_arg, "", right); - goto exit; - } - - /* matched [] */ - ParserState_forEachTokenExistPs(ps, right) { - ParserState_iterStart(&ps); - /* found '[' */ - if ((TOKEN_devider == ps.token2.type) && - (strEqu(ps.token2.pyload, "["))) { - /* get 'obj' from obj[] */ - args_setStr(&buffs, "obj", ps.token1.pyload); - is_in_brancket = 1; - /* fond ']' */ - } else if ((TOKEN_devider == ps.token2.type) && - (strEqu(ps.token2.pyload, "]"))) { - is_in_brancket = 0; - char* inner = args_getStr(&buffs, "inner"); - Arg* inner_arg = arg_setStr(NULL, "", inner); - inner_arg = arg_strAppend(inner_arg, ps.token1.pyload); - args_setStr(&buffs, "inner", arg_getStr(inner_arg)); - arg_deinit(inner_arg); - /* update inner pointer */ - inner = args_getStr(&buffs, "inner"); - char* start = NULL; - char* end = NULL; - char* step = NULL; - Slice_getPars(&buffs, inner, &start, &end, &step); - /* __slice__(obj, start, end, step) */ - right_arg = arg_strAppend(right_arg, "__slice__("); - right_arg = arg_strAppend(right_arg, args_getStr(&buffs, "obj")); - right_arg = arg_strAppend(right_arg, ","); - /* slice only one item */ - /* end = start + 1 */ - right_arg = arg_strAppend(right_arg, start); - /* __slice__(obj, index, indxe + 1, 1) */ - right_arg = arg_strAppend(right_arg, ","); - right_arg = arg_strAppend(right_arg, end); - right_arg = arg_strAppend(right_arg, ","); - right_arg = arg_strAppend(right_arg, step); - right_arg = arg_strAppend(right_arg, ")"); - /* clean the inner */ - args_setStr(&buffs, "inner", ""); - /* in brancket and found '[' */ - } else if (is_in_brancket && (!strEqu(ps.token1.pyload, "["))) { - char* inner = args_getStr(&buffs, "inner"); - Arg* index_arg = arg_setStr(NULL, "", inner); - index_arg = arg_strAppend(index_arg, ps.token1.pyload); - args_setStr(&buffs, "inner", arg_getStr(index_arg)); - arg_deinit(index_arg); - /* out of brancket and not found ']' */ - } else if (!is_in_brancket && (!strEqu(ps.token1.pyload, "]"))) { - if (TOKEN_strEnd != ps.token1.type) { - right_arg = arg_strAppend(right_arg, ps.token1.pyload); - } - } - ParserState_iterEnd(&ps); - } - ParserState_deinit(&ps); -exit: - /* clean and return */ - right_res = strsCopy(outBuffs, arg_getStr(right_arg)); - arg_deinit(right_arg); - strsDeinit(&buffs); - return right_res; -} - -char* Suger_solveLeftBranckets(Args* outBuffs, char* right, char* left) { +char* Suger_solveLeftBranckets(Args* outBuffs, char* right, char** left_p) { /* init objects */ Args buffs = {0}; Arg* right_arg = arg_setStr(NULL, "", ""); + char* left = *left_p; uint8_t is_in_brancket = 0; args_setStr(&buffs, "inner", ""); uint8_t matched = 0; @@ -1324,6 +1229,46 @@ PIKA_RES AST_parseSubStmt(AST* ast, char* node_content) { return PIKA_RES_OK; } +char* Parser_popSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { + Arg* substmt_arg = arg_setStr(NULL, "", ""); + Arg* newstmt_arg = arg_setStr(NULL, "", ""); + char* stmt = *stmt_p; + PIKA_BOOL is_get_substmt = 0; + Args buffs = {0}; + ParserState_forEachToken(ps, stmt) { + ParserState_iterStart(&ps); + if (is_get_substmt) { + /* get new stmt */ + newstmt_arg = arg_strAppend(newstmt_arg, ps.token1.pyload); + ParserState_iterEnd(&ps); + continue; + } + if (ps.branket_deepth > 0) { + /* ignore */ + substmt_arg = arg_strAppend(substmt_arg, ps.token1.pyload); + ParserState_iterEnd(&ps); + continue; + } + if (strEqu(ps.token1.pyload, delimiter)) { + /* found delimiter */ + is_get_substmt = 1; + ParserState_iterEnd(&ps); + continue; + } + /* collect substmt */ + substmt_arg = arg_strAppend(substmt_arg, ps.token1.pyload); + ParserState_iterEnd(&ps); + } + ParserState_deinit(&ps); + + strsDeinit(&buffs); + + char* substmt = strsCacheArg(outbuffs, substmt_arg); + char* newstmt = strsCacheArg(outbuffs, newstmt_arg); + *stmt_p = newstmt; + return substmt; +} + AST* AST_parseStmt(AST* ast, char* stmt) { Args buffs = {0}; char* assignment = strsGetFirstToken(&buffs, stmt, '('); @@ -1369,8 +1314,7 @@ AST* AST_parseStmt(AST* ast, char* stmt) { #if PIKA_SYNTAX_SLICE_ENABLE /* solve the [] stmt */ - right = Suger_solveRightBranckets(&buffs, right); - right = Suger_solveLeftBranckets(&buffs, right, left); + right = Suger_solveLeftBranckets(&buffs, right, &left); #endif #if PIKA_SYNTAX_FORMAT_ENABLE @@ -1407,73 +1351,33 @@ AST* AST_parseStmt(AST* ast, char* stmt) { AST_setThisNode(ast, (char*)"list", "list"); char* subStmts = strsCut(&buffs, right, '[', ']'); subStmts = strsAppend(&buffs, subStmts, ","); - Arg* subStmt = arg_setStr(NULL, "", ""); - char* subStmt_str = NULL; - ParserState_forEachToken(ps, subStmts) { - ParserState_iterStart(&ps); - if (ps.branket_deepth > 0) { - /* in brankets */ - /* append token to subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } else { - /* not in brankets */ - if (strEqu(ps.token1.pyload, ",")) { - /* found "," push subStmt */ - subStmt_str = arg_getStr(subStmt); - AST_parseSubStmt(ast, subStmt_str); - /* clear subStmt */ - arg_deinit(subStmt); - subStmt = arg_setStr(NULL, "", ""); - } else { - /* not "," append subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } + while (1) { + char* subStmt = Parser_popSubStmt(&buffs, &subStmts, ","); + AST_parseSubStmt(ast, subStmt); + if (strEqu(subStmts, "")) { + break; } - ParserState_iterEnd(&ps); } - ParserState_deinit(&ps); - arg_deinit(subStmt); goto exit; } #endif #if PIKA_BUILTIN_DICT_ENABLE - /* solve list stmt */ + /* solve dict stmt */ if (STMT_dict == stmtType) { AST_setThisNode(ast, (char*)"dict", "dict"); char* subStmts = strsCut(&buffs, right, '{', '}'); subStmts = strsAppend(&buffs, subStmts, ","); - Arg* subStmt = arg_setStr(NULL, "", ""); - char* subStmt_str = NULL; - ParserState_forEachToken(ps, subStmts) { - ParserState_iterStart(&ps); - if (ps.branket_deepth > 0) { - /* in brankets */ - /* append token to subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } else { - /* not in brankets */ - if (strEqu(ps.token1.pyload, ",") || - strEqu(ps.token1.pyload, ":")) { - /* found "," or ":" push subStmt */ - subStmt_str = arg_getStr(subStmt); - AST_parseSubStmt(ast, subStmt_str); - /* clear subStmt */ - arg_deinit(subStmt); - subStmt = arg_setStr(NULL, "", ""); - } else { - /* not "," append subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } + while (1) { + char* subStmt = Parser_popSubStmt(&buffs, &subStmts, ","); + char* key = Parser_popSubStmt(&buffs, &subStmt, ":"); + char* value = subStmt; + AST_parseSubStmt(ast, key); + AST_parseSubStmt(ast, value); + if (strEqu(subStmts, "")) { + break; } - ParserState_iterEnd(&ps); } - ParserState_deinit(&ps); - arg_deinit(subStmt); goto exit; } #endif @@ -1518,6 +1422,30 @@ AST* AST_parseStmt(AST* ast, char* stmt) { goto exit; } + if (STMT_slice == stmtType) { + /* solve slice stmt */ + AST_setThisNode(ast, (char*)"slice", "slice"); + AST_parseSubStmt(ast, strsGetFirstToken(&buffs, right, '[')); + char* slice_list = strsCut(&buffs, right, '[', ']'); + slice_list = strsAppend(&buffs, slice_list, ":"); + int index = 0; + while (1) { + char* slice_str = Parser_popSubStmt(&buffs, &slice_list, ":"); + if (index == 0 && strEqu(slice_str, "")) { + AST_parseSubStmt(ast, "0"); + } else if (index == 1 && strEqu(slice_str, "")) { + AST_parseSubStmt(ast, "-1"); + } else { + AST_parseSubStmt(ast, slice_str); + } + index++; + if (strEqu("", slice_list)) { + break; + } + } + goto exit; + } + /* solve method stmt */ if (STMT_method == stmtType) { method = strsGetFirstToken(&buffs, right, '('); @@ -1526,39 +1454,13 @@ AST* AST_parseStmt(AST* ast, char* stmt) { pika_assert(NULL != subStmts); /* add ',' at the end */ subStmts = strsAppend(&buffs, subStmts, ","); - /* init process values */ - Arg* subStmt = arg_setStr(NULL, "", ""); - /* start iteration */ - char* subStmt_str = NULL; - ParserState_forEachToken(ps, subStmts) { - ParserState_iterStart(&ps); - /* parse process */ - if (ps.branket_deepth > 0) { - /* in brankets */ - /* append token to subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } else { - /* not in brankets */ - if (strEqu(ps.token1.pyload, ",")) { - /* found "," push subStmt */ - subStmt_str = arg_getStr(subStmt); - AST_parseSubStmt(ast, subStmt_str); - /* clear subStmt */ - arg_deinit(subStmt); - subStmt = arg_setStr(NULL, "", ""); - } else { - /* not "," append subStmt */ - subStmt = arg_strAppend(subStmt, ps.token1.pyload); - subStmt_str = arg_getStr(subStmt); - } + while (1) { + char* substmt = Parser_popSubStmt(&buffs, &subStmts, ","); + AST_parseSubStmt(ast, substmt); + if (strEqu("", subStmts)) { + break; } - /* parse preocess end */ - ParserState_iterEnd(&ps); - continue; } - ParserState_deinit(&ps); - arg_deinit(subStmt); goto exit; } /* solve reference stmt */ @@ -2232,6 +2134,7 @@ char* AST_appandPikaASM(AST* ast, AST* subAst, Args* outBuffs, char* pikaAsm) { char* num = obj_getStr(subAst, "num"); char* import = obj_getStr(subAst, "import"); char* buff = args_getBuff(&buffs, PIKA_SPRINTF_BUFF_SIZE); + char* slice = obj_getStr(subAst, "slice"); if (NULL != dict) { __platform_sprintf(buff, "%d DCT \n", deepth); pikaAsm = strsAppend(&buffs, pikaAsm, buff); @@ -2268,6 +2171,10 @@ char* AST_appandPikaASM(AST* ast, AST* subAst, Args* outBuffs, char* pikaAsm) { __platform_sprintf(buff, "%d NUM %s\n", deepth, num); pikaAsm = strsAppend(&buffs, pikaAsm, buff); } + if (NULL != slice) { + __platform_sprintf(buff, "%d SLC \n", deepth); + pikaAsm = strsAppend(&buffs, pikaAsm, buff); + } if (NULL != left) { __platform_sprintf(buff, "%d OUT %s\n", deepth, left); pikaAsm = strsAppend(&buffs, pikaAsm, buff); diff --git a/src/PikaVM.c b/src/PikaVM.c index bf5a9888b..3962352e7 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -170,6 +170,147 @@ static Arg* VM_instruction_handler_NON(PikaObj* self, VMState* vs, char* data) { return NULL; } +Arg* __vm_get(PikaObj* self, Arg* key, Arg* obj) { + ArgType obj_type = arg_getType(obj); + int index = 0; + if (ARG_TYPE_INT == arg_getType(key)) { + index = arg_getInt(key); + } + if (ARG_TYPE_STRING == obj_type) { + char* str_pyload = arg_getStr(obj); + char char_buff[] = " "; + if (index < 0) { + index = strGetSize(str_pyload) + index; + } + char_buff[0] = str_pyload[index]; + return arg_setStr(NULL, "", char_buff); + } + if (ARG_TYPE_BYTES == obj_type) { + uint8_t* bytes_pyload = arg_getBytes(obj); + uint8_t byte_buff[] = " "; + if (index < 0) { + index = arg_getBytesSize(obj) + index; + } + byte_buff[0] = bytes_pyload[index]; + return arg_setBytes(NULL, "", byte_buff, 1); + } + if (argType_isObject(obj_type)) { + PikaObj* arg_obj = arg_getPtr(obj); + obj_setArg(arg_obj, "__key", key); + // pikaVM_runAsm(arg_obj, + // "B0\n" + // "1 REF __key\n" + // "0 RUN __get__\n" + // "0 OUT __res\n"); + const uint8_t bytes[] = { + 0x0c, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x0f, + 0x00, + /* instruct array */ + 0x15, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x5f, 0x5f, 0x67, 0x65, + 0x74, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, + 0x00, /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + return arg_copy(args_getArg(arg_obj->list, "__res")); + } + return arg_setNull(NULL); +} + +Arg* __vm_slice(PikaObj* self, Arg* end, Arg* obj, Arg* start, int step) { +#if PIKA_SYNTAX_SLICE_ENABLE + /* No interger index only support __get__ */ + if (!(arg_getType(start) == ARG_TYPE_INT && + arg_getType(end) == ARG_TYPE_INT)) { + return __vm_get(self, start, obj); + } + + int start_i = arg_getInt(start); + int end_i = arg_getInt(end); + + /* __slice__ is equal to __get__ */ + if (end_i - start_i == 1) { + return __vm_get(self, start, obj); + } + + if (ARG_TYPE_STRING == arg_getType(obj)) { + size_t len = strGetSize(arg_getStr(obj)); + if (start_i < 0) { + start_i += len; + } + if (end_i < 0) { + end_i += len + 1; + } + Arg* sliced_arg = arg_setStr(NULL, "", ""); + for (int i = start_i; i < end_i; i++) { + Arg* i_arg = arg_setInt(NULL, "", i); + Arg* item_arg = __vm_get(self, i_arg, obj); + sliced_arg = arg_strAppend(sliced_arg, arg_getStr(item_arg)); + arg_deinit(item_arg); + arg_deinit(i_arg); + } + return sliced_arg; + } + + if (ARG_TYPE_BYTES == arg_getType(obj)) { + size_t len = arg_getBytesSize(obj); + if (start_i < 0) { + start_i += len; + } + if (end_i < 0) { + end_i += len + 1; + } + Arg* sliced_arg = arg_setBytes(NULL, "", NULL, 0); + for (int i = start_i; i < end_i; i++) { + Arg* i_arg = arg_setInt(NULL, "", i); + Arg* item_arg = __vm_get(self, i_arg, obj); + uint8_t* bytes_origin = arg_getBytes(sliced_arg); + size_t size_origin = arg_getBytesSize(sliced_arg); + Arg* sliced_arg_new = arg_setBytes(NULL, "", NULL, size_origin + 1); + __platform_memcpy(arg_getBytes(sliced_arg_new), bytes_origin, + size_origin); + __platform_memcpy(arg_getBytes(sliced_arg_new) + size_origin, + arg_getBytes(item_arg), 1); + arg_deinit(sliced_arg); + sliced_arg = sliced_arg_new; + arg_deinit(item_arg); + arg_deinit(i_arg); + } + return sliced_arg; + } + return arg_setNull(NULL); +#else + return __vm_get(self, start, obj); +#endif +} + +static Arg* VM_instruction_handler_SLC(PikaObj* self, VMState* vs, char* data) { + int arg_num_input = VMState_getInputArgNum(vs); + if (arg_num_input < 2) { + return arg_setNull(NULL); + } + if (arg_num_input == 2) { + Arg* key = stack_popArg(&vs->stack); + Arg* obj = stack_popArg(&vs->stack); + Arg* res = __vm_get(self, key, obj); + arg_deinit(key); + arg_deinit(obj); + return res; + } + if (arg_num_input == 3) { + Arg* end = stack_popArg(&vs->stack); + Arg* start = stack_popArg(&vs->stack); + Arg* obj = stack_popArg(&vs->stack); + Arg* res = __vm_slice(self, end, obj, start, 1); + arg_deinit(end); + arg_deinit(obj); + arg_deinit(start); + return res; + } + return arg_setNull(NULL); +} + static Arg* VM_instruction_handler_TRY(PikaObj* self, VMState* vs, char* data) { pika_assert(NULL != vs->try_info); vs->try_info->try_state = TRY_STATE_TOP; diff --git a/src/PikaVM.h b/src/PikaVM.h index 4836b4178..f9f1e7358 100644 --- a/src/PikaVM.h +++ b/src/PikaVM.h @@ -162,5 +162,7 @@ InstructUnit* instructArray_getNext(InstructArray* self); VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename); Arg* obj_runMethodArg(PikaObj* self, PikaObj* method_args_obj, Arg* method_arg); PikaObj* pikaVM_runFile(PikaObj* self, char* file_name); +Arg* __vm_slice(PikaObj* self, Arg* end, Arg* obj, Arg* start, int step); +Arg* __vm_get(PikaObj* self, Arg* key, Arg* obj); #endif diff --git a/src/__instruction_table.cfg b/src/__instruction_table.cfg index 770fb668d..b52d5c936 100644 --- a/src/__instruction_table.cfg +++ b/src/__instruction_table.cfg @@ -88,3 +88,5 @@ def_ins(GER) def_ins(SER) /* dict */ def_ins(DCT) +/* slice */ +def_ins(SLC) diff --git a/src/dataStrs.c b/src/dataStrs.c index 8a14a1416..381b7f22f 100644 --- a/src/dataStrs.c +++ b/src/dataStrs.c @@ -107,6 +107,13 @@ char* strsCopy(Args* buffs_p, char* source) { return strCopy(buff, source); } +char* strsCacheArg(Args* buffs_p, Arg* arg) { + pika_assert(arg != NULL); + char* res = strsCopy(buffs_p, arg_getStr(arg)); + arg_deinit(arg); + return res; +} + char* strsFormat(Args* buffs_p, uint16_t buffSize, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -117,7 +124,7 @@ char* strsFormat(Args* buffs_p, uint16_t buffSize, const char* fmt, ...) { } Arg* arg_strAppend(Arg* arg_in, char* str_to_append) { - pika_assert(NULL!=str_to_append); + pika_assert(NULL != str_to_append); Args buffs = {0}; char* str_out = strsAppend(&buffs, arg_getStr(arg_in), str_to_append); Arg* arg_out = arg_setStr(arg_in, "", str_out); diff --git a/src/dataStrs.h b/src/dataStrs.h index 40e369055..df8d8df28 100644 --- a/src/dataStrs.h +++ b/src/dataStrs.h @@ -43,4 +43,5 @@ Arg* arg_strAppend(Arg* arg_in, char* str_to_append); char* strsReplace(Args* buffs, char* orig, char* rep, char* with); char* strsGetLine(Args* buffs, char* code); void strsDeinit(Args* buffs); +char* strsCacheArg(Args* buffs_p, Arg* arg); #endif