1563 lines · 48.1 KB · JavaScript
RawDownload
/* * 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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t