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 )