Sfoglia il codice sorgente

VM support `l[0]()` nad `test()()` stmt

lyon 2 anni fa
parent
commit
0ff4ecd028
7 ha cambiato i file con 60 aggiunte e 16 eliminazioni
  1. 4 3
      port/linux/.vscode/launch.json
  2. 3 0
      src/PikaObj.c
  3. 13 1
      src/PikaParser.c
  4. 14 6
      src/PikaVM.c
  5. 1 1
      test/VM-test.cpp
  6. 21 2
      test/parse-test.cpp
  7. 4 3
      test/python/builtin/fn_fn.py

+ 4 - 3
port/linux/.vscode/launch.json

@@ -23,9 +23,10 @@
                 // "--gtest_filter=vm.var_global_run"
                 // "--gtest_filter=lua.eval"
                 // "--gtest_filter=eventloop.once1"
-                "--gtest_filter=parser.fn_fn"
-                // "--gtest_filter=parser.slice_slice"
-                // "--gtest_filter=parser.page_add"
+                // "--gtest_filter=parser.fn_fn"
+                // "--gtest_filter=vm.fn_fn"
+                // "--gtest_filter=VM.run_def_add"
+                "--gtest_filter=parser.slice_fn"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 3 - 0
src/PikaObj.c

@@ -889,6 +889,9 @@ static PikaObj* _obj_getObjWithKeepDeepth(PikaObj* self,
     char objPath_buff[PIKA_PATH_BUFF_SIZE];
     char* objPath_ptr = objPath_buff;
     pika_assert(NULL != objPath);
+    if ('.' == objPath[0] && '\0' == objPath[1]) {
+        return self;
+    }
     strcpy(objPath_buff, objPath);
     int32_t token_num = strGetTokenNum(objPath, '.');
     PikaObj* obj = self;

+ 13 - 1
src/PikaParser.c

@@ -214,6 +214,7 @@ static enum StmtType Lexer_matchStmtType(char* right) {
         if (strEqu(cs.token1.pyload, "[") && cs.iter_index == 1) {
             /* VOID + <[> */
             is_get_list = PIKA_TRUE;
+            is_get_method = PIKA_FALSE;
             goto iter_continue;
         }
         if (strEqu(cs.token1.pyload, "...")) {
@@ -243,6 +244,7 @@ static enum StmtType Lexer_matchStmtType(char* right) {
         /* <(> */
         if (strEqu(cs.token1.pyload, "(")) {
             is_get_method = PIKA_TRUE;
+            is_get_slice = PIKA_FALSE;
             goto iter_continue;
         }
         if (cs.token1.type == TOKEN_literal) {
@@ -1818,9 +1820,19 @@ AST* AST_parseStmt(AST* ast, char* stmt) {
         char* methodstmt = strsCopy(&buffs, right);
         char* laststmt = methodstmt;
         /* for method()() */
-        if (_Cursor_count(methodstmt, TOKEN_devider, "(", PIKA_TRUE) > 1) {
+        int iBracketNum =
+            _Cursor_count(methodstmt, TOKEN_devider, "(", PIKA_TRUE) +
+            _Cursor_count(methodstmt, TOKEN_devider, "[", PIKA_TRUE);
+        if (iBracketNum > 1) {
             laststmt =
                 _Parser_popLastSubStmt(&buffs, &methodstmt, "(", PIKA_FALSE);
+            /* for (...) */
+            if (_Cursor_count(laststmt, TOKEN_devider, "(", PIKA_FALSE) == 1) {
+                char* sMethodCheck = strsGetFirstToken(&buffs, laststmt, '(');
+                if (strEqu(sMethodCheck, "")) {
+                    laststmt = strsAppend(&buffs, ".", laststmt);
+                }
+            }
             AST_parseSubStmt(ast, methodstmt);
         }
         sMethod = strsGetFirstToken(&buffs, laststmt, '(');

+ 14 - 6
src/PikaVM.c

@@ -1804,7 +1804,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
     PikaObj* oMethodHost = NULL;
     PikaObj* oThis = NULL;
     Arg* aMethod = NULL;
-    Arg* aHost = NULL;
+    Arg* aStack = NULL;
     PIKA_BOOL bIsTemp = PIKA_FALSE;
     PIKA_BOOL bSkipInit = PIKA_FALSE;
     char* sSysOut;
@@ -1880,9 +1880,17 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
         for (int i = 0; i < n_arg; i++) {
             stack_tmp[i] = stack_popArg_alloc(&(vm->stack));
         }
-        aHost = stack_tmp[n_arg - 1];
-        oMethodHost = _arg_to_obj(aHost, &bIsTemp);
-        if (NULL != oMethodHost) {
+        aStack = stack_tmp[n_arg - 1];
+        if (sRunPath[1] == '\0') {
+            /* for .(...) */
+            aMethod = aStack;
+            pika_assert(arg_isCallable(aMethod));
+        } else {
+            /* for .xxx(...) */
+            oMethodHost = _arg_to_obj(aStack, &bIsTemp);
+            pika_assert(NULL != oMethodHost);
+        }
+        if (NULL != aStack) {
             iNumUsed++;
         }
         /* push back other args to stack */
@@ -2067,8 +2075,8 @@ exit:
 #endif
         obj_deinit(oSublocals);
     }
-    if (NULL != aHost) {
-        arg_deinit(aHost);
+    if (NULL != aStack && aMethod != aStack) {
+        arg_deinit(aStack);
     }
     if (NULL != oMethodHost && bIsTemp) {
         /* class method */

+ 1 - 1
test/VM-test.cpp

@@ -2869,7 +2869,7 @@ 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")
+TEST_RUN_SINGLE_FILE_PASS(vm, fn_fn, "test/python/builtin/fn_fn.py")
 
 #endif
 

+ 21 - 2
test/parse-test.cpp

@@ -5652,10 +5652,29 @@ TEST_LINES2ASM(fn_fn,
                "test()()",
                "B0\n"
                "1 RUN test\n"
-               "0 RUN \n"
+               "0 RUN .\n"
                "B0\n")
 
-TEST_LINES2ASM_NOCHECK(slice_slice, "test[1][2][3]")
+TEST_LINES2ASM(slice_slice,
+               "test[1][2][3]",
+               "B0\n"
+               "3 REF test\n"
+               "3 NUM 1\n"
+               "2 SLC \n"
+               "2 NUM 2\n"
+               "1 SLC \n"
+               "1 NUM 3\n"
+               "0 SLC \n"
+               "B0\n")
+
+TEST_LINES2ASM(slice_fn,
+               "l[0]()",
+               "B0\n"
+               "2 REF l\n"
+               "2 NUM 0\n"
+               "1 SLC \n"
+               "0 RUN .\n"
+               "B0\n")
 
 #endif
 

+ 4 - 3
test/python/builtin/fn_fn.py

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