From fa97fbb788c62013c0c06df73bd4cad41c4db4f2 Mon Sep 17 00:00:00 2001 From: lyon Date: Thu, 18 May 2023 23:15:33 +0800 Subject: [PATCH] support parse for 'test()()' and 'test[]()' --- port/linux/.vscode/launch.json | 5 +- src/PikaParser.c | 114 +++++++++++++++++++++++---------- src/PikaParser.h | 4 +- test/VM-test.cpp | 2 + test/parse-test.cpp | 10 ++- test/python/builtin/fn_fn.py | 12 ++++ 6 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 test/python/builtin/fn_fn.py diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 453023ed5..887764b0e 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -22,7 +22,10 @@ // "--gtest_filter=parser.split_slice" // "--gtest_filter=vm.var_global_run" // "--gtest_filter=lua.eval" - "--gtest_filter=eventloop.once1" + // "--gtest_filter=eventloop.once1" + "--gtest_filter=parser.fn_fn" + // "--gtest_filter=parser.slice_slice" + // "--gtest_filter=parser.page_add" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaParser.c b/src/PikaParser.c index 1171cdbcd..6c7a284ea 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -73,7 +73,7 @@ char* Cursor_popLastToken(Args* outBuffs, char** pStmt, char* str) { Arg* poped_arg = arg_newStr(""); Cursor_forEach(cs, stmts) { Cursor_iterStart(&cs); - if (cs.branket_deepth == 0) { + if (cs.bracket_deepth == 0) { if (strEqu(str, cs.token1.pyload)) { divider_index = cs.iter_index; } @@ -903,22 +903,22 @@ void Cursor_iterStart(struct Cursor* cs) { LexToken_update(&cs->token1); LexToken_update(&cs->token2); if (strEqu(cs->token1.pyload, "(")) { - cs->branket_deepth++; + cs->bracket_deepth++; } if (strEqu(cs->token1.pyload, ")")) { - cs->branket_deepth--; + cs->bracket_deepth--; } if (strEqu(cs->token1.pyload, "[")) { - cs->branket_deepth++; + cs->bracket_deepth++; } if (strEqu(cs->token1.pyload, "]")) { - cs->branket_deepth--; + cs->bracket_deepth--; } if (strEqu(cs->token1.pyload, "{")) { - cs->branket_deepth++; + cs->bracket_deepth++; } if (strEqu(cs->token1.pyload, "}")) { - cs->branket_deepth--; + cs->bracket_deepth--; } } @@ -932,7 +932,7 @@ void _Cursor_init(struct Cursor* cs) { cs->tokenStream = NULL; cs->length = 0; cs->iter_index = 0; - cs->branket_deepth = 0; + cs->bracket_deepth = 0; cs->last_token = NULL; cs->iter_buffs = NULL; cs->buffs_p = New_strBuff(); @@ -974,10 +974,36 @@ void _Cursor_beforeIter(struct Cursor* cs) { cs->last_token = arg_newStr(TokenStream_pop(cs->buffs_p, &cs->tokenStream)); } +uint8_t Token_isBranketStart(LexToken* token) { + if (token->type != TOKEN_devider) { + return PIKA_FALSE; + } + if (strEqu(token->pyload, "(") || strEqu(token->pyload, "[") || + strEqu(token->pyload, "{")) { + return PIKA_TRUE; + } + return PIKA_FALSE; +} + +uint8_t Token_isBranketEnd(LexToken* token) { + if (token->type != TOKEN_devider) { + return PIKA_FALSE; + } + if (strEqu(token->pyload, ")") || strEqu(token->pyload, "]") || + strEqu(token->pyload, "}")) { + return PIKA_TRUE; + } + return PIKA_FALSE; +} + +uint8_t Token_isBranket(LexToken* token) { + return Token_isBranketStart(token) || Token_isBranketEnd(token); +} + uint8_t _Cursor_count(char* stmt, TokenType type, char* pyload, - PIKA_BOOL bSkipBranket) { + PIKA_BOOL bSkipbracket) { /* fast return */ if (!strstr(stmt, pyload)) { return PIKA_FALSE; @@ -987,10 +1013,16 @@ uint8_t _Cursor_count(char* stmt, Cursor_forEach(cs, stmt) { Cursor_iterStart(&cs); if (cs.token1.type == type && (strEqu(cs.token1.pyload, pyload))) { - if (bSkipBranket && cs.branket_deepth > 0) { - /* skip branket */ - Cursor_iterEnd(&cs); - continue; + if (bSkipbracket) { + uint8_t branket_deepth_check = 0; + if (Token_isBranketStart(&cs.token1)) { + branket_deepth_check = 1; + } + if (cs.bracket_deepth > branket_deepth_check) { + /* skip bracket */ + Cursor_iterEnd(&cs); + continue; + } } res++; } @@ -1019,7 +1051,7 @@ char* Cursor_popToken(Args* buffs, char** pStmt, char* devide) { Cursor_forEach(cs, *pStmt) { Cursor_iterStart(&cs); if (!is_find_devide) { - if ((cs.branket_deepth == 0 && strEqu(cs.token1.pyload, devide)) || + if ((cs.bracket_deepth == 0 && strEqu(cs.token1.pyload, devide)) || cs.iter_index == cs.length) { is_find_devide = PIKA_TRUE; Cursor_iterEnd(&cs); @@ -1048,14 +1080,14 @@ char* Cursor_popToken(Args* buffs, char** pStmt, char* devide) { char* Cursor_splitCollect(Args* buffs, char* stmt, char* devide, int index) { Arg* aOut = arg_newStr(""); - int expect_branket = 0; + int expect_bracket = 0; if (devide[0] == '(' || devide[0] == '[' || devide[0] == '{') { - expect_branket = 1; + expect_bracket = 1; } int i = 0; Cursor_forEach(cs, stmt) { Cursor_iterStart(&cs); - if (cs.branket_deepth == expect_branket && + if (cs.bracket_deepth == expect_bracket && strEqu(cs.token1.pyload, devide)) { i++; Cursor_iterEnd(&cs); @@ -1092,7 +1124,7 @@ static void Slice_getPars(Args* outBuffs, uint8_t colon_i = 0; Cursor_forEach(cs, inner) { Cursor_iterStart(&cs); - if (strEqu(cs.token1.pyload, ":") && cs.branket_deepth == 0) { + if (strEqu(cs.token1.pyload, ":") && cs.bracket_deepth == 0) { colon_i++; goto iter_continue1; } @@ -1251,7 +1283,7 @@ char* Suger_format(Args* outBuffs, char* right) { PIKA_BOOL is_format = PIKA_FALSE; Cursor_forEach(ps1, right) { Cursor_iterStart(&ps1); - if (ps1.branket_deepth == 0 && strEqu(ps1.token1.pyload, "%")) { + if (ps1.bracket_deepth == 0 && strEqu(ps1.token1.pyload, "%")) { is_format = PIKA_TRUE; } Cursor_iterEnd(&ps1); @@ -1452,7 +1484,7 @@ char* Parser_popSubStmt(Args* outbuffs, char** psStmt, char* delimiter) { Cursor_iterEnd(&cs); continue; } - if (cs.branket_deepth > 0) { + if (cs.bracket_deepth > 0) { /* ignore */ aSubstmt = arg_strAppend(aSubstmt, cs.token1.pyload); Cursor_iterEnd(&cs); @@ -1485,21 +1517,25 @@ int Parser_getSubStmtNum(char* subStmts, char* delimiter) { return _Cursor_count(subStmts, TOKEN_devider, delimiter, PIKA_TRUE); } -char* Parser_popLastSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { +char* _Parser_popLastSubStmt(Args* outbuffs, + char** stmt_p, + char* delimiter, + PIKA_BOOL bSkipBracket) { uint8_t last_stmt_i = 0; char* stmt = *stmt_p; Cursor_forEach(cs, stmt) { Cursor_iterStart(&cs); if (strIsStartWith(cs.token1.pyload, delimiter)) { /* found delimiter */ - if (!strEqu(delimiter, "[") && cs.branket_deepth > 0) { - /* ignore */ + + if (bSkipBracket && cs.bracket_deepth > 0) { + /* skip bracket */ Cursor_iterEnd(&cs); continue; } /* for "[" */ - if (cs.branket_deepth > 1) { + if (cs.bracket_deepth > 1) { /* ignore */ Cursor_iterEnd(&cs); continue; @@ -1531,6 +1567,10 @@ char* Parser_popLastSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { return strsCacheArg(outbuffs, lastStmt); } +char* Parser_popLastSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { + return _Parser_popLastSubStmt(outbuffs, stmt_p, delimiter, PIKA_TRUE); +} + static void _AST_parse_list(AST* ast, Args* buffs, char* stmt) { #if !PIKA_BUILTIN_STRUCT_ENABLE return; @@ -1573,7 +1613,7 @@ static void _AST_parse_slice(AST* ast, Args* buffs, char* stmt) { #endif AST_setNodeAttr(ast, (char*)"slice", "slice"); stmt = strsCopy(buffs, stmt); - char* laststmt = Parser_popLastSubStmt(buffs, &stmt, "["); + char* laststmt = _Parser_popLastSubStmt(buffs, &stmt, "[", PIKA_FALSE); AST_parseSubStmt(ast, stmt); char* slice_list = strsCut(buffs, laststmt, '[', ']'); pika_assert(slice_list != NULL); @@ -1775,8 +1815,16 @@ AST* AST_parseStmt(AST* ast, char* stmt) { /* solve method stmt */ if (STMT_method == stmtType) { char* sRealType = "method"; - sMethod = strsGetFirstToken(&buffs, right, '('); - char* sSubStmts = strsCut(&buffs, right, '(', ')'); + char* methodstmt = strsCopy(&buffs, right); + char* laststmt = methodstmt; + /* for method()() */ + if (_Cursor_count(methodstmt, TOKEN_devider, "(", PIKA_TRUE) > 1) { + laststmt = + _Parser_popLastSubStmt(&buffs, &methodstmt, "(", PIKA_FALSE); + AST_parseSubStmt(ast, methodstmt); + } + sMethod = strsGetFirstToken(&buffs, laststmt, '('); + char* sSubStmts = strsCut(&buffs, laststmt, '(', ')'); if (NULL == sSubStmts) { result = PIKA_RES_ERR_SYNTAX_ERROR; goto __exit; @@ -1975,7 +2023,7 @@ static char* Suger_multiReturn(Args* out_buffs, char* line) { #endif Cursor_forEach(cs, line) { Cursor_iterStart(&cs); - if (cs.branket_deepth == 0 && strEqu(cs.token1.pyload, ",")) { + if (cs.bracket_deepth == 0 && strEqu(cs.token1.pyload, ",")) { line = strsFormat(out_buffs, strGetSize(line) + 3, "(%s)", line); Cursor_iterEnd(&cs); break; @@ -2307,7 +2355,7 @@ static PIKA_BOOL _check_is_multi_assign(char* arg_list) { PIKA_BOOL res = PIKA_FALSE; Cursor_forEach(cs, arg_list) { Cursor_iterStart(&cs); - if ((cs.branket_deepth == 0 && strEqu(cs.token1.pyload, ","))) { + if ((cs.bracket_deepth == 0 && strEqu(cs.token1.pyload, ","))) { res = PIKA_TRUE; } Cursor_iterEnd(&cs); @@ -2333,7 +2381,7 @@ static char* Suger_multiAssign(Args* out_buffs, char* line) { int out_num = 0; Cursor_forEach(cs, line) { Cursor_iterStart(&cs); - if (cs.branket_deepth == 0 && strEqu(cs.token1.pyload, "=")) { + if (cs.bracket_deepth == 0 && strEqu(cs.token1.pyload, "=")) { is_assign = PIKA_TRUE; Cursor_iterEnd(&cs); continue; @@ -2732,15 +2780,15 @@ char* parser_lines2BackendCode(Parser* self, char* sPyLines) { Cursor_deinit(&c); /* auto connection */ if (uLinesIndex < uLinesNum) { - if (c.branket_deepth > 0) { + if (c.bracket_deepth > 0) { aLineConnection = arg_strAppend(aLineConnection, sLine); bIsLineConnection = 1; goto next_line; } } - /* branket match failed */ - if (c.branket_deepth != 0) { + /* bracket match failed */ + if (c.bracket_deepth != 0) { sBackendCode = NULL; goto parse_after; } diff --git a/src/PikaParser.h b/src/PikaParser.h index da4534024..efb2fd9ab 100644 --- a/src/PikaParser.h +++ b/src/PikaParser.h @@ -112,7 +112,7 @@ struct Cursor { char* tokenStream; uint16_t length; uint16_t iter_index; - int8_t branket_deepth; + int8_t bracket_deepth; struct LexToken token1; struct LexToken token2; Arg* last_token; @@ -148,7 +148,7 @@ uint8_t Cursor_count(char* stmt, TokenType type, char* pyload); uint8_t _Cursor_count(char* stmt, TokenType type, char* pyload, - PIKA_BOOL bSkipBranket); + PIKA_BOOL bSkipbracket); AST* AST_parseStmt(AST* ast, char* stmt); char* AST_genAsm(AST* oAST, Args* outBuffs); diff --git a/test/VM-test.cpp b/test/VM-test.cpp index 5ef453211..9162d43c5 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2869,6 +2869,8 @@ TEST_RUN_LINES(vm, TEST_RUN_LINES(vm, import_void, "import \n") +TEST_RUN_SINGLE_FILE(vm, fn_fn, "test/python/builtin/fn_fn.py") + #endif TEST_END \ No newline at end of file diff --git a/test/parse-test.cpp b/test/parse-test.cpp index 34f619f70..36fdb9f20 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -3572,7 +3572,7 @@ TEST(parser, num_issue) { } #if PIKA_SYNTAX_SLICE_ENABLE -TEST(parser, branket_issue2) { +TEST(parser, bracket_issue2) { g_PikaMemInfo.heapUsedMax = 0; Args* buffs = New_strBuff(); char* lines = "temp = hex(int('12'))[0:2]\n"; @@ -3595,7 +3595,7 @@ TEST(parser, branket_issue2) { #endif #if PIKA_SYNTAX_SLICE_ENABLE -TEST(parser, branket_issue3) { +TEST(parser, bracket_issue3) { g_PikaMemInfo.heapUsedMax = 0; Args* buffs = New_strBuff(); char* lines = "a = b[x][y]\n"; @@ -3617,7 +3617,7 @@ TEST(parser, branket_issue3) { #endif #if PIKA_SYNTAX_SLICE_ENABLE -TEST(parser, branket_issue4) { +TEST(parser, bracket_issue4) { g_PikaMemInfo.heapUsedMax = 0; Args* buffs = New_strBuff(); char* lines = "a = b[c[y]]\n"; @@ -5648,6 +5648,10 @@ TEST_LINES2ASM(split_slice, TEST_LINES2ASM(val_hint, "a:int", "B0\nB0\n") +TEST_LINES2ASM_NOCHECK(fn_fn, "test()()") + +TEST_LINES2ASM_NOCHECK(slice_slice, "test[1][2][3]") + #endif TEST_END \ No newline at end of file diff --git a/test/python/builtin/fn_fn.py b/test/python/builtin/fn_fn.py new file mode 100644 index 000000000..f47f5b688 --- /dev/null +++ b/test/python/builtin/fn_fn.py @@ -0,0 +1,12 @@ + + +def test1(): + print("test1") + +def test(): + return test1 + +l = [test1] + +l[0]() +test()()