#include "emul_repl.h" #include "emul_inst_exec.h" #include "emul_inst_decipher.h" #include "emul_io_std.h" #include <stdio.h> #include <string.h> //#include <ncurses.h> #include <panel.h> #define READ_LINE_MAX 64 static int REPL_RUNMODE = REPL_OK; static WINDOW *win; // ヒストリ番号表示のため void emul_repl_show_history(char *input, int line) { int i; int max_y, max_x; int y, x; 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++]); } 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("Summary:\n\n"); printw(" This program is Asembly Emulator.\n\n"); printw("Command to this Emulator REPL:\n\n"); printw(" You need to put ':' for swich command mode.\n\n"); printw(" :help Display help\n"); printw(" :quit Exit repl\n"); refresh(); move(y-1, 0); printw(" Put any key to exit this help."); move(y-1, 0); 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 temp_y, temp_x; int index = 0; int history = 0; getyx(win, y, x); getmaxyx(win, temp_y, temp_x); scrollok(win, TRUE); if (y > temp_y-2) { scrl(1); move(y-1, 0); } printw(">>"); refresh(); noecho(); cbreak(); while( (c = getch()) != '\n' ) { 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(); } void emul_repl_printline(); void emul_repl_init() { emul_inst_exec_init(); // ウィンドウポインタ取得 win = emul_getWin(); keypad(stdscr, TRUE); } char *menu[] = { "Display help >>:help", " Exit >>:quit" }; void emul_repl_start() { char input[READ_LINE_MAX]; exitcode_t state; int y, x; char *title = "Wellcome!"; int i,j; emul_repl_init(); // title getmaxyx(win, y, x); move(y/2-2, (x-strlen(title))/2); printw("%s", title); for (i = 0; i < 2; i++) { move(y/2+i, (x-strlen(menu[i]))/2); printw("%s", menu[i]); } move(0, 0); printw(""); refresh(); getch(); wclear(win); refresh(); 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) { emul_out_std_debug("Abend exit\n"); } else if (state == Success) { emul_out_std_debug("Sucsess\n"); break; } } } void emul_repl_end() { emul_inst_exec_end(); }