Browse Source

support parse for 'test()()' and 'test[]()'

lyon 2 years ago
parent
commit
fa97fbb788
6 changed files with 108 additions and 39 deletions
  1. 4 1
      port/linux/.vscode/launch.json
  2. 81 33
      src/PikaParser.c
  3. 2 2
      src/PikaParser.h
  4. 2 0
      test/VM-test.cpp
  5. 7 3
      test/parse-test.cpp
  6. 12 0
      test/python/builtin/fn_fn.py

+ 4 - 1
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}",

+ 81 - 33
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;
         }

+ 2 - 2
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);

+ 2 - 0
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

+ 7 - 3
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

+ 12 - 0
test/python/builtin/fn_fn.py

@@ -0,0 +1,12 @@
+
+
+def test1():
+    print("test1")
+
+def test():
+    return test1
+
+l = [test1]
+
+l[0]()
+test()()