supporting REPL key_up

This commit is contained in:
lyon 2023-05-01 00:27:33 +08:00
parent 9112661ed3
commit c5751ae48f
7 changed files with 223 additions and 38 deletions

View File

@ -20,7 +20,7 @@
// "--gtest_filter=eventloop.test1"
// "--gtest_filter=parser.tuple_single"
// "--gtest_filter=parser.*"
"--gtest_filter=VM.is"
"--gtest_filter=pikaMain.REPL_key_up"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -51,13 +51,15 @@ volatile PikaObjState g_PikaObjState = {
#endif
};
static volatile ShellConfig g_repl_shell;
PikaObj* New_PikaStdData_Dict(Args* args);
PikaObj* New_PikaStdData_dict_keys(Args* args);
PikaObj* New_PikaStdData_List(Args* args);
PikaObj* New_PikaStdData_Tuple(Args* args);
void PikaStdData_Tuple___init__(PikaObj *self);
void PikaStdData_List___init__(PikaObj *self);
void PikaStdData_List_append(PikaObj *self, Arg* arg);
void PikaStdData_Tuple___init__(PikaObj* self);
void PikaStdData_List___init__(PikaObj* self);
void PikaStdData_List_append(PikaObj* self, Arg* arg);
void _mem_cache_deinit(void);
void _VMEvent_deinit(void);
void pikaGC_markObj(PikaGC* gc, PikaObj* self);
@ -197,6 +199,7 @@ int32_t obj_deinit(PikaObj* self) {
pikaGC_unlock();
if (bisRoot) {
pikaGC_markSweep();
shConfig_deinit((ShellConfig*)&g_repl_shell);
}
return ret;
}
@ -1285,6 +1288,90 @@ 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*));
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);
}
pikaFree(self->history_list, self->max_size * sizeof(char*));
pikaFree(self, sizeof(ShellHistory));
}
char* shHistory_get(ShellHistory* self, int index) {
if (index < 0 || index >= self->current_size) {
return NULL;
}
int actual_index = (self->head + index) % self->max_size;
return self->history_list[actual_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];
}
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];
}
#endif
enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
char inputChar,
ShellConfig* shell) {
@ -1311,7 +1398,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
shell->stat = PIKA_SHELL_STATE_NORMAL;
}
if (shell->stat == PIKA_SHELL_STATE_WAIT_FUNC_KEY) {
if (inputChar == KEY_LEFT) {
if (inputChar == PIKA_KEY_LEFT) {
if (shell->line_curpos) {
shell->line_curpos--;
} else {
@ -1320,7 +1407,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
ctrl = SHELL_CTRL_CONTINUE;
goto exit;
}
if (inputChar == KEY_RIGHT) {
if (inputChar == PIKA_KEY_RIGHT) {
if (shell->line_curpos < shell->line_position) {
// pika_platform_printf("%c",
// shell->lineBuff[shell->line_curpos]);
@ -1331,12 +1418,31 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
ctrl = SHELL_CTRL_CONTINUE;
goto exit;
}
if (inputChar == KEY_UP) {
_putc_cmd(KEY_DOWN, 1);
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 (shell->history->current_index == 0) {
/* save the current line */
shHistory_add(shell->history, shell->lineBuff);
}
char* prev = shHistory_getPrev(shell->history);
/* clear the current line */
for (int i = 0; i < shell->line_position; i++) {
pika_platform_printf("\b \b");
}
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
goto exit;
}
if (inputChar == KEY_DOWN) {
if (inputChar == PIKA_KEY_DOWN) {
ctrl = SHELL_CTRL_CONTINUE;
goto exit;
}
@ -1358,7 +1464,8 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
/* update screen */
pika_platform_printf(shell->lineBuff + shell->line_curpos);
pika_platform_printf(" ");
_putc_cmd(KEY_LEFT, shell->line_position - shell->line_curpos + 1);
_putc_cmd(PIKA_KEY_LEFT,
shell->line_position - shell->line_curpos + 1);
}
ctrl = SHELL_CTRL_CONTINUE;
goto exit;
@ -1379,7 +1486,8 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
shell->lineBuff[shell->line_position + 1] = 0;
if (shell->line_curpos != shell->line_position) {
pika_platform_printf(shell->lineBuff + shell->line_curpos + 1);
_putc_cmd(KEY_LEFT, shell->line_position - shell->line_curpos);
_putc_cmd(PIKA_KEY_LEFT,
shell->line_position - shell->line_curpos);
}
shell->lineBuff[shell->line_curpos] = inputChar;
shell->line_position++;
@ -1391,6 +1499,12 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
if ((inputChar == '\r') || (inputChar == '\n')) {
#if !(defined(__linux) || defined(_WIN32) || PIKA_SHELL_NO_NEWLINE)
pika_platform_printf("\r\n");
#endif
#if PIKA_SHELL_HISTORY_ENABLE
if (NULL == shell->history) {
shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM);
}
shHistory_add(shell->history, shell->lineBuff);
#endif
/* still in block */
if (shell->blockBuffName != NULL && shell->inBlock) {
@ -1485,16 +1599,15 @@ enum shellCTRL _do_obj_runChar(PikaObj* self,
}
enum shellCTRL obj_runChar(PikaObj* self, char inputChar) {
ShellConfig* shell = args_getStruct(self->list, "@shcfg");
ShellConfig* shell = args_getHeapStruct(self->list, "@shcfg");
if (NULL == shell) {
/* init the shell */
ShellConfig newShell = {
.prefix = ">>> ",
.blockBuffName = "@sh1",
.handler = __obj_shellLineHandler_REPL,
};
args_setStruct(self->list, "@shcfg", newShell);
shell = args_getStruct(self->list, "@shcfg");
ShellConfig newShell = {0};
newShell.prefix = ">>> ";
newShell.blockBuffName = "@sh1";
newShell.handler = __obj_shellLineHandler_REPL;
args_setHeapStruct(self->list, "@shcfg", newShell, shConfig_deinit);
shell = args_getHeapStruct(self->list, "@shcfg");
_obj_runChar_beforeRun(self, shell);
}
return _do_obj_runChar(self, inputChar, shell);
@ -1679,6 +1792,9 @@ static volatile ShellConfig g_repl_shell = {
.handler = __obj_shellLineHandler_REPL,
.prefix = ">>> ",
.blockBuffName = "@sh0",
#if PIKA_SHELL_HISTORY_ENABLE
.history = NULL,
#endif
};
void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn) {
@ -1686,6 +1802,16 @@ void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn) {
_do_pikaScriptShell(self, (ShellConfig*)&g_repl_shell);
}
int shConfig_deinit(ShellConfig* self) {
#if PIKA_SHELL_HISTORY_ENABLE
if (NULL != self->history) {
shHistory_destroy(self->history);
self->history = NULL;
}
#endif
return 0;
}
void pikaScriptShell(PikaObj* self) {
pikaScriptShell_withGetchar(self, pika_platform_getchar);
}
@ -2471,8 +2597,8 @@ void pks_printVersion(void) {
}
void pks_getVersion(char* buff) {
pika_sprintf(buff, "%d.%d.%d", PIKA_VERSION_MAJOR,
PIKA_VERSION_MINOR, PIKA_VERSION_MICRO);
pika_sprintf(buff, "%d.%d.%d", PIKA_VERSION_MAJOR, PIKA_VERSION_MINOR,
PIKA_VERSION_MICRO);
}
void* obj_getStruct(PikaObj* self, char* name) {

View File

@ -137,10 +137,10 @@ struct PikaObjState {
#define OBJ_FLAG_GC_MARKED 1 << 6
#define OBJ_FLAG_GC_ROOT 1 << 7
#define KEY_UP 0x41
#define KEY_DOWN 0x42
#define KEY_RIGHT 0x43
#define KEY_LEFT 0x44
#define PIKA_KEY_UP 0x41
#define PIKA_KEY_DOWN 0x42
#define PIKA_KEY_RIGHT 0x43
#define PIKA_KEY_LEFT 0x44
static inline uint8_t obj_getFlag(PikaObj* self, uint8_t flag) {
pika_assert(self);
@ -335,6 +335,8 @@ typedef struct ShellConfig ShellConfig;
typedef enum shellCTRL (*sh_handler)(PikaObj*, char*, ShellConfig*);
typedef char (*sh_getchar)(void);
int shConfig_deinit(ShellConfig* self);
#if PIKA_SHELL_FILTER_ENABLE
typedef struct FilterFIFO {
ByteQueue queue;
@ -361,6 +363,15 @@ struct FilterItem {
#endif
typedef struct {
int max_size;
int current_size;
int head;
int tail;
int current_index;
char** history_list;
} ShellHistory;
struct ShellConfig {
#if PIKA_SHELL_FILTER_ENABLE
FilterFIFO filter_fifo;
@ -379,8 +390,21 @@ struct ShellConfig {
char lastChar;
sh_getchar fn_getchar;
uint8_t stat;
#if PIKA_SHELL_HISTORY_ENABLE
ShellHistory* history;
#endif
};
#if PIKA_SHELL_HISTORY_ENABLE
ShellHistory* shHistory_create(int max_size);
void shHistory_destroy(ShellHistory* self);
void shHistory_add(ShellHistory* self, char* command);
void shHistory_setMaxSize(ShellHistory* self, int max_size);
char* shHistory_get(ShellHistory* self, int index);
char* shHistory_getPrev(ShellHistory* self);
char* shHistory_getNext(ShellHistory* self);
#endif
void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);
void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);
@ -653,8 +677,9 @@ Arg* pks_eventListener_sendSignalAwaitResult(PikaEventListener* self,
void obj_printModules(PikaObj* self);
#if PIKA_DEBUG_ENABLE
#define pika_debug(fmt, ...) \
pika_platform_printf(COLOR_GREEN "[PikaDBG] " fmt "\r\n" COLOR_RESET, ##__VA_ARGS__)
#define pika_debug(fmt, ...) \
pika_platform_printf(COLOR_GREEN "[PikaDBG] " fmt "\r\n" COLOR_RESET, \
##__VA_ARGS__)
#else
#define pika_debug(...) \
do { \

View File

@ -675,6 +675,6 @@ PIKA_WEAK void pika_platform_clear(void) {
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
}
PIKA_WEAK void pika_platform_abort_handler(void){
PIKA_WEAK void pika_platform_abort_handler(void) {
return;
}

View File

@ -274,6 +274,9 @@ void* args_getStruct(Args* self, char* name) {
void* args_getHeapStruct(Args* self, char* name) {
Arg* struct_arg = args_getArg(self, name);
if (NULL == struct_arg) {
return NULL;
}
return arg_getHeapStruct(struct_arg);
}
@ -564,7 +567,7 @@ Arg* pikaList_pop_withIndex(PikaList* list, int index) {
if (top <= 0) {
return NULL;
}
if (index < 0){
if (index < 0) {
index = top + index;
}
Arg* arg = pikaList_getArg(list, index);

View File

@ -89,6 +89,10 @@ extern "C" {
#define PIKA_GC_MARK_SWEEP_ENABLE 0
#endif
#ifndef PIKA_SHELL_HISTORY_ENABLE
#define PIKA_SHELL_HISTORY_ENABLE 0
#endif
#endif
/* default optimize */
@ -463,6 +467,14 @@ extern "C" {
#define PIKA_KERNAL_DEBUG_ENABLE 0
#endif
#ifndef PIKA_SHELL_HISTORY_ENABLE
#define PIKA_SHELL_HISTORY_ENABLE 1
#endif
#ifndef PIKA_SHELL_HISTORY_NUM
#define PIKA_SHELL_HISTORY_NUM 5
#endif
/* configuration validation */
#endif

View File

@ -1116,11 +1116,11 @@ TEST(pikaMain, class_arg) {
__platform_printf("BEGIN\r\n");
Args* buffs = New_strBuff();
char* pikaAsm = pika_lines2Asm(buffs,
"class Test(TinyObj):\n"
" x = 1\n"
"\n"
"test = Test()\n"
"print(test.x)\n");
"class Test(TinyObj):\n"
" x = 1\n"
"\n"
"test = Test()\n"
"print(test.x)\n");
printf("%s", pikaAsm);
pikaVM_runAsm(pikaMain, pikaAsm);
/* assert */
@ -2790,8 +2790,8 @@ TEST(pikaMain, REPL_backspace_issue_2) {
}
TEST(pikaMain, REPL_key_left) {
char lines[] = {'1', '2', '+', '3', '4', 0x1b,
0x5b, KEY_LEFT, '5', '\n', 0x00};
char lines[] = {'1', '2', '+', '3', '4', 0x1b,
0x5b, PIKA_KEY_LEFT, '5', '\n', 0x00};
/* init */
g_PikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
@ -2809,8 +2809,8 @@ TEST(pikaMain, REPL_key_left) {
}
TEST(pikaMain, REPL_key_left_del) {
char lines[] = {'1', '2', '+', '3', '4', 0x1b,
0x5b, KEY_LEFT, '\b', '\n', 0x00};
char lines[] = {'1', '2', '+', '3', '4', 0x1b,
0x5b, PIKA_KEY_LEFT, '\b', '\n', 0x00};
/* init */
g_PikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
@ -2827,6 +2827,25 @@ TEST(pikaMain, REPL_key_left_del) {
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(pikaMain, REPL_key_up) {
char lines[] = {'1', '2', '+', '3', '4', '5', '\n',
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);
}
#if PIKA_SHELL_FILTER_ENABLE
TEST(pikaMain, SHELL_filter_hi_pika) {