/* * QuickJS Read Eval Print Loop * * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */"use strip"; (function(g) { /* add 'os' and 'std' bindings */ g.os = os; g.std = std; /* close global objects */ var Object = g.Object; var String = g.String; var Array = g.Array; var Date = g.Date; var Math = g.Math; var isFinite = g.isFinite; var parseFloat = g.parseFloat; /* XXX: use preprocessor ? */ var config_numcalc = (typeof os.open === "undefined"); var has_jscalc = (typeof Fraction === "function"); var has_bignum = (typeof BigFloat === "function"); var colors = { none: "\x1b[0m", black: "\x1b[30m", red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", blue: "\x1b[34m", magenta: "\x1b[35m", cyan: "\x1b[36m", white: "\x1b[37m", gray: "\x1b[30;1m", grey: "\x1b[30;1m", bright_red: "\x1b[31;1m", bright_green: "\x1b[32;1m", bright_yellow: "\x1b[33;1m", bright_blue: "\x1b[34;1m", bright_magenta: "\x1b[35;1m", bright_cyan: "\x1b[36;1m", bright_white: "\x1b[37;1m", }; var styles; if (config_numcalc) { styles = { 'default': 'black', 'comment': 'white', 'string': 'green', 'regex': 'cyan', 'number': 'green', 'keyword': 'blue', 'function': 'gray', 'type': 'bright_magenta', 'identifier': 'yellow', 'error': 'bright_red', 'result': 'black', 'error_msg': 'bright_red', }; } else { styles = { 'default': 'bright_green', 'comment': 'white', 'string': 'bright_cyan', 'regex': 'cyan', 'number': 'green', 'keyword': 'bright_white', 'function': 'bright_yellow', 'type': 'bright_magenta', 'identifier': 'bright_green', 'error': 'red', 'result': 'bright_white', 'error_msg': 'bright_red', }; } var history = []; var clip_board = ""; var prec; var expBits; var log2_10; var pstate = ""; var prompt = ""; var plen = 0; var ps1; if (config_numcalc) ps1 = "> "; else ps1 = "qjs > "; var ps2 = " ... "; var utf8 = true; var show_time = false; var show_colors = true; var eval_time = 0; var mexpr = ""; var level = 0; var cmd = ""; var cursor_pos = 0; var last_cmd = ""; var last_cursor_pos = 0; var history_index; var this_fun, last_fun; var quote_flag = false; var utf8_state = 0; var utf8_val = 0; var term_fd; var term_read_buf; var term_width; /* current X position of the cursor in the terminal */ var term_cursor_x = 0; function termInit() { var tab; term_fd = std.in.fileno(); /* get the terminal size */ term_width = 80; if (os.isatty(term_fd)) { if (os.ttyGetWinSize) { tab = os.ttyGetWinSize(term_fd); if (tab) term_width = tab[0]; } if (os.ttySetRaw) { /* set the TTY to raw mode */ os.ttySetRaw(term_fd); } } /* install a Ctrl-C signal handler */ os.signal(os.SIGINT, sigint_handler); /* install a handler to read stdin */ term_read_buf = new Uint8Array(64); os.setReadHandler(term_fd, term_read_handler); } function sigint_handler() { /* send Ctrl-C to readline */ handle_byte(3); } function term_read_handler() { var l, i; l = os.read(term_fd, term_read_buf.buffer, 0, term_read_buf.length); for(i = 0; i < l; i++) handle_byte(term_read_buf[i]); } function handle_byte(c) { if (!utf8) { handle_char(c); } else if (utf8_state !== 0 && (c >= 0x80 && c < 0xc0)) { utf8_val = (utf8_val << 6) | (c & 0x3F); utf8_state--; if (utf8_state === 0) { handle_char(utf8_val); } } else if (c >= 0xc0 && c < 0xf8) { utf8_state = 1 + (c >= 0xe0) + (c >= 0xf0); utf8_val = c & ((1 << (6 - utf8_state)) - 1); } else { utf8_state = 0; handle_char(c); } } function is_alpha(c) { return typeof c === "string" && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); } function is_digit(c) { return typeof c === "string" && (c >= '0' && c <= '9'); } function is_word(c) { return typeof c === "string" && (is_alpha(c) || is_digit(c) || c == '_' || c == '$'); } function ucs_length(str) { var len, c, i, str_len = str.length; len = 0; /* we never count the trailing surrogate to have the following property: ucs_length(str) = ucs_length(str.substring(0, a)) + ucs_length(str.substring(a, str.length)) for 0 <= a <= str.length */ for(i = 0; i < str_len; i++) { c = str.charCodeAt(i); if (c < 0xdc00 || c >= 0xe000) len++; } return len; } function is_trailing_surrogate(c) { var d; if (typeof c !== "string") return false; d = c.codePointAt(0); /* can be NaN if empty string */ return d >= 0xdc00 && d < 0xe000; } function is_balanced(a, b) { switch (a + b) { case "()": case "[]": case "{}": return true; } return false; } function print_color_text(str, start, style_names) { var i, j; for (j = start; j < str.length;) { var style = style_names[i = j]; while (++j < str.length && style_names[j] == style) continue; std.puts(colors[styles[style] || 'default']); std.puts(str.substring(i, j)); std.puts(colors['none']); } } function print_csi(n, code) { std.puts("\x1b[" + ((n != 1) ? n : "") + code); } /* XXX: handle double-width characters */ function move_cursor(delta) { var i, l; if (delta > 0) { while (delta != 0) { if (term_cursor_x == (term_width - 1)) { std.puts("\n"); /* translated to CRLF */ term_cursor_x = 0; delta--; } else { l = Math.min(term_width - 1 - term_cursor_x, delta); print_csi(l, "C"); /* right */ delta -= l; term_cursor_x += l; } } } else { delta = -delta; while (delta != 0) { if (term_cursor_x == 0) { print_csi(1, "A"); /* up */ print_csi(term_width - 1, "C"); /* right */ delta--; term_cursor_x = term_width - 1; } else { l = Math.min(delta, term_cursor_x); print_csi(l, "D"); /* left */ delta -= l; term_cursor_x -= l; } } } } function update() { var i, cmd_len; /* cursor_pos is the position in 16 bit characters inside the UTF-16 string 'cmd' */ if (cmd != last_cmd) { if (!show_colors && last_cmd.substring(0, last_cursor_pos) == cmd.substring(0, last_cursor_pos)) { /* optimize common case */ std.puts(cmd.substring(last_cursor_pos)); } else { /* goto the start of the line */ move_cursor(-ucs_length(last_cmd.substring(0, last_cursor_pos))); if (show_colors) { var str = mexpr ? mexpr + '\n' + cmd : cmd; var start = str.length - cmd.length; var colorstate = colorize_js(str); print_color_text(str, start, colorstate[2]); } else { std.puts(cmd); } } term_cursor_x = (term_cursor_x + ucs_length(cmd)) % term_width; if (term_cursor_x == 0) { /* show the cursor on the next line */ std.puts(" \x08"); } /* remove the trailing characters */ std.puts("\x1b[J"); last_cmd = cmd; last_cursor_pos = cmd.length; } if (cursor_pos > last_cursor_pos) { move_cursor(ucs_length(cmd.substring(last_cursor_pos, cursor_pos))); } else if (cursor_pos < last_cursor_pos) { move_cursor(-ucs_length(cmd.substring(cursor_pos, last_cursor_pos))); } last_cursor_pos = cursor_pos; std.out.flush(); } /* editing commands */ function insert(str) { if (str) { cmd = cmd.substring(0, cursor_pos) + str + cmd.substring(cursor_pos); cursor_pos += str.length; } } function quoted_insert() { quote_flag = true; } function abort() { cmd = ""; cursor_pos = 0; return -2; } function alert() { } function beginning_of_line() { cursor_pos = 0; } function end_of_line() { cursor_pos = cmd.length; } function forward_char() { if (cursor_pos < cmd.length) { cursor_pos++; while (is_trailing_surrogate(cmd.charAt(cursor_pos))) cursor_pos++; } } function backward_char() { if (cursor_pos > 0) { cursor_pos--; while (is_trailing_surrogate(cmd.charAt(cursor_pos))) cursor_pos--; } } function skip_word_forward(pos) { while (pos < cmd.length && !is_word(cmd.charAt(pos))) pos++; while (pos < cmd.length && is_word(cmd.charAt(pos))) pos++; return pos; } function skip_word_backward(pos) { while (pos > 0 && !is_word(cmd.charAt(pos - 1))) pos--; while (pos > 0 && is_word(cmd.charAt(pos - 1))) pos--; return pos; } function forward_word() { cursor_pos = skip_word_forward(cursor_pos); } function backward_word() { cursor_pos = skip_word_backward(cursor_pos); } function accept_line() { std.puts("\n"); history_add(cmd); return -1; } function history_add(str) { if (str) { history.push(str); } history_index = history.length; } function previous_history() { if (history_index > 0) { if (history_index == history.length) { history.push(cmd); } history_index--; cmd = history[history_index]; cursor_pos = cmd.length; } } function next_history() { if (history_index < history.length - 1) { history_index++; cmd = history[history_index]; cursor_pos = cmd.length; } } function history_search(dir) { var pos = cursor_pos; for (var i = 1; i <= history.length; i++) { var index = (history.length + i * dir + history_index) % history.length; if (history[index].substring(0, pos) == cmd.substring(0, pos)) { history_index = index; cmd = history[index]; return; } } } function history_search_backward() { return history_search(-1); } function history_search_forward() { return history_search(1); } function delete_char_dir(dir) { var start, end; start = cursor_pos; if (dir < 0) { start--; while (is_trailing_surrogate(cmd.charAt(start))) start--; } end = start + 1; while (is_trailing_surrogate(cmd.charAt(end))) end++; if (start >= 0 && start < cmd.length) { if (last_fun === kill_region) { kill_region(start, end, dir); } else { cmd = cmd.substring(0, start) + cmd.substring(end); cursor_pos = start; } } } function delete_char() { delete_char_dir(1); } function control_d() { if (cmd.length == 0) { std.puts("\n"); return -3; /* exit read eval print loop */ } else { delete_char_dir(1); } } function backward_delete_char() { delete_char_dir(-1); } function transpose_chars() { var pos = cursor_pos; if (cmd.length > 1 && pos > 0) { if (pos == cmd.length) pos--; cmd = cmd.substring(0, pos - 1) + cmd.substring(pos, pos + 1) + cmd.substring(pos - 1, pos) + cmd.substring(pos + 1); cursor_pos = pos + 1; }Lines 1–500 of 1563. Load more
/* * QuickJS Read Eval Print Loop * * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ "use strip"; (function(g) { /* add 'os' and 'std' bindings */ g.os = os; g.std = std; /* close global objects */ var Object = g.Object; var String = g.String; var Array = g.Array; var Date = g.Date; var Math = g.Math; var isFinite = g.isFinite; var parseFloat = g.parseFloat; /* XXX: use preprocessor ? */ var config_numcalc = (typeof os.open === "undefined"); var has_jscalc = (typeof Fraction === "function"); var has_bignum = (typeof BigFloat === "function"); var colors = { none: "\x1b[0m", black: "\x1b[30m", red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", blue: "\x1b[34m", magenta: "\x1b[35m", cyan: "\x1b[36m", white: "\x1b[37m", gray: "\x1b[30;1m", grey: "\x1b[30;1m", bright_red: "\x1b[31;1m", bright_green: "\x1b[32;1m", bright_yellow: "\x1b[33;1m", bright_blue: "\x1b[34;1m", bright_magenta: "\x1b[35;1m", bright_cyan: "\x1b[36;1m", bright_white: "\x1b[37;1m", }; var styles; if (config_numcalc) { styles = { 'default': 'black', 'comment': 'white', 'string': 'green', 'regex': 'cyan', 'number': 'green', 'keyword': 'blue', 'function': 'gray', 'type': 'bright_magenta', 'identifier': 'yellow', 'error': 'bright_red', 'result': 'black', 'error_msg': 'bright_red', }; } else { styles = { 'default': 'bright_green', 'comment': 'white', 'string': 'bright_cyan', 'regex': 'cyan', 'number': 'green', 'keyword': 'bright_white', 'function': 'bright_yellow', 'type': 'bright_magenta', 'identifier': 'bright_green', 'error': 'red', 'result': 'bright_white', 'error_msg': 'bright_red', }; } var history = []; var clip_board = ""; var prec; var expBits; var log2_10; var pstate = ""; var prompt = ""; var plen = 0; var ps1; if (config_numcalc) ps1 = "> "; else ps1 = "qjs > "; var ps2 = " ... "; var utf8 = true; var show_time = false; var show_colors = true; var eval_time = 0; var mexpr = ""; var level = 0; var cmd = ""; var cursor_pos = 0; var last_cmd = ""; var last_cursor_pos = 0; var history_index; var this_fun, last_fun; var quote_flag = false; var utf8_state = 0; var utf8_val = 0; var term_fd; var term_read_buf; var term_width; /* current X position of the cursor in the terminal */ var term_cursor_x = 0; function termInit() { var tab; term_fd = std.in.fileno(); /* get the terminal size */ term_width = 80; if (os.isatty(term_fd)) { if (os.ttyGetWinSize) { tab = os.ttyGetWinSize(term_fd); if (tab) term_width = tab[0]; } if (os.ttySetRaw) { /* set the TTY to raw mode */ os.ttySetRaw(term_fd); } } /* install a Ctrl-C signal handler */ os.signal(os.SIGINT, sigint_handler); /* install a handler to read stdin */ term_read_buf = new Uint8Array(64); os.setReadHandler(term_fd, term_read_handler); } function sigint_handler() { /* send Ctrl-C to readline */ handle_byte(3); } function term_read_handler() { var l, i; l = os.read(term_fd, term_read_buf.buffer, 0, term_read_buf.length); for(i = 0; i < l; i++) handle_byte(term_read_buf[i]); } function handle_byte(c) { if (!utf8) { handle_char(c); } else if (utf8_state !== 0 && (c >= 0x80 && c < 0xc0)) { utf8_val = (utf8_val << 6) | (c & 0x3F); utf8_state--; if (utf8_state === 0) { handle_char(utf8_val); } } else if (c >= 0xc0 && c < 0xf8) { utf8_state = 1 + (c >= 0xe0) + (c >= 0xf0); utf8_val = c & ((1 << (6 - utf8_state)) - 1); } else { utf8_state = 0; handle_char(c); } } function is_alpha(c) { return typeof c === "string" && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); } function is_digit(c) { return typeof c === "string" && (c >= '0' && c <= '9'); } function is_word(c) { return typeof c === "string" && (is_alpha(c) || is_digit(c) || c == '_' || c == '$'); } function ucs_length(str) { var len, c, i, str_len = str.length; len = 0; /* we never count the trailing surrogate to have the following property: ucs_length(str) = ucs_length(str.substring(0, a)) + ucs_length(str.substring(a, str.length)) for 0 <= a <= str.length */ for(i = 0; i < str_len; i++) { c = str.charCodeAt(i); if (c < 0xdc00 || c >= 0xe000) len++; } return len; } function is_trailing_surrogate(c) { var d; if (typeof c !== "string") return false; d = c.codePointAt(0); /* can be NaN if empty string */ return d >= 0xdc00 && d < 0xe000; } function is_balanced(a, b) { switch (a + b) { case "()": case "[]": case "{}": return true; } return false; } function print_color_text(str, start, style_names) { var i, j; for (j = start; j < str.length;) { var style = style_names[i = j]; while (++j < str.length && style_names[j] == style) continue; std.puts(colors[styles[style] || 'default']); std.puts(str.substring(i, j)); std.puts(colors['none']); } } function print_csi(n, code) { std.puts("\x1b[" + ((n != 1) ? n : "") + code); } /* XXX: handle double-width characters */ function move_cursor(delta) { var i, l; if (delta > 0) { while (delta != 0) { if (term_cursor_x == (term_width - 1)) { std.puts("\n"); /* translated to CRLF */ term_cursor_x = 0; delta--; } else { l = Math.min(term_width - 1 - term_cursor_x, delta); print_csi(l, "C"); /* right */ delta -= l; term_cursor_x += l; } } } else { delta = -delta; while (delta != 0) { if (term_cursor_x == 0) { print_csi(1, "A"); /* up */ print_csi(term_width - 1, "C"); /* right */ delta--; term_cursor_x = term_width - 1; } else { l = Math.min(delta, term_cursor_x); print_csi(l, "D"); /* left */ delta -= l; term_cursor_x -= l; } } } } function update() { var i, cmd_len; /* cursor_pos is the position in 16 bit characters inside the UTF-16 string 'cmd' */ if (cmd != last_cmd) { if (!show_colors && last_cmd.substring(0, last_cursor_pos) == cmd.substring(0, last_cursor_pos)) { /* optimize common case */ std.puts(cmd.substring(last_cursor_pos)); } else { /* goto the start of the line */ move_cursor(-ucs_length(last_cmd.substring(0, last_cursor_pos))); if (show_colors) { var str = mexpr ? mexpr + '\n' + cmd : cmd; var start = str.length - cmd.length; var colorstate = colorize_js(str); print_color_text(str, start, colorstate[2]); } else { std.puts(cmd); } } term_cursor_x = (term_cursor_x + ucs_length(cmd)) % term_width; if (term_cursor_x == 0) { /* show the cursor on the next line */ std.puts(" \x08"); } /* remove the trailing characters */ std.puts("\x1b[J"); last_cmd = cmd; last_cursor_pos = cmd.length; } if (cursor_pos > last_cursor_pos) { move_cursor(ucs_length(cmd.substring(last_cursor_pos, cursor_pos))); } else if (cursor_pos < last_cursor_pos) { move_cursor(-ucs_length(cmd.substring(cursor_pos, last_cursor_pos))); } last_cursor_pos = cursor_pos; std.out.flush(); } /* editing commands */ function insert(str) { if (str) { cmd = cmd.substring(0, cursor_pos) + str + cmd.substring(cursor_pos); cursor_pos += str.length; } } function quoted_insert() { quote_flag = true; } function abort() { cmd = ""; cursor_pos = 0; return -2; } function alert() { } function beginning_of_line() { cursor_pos = 0; } function end_of_line() { cursor_pos = cmd.length; } function forward_char() { if (cursor_pos < cmd.length) { cursor_pos++; while (is_trailing_surrogate(cmd.charAt(cursor_pos))) cursor_pos++; } } function backward_char() { if (cursor_pos > 0) { cursor_pos--; while (is_trailing_surrogate(cmd.charAt(cursor_pos))) cursor_pos--; } } function skip_word_forward(pos) { while (pos < cmd.length && !is_word(cmd.charAt(pos))) pos++; while (pos < cmd.length && is_word(cmd.charAt(pos))) pos++; return pos; } function skip_word_backward(pos) { while (pos > 0 && !is_word(cmd.charAt(pos - 1))) pos--; while (pos > 0 && is_word(cmd.charAt(pos - 1))) pos--; return pos; } function forward_word() { cursor_pos = skip_word_forward(cursor_pos); } function backward_word() { cursor_pos = skip_word_backward(cursor_pos); } function accept_line() { std.puts("\n"); history_add(cmd); return -1; } function history_add(str) { if (str) { history.push(str); } history_index = history.length; } function previous_history() { if (history_index > 0) { if (history_index == history.length) { history.push(cmd); } history_index--; cmd = history[history_index]; cursor_pos = cmd.length; } } function next_history() { if (history_index < history.length - 1) { history_index++; cmd = history[history_index]; cursor_pos = cmd.length; } } function history_search(dir) { var pos = cursor_pos; for (var i = 1; i <= history.length; i++) { var index = (history.length + i * dir + history_index) % history.length; if (history[index].substring(0, pos) == cmd.substring(0, pos)) { history_index = index; cmd = history[index]; return; } } } function history_search_backward() { return history_search(-1); } function history_search_forward() { return history_search(1); } function delete_char_dir(dir) { var start, end; start = cursor_pos; if (dir < 0) { start--; while (is_trailing_surrogate(cmd.charAt(start))) start--; } end = start + 1; while (is_trailing_surrogate(cmd.charAt(end))) end++; if (start >= 0 && start < cmd.length) { if (last_fun === kill_region) { kill_region(start, end, dir); } else { cmd = cmd.substring(0, start) + cmd.substring(end); cursor_pos = start; } } } function delete_char() { delete_char_dir(1); } function control_d() { if (cmd.length == 0) { std.puts("\n"); return -3; /* exit read eval print loop */ } else { delete_char_dir(1); } } function backward_delete_char() { delete_char_dir(-1); } function transpose_chars() { var pos = cursor_pos; if (cmd.length > 1 && pos > 0) { if (pos == cmd.length) pos--; cmd = cmd.substring(0, pos - 1) + cmd.substring(pos, pos + 1) + cmd.substring(pos - 1, pos) + cmd.substring(pos + 1); cursor_pos = pos + 1; }