JavaScript-QuickJS

 view release on metacpan or  search on metacpan

quickjs/repl.js  view on Meta::CPAN

    }
    
    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;
                }
            }

quickjs/repl.js  view on Meta::CPAN


    function backward_kill_line() {
        kill_region(0, cursor_pos, -1);
    }

    function kill_word() {
        kill_region(cursor_pos, skip_word_forward(cursor_pos), 1);
    }

    function backward_kill_word() {
        kill_region(skip_word_backward(cursor_pos), cursor_pos, -1);
    }

    function yank() {
        insert(clip_board);
    }

    function control_c() {
        if (last_fun === control_c) {
            std.puts("\n");
            std.exit(0);
        } else {
            std.puts("\n(Press Ctrl-C again to quit)\n");
            readline_print_prompt();
        }
    }
    
    function reset() {
        cmd = "";
        cursor_pos = 0;
    }

    function get_context_word(line, pos) {
        var s = "";
        while (pos > 0 && is_word(line[pos - 1])) {
            pos--;
            s = line[pos] + s;
        }
        return s;
    }
    function get_context_object(line, pos) {
        var obj, base, c;
        if (pos <= 0 || " ~!%^&*(-+={[|:;,<>?/".indexOf(line[pos - 1]) >= 0)
            return g;
        if (pos >= 2 && line[pos - 1] === ".") {
            pos--;
            obj = {};
            switch (c = line[pos - 1]) {
            case '\'':
            case '\"':
                return "a";
            case ']':
                return [];
            case '}':
                return {};
            case '/':
                return / /;
            default:
                if (is_word(c)) {
                    base = get_context_word(line, pos);
                    if (["true", "false", "null", "this"].includes(base) || !isNaN(+base))
                        return eval(base);
                    obj = get_context_object(line, pos - base.length);
                    if (obj === null || obj === void 0)
                        return obj;
                    if (obj === g && obj[base] === void 0)
                        return eval(base);
                    else
                        return obj[base];
                }
                return {};
            }
        }
        return void 0;
    }

    function get_completions(line, pos) {
        var s, obj, ctx_obj, r, i, j, paren;

        s = get_context_word(line, pos);
        ctx_obj = get_context_object(line, pos - s.length);
        r = [];
        /* enumerate properties from object and its prototype chain,
           add non-numeric regular properties with s as e prefix
         */
        for (i = 0, obj = ctx_obj; i < 10 && obj !== null && obj !== void 0; i++) {
            var props = Object.getOwnPropertyNames(obj);
            /* add non-numeric regular properties */
            for (j = 0; j < props.length; j++) {
                var prop = props[j];
                if (typeof prop == "string" && ""+(+prop) != prop && prop.startsWith(s))
                    r.push(prop);
            }
            obj = Object.getPrototypeOf(obj);
        }
        if (r.length > 1) {
            /* sort list with internal names last and remove duplicates */
            function symcmp(a, b) {
                if (a[0] != b[0]) {
                    if (a[0] == '_')
                        return 1;
                    if (b[0] == '_')
                        return -1;
                }
                if (a < b)
                    return -1;
                if (a > b)
                    return +1;
                return 0;
            }
            r.sort(symcmp);
            for(i = j = 1; i < r.length; i++) {
                if (r[i] != r[i - 1])
                    r[j++] = r[i];
            }
            r.length = j;
        }
        /* 'tab' = list of completions, 'pos' = cursor position inside
           the completions */
        return { tab: r, pos: s.length, ctx: ctx_obj };
    }

quickjs/repl.js  view on Meta::CPAN

                readline_state = 0;
            }
            break;
        case 2: /* '^[[' - CSI */
            readline_keys += c;
            if (!(c == ';' || (c >= '0' && c <= '9'))) {
                handle_key(readline_keys);
                readline_state = 0;
            }
            break;
        case 3: /* '^[O' - ESC2 */
            readline_keys += c;
            handle_key(readline_keys);
            readline_state = 0;
            break;
        }
    }

    function handle_key(keys) {
        var fun;

        if (quote_flag) {
            if (ucs_length(keys) === 1)
                insert(keys);
            quote_flag = false;
        } else if (fun = commands[keys]) {
            this_fun = fun;
            switch (fun(keys)) {
            case -1:
                readline_cb(cmd);
                return;
            case -2:
                readline_cb(null);
                return;
            case -3:
                /* uninstall a Ctrl-C signal handler */
                os.signal(os.SIGINT, null);
                /* uninstall the stdin read handler */
                os.setReadHandler(term_fd, null);
                return;
            }
            last_fun = this_fun;
        } else if (ucs_length(keys) === 1 && keys >= ' ') {
            insert(keys);
            last_fun = insert;
        } else {
            alert(); /* beep! */
        }
        
        cursor_pos = (cursor_pos < 0) ? 0 :
            (cursor_pos > cmd.length) ? cmd.length : cursor_pos;
        update();
    }

    var hex_mode = false;
    var eval_mode = "std";

    function number_to_string(a, radix) {
        var s;
        if (!isFinite(a)) {
            /* NaN, Infinite */
            return a.toString();
        } else {
            if (a == 0) {
                if (1 / a < 0)
                    s = "-0";
                else
                    s = "0";
            } else {
                if (radix == 16 && a === Math.floor(a)) {
                    var s;
                    if (a < 0) {
                        a = -a;
                        s = "-";
                    } else {
                        s = "";
                    }
                    s += "0x" + a.toString(16);
                } else {
                    s = a.toString();
                }
            }
            return s;
        }
    }

    function bigfloat_to_string(a, radix) {
        var s;
        if (!BigFloat.isFinite(a)) {
            /* NaN, Infinite */
            if (eval_mode !== "math") {
                return "BigFloat(" + a.toString() + ")";
            } else {
                return a.toString();
            }
        } else {
            if (a == 0) {
                if (1 / a < 0)
                    s = "-0";
                else
                    s = "0";
            } else {
                if (radix == 16) {
                    var s;
                    if (a < 0) {
                        a = -a;
                        s = "-";
                    } else {
                        s = "";
                    }
                    s += "0x" + a.toString(16);
                } else {
                    s = a.toString();
                }
            }
            if (typeof a === "bigfloat" && eval_mode !== "math") {
                s += "l";
            } else if (eval_mode !== "std" && s.indexOf(".") < 0 &&
                ((radix == 16 && s.indexOf("p") < 0) ||
                 (radix == 10 && s.indexOf("e") < 0))) {
                /* add a decimal point so that the floating point type
                   is visible */
                s += ".0";
            }
            return s;
        }
    }

    function bigint_to_string(a, radix) {
        var s;
        if (radix == 16) {
            var s;
            if (a < 0) {
                a = -a;
                s = "-";
            } else {
                s = "";
            }
            s += "0x" + a.toString(16);
        } else {
            s = a.toString();
        }
        if (eval_mode === "std")
            s += "n";
        return s;
    }
    
    function print(a) {
        var stack = [];

quickjs/repl.js  view on Meta::CPAN

            } else {
                std.puts(a);
            }
        }
        print_rec(a);
    }
    
    function extract_directive(a) {
        var pos;
        if (a[0] !== '\\')
            return "";
        for (pos = 1; pos < a.length; pos++) {
            if (!is_alpha(a[pos]))
                break;
        }
        return a.substring(1, pos);
    }

    /* return true if the string after cmd can be evaluted as JS */
    function handle_directive(cmd, expr) {
        var param, prec1, expBits1;
        
        if (cmd === "h" || cmd === "?" || cmd == "help") {
            help();
        } else if (cmd === "load") {
            var filename = expr.substring(cmd.length + 1).trim();
            if (filename.lastIndexOf(".") <= filename.lastIndexOf("/"))
                filename += ".js";
            std.loadScript(filename);
            return false;
        } else if (cmd === "x") {
            hex_mode = true;
        } else if (cmd === "d") {
            hex_mode = false;
        } else if (cmd === "t") {
            show_time = !show_time;
        } else if (has_bignum && cmd === "p") {
            param = expr.substring(cmd.length + 1).trim().split(" ");
            if (param.length === 1 && param[0] === "") {
                std.puts("BigFloat precision=" + prec + " bits (~" +
                          Math.floor(prec / log2_10) +
                          " digits), exponent size=" + expBits + " bits\n");
            } else if (param[0] === "f16") {
                prec = 11;
                expBits = 5;
            } else if (param[0] === "f32") {
                prec = 24;
                expBits = 8;
            } else if (param[0] === "f64") {
                prec = 53;
                expBits = 11;
            } else if (param[0] === "f128") {
                prec = 113;
                expBits = 15;
            } else {
                prec1 = parseInt(param[0]);
                if (param.length >= 2)
                    expBits1 = parseInt(param[1]);
                else
                    expBits1 = BigFloatEnv.expBitsMax;
                if (Number.isNaN(prec1) ||
                    prec1 < BigFloatEnv.precMin ||
                    prec1 > BigFloatEnv.precMax) {
                    std.puts("Invalid precision\n");
                    return false;
                }
                if (Number.isNaN(expBits1) ||
                    expBits1 < BigFloatEnv.expBitsMin ||
                    expBits1 > BigFloatEnv.expBitsMax) {
                    std.puts("Invalid exponent bits\n");
                    return false;
                }
                prec = prec1;
                expBits = expBits1;
            }
            return false;
        } else if (has_bignum && cmd === "digits") {
            param = expr.substring(cmd.length + 1).trim();
            prec1 = Math.ceil(parseFloat(param) * log2_10);
            if (prec1 < BigFloatEnv.precMin ||
                prec1 > BigFloatEnv.precMax) {
                std.puts("Invalid precision\n");
                return false;
            }
            prec = prec1;
            expBits = BigFloatEnv.expBitsMax;
            return false;
        } else if (has_bignum && cmd === "mode") {
            param = expr.substring(cmd.length + 1).trim();
            if (param === "") {
                std.puts("Running mode=" + eval_mode + "\n");
            } else if (param === "std" || param === "math") {
                eval_mode = param;
            } else {
                std.puts("Invalid mode\n");
            }
            return false;
        } else if (cmd === "clear") {
            std.puts("\x1b[H\x1b[J");
        } else if (cmd === "q") {
            std.exit(0);
        } else if (has_jscalc && cmd === "a") {
            algebraicMode = true;
        } else if (has_jscalc && cmd === "n") {
            algebraicMode = false;
        } else {
            std.puts("Unknown directive: " + cmd + "\n");
            return false;
        }
        return true;
    }

    if (config_numcalc) {
        /* called by the GUI */
        g.execCmd = function (cmd) {
            switch(cmd) {
            case "dec":
                hex_mode = false;
                break;
            case "hex":
                hex_mode = true;
                break;
            case "num":
                algebraicMode = false;
                break;
            case "alg":
                algebraicMode = true;

quickjs/repl.js  view on Meta::CPAN

                    i++;
                } else
                if (c == delim) {
                    pop_state();
                    break;
                }
            }
        }

        function parse_regex() {
            style = 'regex';
            push_state('/');
            while (i < n) {
                c = str[i++];
                if (c == '\n') {
                    style = 'error';
                    continue;
                }
                if (c == '\\') {
                    if (i < n) {
                        i++;
                    }
                    continue;
                }
                if (last_state() == '[') {
                    if (c == ']') {
                        pop_state()
                    }
                    // ECMA 5: ignore '/' inside char classes
                    continue;
                }
                if (c == '[') {
                    push_state('[');
                    if (str[i] == '[' || str[i] == ']')
                        i++;
                    continue;
                }
                if (c == '/') {
                    pop_state();
                    while (i < n && is_word(str[i]))
                        i++;
                    break;
                }
            }
        }

        function parse_number() {
            style = 'number';
            while (i < n && (is_word(str[i]) || (str[i] == '.' && (i == n - 1 || str[i + 1] != '.')))) {
                i++;
            }
        }

        var js_keywords = "|" +
            "break|case|catch|continue|debugger|default|delete|do|" +
            "else|finally|for|function|if|in|instanceof|new|" +
            "return|switch|this|throw|try|typeof|while|with|" +
            "class|const|enum|import|export|extends|super|" +
            "implements|interface|let|package|private|protected|" +
            "public|static|yield|" +
            "undefined|null|true|false|Infinity|NaN|" +
            "eval|arguments|" +
            "await|";

        var js_no_regex = "|this|super|undefined|null|true|false|Infinity|NaN|arguments|";
        var js_types = "|void|var|";

        function parse_identifier() {
            can_regex = 1;

            while (i < n && is_word(str[i]))
                i++;

            var w = '|' + str.substring(start, i) + '|';

            if (js_keywords.indexOf(w) >= 0) {
                style = 'keyword';
                if (js_no_regex.indexOf(w) >= 0)
                    can_regex = 0;
                return;
            }

            var i1 = i;
            while (i1 < n && str[i1] == ' ')
                i1++;

            if (i1 < n && str[i1] == '(') {
                style = 'function';
                return;
            }

            if (js_types.indexOf(w) >= 0) {
                style = 'type';
                return;
            }

            style = 'identifier';
            can_regex = 0;
        }

        function set_style(from, to) {
            while (r.length < from)
                r.push('default');
            while (r.length < to)
                r.push(style);
        }

        for (i = 0; i < n;) {
            style = null;
            start = i;
            switch (c = str[i++]) {
            case ' ':
            case '\t':
            case '\r':
            case '\n':
                continue;
            case '+':
            case '-':
                if (i < n && str[i] == c) {
                    i++;
                    continue;
                }
                can_regex = 1;
                continue;
            case '/':



( run in 0.591 second using v1.01-cache-2.11-cpan-adec679a428 )