Browse Source

!109 default
* add callback test
* def test(a=1, b='test') for default is ok
* getNodeAttr

李昂 3 years ago
parent
commit
55801b28f5

+ 22 - 0
examples/Callback/test1.py

@@ -0,0 +1,22 @@
+class Demo():
+    def __init__(self):
+        print("__init__")
+        self.funcs = []
+        self.funcs.append(self.a)
+        self.funcs.append(self.b)
+
+    def a(self):
+        print('a')
+
+    def b(self):
+        print('b')
+
+    def get_funcs(self):
+        return self.funcs
+
+
+demo = Demo()
+funcs = demo.get_funcs()
+print('----------------------------')
+for func in funcs:
+    func()

+ 30 - 0
examples/Callback/test2.py

@@ -0,0 +1,30 @@
+
+
+class Demo():
+    def __init__(self):
+        print("__init__")
+        self.funcs = []
+        self.funcs.append(self.a)
+        self.funcs.append(self.b)
+
+
+    def a(self):
+        print('a')
+
+    def b(self):
+        print('b')
+
+    def get_funcs(self):
+        return self.funcs
+
+class Test():
+    def funcs_test(self):
+        demo = Demo()
+        funcs = demo.get_funcs()
+        print('----------------------------')
+        for func in funcs:
+            func()
+
+test = Test()
+test.funcs_test()
+

+ 1 - 1
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=VM.run_def_add"
+                // "--gtest_filter=parser.default_fn_1"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 40 - 1
port/linux/test/VM-test.cpp

@@ -1273,4 +1273,43 @@ TEST(vm, vars_keyward) {
     obj_deinit(pikaMain);
     EXPECT_EQ(pikaMemNow(), 0);
 }
-#endif
+
+TEST(vm, cb_1) {
+    /* init */
+    pikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    extern unsigned char pikaModules_py_a[];
+    obj_linkLibrary(pikaMain, pikaModules_py_a);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    pikaVM_runSingleFile(pikaMain, "../../examples/Callback/test1.py");
+    /* collect */
+    /* assert */
+    EXPECT_STREQ(log_buff[3], "__init__\r\n");
+    EXPECT_STREQ(log_buff[1], "a\r\n");
+    EXPECT_STREQ(log_buff[0], "b\r\n");
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
+TEST(vm, cb_2) {
+    /* init */
+    pikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    extern unsigned char pikaModules_py_a[];
+    obj_linkLibrary(pikaMain, pikaModules_py_a);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    pikaVM_runSingleFile(pikaMain, "../../examples/Callback/test2.py");
+    /* collect */
+    /* assert */
+    EXPECT_STREQ(log_buff[3], "__init__\r\n");
+    EXPECT_STREQ(log_buff[1], "a\r\n");
+    EXPECT_STREQ(log_buff[0], "b\r\n");
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
+#endif

+ 12 - 4
port/linux/test/parse-test.cpp

@@ -4079,11 +4079,11 @@ TEST(parser, except_dict) {
 }
 #endif
 
-TEST(parser, defulat_fn_1) {
+TEST(parser, default_fn_1) {
     pikaMemInfo.heapUsedMax = 0;
     Args* buffs = New_strBuff();
     char* lines =
-        "def test(a=1):\n"
+        "def test(a=1, b='test'):\n"
         "    print(a)";
 
     __platform_printf("%s\n", lines);
@@ -4091,14 +4091,22 @@ TEST(parser, defulat_fn_1) {
     __platform_printf("%s", pikaAsm);
     EXPECT_STREQ(pikaAsm,
                  "B0\n"
-                 "0 DEF test(a=)\n"
+                 "0 DEF test(a=,b=)\n"
                  "0 JMP 1\n"
                  "B1\n"
+                 "0 NUM 1\n"
+                 "0 OUT a\n"
+                 "B1\n"
+                 "0 STR test\n"
+                 "0 OUT b\n"
+                 "B1\n"
                  "1 REF a\n"
                  "0 RUN print\n"
                  "B1\n"
                  "0 RET \n"
-                 "B0\n");
+                 "B0\n"
+
+    );
     args_deinit(buffs);
     EXPECT_EQ(pikaMemNow(), 0);
 }

+ 52 - 14
src/PikaParser.c

@@ -1263,8 +1263,12 @@ exit:
     return is_left_exist;
 }
 
-PIKA_RES AST_setNodeAttr(AST* ast, char* node_type, char* node_content) {
-    return obj_setStr(ast, node_type, node_content);
+PIKA_RES AST_setNodeAttr(AST* ast, char* attr_name, char* attr_val) {
+    return obj_setStr(ast, attr_name, attr_val);
+}
+
+char* AST_getNodeAttr(AST* ast, char* attr_name) {
+    return obj_getStr(ast, attr_name);
 }
 
 PIKA_RES AST_setNodeBlock(AST* ast, char* node_content) {
@@ -1690,7 +1694,9 @@ const char control_keywords[][9] = {"break", "continue"};
 /* normal keyward */
 const char normal_keywords[][7] = {"while", "if", "elif"};
 
-AST* AST_parseLine(char* line, Stack* block_stack) {
+AST* AST_parseLine_withBlockStack_withBlockDeepth(char* line,
+                                                  Stack* block_stack,
+                                                  int block_deepth) {
     Stack s;
     stack_init(&s);
     if (block_stack == NULL) {
@@ -1716,10 +1722,11 @@ AST* AST_parseLine(char* line, Stack* block_stack) {
         ast = NULL;
         goto exit;
     }
+    block_deepth_now += block_deepth;
     obj_setInt(ast, "blockDeepth", block_deepth_now);
 
     /* check if exit block */
-    block_deepth_last = stack_getTop(block_stack);
+    block_deepth_last = stack_getTop(block_stack) + block_deepth;
     /* exit each block */
     for (int i = 0; i < block_deepth_last - block_deepth_now; i++) {
         QueueObj* exit_block_queue = obj_getObj(ast, "exitBlock");
@@ -1735,7 +1742,7 @@ AST* AST_parseLine(char* line, Stack* block_stack) {
         queueObj_pushStr(exit_block_queue, block_type);
     }
 
-    line_start = line + block_deepth_now * 4;
+    line_start = line + (block_deepth_now - block_deepth) * 4;
     stmt = line_start;
 
     // "while" "if" "elif"
@@ -1894,7 +1901,7 @@ AST* AST_parseLine(char* line, Stack* block_stack) {
         char* defaultStmt = _defGetDefault(&buffs, &declare);
         AST_setNodeBlock(ast, "def");
         AST_setNodeAttr(ast, "declare", declare);
-        if(defaultStmt[0] != '\0'){
+        if (defaultStmt[0] != '\0') {
             AST_setNodeAttr(ast, "default", defaultStmt);
         }
         stack_pushStr(block_stack, "def");
@@ -1930,6 +1937,23 @@ exit:
     return ast;
 }
 
+static AST* AST_parseLine_withBlockStack(char* line, Stack* block_stack) {
+    return AST_parseLine_withBlockStack_withBlockDeepth(line, block_stack, 0);
+}
+
+static AST* AST_parseLine_withBlockDeepth(char* line, int block_deepth) {
+    return AST_parseLine_withBlockStack_withBlockDeepth(line, NULL,
+                                                        block_deepth);
+}
+
+int AST_getBlockDeepthNow(AST* ast) {
+    return obj_getInt(ast, "blockDeepth");
+}
+
+AST* AST_parseLine(char* line) {
+    return AST_parseLine_withBlockStack(line, NULL);
+}
+
 static char* Suger_import(Args* buffs_p, char* line) {
 #if !PIKA_SYNTAX_IMPORT_EX_ENABLE
     return line;
@@ -2071,7 +2095,7 @@ char* Parser_LineToAsm(Args* buffs_p, char* line, Stack* blockStack) {
     for (int i = 0; i < line_num; i++) {
         char* single_line = strsPopToken(buffs_p, line, '\n');
         /* parse tokens to AST */
-        ast = AST_parseLine(single_line, blockStack);
+        ast = AST_parseLine_withBlockStack(single_line, blockStack);
         /* gen ASM from AST */
         if (ASM == NULL) {
             ASM = AST_genAsm(ast, buffs_p);
@@ -2357,9 +2381,9 @@ char* ASM_addBlockDeepth(AST* ast,
                          uint8_t deepthOffset) {
     pikaAsm = strsAppend(buffs_p, pikaAsm, (char*)"B");
     char buff[11];
-    pikaAsm = strsAppend(
-        buffs_p, pikaAsm,
-        fast_itoa(buff, obj_getInt(ast, "blockDeepth") + deepthOffset));
+    pikaAsm =
+        strsAppend(buffs_p, pikaAsm,
+                   fast_itoa(buff, AST_getBlockDeepthNow(ast) + deepthOffset));
     pikaAsm = strsAppend(buffs_p, pikaAsm, (char*)"\n");
     return pikaAsm;
 }
@@ -2436,7 +2460,7 @@ char* AST_genAsm(AST* ast, Args* outBuffs) {
                     ASM_addBlockDeepth(ast, outBuffs, pikaAsm, block_type_num);
                 char _l_x[] = "_lx";
                 char block_deepth_char =
-                    obj_getInt(ast, "blockDeepth") + block_type_num + '0';
+                    AST_getBlockDeepthNow(ast) + block_type_num + '0';
                 _l_x[sizeof(_l_x) - 2] = block_deepth_char;
                 pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 DEL ");
                 pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)_l_x);
@@ -2475,7 +2499,7 @@ char* AST_genAsm(AST* ast, Args* outBuffs) {
         Arg* newAsm_arg = arg_newStr("");
         char _l_x[] = "_lx";
         char block_deepth_char = '0';
-        block_deepth_char += obj_getInt(ast, "blockDeepth");
+        block_deepth_char += AST_getBlockDeepthNow(ast);
         _l_x[sizeof(_l_x) - 2] = block_deepth_char;
         /* init iter */
         /*     get the iter(_l<x>) */
@@ -2517,11 +2541,25 @@ char* AST_genAsm(AST* ast, Args* outBuffs) {
         goto exit;
     }
     if (strEqu(AST_getThisBlock(ast), "def")) {
+        char* defaultStmts = AST_getNodeAttr(ast, "default");
         pikaAsm = strsAppend(&buffs, pikaAsm, "0 DEF ");
-        pikaAsm = strsAppend(&buffs, pikaAsm, obj_getStr(ast, "declare"));
+        pikaAsm = strsAppend(&buffs, pikaAsm, AST_getNodeAttr(ast, "declare"));
         pikaAsm = strsAppend(&buffs, pikaAsm,
                              "\n"
                              "0 JMP 1\n");
+
+        if (NULL != defaultStmts) {
+            int stmt_num = strGetTokenNum(defaultStmts, ',');
+            for (int i = 0; i < stmt_num; i++) {
+                char* stmt = strsPopToken(&buffs, defaultStmts, ',');
+                AST* ast_this = AST_parseLine_withBlockDeepth(
+                    stmt, AST_getBlockDeepthNow(ast) + 1);
+                pikaAsm =
+                    strsAppend(&buffs, pikaAsm, AST_genAsm(ast_this, &buffs));
+                AST_deinit(ast_this);
+            }
+        }
+
         is_block_matched = 1;
         goto exit;
     }
@@ -2552,7 +2590,7 @@ char* AST_genAsm(AST* ast, Args* outBuffs) {
                                         "0 JMP 1\n"));
         char block_deepth_str[] = "B0\n";
         /* goto deeper block */
-        block_deepth_str[1] += obj_getInt(ast, "blockDeepth") + 1;
+        block_deepth_str[1] += AST_getBlockDeepthNow(ast) + 1;
         pikaAsm = strsAppend(&buffs, pikaAsm, block_deepth_str);
         pikaAsm = strsAppend(&buffs, pikaAsm, "0 RUN ");
         pikaAsm = strsAppend(&buffs, pikaAsm, superClass);