diff --git a/examples/BuiltIn/print.py b/examples/BuiltIn/print.py new file mode 100644 index 000000000..94b2b56ab --- /dev/null +++ b/examples/BuiltIn/print.py @@ -0,0 +1,6 @@ +import PikaStdLib + +print('test') +print('my name is', 'old wang', 'my age is', 43) +print('format: %s,%04d,%.2f' % ('test', 123, 15.5)) + diff --git a/package/PikaStdLib/PikaStdLib.pyi b/package/PikaStdLib/PikaStdLib.pyi index b35f92a04..69d961341 100644 --- a/package/PikaStdLib/PikaStdLib.pyi +++ b/package/PikaStdLib/PikaStdLib.pyi @@ -29,6 +29,7 @@ class SysObj(BaseObj): def ord(self, val: str) -> int: ... def chr(self, val: int) -> str: ... def bytes(self, val: any) -> bytes: ... + def cformat(self, fmt: str, *var) -> str: ... class RangeObj(TinyObj): diff --git a/package/PikaStdLib/PikaStdLib_SysObj.c b/package/PikaStdLib/PikaStdLib_SysObj.c index 4307d37a6..0b88e602b 100644 --- a/package/PikaStdLib/PikaStdLib_SysObj.c +++ b/package/PikaStdLib/PikaStdLib_SysObj.c @@ -1,6 +1,7 @@ -#include "BaseObj.h" +#include "PikaStdLib_SysObj.h" #include "PikaStdLib_RangeObj.h" #include "PikaStdLib_StringObj.h" +#include "PikaVM.h" #include "dataStrs.h" void PikaStdLib_SysObj_remove(PikaObj* self, char* argPath) { @@ -487,3 +488,13 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) { __platform_printf("%s", res); args_deinit(print_args); } + +char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { + Args buffs = {0}; + pikaMemMaxReset(); + char* res = strsFormatList(&buffs, fmt, &var->super); + obj_setStr(self, "_buf", res); + res = obj_getStr(self, "_buf"); + strsDeinit(&buffs); + return res; +} diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 7a4bd9c06..61f814778 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=pikaMain.def_args_err" + // "--gtest_filter=string.format2" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/package/pikascript/PikaStdLib.pyi b/port/linux/package/pikascript/PikaStdLib.pyi index b35f92a04..69d961341 100644 --- a/port/linux/package/pikascript/PikaStdLib.pyi +++ b/port/linux/package/pikascript/PikaStdLib.pyi @@ -29,6 +29,7 @@ class SysObj(BaseObj): def ord(self, val: str) -> int: ... def chr(self, val: int) -> str: ... def bytes(self, val: any) -> bytes: ... + def cformat(self, fmt: str, *var) -> str: ... class RangeObj(TinyObj): diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c index 4307d37a6..0b88e602b 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -1,6 +1,7 @@ -#include "BaseObj.h" +#include "PikaStdLib_SysObj.h" #include "PikaStdLib_RangeObj.h" #include "PikaStdLib_StringObj.h" +#include "PikaVM.h" #include "dataStrs.h" void PikaStdLib_SysObj_remove(PikaObj* self, char* argPath) { @@ -487,3 +488,13 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) { __platform_printf("%s", res); args_deinit(print_args); } + +char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { + Args buffs = {0}; + pikaMemMaxReset(); + char* res = strsFormatList(&buffs, fmt, &var->super); + obj_setStr(self, "_buf", res); + res = obj_getStr(self, "_buf"); + strsDeinit(&buffs); + return res; +} diff --git a/port/linux/test/VM-test.cpp b/port/linux/test/VM-test.cpp index 724994102..034d9d217 100644 --- a/port/linux/test/VM-test.cpp +++ b/port/linux/test/VM-test.cpp @@ -1,16 +1,6 @@ -#include "gtest/gtest.h" #include "test_common.h" + extern "C" { -#include "BaseObj.h" -#include "PikaMain.h" -#include "PikaMath_Operator.h" -#include "PikaParser.h" -#include "PikaStdLib_SysObj.h" -#include "PikaVM.h" -#include "dataMemory.h" -#include "dataQueue.h" -#include "dataStrs.h" -#include "pika_config_gtest.h" extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; /* test head */ VMParameters* pikaVM_runAsmWithPars(PikaObj* self, diff --git a/port/linux/test/arg-test.cpp b/port/linux/test/arg-test.cpp index 7fe915c23..e4c990b33 100644 --- a/port/linux/test/arg-test.cpp +++ b/port/linux/test/arg-test.cpp @@ -1,9 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "dataArg.h" -#include "dataString.h" -} TEST(arg_test, int_) { Arg* arg = New_arg(NULL); diff --git a/port/linux/test/args-test.cpp b/port/linux/test/args-test.cpp index f2977f173..97f4a3097 100644 --- a/port/linux/test/args-test.cpp +++ b/port/linux/test/args-test.cpp @@ -1,10 +1,5 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataString.h" -} + static int mem; TEST(args, test1) { mem = pikaMemNow(); diff --git a/port/linux/test/cJSON-test.cpp b/port/linux/test/cJSON-test.cpp index 7051455c9..55b685b23 100644 --- a/port/linux/test/cJSON-test.cpp +++ b/port/linux/test/cJSON-test.cpp @@ -1,20 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern PikaMemInfo pikaMemInfo; -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(cJSON, parse_print) { /* init */ diff --git a/port/linux/test/chinese-test.cpp b/port/linux/test/chinese-test.cpp index 3e8749903..a3a3fdc0d 100644 --- a/port/linux/test/chinese-test.cpp +++ b/port/linux/test/chinese-test.cpp @@ -1,20 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern PikaMemInfo pikaMemInfo; -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(chinese, test1) { /* init */ diff --git a/port/linux/test/cmodule-test.cpp b/port/linux/test/cmodule-test.cpp index 8ef9c2d64..c03872c13 100644 --- a/port/linux/test/cmodule-test.cpp +++ b/port/linux/test/cmodule-test.cpp @@ -1,20 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern PikaMemInfo pikaMemInfo; -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(cmodule, print_) { /* init */ diff --git a/port/linux/test/compile-test.cpp b/port/linux/test/compile-test.cpp index 95eecd558..2a93fda54 100644 --- a/port/linux/test/compile-test.cpp +++ b/port/linux/test/compile-test.cpp @@ -1,19 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaCompiler.h" -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(compiler, file) { char* lines = diff --git a/port/linux/test/content-test.cpp b/port/linux/test/content-test.cpp index 4992e1630..af5b30e57 100644 --- a/port/linux/test/content-test.cpp +++ b/port/linux/test/content-test.cpp @@ -1,9 +1,5 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "dataArg.h" -#include "dataString.h" -} + #if 0 TEST(content, init) { uint8_t contentIn[4] = {0}; diff --git a/port/linux/test/ctypes-test.cpp b/port/linux/test/ctypes-test.cpp index f02afb89e..08713ada9 100644 --- a/port/linux/test/ctypes-test.cpp +++ b/port/linux/test/ctypes-test.cpp @@ -1,20 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern PikaMemInfo pikaMemInfo; -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; #if PIKA_SYNTEX_ITEM_SLICE_ENABLE TEST(ctypes, test1) { diff --git a/port/linux/test/gc-test.cpp b/port/linux/test/gc-test.cpp index cbe57581a..6ad6553fc 100644 --- a/port/linux/test/gc-test.cpp +++ b/port/linux/test/gc-test.cpp @@ -1,17 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(gc, root) { PikaObj* root = newRootObj("root", New_PikaMain); diff --git a/port/linux/test/mem_test.cpp b/port/linux/test/mem_test.cpp index 0e441cc2a..2ed90311a 100644 --- a/port/linux/test/mem_test.cpp +++ b/port/linux/test/mem_test.cpp @@ -1,9 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "dataArgs.h" -#include "dataString.h" -} TEST(bitmap, init) { uint8_t* bitmap = bitmap_init(10); diff --git a/port/linux/test/module-test.cpp b/port/linux/test/module-test.cpp index a7a3c53e2..d46b415b8 100644 --- a/port/linux/test/module-test.cpp +++ b/port/linux/test/module-test.cpp @@ -1,20 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} - -extern PikaMemInfo pikaMemInfo; -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(module, cmodule_import) { /* init */ diff --git a/port/linux/test/object-test.cpp b/port/linux/test/object-test.cpp index 9f8239776..1f66ceaa2 100644 --- a/port/linux/test/object-test.cpp +++ b/port/linux/test/object-test.cpp @@ -1,11 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "BaseObj.h" -#include "PikaStdLib_SysObj.h" -#include "TinyObj.h" -#include "pika_config_gtest.h" -} void testFloat(PikaObj* obj, Args* args) { float val1 = args_getFloat(args, "val1"); diff --git a/port/linux/test/parse-test.cpp b/port/linux/test/parse-test.cpp index 1f5b587d3..eef82db20 100644 --- a/port/linux/test/parse-test.cpp +++ b/port/linux/test/parse-test.cpp @@ -1,11 +1,6 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "BaseObj.h" -#include "PikaParser.h" -#include "dataMemory.h" -#include "dataStrs.h" +extern "C" { /* head infomation */ typedef QueueObj AST; char* Parser_multiLineToAsm(Args* outBuffs, char* multiLine); @@ -3115,4 +3110,42 @@ TEST(parser, connection2) { "0 RUN print\n"); args_deinit(buffs); EXPECT_EQ(pikaMemNow(), 0); -} \ No newline at end of file +} + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(parser, format1) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = "s = 'res:%d' % 23"; + printf("%s", lines); + char* pikaAsm = Parser_multiLineToAsm(buffs, lines); + printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "1 STR res:%d\n" + "1 NUM 23\n" + "0 RUN cformat\n" + "0 OUT s\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(parser, format2) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = "'res:%d:%d' % (23, 25)"; + printf("%s\n", lines); + char* pikaAsm = Parser_multiLineToAsm(buffs, lines); + printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "1 STR res:%d:%d\n" + "1 NUM 23\n" + "1 NUM 25\n" + "0 RUN cformat\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif diff --git a/port/linux/test/pikaMain-test.cpp b/port/linux/test/pikaMain-test.cpp index a7c4912e5..e5b085e59 100644 --- a/port/linux/test/pikaMain-test.cpp +++ b/port/linux/test/pikaMain-test.cpp @@ -1,18 +1,5 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} -extern PikaMemInfo pikaMemInfo; TEST(pikaMain, init) { pikaMemInfo.heapUsedMax = 0; PikaObj* pikaMain = pikaScriptInit(); diff --git a/port/linux/test/pool-test.cpp b/port/linux/test/pool-test.cpp index f5945e9e6..52bcf7650 100644 --- a/port/linux/test/pool-test.cpp +++ b/port/linux/test/pool-test.cpp @@ -1,10 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "dataArg.h" -#include "dataMemory.h" -#include "dataString.h" -} TEST(pool, init) { Pool p = pool_init(125, 4); diff --git a/port/linux/test/queue-test.cpp b/port/linux/test/queue-test.cpp index 4b6b7184e..c1549519c 100644 --- a/port/linux/test/queue-test.cpp +++ b/port/linux/test/queue-test.cpp @@ -1,11 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "BaseObj.h" -#include "dataMemory.h" -#include "dataQueue.h" -#include "dataQueueObj.h" -} TEST(queue, NEW) { Queue* q = New_queue(); diff --git a/port/linux/test/stack-test.cpp b/port/linux/test/stack-test.cpp index b458d241c..d4b085825 100644 --- a/port/linux/test/stack-test.cpp +++ b/port/linux/test/stack-test.cpp @@ -1,10 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "BaseObj.h" -#include "dataMemory.h" -#include "dataStack.h" -} TEST(stack, NEW) { Stack s; diff --git a/port/linux/test/string-test.cpp b/port/linux/test/string-test.cpp new file mode 100644 index 000000000..411dd18ec --- /dev/null +++ b/port/linux/test/string-test.cpp @@ -0,0 +1,87 @@ +#include "test_common.h" + +TEST(string, cformat) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + obj_run(pikaMain, "s = cformat('test:%d:%f', 33, 1.5)\n"); + /* collect */ + char* s = obj_getStr(pikaMain, "s"); + /* assert */ + EXPECT_STREQ("test:33:1.500000", s); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(string, cformat1) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + obj_run(pikaMain, "s = 'res:%d' % 23\n"); + /* collect */ + char* s = obj_getStr(pikaMain, "s"); + /* assert */ + EXPECT_STREQ("res:23", s); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif + + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(string, format1) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + obj_run(pikaMain, "print('tes:%d,%f'%(123,1.5))\n"); + /* collect */ + /* assert */ + EXPECT_STREQ("tes:123,1.500000\r\n", log_buff[0]); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(string, format2) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + obj_run(pikaMain, "print('tes:%d,%f'%(123,1.5), 23)\n"); + /* collect */ + /* assert */ + EXPECT_STREQ("tes:123,1.500000 23\r\n", log_buff[0]); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +TEST(string, print_file) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + pikaVM_runFile(pikaMain, "../../examples/BuiltIn/print.py"); + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[0], "format: test,0123,15.50\r\n"); + EXPECT_STREQ(log_buff[1], "my name is old wang my age is 43\r\n"); + EXPECT_STREQ(log_buff[2], "test\r\n"); + EXPECT_STREQ(log_buff[3], "BEGIN\r\n"); + /* deinit */ + obj_deinit(pikaMain); + + EXPECT_EQ(pikaMemNow(), 0); +} +#endif \ No newline at end of file diff --git a/port/linux/test/strs-test.cpp b/port/linux/test/strs-test.cpp index 4f9e316a5..00f3e511a 100644 --- a/port/linux/test/strs-test.cpp +++ b/port/linux/test/strs-test.cpp @@ -1,16 +1,4 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" -} extern PikaMemInfo pikaMemInfo; /* the log_buff of printf */ diff --git a/port/linux/test/sysObj-test.cpp b/port/linux/test/sysObj-test.cpp index c5ebebbf8..9e6ea2603 100644 --- a/port/linux/test/sysObj-test.cpp +++ b/port/linux/test/sysObj-test.cpp @@ -1,14 +1,5 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "BaseObj.h" -#include "PikaStdLib_SysObj.h" -#include "TinyObj.h" -#include "pika_config_gtest.h" -} -/* the log_buff of printf */ -extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; TEST(sysObj, print) { PikaObj* obj = newRootObj("test", New_PikaStdLib_SysObj); VMParameters* globals = obj_runDirect(obj, "print('hello world')"); diff --git a/port/linux/test/test_common.h b/port/linux/test/test_common.h index e6c3bb9ec..a5223a555 100644 --- a/port/linux/test/test_common.h +++ b/port/linux/test/test_common.h @@ -1,2 +1,23 @@ #define __OOC_CPP__ -#define __OOC_DEBUG__ \ No newline at end of file +#define __OOC_DEBUG__ + +#include "gtest/gtest.h" +extern "C" { +#include "BaseObj.h" +#include "PikaCompiler.h" +#include "PikaMain.h" +#include "PikaParser.h" +#include "PikaStdLib_MemChecker.h" +#include "PikaMath_Operator.h" +#include "PikaStdLib_SysObj.h" +#include "PikaVM.h" +#include "TinyObj.h" +#include "dataArgs.h" +#include "dataMemory.h" +#include "dataStrs.h" +#include "pikaScript.h" +#include "pika_config_gtest.h" +extern PikaMemInfo pikaMemInfo; +/* the log_buff of printf */ +extern char log_buff[LOG_BUFF_MAX][LOG_SIZE]; +} diff --git a/port/linux/test/unix-time-test.cpp b/port/linux/test/unix-time-test.cpp index 96258a3e6..032f18910 100644 --- a/port/linux/test/unix-time-test.cpp +++ b/port/linux/test/unix-time-test.cpp @@ -1,21 +1,11 @@ -#include "gtest/gtest.h" #include "test_common.h" -extern "C" { -#include "PikaMain.h" -#include "PikaParser.h" -#include "PikaStdLib_MemChecker.h" -#include "PikaVM.h" -#include "dataArgs.h" -#include "dataMemory.h" -#include "dataStrs.h" -#include "pikaScript.h" -#include "pika_config_gtest.h" #include "time.h" +extern "C" { typedef struct tm _tm; extern int64_t time_mktime(const _tm* this_tm, int locale); extern void time_gmtime(double unix_time, _tm* this_tm); -extern void time_asctime(const _tm* this_tm); +extern void time_asctime(const _tm* this_tm); void time_struct_format(const _tm* this_tm, char* str); } @@ -76,16 +66,13 @@ TEST(unix_time, unix_time) { EXPECT_EQ(pikaMemNow(), 0); } -int compare(const _tm* t1,const _tm* t2) -{ - int size = 8; //只比对前面8个数据 - int *it1 = (int*)t1; - int *it2 = (int*)t2; - for(int i=0;itm_year+=1900; - if(compare(&temp1,temp2)) - { + temp1.tm_yday -= 1; + temp1.tm_isdst = 0; + temp2->tm_year += 1900; + if (compare(&temp1, temp2)) { printf("error!\n"); //格式化字符 time_struct_format(&temp1, str); printf("%s\n", str); time_struct_format(temp2, str); printf("%s\n", str); - flag=0; + flag = 0; break; } - if(tint1 != r) - { - printf("\n error!tint1 = %ld ,r = %ld \n",tint1,r); - flag=0; + if (tint1 != r) { + printf("\n error!tint1 = %ld ,r = %ld \n", tint1, r); + flag = 0; break; } - //printf("\n\n"); + // printf("\n\n"); } - printf("Had passed %d times test !\r\n",record-test_num-1); + printf("Had passed %d times test !\r\n", record - test_num - 1); /* assert */ EXPECT_EQ(flag, 1); /* deinit */ diff --git a/src/PikaParser.c b/src/PikaParser.c index a8b9c3d8f..32c51b433 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -974,6 +974,105 @@ char* Parser_solveLeftBranckets(Args* outBuffs, char* right, char* left) { } #endif +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE +char* Parser_solveFormat(Args* outBuffs, char* right) { + /* quick skip */ + if (!strIsContain(right, '%')) { + return right; + } + + PIKA_BOOL is_format = PIKA_FALSE; + ParserState_forEachToken(ps1, right) { + ParserState_iterStart(&ps1); + if (ps1.branket_deepth == 0 && strEqu(ps1.token1.pyload, "%")) { + is_format = PIKA_TRUE; + } + ParserState_iterEnd(&ps1); + } + ParserState_deinit(&ps1); + if (PIKA_FALSE == is_format) { + return right; + } + + char* res = right; + Arg* str_buf = arg_setStr(NULL, "", ""); + Arg* var_buf = arg_setStr(NULL, "", ""); + PIKA_BOOL is_in_format = PIKA_FALSE; + PIKA_BOOL is_tuple = PIKA_FALSE; + PIKA_BOOL is_out_tuple = PIKA_FALSE; + Args buffs = {0}; + char* fmt = NULL; + ParserState_forEachToken(ps, right) { + char* item = ""; + ParserState_iterStart(&ps); + if (PIKA_FALSE == is_in_format) { + if (ps.token1.type != TOKEN_literal) { + item = ps.token1.pyload; + goto iter_continue; + } + if (ps.token1.pyload[0] != '\'' && ps.token1.pyload[0] != '"') { + item = ps.token1.pyload; + goto iter_continue; + } + if (!strEqu(ps.token2.pyload, "%")) { + item = ps.token1.pyload; + goto iter_continue; + } + /* found the format stmt */ + is_in_format = PIKA_TRUE; + fmt = strsCopy(&buffs, ps.token1.pyload); + goto iter_continue; + } + if (PIKA_TRUE == is_in_format) { + /* check the format vars */ + if (strEqu(ps.token1.pyload, "%")) { + /* is a tuple */ + if (strEqu(ps.token2.pyload, "(")) { + is_tuple = PIKA_TRUE; + } + goto iter_continue; + } + if (!is_tuple) { + str_buf = arg_strAppend(str_buf, "cformat("); + str_buf = arg_strAppend(str_buf, fmt); + str_buf = arg_strAppend(str_buf, ","); + str_buf = arg_strAppend(str_buf, ps.token1.pyload); + str_buf = arg_strAppend(str_buf, ")"); + is_in_format = PIKA_FALSE; + } + if (is_tuple) { + /* found the end of tuple */ + if (ps.branket_deepth == 0 && strEqu(ps.token1.pyload, ")")) { + is_out_tuple = 1; + is_in_format = PIKA_FALSE; + } else { + /* push the vars inner the tuple */ + var_buf = arg_strAppend(var_buf, ps.token2.pyload); + } + } + if (is_out_tuple) { + str_buf = arg_strAppend(str_buf, "cformat("); + str_buf = arg_strAppend(str_buf, fmt); + str_buf = arg_strAppend(str_buf, ","); + str_buf = arg_strAppend(str_buf, arg_getStr(var_buf)); + } + } + iter_continue: + if (!is_in_format) { + str_buf = arg_strAppend(str_buf, item); + } + ParserState_iterEnd(&ps); + } + ParserState_deinit(&ps); + + res = strsCopy(outBuffs, arg_getStr(str_buf)); + arg_deinit(str_buf); + arg_deinit(var_buf); + strsDeinit(&buffs); + return res; +} +#endif + uint8_t Parser_solveSelfOperator(Args* outbuffs, char* stmt, char** right_p, @@ -1094,13 +1193,11 @@ AST* AST_parseStmt(AST* ast, char* stmt) { isLeftExist = Parser_solveSelfOperator(&buffs, stmt, &right, &left); } - char* right_new = right; #if PIKA_SYNTEX_ITEM_SLICE_ENABLE + char* right_new = right; /* solve the [] stmt */ right = Parser_solveRightBranckets(&buffs, right); right_new = Parser_solveLeftBranckets(&buffs, right, left); -#endif - /* left is contain the '[]' */ if (!strEqu(right_new, right)) { /* update new right */ @@ -1108,6 +1205,11 @@ AST* AST_parseStmt(AST* ast, char* stmt) { /* cancel left */ isLeftExist = 0; } +#endif + +#if PIKA_SYNTEX_ITEM_FORMAT_ENABLE + right = Parser_solveFormat(&buffs, right); +#endif /* set left */ if (isLeftExist) { diff --git a/src/PikaParser.h b/src/PikaParser.h index b27e2cc73..521d92f35 100644 --- a/src/PikaParser.h +++ b/src/PikaParser.h @@ -101,7 +101,7 @@ char* Parser_parsePyLines(Args* outBuffs, ParserState_forEach(parseState) #define ParserState_forEachToken(parseState, tokens) \ - struct ParserState ps; \ + struct ParserState parseState; \ ParserState_forEachTokenExistPs(parseState, tokens) uint16_t Tokens_getSize(char* tokens); diff --git a/src/PikaVM.c b/src/PikaVM.c index 02f9a6c6d..316d335ba 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -305,27 +305,35 @@ static int VMState_loadArgsFromMethodArg(VMState* vs, /* get variable tuple name */ char* type_list_buff = strsCopy(&buffs, type_list); + int variable_arg_start = 0; for (int i = 0; i < arg_num_dec; i++) { char* arg_def = strPopLastToken(type_list_buff, ','); if (strIsStartWith(arg_def, "*")) { /* skip the '*' */ variable_tuple_name = arg_def + 1; + variable_arg_start = arg_num_dec - i - 1; + is_get_variable_arg = PIKA_TRUE; + break; } } + /* found variable arg */ + if (PIKA_TRUE == is_get_variable_arg) { + tuple = New_tuple(); + strPopLastToken(type_list, ','); + } + /* load pars */ for (int i = 0; i < arg_num; i++) { - char* arg_def = strPopLastToken(type_list, ','); - strPopLastToken(arg_def, ':'); - char* arg_name = arg_def; - /* found variable arg */ - if (strIsStartWith(arg_name, "*")) { - is_get_variable_arg = PIKA_TRUE; - tuple = New_tuple(); - /* clear the type_list */ - type_list = ""; + char* arg_name = NULL; + if (arg_num - i <= variable_arg_start) { + is_get_variable_arg = PIKA_FALSE; } - if (PIKA_TRUE == is_get_variable_arg) { + if (PIKA_FALSE == is_get_variable_arg) { + char* arg_def = strPopLastToken(type_list, ','); + strPopLastToken(arg_def, ':'); + arg_name = arg_def; + } else { /* clear the variable arg name */ arg_name = strsCopy(&buffs, ""); } diff --git a/src/dataArgs.c b/src/dataArgs.c index 2c032e542..f11d60300 100644 --- a/src/dataArgs.c +++ b/src/dataArgs.c @@ -562,3 +562,53 @@ PikaTuple* New_tuple(void) { PikaTuple* self = (PikaTuple*)New_list(); return self; } + +char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg) { + Args buffs = {0}; + char* res = NULL; + ArgType type = arg_getType(arg); + if (ARG_TYPE_INT == type) { + int val = arg_getInt(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } + if (ARG_TYPE_FLOAT == type) { + double val = arg_getFloat(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } + if (ARG_TYPE_STRING == type) { + char* val = arg_getStr(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } +exit: + res = strsCopy(out_buffs, res); + strsDeinit(&buffs); + return res; +} + +char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list) { + Args buffs = {0}; + char* res = NULL; + char* fmt_buff = strsCopy(&buffs, fmt); + char* fmt_item = strsPopToken(&buffs, fmt_buff, '%'); + Arg* res_buff = arg_setStr(NULL, "", fmt_item); + + for (size_t i = 0; i < list_getSize(list); i++) { + Args buffs_item = {0}; + Arg* arg = list_getArg(list, i); + char* fmt_item = strsPopToken(&buffs_item, fmt_buff, '%'); + fmt_item = strsAppend(&buffs_item, "%", fmt_item); + char* str_format = strsFormatArg(&buffs_item, fmt_item, arg); + res_buff = arg_strAppend(res_buff, str_format); + strsDeinit(&buffs_item); + } + goto exit; + +exit: + res = strsCopy(out_buffs, arg_getStr(res_buff)); + strsDeinit(&buffs); + arg_deinit(res_buff); + return res; +} diff --git a/src/dataArgs.h b/src/dataArgs.h index 44cf8a698..763e43c4a 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -164,6 +164,7 @@ PIKA_RES list_append(PikaList* self, Arg* arg); PIKA_RES list_setArg(PikaList* self, int index, Arg* arg); Arg* list_getArg(PikaList* self, int index); size_t list_getSize(PikaList* self); +char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg); /* tuple api */ #define tuple_deinit(self) (list_deinit((&((self)->super)))) @@ -173,4 +174,6 @@ size_t list_getSize(PikaList* self); PikaList* New_list(void); PikaTuple* New_tuple(void); +char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list); + #endif diff --git a/src/pika_config_valid.h b/src/pika_config_valid.h index ff52b7dc1..b9a89531a 100644 --- a/src/pika_config_valid.h +++ b/src/pika_config_valid.h @@ -41,6 +41,7 @@ #define PIKA_READ_FILE_BUFF_SIZE 0x10000 #define PIKA_INIT_STRING_ENABLE 0 #define PIKA_SYNTEX_ITEM_SLICE_ENABLE 1 + #define PIKA_SYNTEX_ITEM_FORMAT_ENABLE 1 #define PIKA_PLOOC_ENABLE 0 /* optimize options */ @@ -80,6 +81,8 @@ #define PIKA_BUILTIN_LIST_ENABLE 0 #undef PIKA_BUILTIN_DICT_ENABLE #define PIKA_BUILTIN_DICT_ENABLE 0 + #undef PIKA_SYNTEX_ITEM_FORMAT_ENABLE + #define PIKA_SYNTEX_ITEM_FORMAT_ENABLE 0 #elif PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MAXIMAL #undef PIKA_SYNTEX_ITEM_SLICE_ENABLE #define PIKA_SYNTEX_ITEM_SLICE_ENABLE 1 @@ -87,6 +90,8 @@ #define PIKA_BUILTIN_LIST_ENABLE 1 #undef PIKA_BUILTIN_DICT_ENABLE #define PIKA_BUILTIN_DICT_ENABLE 1 + #undef PIKA_SYNTEX_ITEM_FORMAT_ENABLE + #define PIKA_SYNTEX_ITEM_FORMAT_ENABLE 1 #endif /* configuration validation */ diff --git a/tools/pikaByteCodeGen/pikascript/PikaStdLib.pyi b/tools/pikaByteCodeGen/pikascript/PikaStdLib.pyi index b35f92a04..69d961341 100644 --- a/tools/pikaByteCodeGen/pikascript/PikaStdLib.pyi +++ b/tools/pikaByteCodeGen/pikascript/PikaStdLib.pyi @@ -29,6 +29,7 @@ class SysObj(BaseObj): def ord(self, val: str) -> int: ... def chr(self, val: int) -> str: ... def bytes(self, val: any) -> bytes: ... + def cformat(self, fmt: str, *var) -> str: ... class RangeObj(TinyObj): diff --git a/tools/pikaByteCodeGen/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c b/tools/pikaByteCodeGen/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c index 4307d37a6..0b88e602b 100644 --- a/tools/pikaByteCodeGen/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/tools/pikaByteCodeGen/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -1,6 +1,7 @@ -#include "BaseObj.h" +#include "PikaStdLib_SysObj.h" #include "PikaStdLib_RangeObj.h" #include "PikaStdLib_StringObj.h" +#include "PikaVM.h" #include "dataStrs.h" void PikaStdLib_SysObj_remove(PikaObj* self, char* argPath) { @@ -487,3 +488,13 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) { __platform_printf("%s", res); args_deinit(print_args); } + +char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { + Args buffs = {0}; + pikaMemMaxReset(); + char* res = strsFormatList(&buffs, fmt, &var->super); + obj_setStr(self, "_buf", res); + res = obj_getStr(self, "_buf"); + strsDeinit(&buffs); + return res; +}