fix: gd damn it

This commit is contained in:
TopchetoEU 2024-11-24 12:47:15 +02:00
parent 41bb27e4dd
commit 61c5df5003
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
4 changed files with 443 additions and 480 deletions

6
.gitignore vendored
View File

@ -1,6 +1,6 @@
* *
!/src !/src/
!/src/**/* !/src/**/*
!/doc !/doc
@ -21,4 +21,6 @@
!/gradle.properties !/gradle.properties
!/gradle !/gradle
!/gradle/wrapper !/gradle/wrapper
!/gradle/wrapper/gradle-wrapper.properties !/gradle/wrapper/gradle-wrapper.properties
!/

View File

@ -80,7 +80,7 @@ public class IfNode extends Node {
var a = JavaScript.parseExpression(src, i + n, 2); 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."); if (!a.isSuccess()) return a.chainError(src.loc(i + n), "Expected a value after the ternary operator.");
n += a.n; n += a.n;
n += Parsing.skipEmpty(src, i); n += Parsing.skipEmpty(src, i + n);
if (!src.is(i + n, ":")) return ParseRes.failed(); if (!src.is(i + n, ":")) return ParseRes.failed();
n++; n++;

View File

@ -10,6 +10,7 @@ import me.topchetoeu.jscript.common.Metadata;
import me.topchetoeu.jscript.common.Reading; import me.topchetoeu.jscript.common.Reading;
import me.topchetoeu.jscript.common.SyntaxException; import me.topchetoeu.jscript.common.SyntaxException;
import me.topchetoeu.jscript.common.environment.Environment; 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.json.JSON;
import me.topchetoeu.jscript.common.parsing.Filename; import me.topchetoeu.jscript.common.parsing.Filename;
import me.topchetoeu.jscript.runtime.debug.DebugContext; import me.topchetoeu.jscript.runtime.debug.DebugContext;
@ -252,21 +253,17 @@ public class SimpleRepl {
res.defineOwnMember(env, "parse", new NativeFunction(args -> { res.defineOwnMember(env, "parse", new NativeFunction(args -> {
return JSONConverter.toJs(JSON.parse(null, args.get(0).toString(env))); 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; 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) { private static ObjectValue primordials(Environment env) {
var res = new ObjectValue(); var res = new ObjectValue();
res.setPrototype(null, null); res.setPrototype(null, null);
@ -280,45 +277,20 @@ public class SimpleRepl {
int[] i = new int[1]; int[] i = new int[1];
res.defineOwnMember(env, "setGlobalPrototype", new NativeFunction(args -> { res.defineOwnMember(env, "setGlobalPrototypes", new NativeFunction(args -> {
var type = args.get(0).toString(env);
var obj = (ObjectValue)args.get(1); var obj = (ObjectValue)args.get(1);
switch (type) { setProto(args.env, env, Value.OBJECT_PROTO, obj, "object");
case "object": setProto(args.env, env, Value.FUNCTION_PROTO, obj, "function");
args.env.add(Value.OBJECT_PROTO, obj); setProto(args.env, env, Value.ARRAY_PROTO, obj, "array");
break; setProto(args.env, env, Value.BOOL_PROTO, obj, "boolean");
case "function": setProto(args.env, env, Value.NUMBER_PROTO, obj, "number");
args.env.add(Value.FUNCTION_PROTO, obj); setProto(args.env, env, Value.STRING_PROTO, obj, "string");
break; setProto(args.env, env, Value.SYMBOL_PROTO, obj, "symbol");
case "array": setProto(args.env, env, Value.ERROR_PROTO, obj, "error");
args.env.add(Value.ARRAY_PROTO, obj); setProto(args.env, env, Value.SYNTAX_ERR_PROTO, obj, "syntax");
break; setProto(args.env, env, Value.TYPE_ERR_PROTO, obj, "type");
case "boolean": setProto(args.env, env, Value.RANGE_ERR_PROTO, obj, "range");
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;
}
return Value.UNDEFINED; return Value.UNDEFINED;
})); }));

View File

@ -1,429 +1,418 @@
const target = arguments[0]; return;
const primordials = arguments[1]; (function main() {
var __extends = (this && this.__extends) || (function () {
const symbol = primordials.symbol || (() => { var extendStatics = function (d, b) {
const repo = {}; extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
return { function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
makeSymbol: (name) => { name }, return extendStatics(d, b);
getSymbol(name) { };
if (name in repo) return repo[name]; return function (d, b) {
else return repo[name] = { name }; if (typeof b !== "function" && b !== null)
}, throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
getSymbolKey(symbol) { extendStatics(d, b);
if (symbol.name in repo && repo[symbol.name] === symbol) return symbol.name; function __() { this.constructor = d; }
else return undefined; d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}, };
getSymbolDescription: ({ name }) => name, })();
};
}); var target = arguments[0];
var primordials = arguments[1];
const number = primordials.number || { var symbol = primordials.symbol || (function () {
parseInt() { throw new Error("parseInt not supported"); }, var repo = {};
parseFloat() { throw new Error("parseFloat not supported"); }, return {
isNaN: (val) => val !== val, makeSymbol: function (name) { return { name: name }; },
NaN: 0 / 0, getSymbol: function (name) {
Infinity: 1 / 0, if (name in repo) return repo[name];
}; else return repo[name] = { name: name };
},
const string = primordials.string; getSymbolKey: function (symbol) {
if (symbol.name in repo && repo[symbol.name] === symbol) return symbol.name;
const object = primordials.object || { else return undefined;
defineProperty() { throw new Error("Define property not polyfillable"); }, },
defineField(obj, key, a, b, c, value) { obj[key] = value; }, getSymbolDescription: function (symbol) {
getOwnMember() { throw new Error("Get own member not polyfillable"); }, return symbol.name;
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"); }, var number = primordials.number || {
setPrototype() { throw new Error("Set prototype not polyfillable"); }, parseInt: function () { throw new Error("parseInt not supported"); },
} parseFloat: function () { throw new Error("parseFloat not supported"); },
isNaN: function (val) { return val !== val; },
const invokeType = primordials.function.invokeType; NaN: 0 / 0,
const setConstructable = primordials.function.setConstructable; Infinity: 1 / 0,
const setCallable = primordials.function.setCallable; };
const invoke = primordials.function.invoke; var string = primordials.string;
const construct = primordials.function.construct; var object = primordials.object || {
defineProperty: function () { throw new Error("Define property not polyfillable"); },
const json = primordials.json; defineField: function (obj, key, a, b, c, value) { obj[key] = value; },
getOwnMember: function () { throw new Error("Get own member not polyfillable"); },
const setGlobalPrototype = primordials.setGlobalPrototype; getOwnSymbolMember: function () { throw new Error("Get own symbol member not polyfillable"); },
const compile = primordials.compile; getOwnMembers: function () { throw new Error("Get own members not polyfillable"); },
const setIntrinsic = primordials.setIntrinsic; getOwnSymbolMembers: function () { throw new Error("Get own symbol members not polyfillable"); },
getPrototype: function () { throw new Error("Get prototype not polyfillable"); },
const valueKey = symbol.makeSymbol("Primitive.value"); setPrototype: function () { throw new Error("Set prototype not polyfillable"); },
const undefined = ({}).definitelyDefined; };
var func = primordials.function || {
target.undefined = undefined; invokeType: function (args, self) {
if (typeof self === "object") return "new";
const unwrapThis = (self, type, constr, name, arg = "this", defaultVal) => { else return "call";
if (typeof self === type) return self; },
if (self instanceof constr && valueKey in self) self = self[valueKey]; setConstructable: function () { throw new Error("Set constructable not polyfillable"); },
if (typeof self === type) return self; setCallable: function () { throw new Error("Set callable not polyfillable"); },
if (defaultVal !== undefined) return defaultVal; invoke: function () { throw new Error("Invoke not polyfillable"); },
construct: function () { throw new Error("Construct not polyfillable"); },
throw new TypeError(name + " requires that '" + arg + "' be a " + constr.name); };
} var json = primordials.json || {
stringify: function (val) { throw new Error("JSON stringify not polyfillable"); },
const wrapIndex = (i, len) => {}; parse: function (val) { throw new Error("JSON parse not polyfillable"); },
}
class Symbol {
get description() { var setGlobalPrototypes = primordials.setGlobalPrototype;
return symbol.getSymbolDescriptor(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description")); var compile = primordials.compile;
} var setIntrinsic = primordials.setIntrinsic;
toString() { var valueKey = symbol.makeSymbol("Primitive.value");
return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")"; var undefined = void 0;
} target.undefined = undefined;
valueOf() {
return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf"); function unwrapThis(self, type, constr, name, arg, defaultVal) {
} if (arg === void 0) { arg = "this"; }
if (typeof self === type)
constructor(name = "") { return self;
return symbol.makeSymbol(name); if (self instanceof constr && valueKey in self)
} self = self[valueKey];
if (typeof self === type)
static for(name) { return self;
return symbol.getSymbol(name + ""); if (defaultVal !== undefined)
} return defaultVal;
static keyFor(value) { throw new TypeError(name + " requires that '" + arg + "' be a " + constr.name);
return symbol.getSymbolKey(unwrapThis(value, "symbol", Symbol, "Symbol.keyFor")); }
} function wrapIndex(i, len) { }
} var Symbol = /** @class */ (function () {
function Symbol(name) {
setCallable(Symbol, true); if (name === undefined) name = "";
setConstructable(Symbol, false); return symbol.makeSymbol(name);
}
object.defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator")); Symbol.prototype.toString = function () {
object.defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator")); return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")";
object.defineField(Symbol, "match", false, false, false, Symbol("Symbol.match")); };
object.defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll")); Symbol.prototype.valueOf = function () {
object.defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace")); return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf");
object.defineField(Symbol, "search", false, false, false, Symbol("Symbol.search")); };
object.defineField(Symbol, "split", false, false, false, Symbol("Symbol.split")); Symbol.for = function (name) {
object.defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag")); return symbol.getSymbol(name + "");
};
Symbol(); Symbol.keyFor = function (value) {
target.Symbol = Symbol; return symbol.getSymbolKey(unwrapThis(value, "symbol", Symbol, "Symbol.keyFor"));
};
class Number { return Symbol;
toString() { }());
return "" + unwrapThis(this, "number", Number, "Number.prototype.toString"); ;
} object.defineProperty(Symbol.prototype, "desc", false, true, function () {
valueOf() { return symbol.getSymbolDescriptor(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description"));
return unwrapThis(this, "number", Number, "Number.prototype.toString"); });
} object.defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator"));
object.defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator"));
constructor(value) { object.defineField(Symbol, "match", false, false, false, Symbol("Symbol.match"));
if (invokeType(arguments) === "call") { object.defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll"));
if (arguments.length === 0) return 0; object.defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace"));
else return +value; 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"));
this[valueKey] = target.Number(value); func.setConstructable(Symbol, false);
}
function Number(value) {
static isFinite(value) { if (func.invokeType(arguments, this) === "call") {
value = unwrapThis(value, "number", Number, "Number.isFinite", "value", undefined); if (arguments.length === 0) return 0;
else return +value;
if (value === undefined || value !== value) return false; }
if (value === Infinity || value === -Infinity) return false; this[valueKey] = target.Number(value);
}
return true; Number.prototype.toString = function () {
} return "" + unwrapThis(this, "number", Number, "Number.prototype.toString");
static isInteger(value) { };
value = unwrapThis(value, "number", Number, "Number.isInteger", "value", undefined); Number.prototype.valueOf = function () {
if (value === undefined) return false; return unwrapThis(this, "number", Number, "Number.prototype.toString");
return number.parseInt(value) === value; };
} Number.isFinite = function (value) {
static isNaN(value) { value = unwrapThis(value, "number", Number, "Number.isFinite", "value", undefined);
return number.isNaN(value); if (value === undefined || value !== value)
} return false;
static isSafeInteger(value) { if (value === Infinity || value === -Infinity)
value = unwrapThis(value, "number", Number, "Number.isSafeInteger", "value", undefined); return false;
if (value === undefined || number.parseInt(value) !== value) return false; return true;
return value >= -9007199254740991 && value <= 9007199254740991; };
} Number.isInteger = function (value) {
static parseFloat(value) { value = unwrapThis(value, "number", Number, "Number.isInteger", "value", undefined);
value = 0 + value; if (value === undefined)
return number.parseFloat(value); return false;
} return number.parseInt(value) === value;
static parseInt(value, radix) { };
value = 0 + value; Number.isNaN = function (value) {
radix = +radix; return number.isNaN(value);
if (number.isNaN(radix)) radix = 10; };
Number.isSafeInteger = function (value) {
return number.parseInt(value, radix); value = unwrapThis(value, "number", Number, "Number.isSafeInteger", "value", undefined);
} if (value === undefined || number.parseInt(value) !== value)
} return false;
return value >= -9007199254740991 && value <= 9007199254740991;
object.defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16); };
object.defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991); Number.parseFloat = function (value) {
object.defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991); value = 0 + value;
object.defineField(Number, "POSITIVE_INFINITY", false, false, false, +number.Infinity); return number.parseFloat(value);
object.defineField(Number, "NEGATIVE_INFINITY", false, false, false, -number.Infinity); };
object.defineField(Number, "NaN", false, false, false, number.NaN); Number.parseInt = function (value, radix) {
object.defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308); value = 0 + value;
object.defineField(Number, "MIN_VALUE", false, false, false, 5e-324); radix = +radix;
if (number.isNaN(radix))
setCallable(Number, true); radix = 10;
target.Number = Number; return number.parseInt(value, radix);
target.parseInt = Number.parseInt; };
target.parseFloat = Number.parseFloat;
target.NaN = Number.NaN; object.defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16);
target.Infinity = Number.POSITIVE_INFINITY; object.defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991);
object.defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991);
class String { object.defineField(Number, "POSITIVE_INFINITY", false, false, false, +number.Infinity);
at(index) { object.defineField(Number, "NEGATIVE_INFINITY", false, false, false, -number.Infinity);
throw "Not implemented :/"; object.defineField(Number, "NaN", false, false, false, number.NaN);
return unwrapThis(this, "string", String, "String.prototype.at")[index]; object.defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308);
} object.defineField(Number, "MIN_VALUE", false, false, false, 5e-324);
toString() { func.setCallable(Number, true);
return unwrapThis(this, "string", String, "String.prototype.toString"); target.Number = Number;
} target.parseInt = Number.parseInt;
valueOf() { target.parseFloat = Number.parseFloat;
return unwrapThis(this, "string", String, "String.prototype.valueOf"); target.NaN = Number.NaN;
} target.Infinity = Number.POSITIVE_INFINITY;
constructor(value) { function String(value) {
if (invokeType(arguments) === "call") { if (func.invokeType(arguments, this) === "call") {
if (arguments.length === 0) return ""; if (arguments.length === 0)
else return value + ""; return "";
} else
return value + "";
this[valueKey] = String(value); }
} this[valueKey] = String(value);
}
static fromCharCode() { String.prototype.at = function (index) {
const res = []; throw "Not implemented :/";
res[arguments.length] = 0; return unwrapThis(this, "string", String, "String.prototype.at")[index];
};
for (let i = 0; i < arguments.length; i++) { String.prototype.toString = function () {
res[i] = string.fromCharCode(+arguments[i]); return unwrapThis(this, "string", String, "String.prototype.toString");
} };
String.prototype.valueOf = function () {
return string.stringBuild(res); return unwrapThis(this, "string", String, "String.prototype.valueOf");
} };
static fromCodePoint() { String.fromCharCode = function () {
const res = []; var res = [];
res[arguments.length] = 0; res[arguments.length] = 0;
for (var i = 0; i < arguments.length; i++) {
for (let i = 0; i < arguments.length; i++) { res[i] = string.fromCharCode(+arguments[i]);
res[i] = string.fromCodePoint(+arguments[i]); }
} return string.stringBuild(res);
};
return string.stringBuild(res); String.fromCodePoint = function () {
} var res = [];
} res[arguments.length] = 0;
setCallable(String, true); for (var i = 0; i < arguments.length; i++) {
target.String = String; res[i] = string.fromCodePoint(+arguments[i]);
}
class Boolean { return string.stringBuild(res);
toString() { };
return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString"); func.setCallable(String, true);
} target.String = String;
valueOf() {
return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf"); function Boolean(value) {
} if (func.invokeType(arguments, this) === "call") {
if (arguments.length === 0) return false;
constructor(value) { else return !!value;
if (invokeType(arguments) === "call") { }
if (arguments.length === 0) return false; this[valueKey] = Boolean(value);
else return !!value; }
} Boolean.prototype.toString = function () {
return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString");
this[valueKey] = Boolean(value); };
} Boolean.prototype.valueOf = function () {
} return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf");
};
setCallable(Boolean, true); func.setCallable(Boolean, true);
target.Boolean = Boolean; target.Boolean = Boolean;
class Object { function Object(value) {
toString() { if (typeof value === 'object' && value !== null) return value;
if (this !== null && this !== undefined && (Symbol.toStringTag in this)) return "[object " + this[Symbol.toStringTag] + "]"; if (typeof value === 'string') return new String(value);
else if (typeof this === "number" || this instanceof Number) return "[object Number]"; if (typeof value === 'number') return new Number(value);
else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]"; if (typeof value === 'boolean') return new Boolean(value);
else if (typeof this === "string" || this instanceof String) return "[object String]"; if (typeof value === 'symbol') {
else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]"; var res = {};
else if (typeof this === "function") return "[object Function]"; setPrototype(res, Symbol.prototype);
else return "[object Object]"; res[valueKey] = value;
} return res;
valueOf() { }
return this;
} return {};
// // TODO: use new.target.prototype as proto
constructor(value) { // if (target == null || typeof target !== 'object') target = {};
if (typeof value === 'object' && value !== null) return value; // return target;
if (typeof value === 'string') return new String(value); }
if (typeof value === 'number') return new Number(value); Object.prototype.toString = function () {
if (typeof value === 'boolean') return new Boolean(value); if (this !== null && this !== undefined && (Symbol.toStringTag in this)) return "[object " + this[Symbol.toStringTag] + "]";
if (typeof value === 'symbol') { else if (typeof this === "number" || this instanceof Number) return "[object Number]";
const res = {}; else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]";
setPrototype(res, Symbol.prototype); else if (typeof this === "string" || this instanceof String) return "[object String]";
res[valueKey] = value; else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]";
return res; else if (typeof this === "function") return "[object Function]";
} else return "[object Object]";
};
return {}; Object.prototype.valueOf = function () {
// // TODO: use new.target.prototype as proto return this;
// if (target == null || typeof target !== 'object') target = {}; };
Object.defineProperty = function (obj, key, desc) {
// return target; 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) {
static defineProperty(obj, key, desc) { var get = desc.get, set = desc.set;
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 !== 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 ("get" in desc || "set" in desc) { if ("value" in desc || "writable" in desc) {
let get = desc.get, set = desc.set; throw new TypeError("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");
}
if (get !== undefined && typeof get !== "function") throw new TypeError("Getter must be a function: " + get); if (!object.defineProperty(obj, key, desc.enumerable, desc.configurable, get, set)) {
if (set !== undefined && typeof set !== "function") throw new TypeError("Setter must be a function: " + set); throw new TypeError("Cannot redefine property: " + key);
}
if ("value" in desc || "writable" in desc) { }
throw new TypeError("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute"); else if (!object.defineField(obj, key, desc.writable, desc.enumerable, desc.configurable, desc.value)) {
} throw new TypeError("Cannot redefine property: " + key);
}
if (!object.defineProperty(obj, key, desc.enumerable, desc.configurable, get, set)) {
throw new TypeError("Cannot redefine property: " + key); return obj;
} };
} func.setCallable(Object, true);
else if (!object.defineField(obj, key, desc.writable, desc.enumerable, desc.configurable, desc.value)) { object.setPrototype(Object.prototype, null);
throw new TypeError("Cannot redefine property: " + key); target.Object = Object;
}
function Function() {
return obj; var parts = ["(function annonymous("];
} for (var i = 0; i < arguments.length - 1; i++) {
} if (i > 0)
parts[parts.length] = ",";
setCallable(Object, true); parts[parts.length] = arguments[i];
object.setPrototype(Object.prototype, null); }
target.Object = Object; parts[parts.length] = "){\n";
parts[parts.length] = String(arguments[arguments.length - 1]);
class Function { parts[parts.length] = "\n})";
toString() { var res = compile(string.stringBuild(parts))();
if (this.name !== "") return "function " + this.name + "(...) { ... }"; return res;
else return "function (...) { ... }"; }
} Function.prototype.toString = function () {
if (this.name !== "")
constructor() { return "function " + this.name + "(...) { ... }";
const parts = ["(function annonymous("]; else
return "function (...) { ... }";
for (let i = 0; i < arguments.length - 1; i++) { };
if (i > 0) parts[parts.length] = ","; Function.compile = function (src, opts) {
parts[parts.length] = arguments[i]; if (src === void 0) src = "";
} if (opts === void 0) opts = {};
parts[parts.length] = "){\n"; if (opts.globals === void 0) opts.globals = [];
parts[parts.length] = String(arguments[arguments.length - 1]); if (opts.wrap === void 0) opts.wrap = false;
parts[parts.length] = "\n})";
var globals = opts.globals;
const res = compile(string.stringBuild(parts))(); var wrap = opts.wrap;
return res; var parts = [];
}
if (wrap) parts[parts.length] = "return (function() {\n";
static compile(src = "", { globals = [], wrap = false } = {}) { if (globals.length > 0) {
const parts = []; parts[parts.length] = "let {";
for (var i = 0; i < globals.length; i++) {
if (wrap) parts[parts.length] = "return (function() {\n"; if (i > 0) parts[parts.length] = ",";
if (globals.length > 0) { parts[parts.length] = globals[i];
parts[parts.length] = "let {"; }
parts[parts.length] = "} = arguments[0];";
for (let i = 0; i < globals.length; i++) { }
if (i > 0) parts[parts.length] = ","; parts[parts.length] = src;
parts[parts.length] = globals[i]; if (wrap) parts[parts.length] = "\n})(arguments[0])";
}
var res = compile(string.stringBuild(parts));
parts[parts.length] = "} = arguments[0];"; return res;
} };
func.setCallable(Function, true);
parts[parts.length] = src; target.Function = Function;
if (wrap) parts[parts.length] = "\n})(arguments[0])";
function Array(len) {
const res = compile(string.stringBuild(parts)); if (arguments.length === 1 && typeof len === "number") {
return res; var res = [];
} res.length = len;
} return res;
}
setCallable(Function, true); // TODO: Implement spreading
target.Function = Function; else throw new Error("Spreading not implemented");
}
class Array { func.setCallable(Array, true);
constructor(len) { target.Array = Array;
if (arguments.length === 1 && typeof len === "number") {
const res = []; function Error(msg) {
res.length = len; if (msg === void 0) { msg = ""; }
return res; if (func.invokeType(arguments, this) === "call")
} return new Error(msg);
// TODO: Implement spreading this.message = msg + "";
else throw new Error("Spreading not implemented"); }
} Error.prototype.toString = function () {
} var res = this.name || "Error";
var msg = this.message;
setCallable(Array, true); if (msg)
target.Array = Array; res += ": " + msg;
return res;
class Error { };
toString() { object.defineField(Error.prototype, "name", true, false, true, "Error");
let res = this.name || "Error"; object.defineField(Error.prototype, "message", true, false, true, "");
func.setCallable(Error, true);
const msg = this.message; target.Error = Error;
if (msg) res += ": " + msg;
__extends(SyntaxError, Error);
return res; function SyntaxError(msg) {
} if (func.invokeType(arguments, this) === "call")
return new SyntaxError(msg);
constructor (msg = "") { return _super.call(this, msg) || this;
if (invokeType(arguments) === "call") return new Error(msg); }
this.message = msg + ""; object.defineField(SyntaxError.prototype, "name", true, false, true, "SyntaxError");
} func.setCallable(SyntaxError, true);
} target.SyntaxError = SyntaxError;
object.defineField(Error.prototype, "name", true, false, true, "Error"); __extends(TypeError, Error);
object.defineField(Error.prototype, "message", true, false, true, ""); function TypeError(msg) {
setCallable(Error, true); if (func.invokeType(arguments, this) === "call")
target.Error = Error; return new TypeError(msg);
return _super.call(this, msg) || this;
class SyntaxError extends Error { }
constructor (msg) { object.defineField(TypeError.prototype, "name", true, false, true, "TypeError");
if (invokeType(arguments) === "call") return new SyntaxError(msg); func.setCallable(TypeError, true);
super(msg); target.TypeError = TypeError;
}
} __extends(RangeError, Error);
function RangeError(msg) {
object.defineField(SyntaxError.prototype, "name", true, false, true, "SyntaxError"); if (func.invokeType(arguments, this) === "call")
setCallable(SyntaxError, true); return new RangeError(msg);
target.SyntaxError = SyntaxError; return _super.call(this, msg) || this;
}
class TypeError extends Error { object.defineField(RangeError.prototype, "name", true, false, true, "RangeError");
constructor (msg) { func.setCallable(RangeError, true);
if (invokeType(arguments) === "call") return new TypeError(msg); target.RangeError = RangeError;
super(msg);
} target.uint8 = primordials.uint8;
}
setGlobalPrototypes({
object.defineField(TypeError.prototype, "name", true, false, true, "TypeError"); string: String.prototype,
setCallable(TypeError, true); number: Number.prototype,
target.TypeError = TypeError; boolean: Boolean.prototype,
symbol: Symbol.prototype,
class RangeError extends Error { object: Object.prototype,
constructor (msg) { array: Array.prototype,
if (invokeType(arguments) === "call") return new RangeError(msg); function: Function.prototype,
super(msg); error: Error.prototype,
} syntax: SyntaxError.prototype,
} range: RangeError.prototype,
type: TypeError.prototype,
object.defineField(RangeError.prototype, "name", true, false, true, "RangeError"); });
setCallable(RangeError, true); })(arguments[0], arguments[1]);
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);