diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 5e3e46300..64545a91a 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=socket.thread" + // "--gtest_filter=parser.def_add" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaParser.c b/src/PikaParser.c index deb9dd081..69c0fac1f 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -1013,7 +1013,7 @@ char* Cursor_popToken(Args* buffs, char** pStmt, char* devide) { } char* Cursor_splitCollect(Args* buffs, char* stmt, char* devide, int index) { - Arg* out_arg = arg_newStr(""); + Arg* aOut = arg_newStr(""); int expect_branket = 0; if (devide[0] == '(' || devide[0] == '[' || devide[0] == '{') { expect_branket = 1; @@ -1024,18 +1024,21 @@ char* Cursor_splitCollect(Args* buffs, char* stmt, char* devide, int index) { if (cs.branket_deepth == expect_branket && strEqu(cs.token1.pyload, devide)) { i++; - if (i == index) { - Cursor_iterEnd(&cs); - break; - } + Cursor_iterEnd(&cs); + continue; } if (i == index) { - out_arg = arg_strAppend(out_arg, cs.token1.pyload); + aOut = arg_strAppend(aOut, cs.token1.pyload); } Cursor_iterEnd(&cs); } Cursor_deinit(&cs); - return strsCacheArg(buffs, out_arg); + /* if not found, return origin string */ + if (i == 0) { + arg_deinit(aOut); + aOut = arg_newStr(stmt); + } + return strsCacheArg(buffs, aOut); } static void Slice_getPars(Args* outBuffs, @@ -1654,7 +1657,8 @@ AST* AST_parseStmt(AST* ast, char* stmt) { /* set left */ if (isLeftExist) { - AST_setNodeAttr(ast, (char*)"left", left); + char* left_without_hint = Cursor_splitCollect(&buffs, left, ":", 0); + AST_setNodeAttr(ast, (char*)"left", left_without_hint); } /* match statment type */ enum StmtType stmtType = Lexer_matchStmtType(right); @@ -1835,43 +1839,52 @@ char* Parser_removeAnnotation(char* line) { return line; } -char* _defGetDefault(Args* outBuffs, char** dec_out) { +char* _defGetDefault(Args* outBuffs, char** psDeclearOut) { #if PIKA_NANO_ENABLE return ""; #endif Args buffs = {0}; - char* dec_str = strsCopy(&buffs, *dec_out); - char* fn_name = strsGetFirstToken(&buffs, dec_str, '('); - Arg* dec_arg = arg_strAppend(arg_newStr(fn_name), "("); - Arg* default_arg = arg_newStr(""); - char* arg_list = strsCut(&buffs, dec_str, '(', ')'); - char* default_out = NULL; - pika_assert(NULL != arg_list); - int arg_num = strCountSign(arg_list, ',') + 1; - for (int i = 0; i < arg_num; i++) { - char* arg_str = strsPopToken(&buffs, &arg_list, ','); + char* sDeclear = strsCopy(&buffs, *psDeclearOut); + char* sFnName = strsGetFirstToken(&buffs, sDeclear, '('); + Arg* aDeclear = arg_strAppend(arg_newStr(sFnName), "("); + Arg* aDefault = arg_newStr(""); + char* sArgList = strsCut(&buffs, sDeclear, '(', ')'); + char* sDefaultOut = NULL; + pika_assert(NULL != sArgList); + int argNum = strCountSign(sArgList, ',') + 1; + for (int i = 0; i < argNum; i++) { + char* sItem = strsPopToken(&buffs, &sArgList, ','); + char* sDefaultVal = NULL; + char* sDefaultKey = NULL; int is_default = 0; - if (strIsContain(arg_str, '=')) { - default_arg = arg_strAppend(default_arg, arg_str); - default_arg = arg_strAppend(default_arg, ","); - arg_str = strsPopToken(&buffs, &arg_str, '='); + if (strIsContain(sItem, '=')) { + /* has default value */ + sDefaultVal = Cursor_splitCollect(&buffs, sItem, "=", 1); + sDefaultKey = Cursor_splitCollect(&buffs, sItem, "=", 0); + sDefaultKey = Cursor_splitCollect(&buffs, sDefaultKey, ":", 0); + aDefault = arg_strAppend(aDefault, sDefaultKey); + aDefault = arg_strAppend(aDefault, "="); + aDefault = arg_strAppend(aDefault, sDefaultVal); + aDefault = arg_strAppend(aDefault, ","); is_default = 1; + } else { + sDefaultKey = sItem; } - dec_arg = arg_strAppend(dec_arg, arg_str); + aDeclear = arg_strAppend(aDeclear, sDefaultKey); if (is_default) { - dec_arg = arg_strAppend(dec_arg, "="); + aDeclear = arg_strAppend(aDeclear, "="); } - dec_arg = arg_strAppend(dec_arg, ","); + aDeclear = arg_strAppend(aDeclear, ","); } - strPopLastToken(arg_getStr(dec_arg), ','); - dec_arg = arg_strAppend(dec_arg, ")"); - *dec_out = strsCopy(outBuffs, arg_getStr(dec_arg)); - default_out = strsCopy(outBuffs, arg_getStr(default_arg)); - strPopLastToken(default_out, ','); - arg_deinit(dec_arg); - arg_deinit(default_arg); + strPopLastToken(arg_getStr(aDeclear), ','); + aDeclear = arg_strAppend(aDeclear, ")"); + *psDeclearOut = strsCopy(outBuffs, arg_getStr(aDeclear)); + sDefaultOut = strsCopy(outBuffs, arg_getStr(aDefault)); + strPopLastToken(sDefaultOut, ','); + arg_deinit(aDeclear); + arg_deinit(aDefault); strsDeinit(&buffs); - return default_out; + return sDefaultOut; } static char* Suger_multiReturn(Args* out_buffs, char* line) { diff --git a/test/parse-test.cpp b/test/parse-test.cpp index 831d1b70b..3054fdac7 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -3230,7 +3230,6 @@ TEST(parser, try1) { EXPECT_EQ(pikaMemNow(), 0); } - TEST(parser, except_issue) { pikaMemInfo.heapUsedMax = 0; Args* buffs = New_strBuff(); @@ -4226,6 +4225,42 @@ TEST(parser, default_fn_1) { args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); } + +TEST(parser, default_fn_1_hint) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = + "def test(a:int =1, b:str ='test'):\n" + " print(a)"; + + __platform_printf("%s\n", lines); + char* pikaAsm = Parser_linesToAsm(buffs, lines); + __platform_printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "0 DEF test(a=,b=)\n" + "0 JMP 1\n" + "B1\n" + "0 EST a\n" + "0 JNZ 2\n" + "B1\n" + "0 NUM 1\n" + "0 OUT a\n" + "B1\n" + "0 EST b\n" + "0 JNZ 2\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"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} #endif #if !PIKA_NANO_ENABLE @@ -5282,6 +5317,27 @@ TEST(parser, page_add) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(parser, hint_assign) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = + "a:int = 1\n" + "d:{str:int} = {}\n"; + printf("%s\r\n", lines); + char* pikaAsm = Parser_linesToAsm(buffs, lines); + printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "0 NUM 1\n" + "0 OUT a\n" + "B0\n" + "0 DCT \n" + "0 OUT d\n" + "B0\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif TEST_END \ No newline at end of file