TopchetoEU/revert-ES5 #31
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
*
|
||||
|
||||
!/src
|
||||
!/src/
|
||||
!/src/**/*
|
||||
|
||||
!/doc
|
||||
@ -22,3 +22,5 @@
|
||||
!/gradle
|
||||
!/gradle/wrapper
|
||||
!/gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
!/
|
@ -80,7 +80,7 @@ public class IfNode extends Node {
|
||||
var a = JavaScript.parseExpression(src, i + n, 2);
|
||||
if (!a.isSuccess()) return a.chainError(src.loc(i + n), "Expected a value after the ternary operator.");
|
||||
n += a.n;
|
||||
n += Parsing.skipEmpty(src, i);
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
if (!src.is(i + n, ":")) return ParseRes.failed();
|
||||
n++;
|
||||
|
@ -10,6 +10,7 @@ import me.topchetoeu.jscript.common.Metadata;
|
||||
import me.topchetoeu.jscript.common.Reading;
|
||||
import me.topchetoeu.jscript.common.SyntaxException;
|
||||
import me.topchetoeu.jscript.common.environment.Environment;
|
||||
import me.topchetoeu.jscript.common.environment.Key;
|
||||
import me.topchetoeu.jscript.common.json.JSON;
|
||||
import me.topchetoeu.jscript.common.parsing.Filename;
|
||||
import me.topchetoeu.jscript.runtime.debug.DebugContext;
|
||||
@ -252,21 +253,17 @@ public class SimpleRepl {
|
||||
res.defineOwnMember(env, "parse", new NativeFunction(args -> {
|
||||
return JSONConverter.toJs(JSON.parse(null, args.get(0).toString(env)));
|
||||
}));
|
||||
res.defineOwnMember(env, "invokeType", new NativeFunction(args -> {
|
||||
if (((ArgumentsValue)args.get(0)).frame.isNew) return StringValue.of("new");
|
||||
else return StringValue.of("call");
|
||||
}));
|
||||
res.defineOwnMember(env, "invoke", new NativeFunction(args -> {
|
||||
var func = (FunctionValue)args.get(0);
|
||||
var self = args.get(1);
|
||||
var funcArgs = (ArrayValue)args.get(2);
|
||||
|
||||
return func.apply(env, self, funcArgs.toArray());
|
||||
}));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void setProto(Environment env, Environment target, Key<ObjectValue> key, ObjectValue repo, String name) {
|
||||
var val = repo.getMember(env, name);
|
||||
if (val instanceof ObjectValue obj) {
|
||||
target.add(key, obj);
|
||||
}
|
||||
}
|
||||
|
||||
private static ObjectValue primordials(Environment env) {
|
||||
var res = new ObjectValue();
|
||||
res.setPrototype(null, null);
|
||||
@ -280,45 +277,20 @@ public class SimpleRepl {
|
||||
|
||||
int[] i = new int[1];
|
||||
|
||||
res.defineOwnMember(env, "setGlobalPrototype", new NativeFunction(args -> {
|
||||
var type = args.get(0).toString(env);
|
||||
res.defineOwnMember(env, "setGlobalPrototypes", new NativeFunction(args -> {
|
||||
var obj = (ObjectValue)args.get(1);
|
||||
|
||||
switch (type) {
|
||||
case "object":
|
||||
args.env.add(Value.OBJECT_PROTO, obj);
|
||||
break;
|
||||
case "function":
|
||||
args.env.add(Value.FUNCTION_PROTO, obj);
|
||||
break;
|
||||
case "array":
|
||||
args.env.add(Value.ARRAY_PROTO, obj);
|
||||
break;
|
||||
case "boolean":
|
||||
args.env.add(Value.BOOL_PROTO, obj);
|
||||
break;
|
||||
case "number":
|
||||
args.env.add(Value.NUMBER_PROTO, obj);
|
||||
break;
|
||||
case "string":
|
||||
args.env.add(Value.STRING_PROTO, obj);
|
||||
break;
|
||||
case "symbol":
|
||||
args.env.add(Value.SYMBOL_PROTO, obj);
|
||||
break;
|
||||
case "error":
|
||||
args.env.add(Value.ERROR_PROTO, obj);
|
||||
break;
|
||||
case "syntax":
|
||||
args.env.add(Value.SYNTAX_ERR_PROTO, obj);
|
||||
break;
|
||||
case "type":
|
||||
args.env.add(Value.TYPE_ERR_PROTO, obj);
|
||||
break;
|
||||
case "range":
|
||||
args.env.add(Value.RANGE_ERR_PROTO, obj);
|
||||
break;
|
||||
}
|
||||
setProto(args.env, env, Value.OBJECT_PROTO, obj, "object");
|
||||
setProto(args.env, env, Value.FUNCTION_PROTO, obj, "function");
|
||||
setProto(args.env, env, Value.ARRAY_PROTO, obj, "array");
|
||||
setProto(args.env, env, Value.BOOL_PROTO, obj, "boolean");
|
||||
setProto(args.env, env, Value.NUMBER_PROTO, obj, "number");
|
||||
setProto(args.env, env, Value.STRING_PROTO, obj, "string");
|
||||
setProto(args.env, env, Value.SYMBOL_PROTO, obj, "symbol");
|
||||
setProto(args.env, env, Value.ERROR_PROTO, obj, "error");
|
||||
setProto(args.env, env, Value.SYNTAX_ERR_PROTO, obj, "syntax");
|
||||
setProto(args.env, env, Value.TYPE_ERR_PROTO, obj, "type");
|
||||
setProto(args.env, env, Value.RANGE_ERR_PROTO, obj, "range");
|
||||
|
||||
return Value.UNDEFINED;
|
||||
}));
|
||||
|
@ -1,98 +1,116 @@
|
||||
const target = arguments[0];
|
||||
const primordials = arguments[1];
|
||||
|
||||
const symbol = primordials.symbol || (() => {
|
||||
const repo = {};
|
||||
return;
|
||||
(function main() {
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
|
||||
var target = arguments[0];
|
||||
var primordials = arguments[1];
|
||||
var symbol = primordials.symbol || (function () {
|
||||
var repo = {};
|
||||
return {
|
||||
makeSymbol: (name) => { name },
|
||||
getSymbol(name) {
|
||||
makeSymbol: function (name) { return { name: name }; },
|
||||
getSymbol: function (name) {
|
||||
if (name in repo) return repo[name];
|
||||
else return repo[name] = { name };
|
||||
else return repo[name] = { name: name };
|
||||
},
|
||||
getSymbolKey(symbol) {
|
||||
getSymbolKey: function (symbol) {
|
||||
if (symbol.name in repo && repo[symbol.name] === symbol) return symbol.name;
|
||||
else return undefined;
|
||||
},
|
||||
getSymbolDescription: ({ name }) => name,
|
||||
getSymbolDescription: function (symbol) {
|
||||
return symbol.name;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const number = primordials.number || {
|
||||
parseInt() { throw new Error("parseInt not supported"); },
|
||||
parseFloat() { throw new Error("parseFloat not supported"); },
|
||||
isNaN: (val) => val !== val,
|
||||
var number = primordials.number || {
|
||||
parseInt: function () { throw new Error("parseInt not supported"); },
|
||||
parseFloat: function () { throw new Error("parseFloat not supported"); },
|
||||
isNaN: function (val) { return val !== val; },
|
||||
NaN: 0 / 0,
|
||||
Infinity: 1 / 0,
|
||||
};
|
||||
|
||||
const string = primordials.string;
|
||||
|
||||
const object = primordials.object || {
|
||||
defineProperty() { throw new Error("Define property not polyfillable"); },
|
||||
defineField(obj, key, a, b, c, value) { obj[key] = value; },
|
||||
getOwnMember() { throw new Error("Get own member not polyfillable"); },
|
||||
getOwnSymbolMember() { throw new Error("Get own symbol member not polyfillable"); },
|
||||
getOwnMembers() { throw new Error("Get own members not polyfillable"); },
|
||||
getOwnSymbolMembers() { throw new Error("Get own symbol members not polyfillable"); },
|
||||
getPrototype() { throw new Error("Get prototype not polyfillable"); },
|
||||
setPrototype() { throw new Error("Set prototype not polyfillable"); },
|
||||
var string = primordials.string;
|
||||
var object = primordials.object || {
|
||||
defineProperty: function () { throw new Error("Define property not polyfillable"); },
|
||||
defineField: function (obj, key, a, b, c, value) { obj[key] = value; },
|
||||
getOwnMember: function () { throw new Error("Get own member not polyfillable"); },
|
||||
getOwnSymbolMember: function () { throw new Error("Get own symbol member not polyfillable"); },
|
||||
getOwnMembers: function () { throw new Error("Get own members not polyfillable"); },
|
||||
getOwnSymbolMembers: function () { throw new Error("Get own symbol members not polyfillable"); },
|
||||
getPrototype: function () { throw new Error("Get prototype not polyfillable"); },
|
||||
setPrototype: function () { throw new Error("Set prototype not polyfillable"); },
|
||||
};
|
||||
var func = primordials.function || {
|
||||
invokeType: function (args, self) {
|
||||
if (typeof self === "object") return "new";
|
||||
else return "call";
|
||||
},
|
||||
setConstructable: function () { throw new Error("Set constructable not polyfillable"); },
|
||||
setCallable: function () { throw new Error("Set callable not polyfillable"); },
|
||||
invoke: function () { throw new Error("Invoke not polyfillable"); },
|
||||
construct: function () { throw new Error("Construct not polyfillable"); },
|
||||
};
|
||||
var json = primordials.json || {
|
||||
stringify: function (val) { throw new Error("JSON stringify not polyfillable"); },
|
||||
parse: function (val) { throw new Error("JSON parse not polyfillable"); },
|
||||
}
|
||||
|
||||
const invokeType = primordials.function.invokeType;
|
||||
const setConstructable = primordials.function.setConstructable;
|
||||
const setCallable = primordials.function.setCallable;
|
||||
const invoke = primordials.function.invoke;
|
||||
const construct = primordials.function.construct;
|
||||
|
||||
const json = primordials.json;
|
||||
|
||||
const setGlobalPrototype = primordials.setGlobalPrototype;
|
||||
const compile = primordials.compile;
|
||||
const setIntrinsic = primordials.setIntrinsic;
|
||||
|
||||
const valueKey = symbol.makeSymbol("Primitive.value");
|
||||
const undefined = ({}).definitelyDefined;
|
||||
|
||||
var setGlobalPrototypes = primordials.setGlobalPrototype;
|
||||
var compile = primordials.compile;
|
||||
var setIntrinsic = primordials.setIntrinsic;
|
||||
var valueKey = symbol.makeSymbol("Primitive.value");
|
||||
var undefined = void 0;
|
||||
target.undefined = undefined;
|
||||
|
||||
const unwrapThis = (self, type, constr, name, arg = "this", defaultVal) => {
|
||||
if (typeof self === type) return self;
|
||||
if (self instanceof constr && valueKey in self) self = self[valueKey];
|
||||
if (typeof self === type) return self;
|
||||
if (defaultVal !== undefined) return defaultVal;
|
||||
|
||||
function unwrapThis(self, type, constr, name, arg, defaultVal) {
|
||||
if (arg === void 0) { arg = "this"; }
|
||||
if (typeof self === type)
|
||||
return self;
|
||||
if (self instanceof constr && valueKey in self)
|
||||
self = self[valueKey];
|
||||
if (typeof self === type)
|
||||
return self;
|
||||
if (defaultVal !== undefined)
|
||||
return defaultVal;
|
||||
throw new TypeError(name + " requires that '" + arg + "' be a " + constr.name);
|
||||
}
|
||||
|
||||
const wrapIndex = (i, len) => {};
|
||||
|
||||
class Symbol {
|
||||
get description() {
|
||||
return symbol.getSymbolDescriptor(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description"));
|
||||
}
|
||||
toString() {
|
||||
return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")";
|
||||
}
|
||||
valueOf() {
|
||||
return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf");
|
||||
}
|
||||
|
||||
constructor(name = "") {
|
||||
function wrapIndex(i, len) { }
|
||||
var Symbol = /** @class */ (function () {
|
||||
function Symbol(name) {
|
||||
if (name === undefined) name = "";
|
||||
return symbol.makeSymbol(name);
|
||||
}
|
||||
|
||||
static for(name) {
|
||||
Symbol.prototype.toString = function () {
|
||||
return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")";
|
||||
};
|
||||
Symbol.prototype.valueOf = function () {
|
||||
return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf");
|
||||
};
|
||||
Symbol.for = function (name) {
|
||||
return symbol.getSymbol(name + "");
|
||||
}
|
||||
static keyFor(value) {
|
||||
};
|
||||
Symbol.keyFor = function (value) {
|
||||
return symbol.getSymbolKey(unwrapThis(value, "symbol", Symbol, "Symbol.keyFor"));
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(Symbol, true);
|
||||
setConstructable(Symbol, false);
|
||||
|
||||
};
|
||||
return Symbol;
|
||||
}());
|
||||
;
|
||||
object.defineProperty(Symbol.prototype, "desc", false, true, function () {
|
||||
return symbol.getSymbolDescriptor(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description"));
|
||||
});
|
||||
object.defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator"));
|
||||
object.defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator"));
|
||||
object.defineField(Symbol, "match", false, false, false, Symbol("Symbol.match"));
|
||||
@ -101,60 +119,55 @@ object.defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replac
|
||||
object.defineField(Symbol, "search", false, false, false, Symbol("Symbol.search"));
|
||||
object.defineField(Symbol, "split", false, false, false, Symbol("Symbol.split"));
|
||||
object.defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag"));
|
||||
func.setConstructable(Symbol, false);
|
||||
|
||||
Symbol();
|
||||
target.Symbol = Symbol;
|
||||
|
||||
class Number {
|
||||
toString() {
|
||||
return "" + unwrapThis(this, "number", Number, "Number.prototype.toString");
|
||||
}
|
||||
valueOf() {
|
||||
return unwrapThis(this, "number", Number, "Number.prototype.toString");
|
||||
}
|
||||
|
||||
constructor(value) {
|
||||
if (invokeType(arguments) === "call") {
|
||||
function Number(value) {
|
||||
if (func.invokeType(arguments, this) === "call") {
|
||||
if (arguments.length === 0) return 0;
|
||||
else return +value;
|
||||
}
|
||||
|
||||
this[valueKey] = target.Number(value);
|
||||
}
|
||||
|
||||
static isFinite(value) {
|
||||
Number.prototype.toString = function () {
|
||||
return "" + unwrapThis(this, "number", Number, "Number.prototype.toString");
|
||||
};
|
||||
Number.prototype.valueOf = function () {
|
||||
return unwrapThis(this, "number", Number, "Number.prototype.toString");
|
||||
};
|
||||
Number.isFinite = function (value) {
|
||||
value = unwrapThis(value, "number", Number, "Number.isFinite", "value", undefined);
|
||||
|
||||
if (value === undefined || value !== value) return false;
|
||||
if (value === Infinity || value === -Infinity) return false;
|
||||
|
||||
if (value === undefined || value !== value)
|
||||
return false;
|
||||
if (value === Infinity || value === -Infinity)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
static isInteger(value) {
|
||||
};
|
||||
Number.isInteger = function (value) {
|
||||
value = unwrapThis(value, "number", Number, "Number.isInteger", "value", undefined);
|
||||
if (value === undefined) return false;
|
||||
if (value === undefined)
|
||||
return false;
|
||||
return number.parseInt(value) === value;
|
||||
}
|
||||
static isNaN(value) {
|
||||
};
|
||||
Number.isNaN = function (value) {
|
||||
return number.isNaN(value);
|
||||
}
|
||||
static isSafeInteger(value) {
|
||||
};
|
||||
Number.isSafeInteger = function (value) {
|
||||
value = unwrapThis(value, "number", Number, "Number.isSafeInteger", "value", undefined);
|
||||
if (value === undefined || number.parseInt(value) !== value) return false;
|
||||
if (value === undefined || number.parseInt(value) !== value)
|
||||
return false;
|
||||
return value >= -9007199254740991 && value <= 9007199254740991;
|
||||
}
|
||||
static parseFloat(value) {
|
||||
};
|
||||
Number.parseFloat = function (value) {
|
||||
value = 0 + value;
|
||||
return number.parseFloat(value);
|
||||
}
|
||||
static parseInt(value, radix) {
|
||||
};
|
||||
Number.parseInt = function (value, radix) {
|
||||
value = 0 + value;
|
||||
radix = +radix;
|
||||
if (number.isNaN(radix)) radix = 10;
|
||||
|
||||
if (number.isNaN(radix))
|
||||
radix = 10;
|
||||
return number.parseInt(value, radix);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
object.defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16);
|
||||
object.defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991);
|
||||
@ -164,102 +177,75 @@ object.defineField(Number, "NEGATIVE_INFINITY", false, false, false, -number.Inf
|
||||
object.defineField(Number, "NaN", false, false, false, number.NaN);
|
||||
object.defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308);
|
||||
object.defineField(Number, "MIN_VALUE", false, false, false, 5e-324);
|
||||
|
||||
setCallable(Number, true);
|
||||
func.setCallable(Number, true);
|
||||
target.Number = Number;
|
||||
target.parseInt = Number.parseInt;
|
||||
target.parseFloat = Number.parseFloat;
|
||||
target.NaN = Number.NaN;
|
||||
target.Infinity = Number.POSITIVE_INFINITY;
|
||||
|
||||
class String {
|
||||
at(index) {
|
||||
throw "Not implemented :/";
|
||||
return unwrapThis(this, "string", String, "String.prototype.at")[index];
|
||||
function String(value) {
|
||||
if (func.invokeType(arguments, this) === "call") {
|
||||
if (arguments.length === 0)
|
||||
return "";
|
||||
else
|
||||
return value + "";
|
||||
}
|
||||
toString() {
|
||||
return unwrapThis(this, "string", String, "String.prototype.toString");
|
||||
}
|
||||
valueOf() {
|
||||
return unwrapThis(this, "string", String, "String.prototype.valueOf");
|
||||
}
|
||||
|
||||
constructor(value) {
|
||||
if (invokeType(arguments) === "call") {
|
||||
if (arguments.length === 0) return "";
|
||||
else return value + "";
|
||||
}
|
||||
|
||||
this[valueKey] = String(value);
|
||||
}
|
||||
|
||||
static fromCharCode() {
|
||||
const res = [];
|
||||
String.prototype.at = function (index) {
|
||||
throw "Not implemented :/";
|
||||
return unwrapThis(this, "string", String, "String.prototype.at")[index];
|
||||
};
|
||||
String.prototype.toString = function () {
|
||||
return unwrapThis(this, "string", String, "String.prototype.toString");
|
||||
};
|
||||
String.prototype.valueOf = function () {
|
||||
return unwrapThis(this, "string", String, "String.prototype.valueOf");
|
||||
};
|
||||
String.fromCharCode = function () {
|
||||
var res = [];
|
||||
res[arguments.length] = 0;
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
res[i] = string.fromCharCode(+arguments[i]);
|
||||
}
|
||||
|
||||
return string.stringBuild(res);
|
||||
}
|
||||
static fromCodePoint() {
|
||||
const res = [];
|
||||
};
|
||||
String.fromCodePoint = function () {
|
||||
var res = [];
|
||||
res[arguments.length] = 0;
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
res[i] = string.fromCodePoint(+arguments[i]);
|
||||
}
|
||||
|
||||
return string.stringBuild(res);
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(String, true);
|
||||
};
|
||||
func.setCallable(String, true);
|
||||
target.String = String;
|
||||
|
||||
class Boolean {
|
||||
toString() {
|
||||
return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString");
|
||||
}
|
||||
valueOf() {
|
||||
return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf");
|
||||
}
|
||||
|
||||
constructor(value) {
|
||||
if (invokeType(arguments) === "call") {
|
||||
function Boolean(value) {
|
||||
if (func.invokeType(arguments, this) === "call") {
|
||||
if (arguments.length === 0) return false;
|
||||
else return !!value;
|
||||
}
|
||||
|
||||
this[valueKey] = Boolean(value);
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(Boolean, true);
|
||||
Boolean.prototype.toString = function () {
|
||||
return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString");
|
||||
};
|
||||
Boolean.prototype.valueOf = function () {
|
||||
return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf");
|
||||
};
|
||||
func.setCallable(Boolean, true);
|
||||
target.Boolean = Boolean;
|
||||
|
||||
class Object {
|
||||
toString() {
|
||||
if (this !== null && this !== undefined && (Symbol.toStringTag in this)) return "[object " + this[Symbol.toStringTag] + "]";
|
||||
else if (typeof this === "number" || this instanceof Number) return "[object Number]";
|
||||
else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]";
|
||||
else if (typeof this === "string" || this instanceof String) return "[object String]";
|
||||
else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]";
|
||||
else if (typeof this === "function") return "[object Function]";
|
||||
else return "[object Object]";
|
||||
}
|
||||
valueOf() {
|
||||
return this;
|
||||
}
|
||||
|
||||
constructor(value) {
|
||||
function Object(value) {
|
||||
if (typeof value === 'object' && value !== null) return value;
|
||||
if (typeof value === 'string') return new String(value);
|
||||
if (typeof value === 'number') return new Number(value);
|
||||
if (typeof value === 'boolean') return new Boolean(value);
|
||||
if (typeof value === 'symbol') {
|
||||
const res = {};
|
||||
var res = {};
|
||||
setPrototype(res, Symbol.prototype);
|
||||
res[valueKey] = value;
|
||||
return res;
|
||||
@ -268,24 +254,31 @@ class Object {
|
||||
return {};
|
||||
// // TODO: use new.target.prototype as proto
|
||||
// if (target == null || typeof target !== 'object') target = {};
|
||||
|
||||
// return target;
|
||||
}
|
||||
|
||||
static defineProperty(obj, key, desc) {
|
||||
Object.prototype.toString = function () {
|
||||
if (this !== null && this !== undefined && (Symbol.toStringTag in this)) return "[object " + this[Symbol.toStringTag] + "]";
|
||||
else if (typeof this === "number" || this instanceof Number) return "[object Number]";
|
||||
else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]";
|
||||
else if (typeof this === "string" || this instanceof String) return "[object String]";
|
||||
else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]";
|
||||
else if (typeof this === "function") return "[object Function]";
|
||||
else return "[object Object]";
|
||||
};
|
||||
Object.prototype.valueOf = function () {
|
||||
return this;
|
||||
};
|
||||
Object.defineProperty = function (obj, key, desc) {
|
||||
if (typeof obj !== "object" || obj === null) throw new TypeError("Object.defineProperty called on non-object");
|
||||
if (typeof desc !== "object" || desc === null) throw new TypeError("Property description must be an object: " + desc);
|
||||
|
||||
if ("get" in desc || "set" in desc) {
|
||||
let get = desc.get, set = desc.set;
|
||||
var get = desc.get, set = desc.set;
|
||||
|
||||
if (get !== undefined && typeof get !== "function") throw new TypeError("Getter must be a function: " + get);
|
||||
if (set !== undefined && typeof set !== "function") throw new TypeError("Setter must be a function: " + set);
|
||||
|
||||
if ("value" in desc || "writable" in desc) {
|
||||
throw new TypeError("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");
|
||||
}
|
||||
|
||||
if (!object.defineProperty(obj, key, desc.enumerable, desc.configurable, get, set)) {
|
||||
throw new TypeError("Cannot redefine property: " + key);
|
||||
}
|
||||
@ -295,135 +288,131 @@ class Object {
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(Object, true);
|
||||
};
|
||||
func.setCallable(Object, true);
|
||||
object.setPrototype(Object.prototype, null);
|
||||
target.Object = Object;
|
||||
|
||||
class Function {
|
||||
toString() {
|
||||
if (this.name !== "") return "function " + this.name + "(...) { ... }";
|
||||
else return "function (...) { ... }";
|
||||
}
|
||||
|
||||
constructor() {
|
||||
const parts = ["(function annonymous("];
|
||||
|
||||
for (let i = 0; i < arguments.length - 1; i++) {
|
||||
if (i > 0) parts[parts.length] = ",";
|
||||
function Function() {
|
||||
var parts = ["(function annonymous("];
|
||||
for (var i = 0; i < arguments.length - 1; i++) {
|
||||
if (i > 0)
|
||||
parts[parts.length] = ",";
|
||||
parts[parts.length] = arguments[i];
|
||||
}
|
||||
parts[parts.length] = "){\n";
|
||||
parts[parts.length] = String(arguments[arguments.length - 1]);
|
||||
parts[parts.length] = "\n})";
|
||||
|
||||
const res = compile(string.stringBuild(parts))();
|
||||
var res = compile(string.stringBuild(parts))();
|
||||
return res;
|
||||
}
|
||||
Function.prototype.toString = function () {
|
||||
if (this.name !== "")
|
||||
return "function " + this.name + "(...) { ... }";
|
||||
else
|
||||
return "function (...) { ... }";
|
||||
};
|
||||
Function.compile = function (src, opts) {
|
||||
if (src === void 0) src = "";
|
||||
if (opts === void 0) opts = {};
|
||||
if (opts.globals === void 0) opts.globals = [];
|
||||
if (opts.wrap === void 0) opts.wrap = false;
|
||||
|
||||
static compile(src = "", { globals = [], wrap = false } = {}) {
|
||||
const parts = [];
|
||||
var globals = opts.globals;
|
||||
var wrap = opts.wrap;
|
||||
var parts = [];
|
||||
|
||||
if (wrap) parts[parts.length] = "return (function() {\n";
|
||||
if (globals.length > 0) {
|
||||
parts[parts.length] = "let {";
|
||||
|
||||
for (let i = 0; i < globals.length; i++) {
|
||||
for (var i = 0; i < globals.length; i++) {
|
||||
if (i > 0) parts[parts.length] = ",";
|
||||
parts[parts.length] = globals[i];
|
||||
}
|
||||
|
||||
parts[parts.length] = "} = arguments[0];";
|
||||
}
|
||||
|
||||
parts[parts.length] = src;
|
||||
if (wrap) parts[parts.length] = "\n})(arguments[0])";
|
||||
|
||||
const res = compile(string.stringBuild(parts));
|
||||
var res = compile(string.stringBuild(parts));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(Function, true);
|
||||
};
|
||||
func.setCallable(Function, true);
|
||||
target.Function = Function;
|
||||
|
||||
class Array {
|
||||
constructor(len) {
|
||||
function Array(len) {
|
||||
if (arguments.length === 1 && typeof len === "number") {
|
||||
const res = [];
|
||||
var res = [];
|
||||
res.length = len;
|
||||
return res;
|
||||
}
|
||||
// TODO: Implement spreading
|
||||
else throw new Error("Spreading not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
setCallable(Array, true);
|
||||
func.setCallable(Array, true);
|
||||
target.Array = Array;
|
||||
|
||||
class Error {
|
||||
toString() {
|
||||
let res = this.name || "Error";
|
||||
|
||||
const msg = this.message;
|
||||
if (msg) res += ": " + msg;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
constructor (msg = "") {
|
||||
if (invokeType(arguments) === "call") return new Error(msg);
|
||||
function Error(msg) {
|
||||
if (msg === void 0) { msg = ""; }
|
||||
if (func.invokeType(arguments, this) === "call")
|
||||
return new Error(msg);
|
||||
this.message = msg + "";
|
||||
}
|
||||
}
|
||||
|
||||
Error.prototype.toString = function () {
|
||||
var res = this.name || "Error";
|
||||
var msg = this.message;
|
||||
if (msg)
|
||||
res += ": " + msg;
|
||||
return res;
|
||||
};
|
||||
object.defineField(Error.prototype, "name", true, false, true, "Error");
|
||||
object.defineField(Error.prototype, "message", true, false, true, "");
|
||||
setCallable(Error, true);
|
||||
func.setCallable(Error, true);
|
||||
target.Error = Error;
|
||||
|
||||
class SyntaxError extends Error {
|
||||
constructor (msg) {
|
||||
if (invokeType(arguments) === "call") return new SyntaxError(msg);
|
||||
super(msg);
|
||||
__extends(SyntaxError, Error);
|
||||
function SyntaxError(msg) {
|
||||
if (func.invokeType(arguments, this) === "call")
|
||||
return new SyntaxError(msg);
|
||||
return _super.call(this, msg) || this;
|
||||
}
|
||||
}
|
||||
|
||||
object.defineField(SyntaxError.prototype, "name", true, false, true, "SyntaxError");
|
||||
setCallable(SyntaxError, true);
|
||||
func.setCallable(SyntaxError, true);
|
||||
target.SyntaxError = SyntaxError;
|
||||
|
||||
class TypeError extends Error {
|
||||
constructor (msg) {
|
||||
if (invokeType(arguments) === "call") return new TypeError(msg);
|
||||
super(msg);
|
||||
__extends(TypeError, Error);
|
||||
function TypeError(msg) {
|
||||
if (func.invokeType(arguments, this) === "call")
|
||||
return new TypeError(msg);
|
||||
return _super.call(this, msg) || this;
|
||||
}
|
||||
}
|
||||
|
||||
object.defineField(TypeError.prototype, "name", true, false, true, "TypeError");
|
||||
setCallable(TypeError, true);
|
||||
func.setCallable(TypeError, true);
|
||||
target.TypeError = TypeError;
|
||||
|
||||
class RangeError extends Error {
|
||||
constructor (msg) {
|
||||
if (invokeType(arguments) === "call") return new RangeError(msg);
|
||||
super(msg);
|
||||
__extends(RangeError, Error);
|
||||
function RangeError(msg) {
|
||||
if (func.invokeType(arguments, this) === "call")
|
||||
return new RangeError(msg);
|
||||
return _super.call(this, msg) || this;
|
||||
}
|
||||
}
|
||||
|
||||
object.defineField(RangeError.prototype, "name", true, false, true, "RangeError");
|
||||
setCallable(RangeError, true);
|
||||
func.setCallable(RangeError, true);
|
||||
target.RangeError = RangeError;
|
||||
|
||||
setGlobalPrototype("string", String.prototype);
|
||||
setGlobalPrototype("number", Number.prototype);
|
||||
setGlobalPrototype("boolean", Boolean.prototype);
|
||||
setGlobalPrototype("symbol", Symbol.prototype);
|
||||
setGlobalPrototype("object", Object.prototype);
|
||||
setGlobalPrototype("array", Array.prototype);
|
||||
setGlobalPrototype("function", Function.prototype);
|
||||
setGlobalPrototype("error", Error.prototype);
|
||||
setGlobalPrototype("syntax", SyntaxError.prototype);
|
||||
target.uint8 = primordials.uint8;
|
||||
|
||||
setGlobalPrototypes({
|
||||
string: String.prototype,
|
||||
number: Number.prototype,
|
||||
boolean: Boolean.prototype,
|
||||
symbol: Symbol.prototype,
|
||||
object: Object.prototype,
|
||||
array: Array.prototype,
|
||||
function: Function.prototype,
|
||||
error: Error.prototype,
|
||||
syntax: SyntaxError.prototype,
|
||||
range: RangeError.prototype,
|
||||
type: TypeError.prototype,
|
||||
});
|
||||
})(arguments[0], arguments[1]);
|
||||
|
Loading…
Reference in New Issue
Block a user