!25 support format output for print()

* test for format with tuple is ok
* 'format'%var is ok (tuple var is not ok)
* rename _cformat to cformat()
* optimize the memory usage of format_list
* add string-test.cpp
* cformat() is ok
* fix variable par load issue
* use test_common.h
* use test_common to simplify the gtest case
* Merge branch 'master' into dev
* fix float->double for bytecodegen
* update to /package
* Use double in C for float in python
This commit is contained in:
李昂 2022-06-14 03:20:17 +00:00
parent cfab053189
commit 6acc0f9ecd
37 changed files with 407 additions and 269 deletions

View File

@ -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))

View File

@ -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):

View File

@ -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;
}

View File

@ -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}",

View File

@ -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):

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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();

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 =

View File

@ -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};

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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");

View File

@ -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);
}
}
#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

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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')");

View File

@ -1,2 +1,23 @@
#define __OOC_CPP__
#define __OOC_DEBUG__
#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];
}

View File

@ -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;i<size;i++)
{
//printf("t1=%d,t2=%d\n",it1[i],it2[i]);
if(it1[i]!=it2[i])
{
int compare(const _tm* t1, const _tm* t2) {
int size = 8; //只比对前面8个数据
int* it1 = (int*)t1;
int* it2 = (int*)t2;
for (int i = 0; i < size; i++) {
// printf("t1=%d,t2=%d\n",it1[i],it2[i]);
if (it1[i] != it2[i]) {
printf("mytime: ");
time_asctime(t1);
printf("ctime: ");
@ -98,47 +85,44 @@ int compare(const _tm* t1,const _tm* t2)
TEST(unix_time, iteration_form_1970_to_2070) {
/* init */
_tm temp1,*temp2;
_tm temp1, *temp2;
int64_t tint1;
int64_t r=123456;
int64_t r = 123456;
int flag = 1;
char str[200];
/* run */
/* 获取数据比对 */
int test_num =365*100;
int test_num = 365 * 100;
int record = test_num;
while(test_num--)
{
//r=randL2();
r+=24*60*60;
time_gmtime(r,&temp1);
tint1 = time_mktime(&temp1,0);
while (test_num--) {
// r=randL2();
r += 24 * 60 * 60;
time_gmtime(r, &temp1);
tint1 = time_mktime(&temp1, 0);
temp2 = gmtime(&r);
temp1.tm_yday -=1;
temp1.tm_isdst =0;
temp2->tm_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 */

View File

@ -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) {

View File

@ -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);

View File

@ -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, "");
}

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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):

View File

@ -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;
}