From 872fefd11ac3622e26e31ea53d9e9e5f8a904293 Mon Sep 17 00:00:00 2001 From: lyon Date: Mon, 1 May 2023 18:34:49 +0800 Subject: [PATCH 1/9] support REPL_HISTORY --- port/linux/.vscode/launch.json | 2 +- port/linux/boot/demo06-pikamain/main.c | 4 +- src/PikaObj.c | 233 ++++++++++++++++--------- src/PikaObj.h | 10 +- test/pikaMain-test.cpp | 84 +++++++++ 5 files changed, 243 insertions(+), 90 deletions(-) diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 6ef2a6e89..7bdf4ec36 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -20,7 +20,7 @@ // "--gtest_filter=eventloop.test1" // "--gtest_filter=parser.tuple_single" // "--gtest_filter=parser.*" - "--gtest_filter=pikaMain.REPL_key_up" + "--gtest_filter=pikaMain.REPL_key_down_over" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/boot/demo06-pikamain/main.c b/port/linux/boot/demo06-pikamain/main.c index 4dcc18733..d465957dc 100644 --- a/port/linux/boot/demo06-pikamain/main.c +++ b/port/linux/boot/demo06-pikamain/main.c @@ -6,7 +6,9 @@ int main(int argc, char* argv[]) { if (1 == argc) { - pikaScriptShell(pikaScriptInit()); + PikaObj* pikaMain = pikaScriptInit(); + pikaScriptShell(pikaMain); + obj_deinit(pikaMain); return 0; } if (2 == argc) { diff --git a/src/PikaObj.c b/src/PikaObj.c index 08dadf8ec..b3221f37a 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -37,6 +37,11 @@ #include "dataQueue.h" #include "dataString.h" #include "dataStrs.h" +#if __linux +#include "signal.h" +#include "termios.h" +#include "unistd.h" +#endif extern volatile VMSignal g_PikaVMSignal; volatile PikaObjState g_PikaObjState = { @@ -66,6 +71,7 @@ void pikaGC_markObj(PikaGC* gc, PikaObj* self); void _pikaGC_mark(PikaGC* gc); void obj_dump(PikaObj* self); void Locals_deinit(PikaObj* self); +static void disable_raw_mode(void); static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self, char* input_line, @@ -200,6 +206,9 @@ int32_t obj_deinit(PikaObj* self) { if (bisRoot) { pikaGC_markSweep(); shConfig_deinit((ShellConfig*)&g_repl_shell); +#if __linux + disable_raw_mode(); +#endif } return ret; } @@ -639,6 +648,41 @@ static int set_disp_mode(int fd, int option) { static volatile uint8_t logo_printed = 0; +#if __linux +struct termios original_termios; + +static void enable_raw_mode(void) { + struct termios raw; + + tcgetattr(STDIN_FILENO, &original_termios); // 获取当前终端属性 + raw = original_termios; + raw.c_lflag &= ~(ECHO | ICANON); // 禁用回显和规范模式 + tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); // 设置终端属性 +} + +static void disable_raw_mode(void) { + tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_termios); // 恢复原始终端属性 + printf("\n"); +} + +static void signal_handler(int sig) { + if (sig == SIGSEGV) { + printf("Segmentation fault"); + } else if (sig == SIGINT) { + printf("Ctrl+C"); + } else if (sig == SIGTERM) { + printf("SIGTERM"); + } else if (sig == SIGHUP) { + printf("SIGHUP"); + } else if (sig == SIGABRT) { + printf("Aborted"); + } + disable_raw_mode(); + exit(1); +} + +#endif + extern volatile PikaObj* __pikaMain; PikaObj* newRootObj(char* name, NewFun newObjFun) { g_PikaObjState.inRootObj = PIKA_TRUE; @@ -646,7 +690,12 @@ PikaObj* newRootObj(char* name, NewFun newObjFun) { mem_pool_init(); #endif #ifdef __linux - // set_disp_mode(STDIN_FILENO, 0); + signal(SIGINT, signal_handler); // 捕获 SIGINT 信号(Ctrl+C) + signal(SIGTERM, signal_handler); // 捕获 SIGTERM 信号 + signal(SIGHUP, signal_handler); // 捕获 SIGHUP 信号 + signal(SIGSEGV, signal_handler); // 捕获 SIGHUP 信号 + signal(SIGABRT, signal_handler); + enable_raw_mode(); #endif PikaObj* newObj = newNormalObj(newObjFun); if (!logo_printed) { @@ -1289,111 +1338,102 @@ int16_t _do_stream_filter(PikaObj* self, ShellConfig* shell) { #endif #if PIKA_SHELL_HISTORY_ENABLE -void shHistory_add(ShellHistory* self, char* command) { - pika_assert(NULL != self); - pika_assert(NULL != command); - if (self->current_size == self->max_size) { - pikaFree(self->history_list[self->head], - strGetSize(self->history_list[self->head]) + 1); - self->head = (self->head + 1) % self->max_size; - } else { - self->current_size++; - } - - // 使用pikaMalloc分配内存并复制字符串 - size_t command_length = strGetSize(command); - self->history_list[self->tail] = (char*)pikaMalloc(command_length + 1); - pika_platform_memcpy(self->history_list[self->tail], command, - command_length); - self->history_list[self->tail][command_length] = '\0'; - - self->tail = (self->tail + 1) % self->max_size; - self->current_index = (self->tail - 1 + self->max_size) % self->max_size; -} - ShellHistory* shHistory_create(int max_size) { ShellHistory* self = (ShellHistory*)pikaMalloc(sizeof(ShellHistory)); self->max_size = max_size; - self->current_size = 0; - self->head = 0; - self->tail = 0; - self->current_index = -1; - self->history_list = (char**)pikaMalloc(max_size * sizeof(char*)); + self->current = -1; + self->count = 0; + self->last_offset = 0; + self->history = (char**)pikaMalloc(max_size * sizeof(char*)); return self; } void shHistory_destroy(ShellHistory* self) { - for (int i = 0; i < self->current_size; i++) { - pikaFree(self->history_list[i], strGetSize(self->history_list[i]) + 1); + for (int i = 0; i < self->count; i++) { + pikaFree(self->history[i], strGetSize(self->history[i]) + 1); } - pikaFree(self->history_list, self->max_size * sizeof(char*)); + pikaFree(self->history, sizeof(char*) * self->max_size); pikaFree(self, sizeof(ShellHistory)); } -char* shHistory_get(ShellHistory* self, int index) { - if (index < 0 || index >= self->current_size) { - return NULL; +void shHistory_add(ShellHistory* self, char* command) { + if (self->count == self->max_size) { + pikaFree(self->history[0], strGetSize(self->history[0]) + 1); + pika_platform_memmove(self->history, self->history + 1, + (self->max_size - 1) * sizeof(char*)); + self->count--; } - int actual_index = (self->head + index) % self->max_size; - return self->history_list[actual_index]; + /* filter for empty command */ + if (self->count > 0 && self->history[self->count - 1][0] == '\0') { + pikaFree(self->history[self->count - 1], + strGetSize(self->history[self->count - 1]) + 1); + self->count--; + } + + /* filter for same command */ + if (self->count > 0 && strEqu(self->history[self->count - 1], command)) { + return; + } + + self->history[self->count] = pikaMalloc(strGetSize(command) + 1); + pika_platform_memcpy(self->history[self->count], command, + strGetSize(command) + 1); + self->count++; + self->current = self->count - 1; + self->last_offset = 0; +} + +char* shHistory_get(ShellHistory* self, int offset) { + int actual_offset = offset + self->last_offset; + int index = self->current + actual_offset; + if (index < 0 || index >= self->count) { + return NULL; + } + self->last_offset = actual_offset; + return self->history[index]; } char* shHistory_getPrev(ShellHistory* self) { - if (self->current_size == 0) { - return NULL; - } - - self->current_index = - (self->current_index - 1 + self->max_size) % self->max_size; - - if (self->current_index == self->tail) { - self->current_index = - (self->current_index - 1 + self->max_size) % self->max_size; - } - - return self->history_list[self->current_index]; + return shHistory_get(self, -1); } char* shHistory_getNext(ShellHistory* self) { - if (self->current_size == 0) { - return NULL; - } - - int next_index = (self->current_index + 1) % self->max_size; - - if (next_index == self->tail) { - return NULL; - } - - self->current_index = next_index; - return self->history_list[self->current_index]; + return shHistory_get(self, 1); } #endif +#if __linux +#define PIKA_BACKSPACE() printf("\b \b") +#else +#define PIKA_BACKSPACE() pika_platform_printf(" \b") +#endif + enum shellCTRL _inner_do_obj_runChar(PikaObj* self, char inputChar, ShellConfig* shell) { char* input_line = NULL; enum shellCTRL ctrl = SHELL_CTRL_CONTINUE; -#if !(defined(__linux) || defined(_WIN32)) +#if __linux + printf("%c", inputChar); +#elif !(defined(_WIN32)) pika_platform_printf("%c", inputChar); #endif if (inputChar == '\n' && shell->lastChar == '\r') { ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if (inputChar == 0x1b) { shell->stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY; ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if (shell->stat == PIKA_SHELL_STATE_WAIT_SPEC_KEY) { if (inputChar == 0x5b) { shell->stat = PIKA_SHELL_STATE_WAIT_FUNC_KEY; ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } shell->stat = PIKA_SHELL_STATE_NORMAL; } @@ -1405,7 +1445,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, pika_platform_printf(" "); } ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if (inputChar == PIKA_KEY_RIGHT) { if (shell->line_curpos < shell->line_position) { @@ -1416,7 +1456,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, pika_platform_printf("\b"); } ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if (inputChar == PIKA_KEY_UP) { _putc_cmd(PIKA_KEY_DOWN, 1); @@ -1425,14 +1465,18 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, if (NULL == shell->history) { shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM); } - if (NULL == shHistory_getNext(shell->history)) { + if (0 == shell->history->cached_current) { /* save the current line */ shHistory_add(shell->history, shell->lineBuff); + shell->history->cached_current = 1; } char* prev = shHistory_getPrev(shell->history); + if (NULL == prev) { + goto __exit; + } /* clear the current line */ for (int i = 0; i < shell->line_position; i++) { - pika_platform_printf("\b \b"); + PIKA_BACKSPACE(); } pika_platform_memcpy(shell->lineBuff, prev, strGetSize(prev) + 1); /* show the previous line */ @@ -1440,20 +1484,39 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, shell->line_position = strGetSize(prev); shell->line_curpos = shell->line_position; #endif - goto exit; + goto __exit; } if (inputChar == PIKA_KEY_DOWN) { ctrl = SHELL_CTRL_CONTINUE; - goto exit; +#if PIKA_SHELL_HISTORY_ENABLE + char* next = shHistory_getNext(shell->history); + if (NULL == next) { + goto __exit; + } + /* clear the current line */ + for (int i = 0; i < shell->line_position; i++) { + PIKA_BACKSPACE(); + } + pika_platform_memcpy(shell->lineBuff, next, strGetSize(next) + 1); + /* show the previous line */ + pika_platform_printf("%s", shell->lineBuff); + shell->line_position = strGetSize(next); + shell->line_curpos = shell->line_position; +#endif + goto __exit; } } if ((inputChar == '\b') || (inputChar == 127)) { - if (shell->line_position == 0) { + if (shell->line_curpos == 0) { +#if __linux + printf("\b "); +#else pika_platform_printf(" "); +#endif ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } - pika_platform_printf(" \b"); + PIKA_BACKSPACE(); shell->line_position--; shell->line_curpos--; pika_platform_memmove(shell->lineBuff + shell->line_curpos, @@ -1468,7 +1531,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, shell->line_position - shell->line_curpos + 1); } ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if ((inputChar != '\r') && (inputChar != '\n')) { if (shell->line_position + 1 >= PIKA_LINE_BUFF_SIZE) { @@ -1477,7 +1540,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, "'PIKA_LINE_BUFF_SIZE'\r\n"); ctrl = SHELL_CTRL_EXIT; __clearBuff(shell); - goto exit; + goto __exit; } if ('\0' != inputChar) { pika_platform_memmove(shell->lineBuff + shell->line_curpos + 1, @@ -1494,7 +1557,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, shell->line_curpos++; } ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } if ((inputChar == '\r') || (inputChar == '\n')) { #if !(defined(__linux) || defined(_WIN32) || PIKA_SHELL_NO_NEWLINE) @@ -1504,7 +1567,11 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, if (NULL == shell->history) { shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM); } - shHistory_add(shell->history, shell->lineBuff); + if (shell->lineBuff[0] != '\0') { + shHistory_add(shell->history, shell->lineBuff); + } + shell->history->last_offset = 0; + shell->history->cached_current = 0; #endif /* still in block */ if (shell->blockBuffName != NULL && shell->inBlock) { @@ -1524,13 +1591,13 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, ctrl = shell->handler(self, input_line, shell); __clearBuff(shell); pika_platform_printf(">>> "); - goto exit; + goto __exit; } else { pika_platform_printf("... "); } __clearBuff(shell); ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } /* go in block */ if (shell->blockBuffName != NULL && 0 != strGetSize(shell->lineBuff)) { @@ -1542,16 +1609,16 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, __clearBuff(shell); pika_platform_printf("... "); ctrl = SHELL_CTRL_CONTINUE; - goto exit; + goto __exit; } } shell->lineBuff[shell->line_position] = '\0'; ctrl = shell->handler(self, shell->lineBuff, shell); pika_platform_printf("%s", shell->prefix); __clearBuff(shell); - goto exit; + goto __exit; } -exit: +__exit: shell->lastChar = inputChar; return ctrl; } diff --git a/src/PikaObj.h b/src/PikaObj.h index 589bb341f..7e85c3027 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -365,11 +365,11 @@ struct FilterItem { typedef struct { int max_size; - int current_size; - int head; - int tail; - int current_index; - char** history_list; + int current; + int count; + int last_offset; + char** history; + int cached_current; } ShellHistory; struct ShellConfig { diff --git a/test/pikaMain-test.cpp b/test/pikaMain-test.cpp index da84cab13..2cd6865b6 100644 --- a/test/pikaMain-test.cpp +++ b/test/pikaMain-test.cpp @@ -2827,6 +2827,7 @@ TEST(pikaMain, REPL_key_left_del) { EXPECT_EQ(pikaMemNow(), 0); } +#if PIKA_SHELL_HISTORY_ENABLE TEST(pikaMain, REPL_key_up) { char lines[] = {'1', '2', '+', '3', '4', '5', '\n', 0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00}; @@ -2846,6 +2847,89 @@ TEST(pikaMain, REPL_key_up) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(pikaMain, REPL_key_up_void) { + char lines[] = {0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00}; + /* init */ + g_PikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + for (size_t i = 0; i < strGetSize(lines); i++) { + obj_runChar(pikaMain, lines[i]); + } + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[1], "2\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(pikaMain, REPL_key_up_2) { + char lines[] = {'1', '2', '+', '3', '4', '5', '\n', + '1', '3', '*', '2', '\n', 0x1b, 0x5b, + PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00}; + /* init */ + g_PikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + for (size_t i = 0; i < strGetSize(lines); i++) { + obj_runChar(pikaMain, lines[i]); + } + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[1], "3464\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(pikaMain, REPL_key_down) { + char lines[] = {'1', '2', '+', '3', '4', '5', + '\n', '1', '3', '*', '2', '\n', + 0x1b, 0x5b, PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP, + 0x1b, 0x5b, PIKA_KEY_DOWN, '2', '\n', 0x00}; + /* init */ + g_PikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + for (size_t i = 0; i < strGetSize(lines); i++) { + obj_runChar(pikaMain, lines[i]); + } + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[1], "286\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(pikaMain, REPL_key_down_over) { + char lines[] = {'1', '2', '+', '3', '4', '5', + '\n', '1', '3', '*', '2', '\n', + 0x1b, 0x5b, PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP, + 0x1b, 0x5b, PIKA_KEY_DOWN, 0x1b, 0x5b, PIKA_KEY_DOWN, + 0x1b, 0x5b, PIKA_KEY_DOWN, '2', '\n', 0x00}; + /* init */ + g_PikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + for (size_t i = 0; i < strGetSize(lines); i++) { + obj_runChar(pikaMain, lines[i]); + } + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[1], "2\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + +#endif + #if PIKA_SHELL_FILTER_ENABLE TEST(pikaMain, SHELL_filter_hi_pika) { From cf09b8e5075e5413da7cfaefd566000787ba0054 Mon Sep 17 00:00:00 2001 From: lyon Date: Mon, 1 May 2023 18:40:34 +0800 Subject: [PATCH 2/9] fix KEY_UP --- src/PikaObj.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/PikaObj.c b/src/PikaObj.c index b3221f37a..05f44d04a 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1474,6 +1474,11 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, if (NULL == prev) { goto __exit; } + /* move to the last position */ + for (int i = 0; i < shell->line_position - shell->line_curpos; + i++) { + _putc_cmd(PIKA_KEY_RIGHT, 1); + } /* clear the current line */ for (int i = 0; i < shell->line_position; i++) { PIKA_BACKSPACE(); From f1154e5e0f58610e56cf2aeec19a10e99f581181 Mon Sep 17 00:00:00 2001 From: lyon Date: Mon, 1 May 2023 18:59:02 +0800 Subject: [PATCH 3/9] fix REPL history on keil-simu --- src/PikaObj.c | 86 +++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/PikaObj.c b/src/PikaObj.c index 05f44d04a..333f699df 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1410,6 +1410,47 @@ char* shHistory_getNext(ShellHistory* self) { #define PIKA_BACKSPACE() pika_platform_printf(" \b") #endif +#if __linux +#define PIKA_BACKSPACE_FORCE() printf("\b \b") +#else +#define PIKA_BACKSPACE_FORCE() pika_platform_printf("\b \b") +#endif + +static void handle_history_navigation(char inputChar, + ShellConfig* shell, + PIKA_BOOL bIsUp) { +#if PIKA_SHELL_HISTORY_ENABLE + if (NULL == shell->history) { + shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM); + } + if (0 == shell->history->cached_current) { + /* save the current line */ + shHistory_add(shell->history, shell->lineBuff); + shell->history->cached_current = 1; + } + char* history_line = bIsUp ? shHistory_getPrev(shell->history) + : shHistory_getNext(shell->history); + if (NULL == history_line) { + return; + } + /* move to the last position */ + for (int i = 0; i < shell->line_position - shell->line_curpos; i++) { + _putc_cmd(PIKA_KEY_RIGHT, 1); + } + /* clear the current line */ + for (int i = 0; i < shell->line_position; i++) { + PIKA_BACKSPACE_FORCE(); + } + pika_platform_memcpy(shell->lineBuff, history_line, + strGetSize(history_line) + 1); + /* show the previous line */ + pika_platform_printf("%s", shell->lineBuff); + shell->line_position = strGetSize(history_line); + shell->line_curpos = shell->line_position; +#endif + return; +} + enum shellCTRL _inner_do_obj_runChar(PikaObj* self, char inputChar, ShellConfig* shell) { @@ -1461,53 +1502,12 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self, if (inputChar == PIKA_KEY_UP) { _putc_cmd(PIKA_KEY_DOWN, 1); ctrl = SHELL_CTRL_CONTINUE; -#if PIKA_SHELL_HISTORY_ENABLE - if (NULL == shell->history) { - shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM); - } - if (0 == shell->history->cached_current) { - /* save the current line */ - shHistory_add(shell->history, shell->lineBuff); - shell->history->cached_current = 1; - } - char* prev = shHistory_getPrev(shell->history); - if (NULL == prev) { - goto __exit; - } - /* move to the last position */ - for (int i = 0; i < shell->line_position - shell->line_curpos; - i++) { - _putc_cmd(PIKA_KEY_RIGHT, 1); - } - /* clear the current line */ - for (int i = 0; i < shell->line_position; i++) { - PIKA_BACKSPACE(); - } - pika_platform_memcpy(shell->lineBuff, prev, strGetSize(prev) + 1); - /* show the previous line */ - pika_platform_printf("%s", shell->lineBuff); - shell->line_position = strGetSize(prev); - shell->line_curpos = shell->line_position; -#endif + handle_history_navigation(inputChar, shell, PIKA_TRUE); goto __exit; } if (inputChar == PIKA_KEY_DOWN) { ctrl = SHELL_CTRL_CONTINUE; -#if PIKA_SHELL_HISTORY_ENABLE - char* next = shHistory_getNext(shell->history); - if (NULL == next) { - goto __exit; - } - /* clear the current line */ - for (int i = 0; i < shell->line_position; i++) { - PIKA_BACKSPACE(); - } - pika_platform_memcpy(shell->lineBuff, next, strGetSize(next) + 1); - /* show the previous line */ - pika_platform_printf("%s", shell->lineBuff); - shell->line_position = strGetSize(next); - shell->line_curpos = shell->line_position; -#endif + handle_history_navigation(inputChar, shell, PIKA_FALSE); goto __exit; } } From 226cba58e474448a9d8773c5a1a1bd83f148baee Mon Sep 17 00:00:00 2001 From: lyon1998 Date: Mon, 1 May 2023 20:11:18 +0800 Subject: [PATCH 4/9] add_files --- package/PikaStdDevice/PikaStdDevice_UART.c | 38 +++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 2de444d80..1c00d58ff 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -1,5 +1,6 @@ #include "PikaStdDevice_UART.h" #include "PikaStdDevice_common.h" +#include "pika_hal.h" void PikaStdDevice_UART_enable(PikaObj* self) { obj_runNativeMethod(self, "platformEnable", NULL); @@ -39,6 +40,7 @@ void PikaStdDevice_UART_init(PikaObj* self) { obj_setInt(self, "dataBits", 8); obj_setInt(self, "parity", PIKA_HAL_UART_PARITY_NONE); obj_setInt(self, "stopBits", PIKA_HAL_UART_STOP_BITS_1); + obj_setInt(self, "enabled", 0); } void PikaStdDevice_UART___init__(PikaObj* self) { @@ -57,24 +59,52 @@ Arg* PikaStdDevice_UART_readBytes(PikaObj* self, int length) { return arg_copy(obj_getArg(self, "readData")); } +int _config_update(PikaObj* self, pika_hal_UART_config* cfg){ + if (obj_getInt(self, "enabled")) { + pika_debug("UART %s config update.\r\n", obj_getStr(self, "id")); + int err = pika_hal_ioctl(obj_getPtr(self, "pika_dev"), + PIKA_HAL_IOCTL_CONFIG, cfg); + if (err == 0) { + return 0; + } + pika_debug("UART %s config update failed.\r\n", obj_getStr(self, "id")); + } + return -1; +} + void PikaStdDevice_UART_setBaudRate(PikaObj* self, int baudRate) { obj_setInt(self, "baudRate", baudRate); + pika_hal_UART_config cfg = {0}; + cfg.baudrate = baudRate; + _config_update(self, &cfg); } void PikaStdDevice_UART_setFlowControl(PikaObj* self, int flowControl) { obj_setInt(self, "flowControl", flowControl); + pika_hal_UART_config cfg = {0}; + cfg.flow_control = flowControl; + _config_update(self, &cfg); } void PikaStdDevice_UART_setDataBits(PikaObj* self, int dataBits) { obj_setInt(self, "dataBits", dataBits); + pika_hal_UART_config cfg = {0}; + cfg.data_bits = dataBits; + _config_update(self, &cfg); } void PikaStdDevice_UART_setParity(PikaObj* self, int parity) { obj_setInt(self, "parity", parity); + pika_hal_UART_config cfg = {0}; + cfg.parity = parity; + _config_update(self, &cfg); } void PikaStdDevice_UART_setStopBits(PikaObj* self, int stopBits) { obj_setInt(self, "stopBits", stopBits); + pika_hal_UART_config cfg = {0}; + cfg.stop_bits = stopBits; + _config_update(self, &cfg); } void PikaStdDevice_UART_setId(PikaObj* self, int id) { @@ -161,6 +191,7 @@ void PikaStdDevice_UART_platformEnable(PikaObj* self) { (int)obj_getInt(self, "id")); return; } + obj_setInt(self, "enabled", 1); } void PikaStdDevice_UART_platformRead(PikaObj* self) { @@ -186,7 +217,12 @@ void PikaStdDevice_UART_platformDisable(PikaObj* self) { (int)obj_getInt(self, "id")); return; } - pika_hal_ioctl(dev, PIKA_HAL_IOCTL_DISABLE); + if (0!= pika_hal_ioctl(dev, PIKA_HAL_IOCTL_DISABLE)){ + __platform_printf("Error: disable UART '%d' failed.\r\n", + (int)obj_getInt(self, "id")); + return; + } + obj_setInt(self, "enabled", 0); } void PikaStdDevice_UART_platformReadBytes(PikaObj* self) { From 851258e7109c49745808fc0d824ca2a7cc477133 Mon Sep 17 00:00:00 2001 From: lyon1998 Date: Mon, 1 May 2023 20:11:18 +0800 Subject: [PATCH 5/9] update_toml --- packages.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index 2ddce5670..b79b35a90 100644 --- a/packages.toml +++ b/packages.toml @@ -187,7 +187,8 @@ releases = [ "v2.3.3 5282cff66fe8f003c75fd82c54c0144aa7da8277", "v2.3.4 69cea1d7188b35b84d819ed8cb8f41b3a64d39d1", "v2.3.5 cd0029b6d1b4340b252532fcee1320667231038c", - "v2.3.6 b9a0109c6125d16270cf02b2a07421a4baf9973c" + "v2.3.6 b9a0109c6125d16270cf02b2a07421a4baf9973c", + "v2.3.7 226cba58e474448a9d8773c5a1a1bd83f148baee" ] [[packages]] From 322893880a8876d2916817898c2e02d1b9b1f613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Mon, 1 May 2023 12:12:39 +0000 Subject: [PATCH 6/9] update src/dataString.c. --- src/dataString.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataString.c b/src/dataString.c index d63b34bc5..341e38507 100644 --- a/src/dataString.c +++ b/src/dataString.c @@ -94,7 +94,7 @@ const char bracketStart[] = {'(', '[', '{', '\'', '\"'}; const char bracketEnd[] = {')', ']', '}', '\'', '\"'}; #define BRACKET_TYPE_NUM (sizeof(bracketStart) / sizeof(char)) -int32_t _strCountSign(char* strIn, char sign, PIKA_BOOL bracketDepth0) { +int _strCountSign(char* strIn, char sign, PIKA_BOOL bracketDepth0) { int32_t iCount = 0; int32_t iTotalDepth = 0; PIKA_BOOL bEscaped = PIKA_FALSE; From a333cc854f6937c885c8946417b6c4ae5603668d Mon Sep 17 00:00:00 2001 From: pikastech Date: Mon, 1 May 2023 21:48:33 +0800 Subject: [PATCH 7/9] support max(), min() builtin --- package/PikaStdLib/PikaStdData_Tuple.c | 3 + package/PikaStdLib/PikaStdLib.pyi | 8 ++ package/PikaStdLib/PikaStdLib_SysObj.c | 88 +++++++++++++++++++ port/linux/.vscode/launch.json | 2 +- port/linux/package/pikascript/PikaStdLib.pyi | 8 ++ .../PikaStdLib/PikaStdData_Tuple.c | 3 + .../PikaStdLib/PikaStdLib_SysObj.c | 88 +++++++++++++++++++ src/PikaObj.c | 1 + test/builtin-test.cpp | 2 + test/compile-test.cpp | 22 ++++- test/python/builtin/max_min.py | 13 +++ 11 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 test/python/builtin/max_min.py diff --git a/package/PikaStdLib/PikaStdData_Tuple.c b/package/PikaStdLib/PikaStdData_Tuple.c index 77c2e2070..f7b6a5c32 100644 --- a/package/PikaStdLib/PikaStdData_Tuple.c +++ b/package/PikaStdLib/PikaStdData_Tuple.c @@ -43,6 +43,9 @@ Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) { } void PikaStdData_Tuple___del__(PikaObj* self) { + if (0 == obj_getInt(self, "needfree")) { + return; + } Args* list = obj_getPtr(self, "list"); args_deinit(list); } diff --git a/package/PikaStdLib/PikaStdLib.pyi b/package/PikaStdLib/PikaStdLib.pyi index 9ad0b1e87..31eccdd29 100644 --- a/package/PikaStdLib/PikaStdLib.pyi +++ b/package/PikaStdLib/PikaStdLib.pyi @@ -126,6 +126,14 @@ class SysObj: @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") def abs(val: any) -> any: ... + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def max(*val) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def min(*val) -> any: ... + @staticmethod @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") def help(name: str): ... diff --git a/package/PikaStdLib/PikaStdLib_SysObj.c b/package/PikaStdLib/PikaStdLib_SysObj.c index 72ddadf64..acae67a01 100644 --- a/package/PikaStdLib/PikaStdLib_SysObj.c +++ b/package/PikaStdLib/PikaStdLib_SysObj.c @@ -707,3 +707,91 @@ Arg* PikaStdLib_SysObj_abs(PikaObj* self, Arg* val) { obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); return NULL; } + +PikaObj* New_PikaStdData_Tuple(Args* args); +/* clang-format off */ +PIKA_PYTHON( +@res_max = @list[0] +for @item in @list: + if @item > @res_max: + @res_max = @item +) +/* clang-format on */ +const uint8_t bc_max[] = { + 0x4c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00, + 0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00, + 0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00, + 0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00, + 0x00, 0x8c, 0x17, 0x00, /* instruct array */ + 0x37, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65, + 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, + 0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00, + 0x3e, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */ +}; + +/* clang-format off */ +PIKA_PYTHON( +@res_max = @list[0] +for @item in @list: + if @item < @res_max: + @res_max = @item + +) +/* clang-format on */ +const uint8_t bc_min[] = { + 0x4c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00, + 0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00, + 0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00, + 0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00, + 0x00, 0x8c, 0x17, 0x00, /* instruct array */ + 0x37, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65, + 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, + 0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00, + 0x3c, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */ +}; + +Arg* _max_min(PikaObj* self, PikaTuple* val, uint8_t* bc) { + int size = pikaTuple_getSize(val); + if (size == 0) { + obj_setSysOut(self, "TypeError: max expected 1 arguments, got 0"); + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + return NULL; + } + if (size == 1) { + ArgType type = arg_getType(pikaTuple_getArg(val, 0)); + if ((!argType_isObject(type) && (type != ARG_TYPE_STRING) && + (type != ARG_TYPE_BYTES))) { + obj_setSysOut(self, "TypeError: object is not iterable"); + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + return NULL; + } + obj_setArg(self, "@list", pikaTuple_getArg(val, 0)); + return pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max"); + } + PikaObj* oTuple = newNormalObj(New_PikaStdData_Tuple); + obj_setPtr(oTuple, "list", val); + obj_setInt(oTuple, "needfree", 0); + Arg* aTuple = arg_newObj(oTuple); + obj_setArg(self, "@list", aTuple); + Arg* aRet = pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max"); + arg_deinit(aTuple); + return aRet; +} + +Arg* PikaStdLib_SysObj_max(PikaObj* self, PikaTuple* val) { + return _max_min(self, val, (uint8_t*)bc_max); +} + +Arg* PikaStdLib_SysObj_min(PikaObj* self, PikaTuple* val) { + return _max_min(self, val, (uint8_t*)bc_min); +} diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 7bdf4ec36..45ea0c4b3 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -20,7 +20,7 @@ // "--gtest_filter=eventloop.test1" // "--gtest_filter=parser.tuple_single" // "--gtest_filter=parser.*" - "--gtest_filter=pikaMain.REPL_key_down_over" + "--gtest_filter=builtin.max_min" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/package/pikascript/PikaStdLib.pyi b/port/linux/package/pikascript/PikaStdLib.pyi index 9ad0b1e87..31eccdd29 100644 --- a/port/linux/package/pikascript/PikaStdLib.pyi +++ b/port/linux/package/pikascript/PikaStdLib.pyi @@ -126,6 +126,14 @@ class SysObj: @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") def abs(val: any) -> any: ... + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def max(*val) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def min(*val) -> any: ... + @staticmethod @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") def help(name: str): ... diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c index 77c2e2070..f7b6a5c32 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c @@ -43,6 +43,9 @@ Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) { } void PikaStdData_Tuple___del__(PikaObj* self) { + if (0 == obj_getInt(self, "needfree")) { + return; + } Args* list = obj_getPtr(self, "list"); args_deinit(list); } 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 72ddadf64..acae67a01 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -707,3 +707,91 @@ Arg* PikaStdLib_SysObj_abs(PikaObj* self, Arg* val) { obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); return NULL; } + +PikaObj* New_PikaStdData_Tuple(Args* args); +/* clang-format off */ +PIKA_PYTHON( +@res_max = @list[0] +for @item in @list: + if @item > @res_max: + @res_max = @item +) +/* clang-format on */ +const uint8_t bc_max[] = { + 0x4c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00, + 0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00, + 0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00, + 0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00, + 0x00, 0x8c, 0x17, 0x00, /* instruct array */ + 0x37, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65, + 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, + 0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00, + 0x3e, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */ +}; + +/* clang-format off */ +PIKA_PYTHON( +@res_max = @list[0] +for @item in @list: + if @item < @res_max: + @res_max = @item + +) +/* clang-format on */ +const uint8_t bc_min[] = { + 0x4c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00, + 0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00, + 0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00, + 0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00, + 0x00, 0x8c, 0x17, 0x00, /* instruct array */ + 0x37, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65, + 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, + 0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00, + 0x3c, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */ +}; + +Arg* _max_min(PikaObj* self, PikaTuple* val, uint8_t* bc) { + int size = pikaTuple_getSize(val); + if (size == 0) { + obj_setSysOut(self, "TypeError: max expected 1 arguments, got 0"); + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + return NULL; + } + if (size == 1) { + ArgType type = arg_getType(pikaTuple_getArg(val, 0)); + if ((!argType_isObject(type) && (type != ARG_TYPE_STRING) && + (type != ARG_TYPE_BYTES))) { + obj_setSysOut(self, "TypeError: object is not iterable"); + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + return NULL; + } + obj_setArg(self, "@list", pikaTuple_getArg(val, 0)); + return pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max"); + } + PikaObj* oTuple = newNormalObj(New_PikaStdData_Tuple); + obj_setPtr(oTuple, "list", val); + obj_setInt(oTuple, "needfree", 0); + Arg* aTuple = arg_newObj(oTuple); + obj_setArg(self, "@list", aTuple); + Arg* aRet = pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max"); + arg_deinit(aTuple); + return aRet; +} + +Arg* PikaStdLib_SysObj_max(PikaObj* self, PikaTuple* val) { + return _max_min(self, val, (uint8_t*)bc_max); +} + +Arg* PikaStdLib_SysObj_min(PikaObj* self, PikaTuple* val) { + return _max_min(self, val, (uint8_t*)bc_min); +} diff --git a/src/PikaObj.c b/src/PikaObj.c index 333f699df..30f3055b8 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1344,6 +1344,7 @@ ShellHistory* shHistory_create(int max_size) { self->current = -1; self->count = 0; self->last_offset = 0; + self->cached_current = 0; self->history = (char**)pikaMalloc(max_size * sizeof(char*)); return self; } diff --git a/test/builtin-test.cpp b/test/builtin-test.cpp index 19ab2957b..712aa2d0f 100644 --- a/test/builtin-test.cpp +++ b/test/builtin-test.cpp @@ -200,6 +200,8 @@ TEST_RUN_SINGLE_FILE_PASS(builtin, fn_default_tuple, "test/python/builtin/fn_default_tuple.py") +TEST_RUN_SINGLE_FILE_PASS(builtin, max_min, "test/python/builtin/max_min.py") + #endif TEST_END \ No newline at end of file diff --git a/test/compile-test.cpp b/test/compile-test.cpp index e40320625..277c505b8 100644 --- a/test/compile-test.cpp +++ b/test/compile-test.cpp @@ -755,11 +755,29 @@ TEST(compiler, str_join) { } TEST(compiler, thread_void_arg) { - char* lines = - "thread()"; + char* lines = "thread()"; pika_lines2Array(lines); EXPECT_EQ(pikaMemNow(), 0); } +TEST(compiler, max) { + char* lines = + "@res_max = @list[0]\n" + "for @item in @list:\n" + " if @item > @res_max:\n" + " @res_max = @item\n"; + pika_lines2Array(lines); + EXPECT_EQ(pikaMemNow(), 0); +} + +TEST(compiler, min) { + char* lines = + "@res_max = @list[0]\n" + "for @item in @list:\n" + " if @item < @res_max:\n" + " @res_max = @item\n"; + pika_lines2Array(lines); + EXPECT_EQ(pikaMemNow(), 0); +} TEST_END \ No newline at end of file diff --git a/test/python/builtin/max_min.py b/test/python/builtin/max_min.py new file mode 100644 index 000000000..7b2b2d6dc --- /dev/null +++ b/test/python/builtin/max_min.py @@ -0,0 +1,13 @@ +# 测试 max() 函数 +assert max(1, 2, 3) == 3, "max() 函数错误: max(1, 2, 3) 应返回 3" +assert max(-1, -2, -3) == -1, "max() 函数错误: max(-1, -2, -3) 应返回 -1" +assert max(5, 5) == 5, "max() 函数错误: max(5, 5) 应返回 5" +assert max([1, 2, 3, 4]) == 4, "max() 函数错误: max([1, 2, 3, 4]) 应返回 4" + +# 测试 min() 函数 +assert min(1, 2, 3) == 1, "min() 函数错误: min(1, 2, 3) 应返回 1" +assert min(-1, -2, -3) == -3, "min() 函数错误: min(-1, -2, -3) 应返回 -3" +assert min(5, 5) == 5, "min() 函数错误: min(5, 5) 应返回 5" +assert min([1, 2, 3, 4]) == 1, "min() 函数错误: min([1, 2, 3, 4]) 应返回 1" + +print('PASS') From 0c47b42a014e66458bd0848bb19de069e6933f1b Mon Sep 17 00:00:00 2001 From: lyon1998 Date: Tue, 2 May 2023 22:16:41 +0800 Subject: [PATCH 8/9] add_files --- package/ESP32/pika_hal_ESP32_UART.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/package/ESP32/pika_hal_ESP32_UART.c b/package/ESP32/pika_hal_ESP32_UART.c index 47ad83d09..e7b54b685 100644 --- a/package/ESP32/pika_hal_ESP32_UART.c +++ b/package/ESP32/pika_hal_ESP32_UART.c @@ -3,7 +3,10 @@ #include "dataStrs.h" #include "driver/uart.h" #include "pika_hal_ESP32_common.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +extern volatile PikaMemInfo g_PikaMemInfo; typedef struct platform_data_UART { uart_port_t uartPort; uart_config_t uart_conf; @@ -12,8 +15,11 @@ typedef struct platform_data_UART { gpio_num_t rx_port; gpio_num_t rts_port; gpio_num_t cts_port; + PIKA_BOOL event_thread_started; } platform_data_UART; +static SemaphoreHandle_t g_event_lock = NULL; + int pika_hal_platform_UART_open(pika_dev* dev, char* name) { /* UARTX */ if (name[0] != 'U' || name[1] != 'A' || name[2] != 'R' || name[3] != 'T') { @@ -79,7 +85,10 @@ static void uart_event_task(void* pvParameters) { data events than other types of events. If we take too much time on data event, the queue might be full.*/ case UART_DATA: + pika_assert(g_event_lock != NULL); + xSemaphoreTake(g_event_lock, portMAX_DELAY); cfg->event_callback(dev, event.type); + xSemaphoreGive(g_event_lock); break; // Others default: @@ -87,6 +96,7 @@ static void uart_event_task(void* pvParameters) { } } } + g_PikaMemInfo.heapUsed -= PIKA_THREAD_STACK_SIZE; vTaskDelete(NULL); } @@ -220,6 +230,11 @@ int pika_hal_platform_UART_ioctl_config(pika_dev* dev, uart->cts_port = UART_PIN_NO_CHANGE; } + if (dev->is_enabled){ + pika_debug("UART%d: uart is enabled, reconfig\r\n", uart->uartPort); + uart_param_config(uart->uartPort, &uart->uart_conf); + } + /* support event callback */ if (dev->is_enabled == PIKA_TRUE && NULL != cfg->event_callback && PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE == cfg->event_callback_ena) { @@ -241,8 +256,16 @@ int pika_hal_platform_UART_ioctl_config(pika_dev* dev, cfg->event_callback_filter); return -1; } - /* start irq task thread */ - xTaskCreate(uart_event_task, "uart_event_task", 8192, dev, 12, NULL); + if (uart->event_thread_started == PIKA_FALSE){ + /* start irq task thread */ + pika_debug("Starting uart event task:%p\r\n", dev); + if (NULL == g_event_lock){ + g_event_lock = xSemaphoreCreateMutex(); + } + g_PikaMemInfo.heapUsed += PIKA_THREAD_STACK_SIZE; + xTaskCreate(uart_event_task, "uart_event_task", PIKA_THREAD_STACK_SIZE, dev, 12, NULL); + uart->event_thread_started = PIKA_TRUE; + } } return 0; } From 040d1c0efc3400ff8791f4d3f42f75f111867f69 Mon Sep 17 00:00:00 2001 From: lyon1998 Date: Tue, 2 May 2023 22:16:41 +0800 Subject: [PATCH 9/9] update_toml --- packages.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index b79b35a90..7f4ec17b5 100644 --- a/packages.toml +++ b/packages.toml @@ -399,7 +399,8 @@ releases = [ "v0.1.0 ee7e38e9422970bba86f5cd7774db8654edd38dc", "v0.2.0 93591e92863f5e192dc89aed6666fd9dab4f7a82", "v0.3.0 8202a1ab52f15f70cd93abb0d409aa03da8170b0", - "v0.3.1 918464a8567f84c87ddda68de99f3d032ee812e0" + "v0.3.1 918464a8567f84c87ddda68de99f3d032ee812e0", + "v0.4.0 0c47b42a014e66458bd0848bb19de069e6933f1b" ] [[packages]]