ES6 Support Groundwork + Fixes #26

Merged
TopchetoEU merged 49 commits from ES6 into master 2024-09-05 14:26:07 +00:00
Showing only changes of commit ce9b419757 - Show all commits

View File

@ -1,43 +1,46 @@
#! my special comment lol const target = arguments[0];
const primordials = arguments[1];
(function(target, primordials) { const makeSymbol = primordials.symbol.makeSymbol;
var makeSymbol = primordials.symbol.makeSymbol; const getSymbol = primordials.symbol.getSymbol;
var getSymbol = primordials.symbol.getSymbol; const getSymbolKey = primordials.symbol.getSymbolKey;
var getSymbolKey = primordials.symbol.getSymbolKey; const getSymbolDescription = primordials.symbol.getSymbolDescription;
var getSymbolDescription = primordials.symbol.getSymbolDescription;
var parseInt = primordials.number.parseInt; const parseInt = primordials.number.parseInt;
var parseFloat = primordials.number.parseFloat; const parseFloat = primordials.number.parseFloat;
var isNaN = primordials.number.isNaN; const isNaN = primordials.number.isNaN;
var NaN = primordials.number.NaN; const NaN = primordials.number.NaN;
var Infinity = primordials.number.Infinity; const Infinity = primordials.number.Infinity;
var fromCharCode = primordials.string.fromCharCode; const fromCharCode = primordials.string.fromCharCode;
var fromCodePoint = primordials.string.fromCodePoint; const fromCodePoint = primordials.string.fromCodePoint;
var stringBuild = primordials.string.stringBuild; const stringBuild = primordials.string.stringBuild;
var defineProperty = primordials.object.defineProperty; const defineProperty = primordials.object.defineProperty;
var defineField = primordials.object.defineField; const defineField = primordials.object.defineField;
var getOwnMember = primordials.object.getMember; const getOwnMember = primordials.object.getMember;
var getOwnSymbolMember = primordials.object.getOwnSymbolMember; const getOwnSymbolMember = primordials.object.getOwnSymbolMember;
var getOwnMembers = primordials.object.getOwnMembers; const getOwnMembers = primordials.object.getOwnMembers;
var getOwnSymbolMembers = primordials.object.getOwnSymbolMembers; const getOwnSymbolMembers = primordials.object.getOwnSymbolMembers;
var getPrototype = primordials.object.getPrototype; const getPrototype = primordials.object.getPrototype;
var setPrototype = primordials.object.setPrototype; const setPrototype = primordials.object.setPrototype;
var invokeType = primordials.function.invokeType; const invokeType = primordials.function.invokeType;
var setConstructable = primordials.function.setConstructable; const setConstructable = primordials.function.setConstructable;
var setCallable = primordials.function.setCallable; const setCallable = primordials.function.setCallable;
var invoke = primordials.function.invoke; const invoke = primordials.function.invoke;
var setGlobalPrototype = primordials.setGlobalPrototype; const setGlobalPrototype = primordials.setGlobalPrototype;
var compile = primordials.compile; const compile = primordials.compile;
var json = primordials.json; const json = primordials.json;
var valueKey = makeSymbol("Primitive.value"); const valueKey = makeSymbol("Primitive.value");
const undefined = ({}).definitelyDefined;
function unwrapThis(self, type, constr, name, arg, defaultVal) { target.undefined = undefined;
const unwrapThis = (self, type, constr, name, arg, defaultVal) => {
if (arg == null) arg = "this"; if (arg == null) arg = "this";
if (typeof self === type) return self; if (typeof self === type) return self;
if (self instanceof constr && valueKey in self) self = self[valueKey]; if (self instanceof constr && valueKey in self) self = self[valueKey];
@ -45,194 +48,190 @@
if (arguments.length > 5) return defaultVal; if (arguments.length > 5) return defaultVal;
throw new TypeError(name + " requires that '" + arg + "' be a " + constr.name); throw new TypeError(name + " requires that '" + arg + "' be a " + constr.name);
} }
function wrapIndex(i, len) { const wrapIndex = (i, len) => {};
}
var Symbol = function(name) { const Symbol = (name = "") => makeSymbol(name);
if (arguments.length === 0) return makeSymbol("");
else return makeSymbol(name + "");
};
setConstructable(Symbol, false);
defineField(Symbol, "for", true, false, true, function(name) { defineField(Symbol, "for", true, false, true, function(name) {
return getSymbol(name + ""); return getSymbol(name + "");
}); });
defineField(Symbol, "keyFor", true, false, true, function(symbol) { defineField(Symbol, "keyFor", true, false, true, function(symbol) {
return getSymbolKey(unwrapThis(symbol, "symbol", Symbol, "Symbol.keyFor")); return getSymbolKey(unwrapThis(symbol, "symbol", Symbol, "Symbol.keyFor"));
}); });
defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator")); defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator"));
defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator")); defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator"));
defineField(Symbol, "match", false, false, false, Symbol("Symbol.match")); defineField(Symbol, "match", false, false, false, Symbol("Symbol.match"));
defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll")); defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll"));
defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace")); defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace"));
defineField(Symbol, "search", false, false, false, Symbol("Symbol.search")); defineField(Symbol, "search", false, false, false, Symbol("Symbol.search"));
defineField(Symbol, "split", false, false, false, Symbol("Symbol.split")); defineField(Symbol, "split", false, false, false, Symbol("Symbol.split"));
defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag")); defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag"));
defineField(Symbol, "prototype", false, false, false, {}); defineField(Symbol, "prototype", false, false, false, {});
defineProperty(Symbol.prototype, "description", false, true, function () { defineProperty(Symbol.prototype, "description", false, true, function () {
return getSymbolDescription(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description")); return getSymbolDescription(unwrapThis(this, "symbol", Symbol, "Symbol.prototype.description"));
}, undefined); }, undefined);
defineField(Symbol.prototype, "toString", true, false, true, function() { defineField(Symbol.prototype, "toString", true, false, true, function() {
return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")"; return "Symbol(" + unwrapThis(this, "symbol", Symbol, "Symbol.prototype.toString").description + ")";
}); });
defineField(Symbol.prototype, "valueOf", true, false, true, function() { defineField(Symbol.prototype, "valueOf", true, false, true, function() {
return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf"); return unwrapThis(this, "symbol", Symbol, "Symbol.prototype.valueOf");
}); });
target.Symbol = Symbol; target.Symbol = Symbol;
var Number = function(value) { const Number = function(value) {
if (invokeType(arguments) === "call") { if (invokeType(arguments) === "call") {
if (arguments.length === 0) return 0; if (arguments.length === 0) return 0;
else return +value; else return +value;
} }
this[valueKey] = target.Number(value); this[valueKey] = target.Number(value);
}; };
defineField(Number, "isFinite", true, false, true, function(value) { defineField(Number, "isFinite", true, false, true, function(value) {
value = unwrapThis(value, "number", Number, "Number.isFinite", "value", undefined); value = unwrapThis(value, "number", Number, "Number.isFinite", "value", undefined);
if (value === undefined || isNaN(value)) return false; if (value === undefined || isNaN(value)) return false;
if (value === Infinity || value === -Infinity) return false; if (value === Infinity || value === -Infinity) return false;
return true; return true;
}); });
defineField(Number, "isInteger", true, false, true, function(value) { defineField(Number, "isInteger", true, false, true, function(value) {
value = unwrapThis(value, "number", Number, "Number.isInteger", "value", undefined); value = unwrapThis(value, "number", Number, "Number.isInteger", "value", undefined);
if (value === undefined) return false; if (value === undefined) return false;
return parseInt(value) === value; return parseInt(value) === value;
}); });
defineField(Number, "isNaN", true, false, true, function(value) { defineField(Number, "isNaN", true, false, true, function(value) {
return isNaN(value); return isNaN(value);
}); });
defineField(Number, "isSafeInteger", true, false, true, function(value) { defineField(Number, "isSafeInteger", true, false, true, function(value) {
value = unwrapThis(value, "number", Number, "Number.isSafeInteger", "value", undefined); value = unwrapThis(value, "number", Number, "Number.isSafeInteger", "value", undefined);
if (value === undefined || parseInt(value) !== value) return false; if (value === undefined || parseInt(value) !== value) return false;
return value >= -9007199254740991 && value <= 9007199254740991; return value >= -9007199254740991 && value <= 9007199254740991;
}); });
defineField(Number, "parseFloat", true, false, true, function(value) { defineField(Number, "parseFloat", true, false, true, function(value) {
value = 0 + value; value = 0 + value;
return parseFloat(value); return parseFloat(value);
}); });
defineField(Number, "parseInt", true, false, true, function(value, radix) { defineField(Number, "parseInt", true, false, true, function(value, radix) {
value = 0 + value; value = 0 + value;
radix = +radix; radix = +radix;
if (isNaN(radix)) radix = 10; if (isNaN(radix)) radix = 10;
return parseInt(value, radix); return parseInt(value, radix);
}); });
defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16); defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16);
defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991); defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991);
defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991); defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991);
defineField(Number, "POSITIVE_INFINITY", false, false, false, +Infinity); defineField(Number, "POSITIVE_INFINITY", false, false, false, +Infinity);
defineField(Number, "NEGATIVE_INFINITY", false, false, false, -Infinity); defineField(Number, "NEGATIVE_INFINITY", false, false, false, -Infinity);
defineField(Number, "NaN", false, false, false, NaN); defineField(Number, "NaN", false, false, false, NaN);
defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308); defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308);
defineField(Number, "MIN_VALUE", false, false, false, 5e-324); defineField(Number, "MIN_VALUE", false, false, false, 5e-324);
defineField(Number, "prototype", false, false, false, {}); defineField(Number, "prototype", false, false, false, {});
defineField(Number.prototype, "toString", true, false, true); defineField(Number.prototype, "toString", true, false, true);
defineField(Number.prototype, "toString", true, false, true, function() { defineField(Number.prototype, "toString", true, false, true, function() {
return "" + unwrapThis(this, "number", Number, "Number.prototype.toString"); return "" + unwrapThis(this, "number", Number, "Number.prototype.toString");
}); });
defineField(Number.prototype, "valueOf", true, false, true, function() { defineField(Number.prototype, "valueOf", true, false, true, function() {
return unwrapThis(this, "number", Number, "Number.prototype.toString"); return unwrapThis(this, "number", Number, "Number.prototype.toString");
}); });
target.Number = Number; target.Number = Number;
var String = function(value) { const String = function(value) {
if (invokeType(arguments) === "call") { if (invokeType(arguments) === "call") {
if (arguments.length === 0) return ""; if (arguments.length === 0) return "";
else return value + ""; else return value + "";
} }
this[valueKey] = target.String(value); this[valueKey] = String(value);
}; };
defineField(String, "fromCharCode", true, false, true, function() { defineField(String, "fromCharCode", true, false, true, function() {
var res = []; const 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[res.length] = fromCharCode(+arguments[i]); res[i] = fromCharCode(+arguments[i]);
} }
return stringBuild(res); return stringBuild(res);
}); });
defineField(String, "fromCodePoint", true, false, true, function(value) { defineField(String, "fromCodePoint", true, false, true, function() {
var res = []; const 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[res.length] = fromCodePoint(+arguments[i]); res[i] = fromCodePoint(+arguments[i]);
} }
return stringBuild(res); return stringBuild(res);
}); });
defineField(String, "prototype", false, false, false, {}); defineField(String, "prototype", false, false, false, {});
defineField(String.prototype, "at", true, false, true, function(index) { defineField(String.prototype, "at", true, false, true, function(index) {
return "" + unwrapThis(this, "string", String, "String.prototype.at"); throw "Not implemented :/";
}); return unwrapThis(this, "string", String, "String.prototype.at")[index];
defineField(String.prototype, "toString", true, false, true, function() { });
defineField(String.prototype, "toString", true, false, true, function() {
return unwrapThis(this, "string", String, "String.prototype.toString"); return unwrapThis(this, "string", String, "String.prototype.toString");
}); });
defineField(String.prototype, "valueOf", true, false, true, function() { defineField(String.prototype, "valueOf", true, false, true, function() {
return unwrapThis(this, "string", String, "String.prototype.valueOf"); return unwrapThis(this, "string", String, "String.prototype.valueOf");
}); });
target.String = String; target.String = String;
var Boolean = function(value) { const Boolean = function(value) {
if (invokeType(arguments) === "call") { if (invokeType(arguments) === "call") {
if (arguments.length === 0) return false; if (arguments.length === 0) return false;
else return !!value; else return !!value;
} }
this[valueKey] = target.Boolean(value); this[valueKey] = Boolean(value);
}; };
defineField(Boolean, "prototype", false, false, false, {}); defineField(Boolean, "prototype", false, false, false, {});
defineField(Boolean.prototype, "toString", true, false, true, function() { defineField(Boolean.prototype, "toString", true, false, true, function() {
return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString"); return "" + unwrapThis(this, "boolean", Boolean, "Boolean.prototype.toString");
}); });
defineField(Boolean.prototype, "valueOf", true, false, true, function() { defineField(Boolean.prototype, "valueOf", true, false, true, function() {
return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf"); return unwrapThis(this, "boolean", Boolean, "Boolean.prototype.valueOf");
}); });
target.Boolean = Boolean; target.Boolean = Boolean;
var Object = function(value) { const Object = function(value) {
if (typeof value === 'object' && value !== null) return value; if (typeof value === 'object' && value !== null) return value;
if (typeof value === 'string') return new String(value); if (typeof value === 'string') return new String(value);
if (typeof value === 'number') return new Number(value); if (typeof value === 'number') return new Number(value);
if (typeof value === 'boolean') return new Boolean(value); if (typeof value === 'boolean') return new Boolean(value);
if (typeof value === 'symbol') { if (typeof value === 'symbol') {
var res = {}; const res = {};
setPrototype(res, Symbol.prototype); setPrototype(res, Symbol.prototype);
res[valueKey] = value; res[valueKey] = value;
return res; return res;
} }
var target = this; const target = this;
if (target === undefined || target === null || typeof target !== 'object') target = {}; if (target == null || typeof target !== 'object') target = {};
this[valueKey] = target.Object(value); this[valueKey] = Object(value);
}; };
defineField(Object, "prototype", false, false, false, setPrototype({}, null)); defineField(Object, "prototype", false, false, false, setPrototype({}, null));
defineField(Object.prototype, "toString", true, false, true, function() { defineField(Object.prototype, "toString", true, false, true, function() {
if (this !== null && this !== undefined && (Symbol.toStringTag in this)) return "[object " + this[Symbol.toStringTag] + "]"; 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 === "number" || this instanceof Number) return "[object Number]";
else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]"; else if (typeof this === "symbol" || this instanceof Symbol) return "[object Symbol]";
@ -240,82 +239,75 @@
else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]"; else if (typeof this === "boolean" || this instanceof Boolean) return "[object Boolean]";
else if (typeof this === "function") return "[object Function]"; else if (typeof this === "function") return "[object Function]";
else return "[object Object]"; else return "[object Object]";
}); });
defineField(Object.prototype, "valueOf", true, false, true, function() { defineField(Object.prototype, "valueOf", true, false, true, function() {
return this; return this;
}); });
target.Boolean = Boolean; target.Boolean = Boolean;
var Function = function() { const Function = function() {
if (invokeType(arguments) === "new") return Function(value); const parts = ["return function annonymous("];
var res = ["return function ("]; for (let i = 0; i < arguments.length - 1; i++) {
if (i > 0) parts[parts.length] = ",";
for (var i = 0; i < arguments.length - 1; i++) { parts[parts.length] = arguments[i];
if (i > 0) res[res.length] = ",";
res[res.length] = arguments[i];
} }
res[res.length] = "){"; parts[parts.length] = "){\n";
res[res.length] = String(arguments[arguments.length - 1]); parts[parts.length] = String(arguments[arguments.length - 1]);
res[res.length] = "}"; parts[parts.length] = "\n}";
log(res); print(parts);
return compile(stringBuild(res))(); const res = compile(stringBuild(parts))();
}; return res;
};
defineField(Function, "compile", true, false, true, function(src, options) {
if (options == null) options = {};
if (src == null) src = "";
defineField(Function, "compile", true, false, true, (src = "", options = {}) => {
if (options.globals == null) options.globals = []; if (options.globals == null) options.globals = [];
if (options.wrap == null) options.wrap = true; if (options.wrap == null) options.wrap = true;
var res = []; const parts = [];
if (options.wrap) res[res.length] = "return (function() {\n"; if (options.wrap) parts[parts.length] = "return (function() {\n";
if (options.globals.length > 0) { if (options.globals.length > 0) {
res[res.length] = "var "; parts[parts.length] = "var ";
for (var i = 0; i < options.globals.length; i++) { for (let i = 0; i < options.globals.length; i++) {
if (i > 0) res[res.length] = ","; if (i > 0) parts[parts.length] = ",";
res[res.length] = options.globals[i]; parts[parts.length] = options.globals[i];
} }
res[res.length] = ";(function(g){"; parts[parts.length] = ";((g=arguments[0])=>{";
for (var i = 0; i < options.globals.length; i++) { for (let i = 0; i < options.globals.length; i++) {
var name = options.globals[i]; const name = options.globals[i];
res[res.length] = name; parts[parts.length] = name + "=g[" + json.stringify(name) + "];";
res[res.length] = "=g[";
res[res.length] = json.stringify(name);
res[res.length] = "];";
} }
res[res.length] = "})(arguments[0] || {});\n"; parts[parts.length] = "})()\n";
} }
res[res.length] = src; parts[parts.length] = src;
if (options.wrap) res[res.length] = "\n})(arguments[0])"; if (options.wrap) parts[parts.length] = "\n})(arguments[0])";
return compile(stringBuild(res)); const res = compile(stringBuild(parts));
}); return res;
defineField(Function, "prototype", false, false, false, setPrototype({}, null)); });
defineField(Function, "prototype", false, false, false, setPrototype({}, null));
defineField(Function.prototype, "toString", true, false, true, function() { defineField(Function.prototype, "toString", true, false, true, function() {
if (this.name !== "") return "function " + this.name + "(...) { ... }"; if (this.name !== "") return "function " + this.name + "(...) { ... }";
else return "function (...) { ... }"; else return "function (...) { ... }";
}); });
defineField(Function.prototype, "valueOf", true, false, true, function() { defineField(Function.prototype, "valueOf", true, false, true, function() {
return this; return this;
}); });
target.Function = Function; target.Function = Function;
setGlobalPrototype("string", String.prototype); setGlobalPrototype("string", String.prototype);
setGlobalPrototype("number", Number.prototype); setGlobalPrototype("number", Number.prototype);
setGlobalPrototype("boolean", Boolean.prototype); setGlobalPrototype("boolean", Boolean.prototype);
setGlobalPrototype("symbol", Symbol.prototype); setGlobalPrototype("symbol", Symbol.prototype);
setGlobalPrototype("object", Object.prototype); setGlobalPrototype("object", Object.prototype);
})(arguments[0], arguments[1]);