From 55801b28f5e120d2fb9213577a7a1d2fe1a8fefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Fri, 2 Sep 2022 11:25:32 +0000 Subject: [PATCH] !109 default * add callback test * def test(a=1, b='test') for default is ok * getNodeAttr --- examples/Callback/test1.py | 22 ++++++++++++ examples/Callback/test2.py | 30 ++++++++++++++++ port/linux/.vscode/launch.json | 2 +- port/linux/test/VM-test.cpp | 41 ++++++++++++++++++++- port/linux/test/parse-test.cpp | 16 ++++++--- src/PikaParser.c | 66 ++++++++++++++++++++++++++-------- 6 files changed, 157 insertions(+), 20 deletions(-) create mode 100644 examples/Callback/test1.py create mode 100644 examples/Callback/test2.py diff --git a/examples/Callback/test1.py b/examples/Callback/test1.py new file mode 100644 index 000000000..c610acf2c --- /dev/null +++ b/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() diff --git a/examples/Callback/test2.py b/examples/Callback/test2.py new file mode 100644 index 000000000..cd2bc3ea6 --- /dev/null +++ b/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() + diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index d279ff093..b30180de0 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=VM.run_def_add" + // "--gtest_filter=parser.default_fn_1" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/test/VM-test.cpp b/port/linux/test/VM-test.cpp index d3f333062..67793018b 100644 --- a/port/linux/test/VM-test.cpp +++ b/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 \ No newline at end of file diff --git a/port/linux/test/parse-test.cpp b/port/linux/test/parse-test.cpp index 343e03ffd..728a351c1 100644 --- a/port/linux/test/parse-test.cpp +++ b/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); } diff --git a/src/PikaParser.c b/src/PikaParser.c index a2655c648..729be30b4 100644 --- a/src/PikaParser.c +++ b/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) */ @@ -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);