diff --git a/Makefile b/Makefile index e6b3644..718d768 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ OBJS=emul.o emul_inst_exec.o emul_inst_decipher.o emul_reg.o emul_mem.o emul_label.o emul_opt.o emul_repl.o emul_io_std.o PROGRAM=emul CC=gcc -CCOPT=-lncurses +CCOPT=-lncurses -lpanel ifeq ($(OS), Windows_NT) # Cygwin diff --git a/emul_io_std.c b/emul_io_std.c index 858f688..7211cd8 100644 --- a/emul_io_std.c +++ b/emul_io_std.c @@ -7,11 +7,18 @@ } static WINDOW *win; +static SCREEN *scr[2]; -WINDOW* emul_getWin() { return win; } +SCREEN* emul_getScr(int i) { return scr[i]; } +WINDOW* emul_getWin() { + return win; +} void emul_std_init() { - win = initscr(); + scr[1] = newterm("xterm", stdout, stdin); + endwin(); + scr[0] = newterm("xterm", stdout, stdin); + win = stdscr; scrollok(win, TRUE); refresh(); } diff --git a/emul_io_std.h b/emul_io_std.h index 5d0e348..86958ff 100644 --- a/emul_io_std.h +++ b/emul_io_std.h @@ -8,6 +8,7 @@ void emul_std_debug(int level); WINDOW* emul_getWin(); +SCREEN* emul_getScr(int i); void emul_std_init(); void emul_std_end(); diff --git a/emul_repl.c b/emul_repl.c index 3c6f535..7997412 100644 --- a/emul_repl.c +++ b/emul_repl.c @@ -4,87 +4,159 @@ #include "emul_io_std.h" #include #include -#include +//#include +#include #define READ_LINE_MAX 64 +static int REPL_RUNMODE = REPL_OK; + static WINDOW *win; - -void emul_repl_readline(char input[READ_LINE_MAX]) { - static int current_line = 0; - int history = 0; - int c; - int i = 0; +// ヒストリ番号表示のため +void emul_repl_show_history(char *input, int line) { + int i; + int max_y, max_x; int y, x; - // ヒストリ番号表示のため - void emul_repl_show_history() { - int max_y, max_x; - input[0] = '\0'; - emul_inst_dec_get_line(input, current_line+history); - getyx(win, y, x); - // 1行削除 - move(y, 0); - clrtoeol(); - // ヒストリ番号表示 - getmaxyx(win, max_y, max_x); - move(y, max_x-8); - printw("L[%5d]", current_line+history); - // ヒストリ表示および格納 - move(y, 0); - printw(">>"); - i = 0; - while ( input[i] != '\n' && input[i] != '\0') { - echochar(input[i++]); - } - refresh(); + input[0] = '\0'; + emul_inst_dec_get_line(input, line); + getyx(win, y, x); + // 1行削除 + move(y, 0); + clrtoeol(); + // ヒストリ番号表示 + getmaxyx(win, max_y, max_x); + move(y, max_x-8); + printw("L[%5d]", line); + // ヒストリ表示および格納 + move(y, 0); + printw(">>"); + i = 0; + while ( input[i] != '\n' && input[i] != '\0') { + echochar(input[i++]); } - current_line = emul_inst_dec_get_program_line_max(); + refresh(); +} + +// ヘルプの表示 +void emul_repl_show_help() { + PANEL *help_panel; + int y, x; + char help_title[] = "Display for help"; + + endwin(); + set_term(emul_getScr(1)); + refresh(); + + // title + getmaxyx(win, y, x); + move(1, (x-strlen(help_title))/2); + printw("%s\n\n", help_title); + printw("Command to this Emulator REPL : You need to put ':' for swich command mode.\n\n"); + printw("\t:help\tDisplay help\n"); + printw("\t:quit\tExit repl\n"); + refresh(); + getch(); + + endwin(); + set_term(emul_getScr(0)); + refresh(); +} + +int emul_repl_read(char *input, int *i, int c) { + static int history; + // プログラムの行数を取得 + int current_line = emul_inst_dec_get_program_line_max(); + int y, x; + if (c == '\n') { + history = 0; + } else if (c == 127 || c == KEY_BACKSPACE || c == KEY_LEFT) { // Delete and back + if ( (*i) > 0 ) { + getyx(win, y, x); + input[--(*i)] = '\0'; + wmove(win, y, x-1); + clrtoeol(); + refresh(); + } + } else if (c == KEY_UP) { + if (current_line+history > 0) { + history--; + emul_repl_show_history(input, current_line+history); + } + } else if (c == KEY_DOWN) { + if (current_line+history < current_line) { + history++; + emul_repl_show_history(input, current_line+history); + } + } else if (c == KEY_RIGHT) { + // Nothing do + } else { + input[(*i)++] = (char)c; + input[(*i)] = '\0'; + printw("%c", c); + refresh(); + } + return c; +} + +// コマンド入力用 +void emul_repl_command() { + char buff[READ_LINE_MAX]; + int index; + int c; + + int temp_y, temp_x; + int y, x; + getyx(win, temp_y, temp_x); + getmaxyx(win, y, x); + y -= 1; + + wmove(win, y, 0); + printw(":"); + refresh(); + + buff[0] = '\0'; + while ((c = getch()) != '\n') { + if (c == KEY_UP || c == KEY_DOWN) continue; + c = emul_repl_read(buff, &index, c); + } + + if (strcmp(buff, "help") == 0) emul_repl_show_help(); + if (strcmp(buff, "quit") == 0) REPL_RUNMODE = REPL_EXIT; + + // end + move(y,0); + clrtoeol(); + move(temp_y, temp_x); + refresh(); +} + +// インタプリンタ入力用 +void emul_repl_readline(char input[READ_LINE_MAX]) { + int c; + int y, x; + int index = 0; + int history = 0; + printw(">>"); refresh(); noecho(); cbreak(); while( (c = getch()) != '\n' ) { - if (c == 127 || c == KEY_BACKSPACE) { // Delete and back - if ( i > 0 ) { - getyx(win, y, x); - input[--i] = '\0'; - move(y, x-1); - clrtoeol(); - refresh(); - } - } else if (c == KEY_UP) { - if (current_line+history > 0) { - history--; - emul_repl_show_history(); - } - } else if (c == KEY_DOWN) { - if (current_line+history < current_line) { - history++; - emul_repl_show_history(); - } - } else if (c == KEY_RIGHT) { - // Nothing do - } else if (c == KEY_LEFT) { - if ( i > 0 ) { - getyx(win, y, x); - input[--i] = '\0'; - move(y, x-1); - clrtoeol(); - refresh(); - } - } else { - input[i++] = c; - input[i] = '\0'; - printw("%c", c); - refresh(); + c = emul_repl_read(input, &index, c); + if (c == ':') { + emul_repl_read(input, &index, KEY_BACKSPACE); + emul_repl_command(); + if (REPL_RUNMODE == REPL_EXIT) break; } + refresh(); } + // キャッシュをクリア + emul_repl_read(input, &index, '\n'); echo(); clrtoeol(); printw("\n"); refresh(); - current_line++; } void emul_repl_printline(); @@ -97,8 +169,8 @@ } char *menu[] = { - "Display help >>#help", - " Exit >>#exit" + "Display help >>:help", + " Exit >>:quit" }; void emul_repl_start() { @@ -127,6 +199,9 @@ while (1) { emul_repl_readline(input); + // フラグを確認 + if (REPL_RUNMODE == REPL_EXIT) break; + emul_inst_exec_loadline(input); state = emul_inst_exec_run(); if (state == Failed) { diff --git a/emul_repl.h b/emul_repl.h index 004dd10..ebc9927 100644 --- a/emul_repl.h +++ b/emul_repl.h @@ -1,6 +1,11 @@ #ifndef ENUL_REPL__ #define ENUL_REPL__ +enum { + REPL_OK, + REPL_EXIT +}; + void emul_repl_init(); void emul_repl_start();