Files
tsvm/assets/JS_INIT.js
2020-10-28 23:42:55 +09:00

372 lines
12 KiB
JavaScript

// Polyfilling some functions from ECMAScript6+
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null)
throw new TypeError('can\'t convert ' + this + ' to object');
var str = '' + this;
// To convert string to integer.
count = +count;
// Check NaN
if (count != count)
count = 0;
if (count < 0)
throw new RangeError('repeat count must be non-negative');
if (count == Infinity)
throw new RangeError('repeat count must be less than infinity');
count = Math.floor(count);
if (str.length == 0 || count == 0)
return '';
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28)
throw new RangeError('repeat count must not overflow maximum string size');
var maxCount = str.length * count;
count = Math.floor(Math.log(count) / Math.log(2));
while (count) {
str += str;
count--;
}
str += str.substring(0, maxCount - str.length);
return str;
}
}
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search, rawPos) {
var pos = rawPos > 0 ? rawPos|0 : 0;
return this.substring(pos, pos + search.length) === search;
}
});
}
if (!Array.prototype.filter){
Array.prototype.filter = function(func, thisArg) {
'use strict';
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
var kValue;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
if (i in this){
kValue = t[i]; // in case t is changed in callback
if (func(t[i], i, t)){
res[c++] = kValue;
}
}
}
}
else{
while (++i !== len){
// checks to see if the key was set
if (i in this){
kValue = t[i];
if (func.call(thisArg, t[i], i, t)){
res[c++] = kValue;
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
Array.prototype.map = function(callback/*, thisArg*/) {
var T, A, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the |this|
// value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal
// method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = arguments[1];
}
// 6. Let A be a new array created as if by the expression new Array(len)
// where Array is the standard built-in constructor with that name and
// len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
// 8. Repeat, while k < len
while (k < len) {
var kValue, mappedValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal
// method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Let mappedValue be the result of calling the Call internal
// method of callback with T as the this value and argument
// list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor
// { Value: mappedValue,
// Writable: true,
// Enumerable: true,
// Configurable: true },
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, k, {
// value: mappedValue,
// writable: true,
// enumerable: true,
// configurable: true
// });
// For best browser support, use the following:
A[k] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
value: function(callback /*, initialValue*/) {
if (this === null) {
throw new TypeError( 'Array.prototype.reduce ' +
'called on null or undefined' );
}
if (typeof callback !== 'function') {
throw new TypeError( callback +
' is not a function');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = o[k++];
}
// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}
// d. Increase k by 1.
k++;
}
// 9. Return accumulator.
return value;
}
});
}
// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
'use strict';
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = len - 1, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k >= 0 && !(k in t)) {
k--;
}
if (k < 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k--];
}
for (; k >= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE TO PROGRAMMERS: this JS_INIT script does not, and must not be invoked with strict mode //
///////////////////////////////////////////////////////////////////////////////////////////////////
// disabling and re-installing JS/Nashorn functions
// alse see: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions
load = undefined;
loadWithNewGlobal = undefined;
exit = undefined;
quit = undefined;
/*var eval = function(s) { // this impl is flawed; it does not return any, and cannot alter Global which may not you actually want
return Function('"use strict";return(function(){'+s+'}())')();
}*/
//
function javaArrayToJs(jarr) {
if (!jarr.toString.startsWith("[")) return jarr;
var arr = [];
for (var k = 0; k < jarr.length; k++) {
arr.push(jarr[k]);
}
return arr;
}
// standard print functions
function print(s) {
sys.print(s);
}
function println(s) {
if (s === undefined)
sys.print("\n");
else
sys.println(s);
}
function read() {
return sys.read();
}
// ncurses-like terminal control
var con = {};
con.getch = function() {
return sys.readKey();
};
con.move = function(y, x) {
print(String.fromCharCode(27,91)+(y|0)+";"+(x|0)+"H");
};
con.addch = function(c) {
graphics.putSymbol(c|0);
};
con.mvaddch = function(y, x, c) {
con.move(y, x); con.addch(c);
};
con.getmaxyx = function() {
return graphics.getTermDimension();
};
con.getyx = function() {
return graphics.getCursorYX();
};
con.hitterminate = function() { // ^C
sys.poke(-40, 1);
return (sys.peek(-41) == 31 && (sys.peek(-42) == 129 || sys.peek(-42) == 130));
};
con.hiteof = function() { // ^D
sys.poke(-40, 1);
return (sys.peek(-41) == 32 && (sys.peek(-42) == 129 || sys.peek(-42) == 130));
};
con.resetkeybuf = function() {
sys.poke(-40, 0);
sys.poke(-41, 0); sys.poke(-42, 0); sys.poke(-43, 0); sys.poke(-44, 0);
sys.poke(-45, 0); sys.poke(-46, 0); sys.poke(-47, 0); sys.poke(-48, 0);
};
con.color_fore = function(n) { // 0..7; -1 for transparent
if (n < 0)
print(String.fromCharCode(27,91)+"38;5;255m");
else
print(String.fromCharCode(27,91)+(((n|0) % 8)+30)+"m");
};
con.color_back = function(n) { // 0..7; -1 for transparent
if (n < 0)
print(String.fromCharCode(27,91)+"48;5;255m");
else
print(String.fromCharCode(27,91)+(((n|0) % 8)+40)+"m");
};
con.color_pair = function(fore, back) { // 0..255
print(String.fromCharCode(27,91)+"38;5;"+fore+"m");
print(String.fromCharCode(27,91)+"48;5;"+back+"m");
};
con.clear = function() {
print(String.fromCharCode(27,91)+"2J");
};
con.curs_set = function(arg) {
print(String.fromCharCode(27,91)+"?25"+(((arg|0) == 0) ? "l" : "h"));
};
Object.freeze(con);
// system management function
var system = {};
system.maxmem = function() {
return sys.peek(-65) | (sys.peek(-66) << 8) | (sys.peek(-67) << 16) | (sys.peek(-68) << 24);
};
system.halt = function() {
exit();
};
Object.freeze(system);
// some utilities functions