fix: reprogram standard library for env api

This commit is contained in:
2023-08-27 21:21:25 +03:00
parent 54c6af52cf
commit a1e07a8046
44 changed files with 2207 additions and 2333 deletions

View File

@@ -1,191 +1,68 @@
type PropertyDescriptor<T, ThisT> = {
value: any;
writable?: boolean;
enumerable?: boolean;
configurable?: boolean;
} | {
get?(this: ThisT): T;
set(this: ThisT, val: T): void;
enumerable?: boolean;
configurable?: boolean;
} | {
get(this: ThisT): T;
set?(this: ThisT, val: T): void;
enumerable?: boolean;
configurable?: boolean;
};
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
type Record<KeyT extends string | number | symbol, ValT> = { [x in KeyT]: ValT }
var env: Environment;
interface IArguments {
[i: number]: any;
length: number;
}
interface MathObject {
readonly E: number;
readonly PI: number;
readonly SQRT2: number;
readonly SQRT1_2: number;
readonly LN2: number;
readonly LN10: number;
readonly LOG2E: number;
readonly LOG10E: number;
asin(x: number): number;
acos(x: number): number;
atan(x: number): number;
atan2(y: number, x: number): number;
asinh(x: number): number;
acosh(x: number): number;
atanh(x: number): number;
sin(x: number): number;
cos(x: number): number;
tan(x: number): number;
sinh(x: number): number;
cosh(x: number): number;
tanh(x: number): number;
sqrt(x: number): number;
cbrt(x: number): number;
hypot(...vals: number[]): number;
imul(a: number, b: number): number;
exp(x: number): number;
expm1(x: number): number;
pow(x: number, y: number): number;
log(x: number): number;
log10(x: number): number;
log1p(x: number): number;
log2(x: number): number;
ceil(x: number): number;
floor(x: number): number;
round(x: number): number;
fround(x: number): number;
trunc(x: number): number;
abs(x: number): number;
max(...vals: number[]): number;
min(...vals: number[]): number;
sign(x: number): number;
random(): number;
clz32(x: number): number;
}
//@ts-ignore
declare const arguments: IArguments;
declare const Math: MathObject;
declare var setTimeout: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number;
declare var setInterval: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number;
declare var clearTimeout: (id: number) => void;
declare var clearInterval: (id: number) => void;
/** @internal */
declare var internals: any;
/** @internal */
declare function run(file: string, pollute?: boolean): void;
/** @internal */
type ReplaceThis<T, ThisT> = T extends ((...args: infer ArgsT) => infer RetT) ?
((this: ThisT, ...args: ArgsT) => RetT) :
T;
/** @internal */
declare var setProps: <
TargetT extends object,
DescT extends { [x in Exclude<keyof TargetT, 'constructor'> ]?: ReplaceThis<TargetT[x], TargetT> }
>(target: TargetT, desc: DescT) => void;
/** @internal */
declare var setConstr: <ConstrT, T extends { constructor: ConstrT }>(target: T, constr: ConstrT) => void;
declare function log(...vals: any[]): void;
/** @internal */
declare var lgt: typeof globalThis, gt: typeof globalThis;
declare function assert(condition: () => unknown, message?: string): boolean;
gt.assert = (cond, msg) => {
try {
if (!cond()) throw 'condition not satisfied';
log('Passed ' + msg);
return true;
}
catch (e) {
log('Failed ' + msg + ' because of: ' + e);
return false;
}
}
try {
lgt.setProps = (target, desc) => {
var props = internals.keys(desc, false);
for (var i = 0; i < props.length; i++) {
var key = props[i];
internals.defineField(
target, key, (desc as any)[key],
true, // writable
false, // enumerable
true // configurable
);
// @ts-ignore
return (_env: Environment) => {
env = _env;
env.global.assert = (cond, msg) => {
try {
if (!cond()) throw 'condition not satisfied';
log('Passed ' + msg);
return true;
}
catch (e) {
log('Failed ' + msg + ' because of: ' + e);
return false;
}
}
lgt.setConstr = (target, constr) => {
internals.defineField(
target, 'constructor', constr,
true, // writable
false, // enumerable
true // configurable
);
try {
run('values/object');
run('values/symbol');
run('values/function');
run('values/errors');
run('values/string');
run('values/number');
run('values/boolean');
run('values/array');
env.internals.special(Object, Function, Error, Array);
env.global.setTimeout = (func, delay, ...args) => {
if (typeof func !== 'function') throw new TypeError("func must be a function.");
delay = (delay ?? 0) - 0;
return env.internals.setTimeout(() => func(...args), delay)
};
env.global.setInterval = (func, delay, ...args) => {
if (typeof func !== 'function') throw new TypeError("func must be a function.");
delay = (delay ?? 0) - 0;
return env.internals.setInterval(() => func(...args), delay)
};
env.global.clearTimeout = (id) => {
id = id | 0;
env.internals.clearTimeout(id);
};
env.global.clearInterval = (id) => {
id = id | 0;
env.internals.clearInterval(id);
};
run('promise');
run('map');
run('set');
run('regex');
run('require');
log('Loaded polyfills!');
}
run('values/object.js');
run('values/symbol.js');
run('values/function.js');
run('values/errors.js');
run('values/string.js');
run('values/number.js');
run('values/boolean.js');
run('values/array.js');
internals.special(Object, Function, Error, Array);
gt.setTimeout = (func, delay, ...args) => {
if (typeof func !== 'function') throw new TypeError("func must be a function.");
delay = (delay ?? 0) - 0;
return internals.setTimeout(() => func(...args), delay)
};
gt.setInterval = (func, delay, ...args) => {
if (typeof func !== 'function') throw new TypeError("func must be a function.");
delay = (delay ?? 0) - 0;
return internals.setInterval(() => func(...args), delay)
};
gt.clearTimeout = (id) => {
id = id | 0;
internals.clearTimeout(id);
};
gt.clearInterval = (id) => {
id = id | 0;
internals.clearInterval(id);
};
run('iterators.js');
run('promise.js');
run('map.js', true);
run('set.js', true);
run('regex.js');
run('require.js');
log('Loaded polyfills!');
}
catch (e: any) {
var err = 'Uncaught error while loading polyfills: ';
if (typeof Error !== 'undefined' && e instanceof Error && e.toString !== {}.toString) err += e;
else if ('message' in e) {
if ('name' in e) err += e.name + ": " + e.message;
else err += 'Error: ' + e.message;
catch (e: any) {
if (!_env.captureErr) throw e;
var err = 'Uncaught error while loading polyfills: ';
if (typeof Error !== 'undefined' && e instanceof Error && e.toString !== {}.toString) err += e;
else if ('message' in e) {
if ('name' in e) err += e.name + ": " + e.message;
else err += 'Error: ' + e.message;
}
else err += e;
log(e);
}
else err += e;
}
};

View File

@@ -1,216 +0,0 @@
interface SymbolConstructor {
readonly iterator: unique symbol;
readonly asyncIterator: unique symbol;
}
type IteratorYieldResult<TReturn> =
{ done?: false; } &
(TReturn extends undefined ? { value?: undefined; } : { value: TReturn; });
type IteratorReturnResult<TReturn> =
{ done: true } &
(TReturn extends undefined ? { value?: undefined; } : { value: TReturn; });
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
interface Iterator<T, TReturn = any, TNext = undefined> {
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
return?(value?: TReturn): IteratorResult<T, TReturn>;
throw?(e?: any): IteratorResult<T, TReturn>;
}
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
interface IterableIterator<T> extends Iterator<T> {
[Symbol.iterator](): IterableIterator<T>;
}
interface Generator<T = unknown, TReturn = any, TNext = unknown> extends Iterator<T, TReturn, TNext> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
return(value: TReturn): IteratorResult<T, TReturn>;
throw(e: any): IteratorResult<T, TReturn>;
[Symbol.iterator](): Generator<T, TReturn, TNext>;
}
interface GeneratorFunction {
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): Generator;
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): Generator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: Generator;
}
interface GeneratorFunctionConstructor {
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
new (...args: string[]): GeneratorFunction;
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
(...args: string[]): GeneratorFunction;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
}
interface AsyncIterator<T, TReturn = any, TNext = undefined> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return?(value?: TReturn | Thenable<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw?(e?: any): Promise<IteratorResult<T, TReturn>>;
}
interface AsyncIterable<T> {
[Symbol.asyncIterator](): AsyncIterator<T>;
}
interface AsyncIterableIterator<T> extends AsyncIterator<T> {
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
}
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> extends AsyncIterator<T, TReturn, TNext> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return(value: TReturn | Thenable<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw(e: any): Promise<IteratorResult<T, TReturn>>;
[Symbol.asyncIterator](): AsyncGenerator<T, TReturn, TNext>;
}
interface AsyncGeneratorFunction {
/**
* Creates a new AsyncGenerator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): AsyncGenerator;
/**
* Creates a new AsyncGenerator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): AsyncGenerator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: AsyncGenerator;
}
interface AsyncGeneratorFunctionConstructor {
/**
* Creates a new AsyncGenerator function.
* @param args A list of arguments the function accepts.
*/
new (...args: string[]): AsyncGeneratorFunction;
/**
* Creates a new AsyncGenerator function.
* @param args A list of arguments the function accepts.
*/
(...args: string[]): AsyncGeneratorFunction;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: AsyncGeneratorFunction;
}
interface Array<T> extends IterableIterator<T> {
entries(): IterableIterator<[number, T]>;
values(): IterableIterator<T>;
keys(): IterableIterator<number>;
}
setProps(Symbol, {
iterator: Symbol("Symbol.iterator") as any,
asyncIterator: Symbol("Symbol.asyncIterator") as any,
});
setProps(Array.prototype, {
[Symbol.iterator]: function() {
return this.values();
},
values() {
var i = 0;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: this[i - 1] };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
keys() {
var i = 0;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: i - 1 };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
entries() {
var i = 0;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: [i - 1, this[i - 1]] };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
});

634
lib/lib.d.ts vendored Normal file
View File

@@ -0,0 +1,634 @@
type PropertyDescriptor<T, ThisT> = {
value: any;
writable?: boolean;
enumerable?: boolean;
configurable?: boolean;
} | {
get?(this: ThisT): T;
set(this: ThisT, val: T): void;
enumerable?: boolean;
configurable?: boolean;
} | {
get(this: ThisT): T;
set?(this: ThisT, val: T): void;
enumerable?: boolean;
configurable?: boolean;
};
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
type Record<KeyT extends string | number | symbol, ValT> = { [x in KeyT]: ValT }
type ReplaceFunc = (match: string, ...args: any[]) => string;
type PromiseFulfillFunc<T> = (val: T) => void;
type PromiseThenFunc<T, NextT> = (val: T) => NextT;
type PromiseRejectFunc = (err: unknown) => void;
type PromiseFunc<T> = (resolve: PromiseFulfillFunc<T>, reject: PromiseRejectFunc) => void;
type PromiseResult<T> ={ type: 'fulfilled'; value: T; } | { type: 'rejected'; reason: any; }
// wippidy-wine, this code is now mine :D
type Awaited<T> =
T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
F extends ((value: infer V, ...args: infer _) => any) ? // if the argument to `then` is callable, extracts the first argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T;
type IteratorYieldResult<TReturn> =
{ done?: false; } &
(TReturn extends undefined ? { value?: undefined; } : { value: TReturn; });
type IteratorReturnResult<TReturn> =
{ done: true } &
(TReturn extends undefined ? { value?: undefined; } : { value: TReturn; });
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
interface Thenable<T> {
then<NextT>(this: Promise<T>, onFulfilled: PromiseThenFunc<T, NextT>, onRejected?: PromiseRejectFunc): Promise<Awaited<NextT>>;
then(this: Promise<T>, onFulfilled: undefined, onRejected?: PromiseRejectFunc): Promise<T>;
}
interface RegExpResultIndices extends Array<[number, number]> {
groups?: { [name: string]: [number, number]; };
}
interface RegExpResult extends Array<string> {
groups?: { [name: string]: string; };
index: number;
input: string;
indices?: RegExpResultIndices;
escape(raw: string, flags: string): RegExp;
}
interface Matcher {
[Symbol.match](target: string): RegExpResult | string[] | null;
[Symbol.matchAll](target: string): IterableIterator<RegExpResult>;
}
interface Splitter {
[Symbol.split](target: string, limit?: number, sensible?: boolean): string[];
}
interface Replacer {
[Symbol.replace](target: string, replacement: string | ReplaceFunc): string;
}
interface Searcher {
[Symbol.search](target: string, reverse?: boolean, start?: number): number;
}
type FlatArray<Arr, Depth extends number> = {
"done": Arr,
"recur": Arr extends Array<infer InnerArr>
? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>
: Arr
}[Depth extends -1 ? "done" : "recur"];
interface IArguments {
[i: number]: any;
length: number;
}
interface Iterator<T, TReturn = any, TNext = undefined> {
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
return?(value?: TReturn): IteratorResult<T, TReturn>;
throw?(e?: any): IteratorResult<T, TReturn>;
}
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
interface IterableIterator<T> extends Iterator<T> {
[Symbol.iterator](): IterableIterator<T>;
}
interface AsyncIterator<T, TReturn = any, TNext = undefined> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return?(value?: TReturn | Thenable<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw?(e?: any): Promise<IteratorResult<T, TReturn>>;
}
interface AsyncIterable<T> {
[Symbol.asyncIterator](): AsyncIterator<T>;
}
interface AsyncIterableIterator<T> extends AsyncIterator<T> {
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
}
interface Generator<T = unknown, TReturn = any, TNext = unknown> extends Iterator<T, TReturn, TNext> {
[Symbol.iterator](): Generator<T, TReturn, TNext>;
return(value?: TReturn): IteratorResult<T, TReturn>;
throw(e?: any): IteratorResult<T, TReturn>;
}
interface GeneratorFunction {
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): Generator;
/**
* Creates a new Generator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): Generator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: Generator;
}
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> extends AsyncIterator<T, TReturn, TNext> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return(value: TReturn | Thenable<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw(e: any): Promise<IteratorResult<T, TReturn>>;
[Symbol.asyncIterator](): AsyncGenerator<T, TReturn, TNext>;
}
interface AsyncGeneratorFunction {
/**
* Creates a new AsyncGenerator object.
* @param args A list of arguments the function accepts.
*/
new (...args: any[]): AsyncGenerator;
/**
* Creates a new AsyncGenerator object.
* @param args A list of arguments the function accepts.
*/
(...args: any[]): AsyncGenerator;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
readonly prototype: AsyncGenerator;
}
interface MathObject {
readonly E: number;
readonly PI: number;
readonly SQRT2: number;
readonly SQRT1_2: number;
readonly LN2: number;
readonly LN10: number;
readonly LOG2E: number;
readonly LOG10E: number;
asin(x: number): number;
acos(x: number): number;
atan(x: number): number;
atan2(y: number, x: number): number;
asinh(x: number): number;
acosh(x: number): number;
atanh(x: number): number;
sin(x: number): number;
cos(x: number): number;
tan(x: number): number;
sinh(x: number): number;
cosh(x: number): number;
tanh(x: number): number;
sqrt(x: number): number;
cbrt(x: number): number;
hypot(...vals: number[]): number;
imul(a: number, b: number): number;
exp(x: number): number;
expm1(x: number): number;
pow(x: number, y: number): number;
log(x: number): number;
log10(x: number): number;
log1p(x: number): number;
log2(x: number): number;
ceil(x: number): number;
floor(x: number): number;
round(x: number): number;
fround(x: number): number;
trunc(x: number): number;
abs(x: number): number;
max(...vals: number[]): number;
min(...vals: number[]): number;
sign(x: number): number;
random(): number;
clz32(x: number): number;
}
interface Array<T> extends IterableIterator<T> {
[i: number]: T;
constructor: ArrayConstructor;
length: number;
toString(): string;
// toLocaleString(): string;
join(separator?: string): string;
fill(val: T, start?: number, end?: number): T[];
pop(): T | undefined;
push(...items: T[]): number;
concat(...items: (T | T[])[]): T[];
concat(...items: (T | T[])[]): T[];
join(separator?: string): string;
reverse(): T[];
shift(): T | undefined;
slice(start?: number, end?: number): T[];
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number | undefined, ...items: T[]): T[];
unshift(...items: T[]): number;
indexOf(searchElement: T, fromIndex?: number): number;
lastIndexOf(searchElement: T, fromIndex?: number): number;
every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
includes(el: any, start?: number): boolean;
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
find(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
findIndex(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): number;
findLast(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
findLastIndex(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): number;
flat<D extends number = 1>(depth?: D): FlatArray<T, D>;
flatMap(func: (val: T, i: number, arr: T[]) => T | T[], thisAarg?: any): FlatArray<T[], 1>;
sort(func?: (a: T, b: T) => number): this;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
entries(): IterableIterator<[number, T]>;
values(): IterableIterator<T>;
keys(): IterableIterator<number>;
}
interface ArrayConstructor {
new <T>(arrayLength?: number): T[];
new <T>(...items: T[]): T[];
<T>(arrayLength?: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): arg is any[];
prototype: Array<any>;
}
interface Boolean {
valueOf(): boolean;
constructor: BooleanConstructor;
}
interface BooleanConstructor {
(val: any): boolean;
new (val: any): Boolean;
prototype: Boolean;
}
interface Error {
constructor: ErrorConstructor;
name: string;
message: string;
stack: string[];
}
interface ErrorConstructor {
(msg?: any): Error;
new (msg?: any): Error;
prototype: Error;
}
interface TypeErrorConstructor extends ErrorConstructor {
(msg?: any): TypeError;
new (msg?: any): TypeError;
prototype: Error;
}
interface TypeError extends Error {
constructor: TypeErrorConstructor;
name: 'TypeError';
}
interface RangeErrorConstructor extends ErrorConstructor {
(msg?: any): RangeError;
new (msg?: any): RangeError;
prototype: Error;
}
interface RangeError extends Error {
constructor: RangeErrorConstructor;
name: 'RangeError';
}
interface SyntaxErrorConstructor extends ErrorConstructor {
(msg?: any): RangeError;
new (msg?: any): RangeError;
prototype: Error;
}
interface SyntaxError extends Error {
constructor: SyntaxErrorConstructor;
name: 'SyntaxError';
}
interface Function {
apply(this: Function, thisArg: any, argArray?: any): any;
call(this: Function, thisArg: any, ...argArray: any[]): any;
bind(this: Function, thisArg: any, ...argArray: any[]): Function;
toString(): string;
prototype: any;
constructor: FunctionConstructor;
readonly length: number;
name: string;
}
interface CallableFunction extends Function {
(...args: any[]): any;
apply<ThisArg, Args extends any[], RetT>(this: (this: ThisArg, ...args: Args) => RetT, thisArg: ThisArg, argArray?: Args): RetT;
call<ThisArg, Args extends any[], RetT>(this: (this: ThisArg, ...args: Args) => RetT, thisArg: ThisArg, ...argArray: Args): RetT;
bind<ThisArg, Args extends any[], Rest extends any[], RetT>(this: (this: ThisArg, ...args: [ ...Args, ...Rest ]) => RetT, thisArg: ThisArg, ...argArray: Args): (this: void, ...args: Rest) => RetT;
}
interface NewableFunction extends Function {
new(...args: any[]): any;
apply<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, argArray?: Args): RetT;
call<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, ...argArray: Args): RetT;
bind<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, ...argArray: Args): new (...args: Args) => RetT;
}
interface FunctionConstructor extends Function {
(...args: string[]): (...args: any[]) => any;
new (...args: string[]): (...args: any[]) => any;
prototype: Function;
async<ArgsT extends any[], RetT>(
func: (await: <T>(val: T) => Awaited<T>) => (...args: ArgsT) => RetT
): (...args: ArgsT) => Promise<RetT>;
asyncGenerator<ArgsT extends any[], RetT>(
func: (await: <T>(val: T) => Awaited<T>, _yield: <T>(val: T) => void) => (...args: ArgsT) => RetT
): (...args: ArgsT) => AsyncGenerator<RetT>;
generator<ArgsT extends any[], T = unknown, RetT = unknown, TNext = unknown>(
func: (_yield: <T>(val: T) => TNext) => (...args: ArgsT) => RetT
): (...args: ArgsT) => Generator<T, RetT, TNext>;
}
interface Number {
toString(): string;
valueOf(): number;
constructor: NumberConstructor;
}
interface NumberConstructor {
(val: any): number;
new (val: any): Number;
prototype: Number;
parseInt(val: unknown): number;
parseFloat(val: unknown): number;
}
interface Object {
constructor: NewableFunction;
[Symbol.typeName]: string;
valueOf(): this;
toString(): string;
hasOwnProperty(key: any): boolean;
}
interface ObjectConstructor extends Function {
(arg: string): String;
(arg: number): Number;
(arg: boolean): Boolean;
(arg?: undefined | null): {};
<T extends object>(arg: T): T;
new (arg: string): String;
new (arg: number): Number;
new (arg: boolean): Boolean;
new (arg?: undefined | null): {};
new <T extends object>(arg: T): T;
prototype: Object;
assign<T extends object>(target: T, ...src: object[]): T;
create<T extends object>(proto: T, props?: { [key: string]: PropertyDescriptor<any, T> }): T;
keys<T extends object>(obj: T, onlyString?: true): (keyof T)[];
keys<T extends object>(obj: T, onlyString: false): any[];
entries<T extends object>(obj: T, onlyString?: true): [keyof T, T[keyof T]][];
entries<T extends object>(obj: T, onlyString: false): [any, any][];
values<T extends object>(obj: T, onlyString?: true): (T[keyof T])[];
values<T extends object>(obj: T, onlyString: false): any[];
fromEntries(entries: Iterable<[any, any]>): object;
defineProperty<T, ThisT extends object>(obj: ThisT, key: any, desc: PropertyDescriptor<T, ThisT>): ThisT;
defineProperties<ThisT extends object>(obj: ThisT, desc: { [key: string]: PropertyDescriptor<any, ThisT> }): ThisT;
getOwnPropertyNames<T extends object>(obj: T): (keyof T)[];
getOwnPropertySymbols<T extends object>(obj: T): (keyof T)[];
hasOwn<T extends object, KeyT>(obj: T, key: KeyT): boolean;
getOwnPropertyDescriptor<T extends object, KeyT extends keyof T>(obj: T, key: KeyT): PropertyDescriptor<T[KeyT], T>;
getOwnPropertyDescriptors<T extends object>(obj: T): { [x in keyof T]: PropertyDescriptor<T[x], T> };
getPrototypeOf(obj: any): object | null;
setPrototypeOf<T>(obj: T, proto: object | null): T;
preventExtensions<T extends object>(obj: T): T;
seal<T extends object>(obj: T): T;
freeze<T extends object>(obj: T): T;
isExtensible(obj: object): boolean;
isSealed(obj: object): boolean;
isFrozen(obj: object): boolean;
}
interface String {
[i: number]: string;
toString(): string;
valueOf(): string;
charAt(pos: number): string;
charCodeAt(pos: number): number;
substring(start?: number, end?: number): string;
slice(start?: number, end?: number): string;
substr(start?: number, length?: number): string;
startsWith(str: string, pos?: number): string;
endsWith(str: string, pos?: number): string;
replace(pattern: string | Replacer, val: string | ReplaceFunc): string;
replaceAll(pattern: string | Replacer, val: string | ReplaceFunc): string;
match(pattern: string | Matcher): RegExpResult | string[] | null;
matchAll(pattern: string | Matcher): IterableIterator<RegExpResult>;
split(pattern: string | Splitter, limit?: number, sensible?: boolean): string;
concat(...others: string[]): string;
indexOf(term: string | Searcher, start?: number): number;
lastIndexOf(term: string | Searcher, start?: number): number;
toLowerCase(): string;
toUpperCase(): string;
trim(): string;
includes(term: string, start?: number): boolean;
length: number;
constructor: StringConstructor;
}
interface StringConstructor {
(val: any): string;
new (val: any): String;
fromCharCode(val: number): string;
prototype: String;
}
interface Symbol {
valueOf(): symbol;
constructor: SymbolConstructor;
}
interface SymbolConstructor {
(val?: any): symbol;
new(...args: any[]): never;
prototype: Symbol;
for(key: string): symbol;
keyFor(sym: symbol): string;
readonly typeName: unique symbol;
readonly match: unique symbol;
readonly matchAll: unique symbol;
readonly split: unique symbol;
readonly replace: unique symbol;
readonly search: unique symbol;
readonly iterator: unique symbol;
readonly asyncIterator: unique symbol;
}
interface Promise<T> extends Thenable<T> {
constructor: PromiseConstructor;
catch(func: PromiseRejectFunc): Promise<T>;
finally(func: () => void): Promise<T>;
}
interface PromiseConstructor {
prototype: Promise<any>;
new <T>(func: PromiseFunc<T>): Promise<Awaited<T>>;
resolve<T>(val: T): Promise<Awaited<T>>;
reject(val: any): Promise<never>;
any<T>(promises: (Promise<T>|T)[]): Promise<T>;
race<T>(promises: (Promise<T>|T)[]): Promise<T>;
all<T extends any[]>(promises: T): Promise<{ [Key in keyof T]: Awaited<T[Key]> }>;
allSettled<T extends any[]>(...promises: T): Promise<[...{ [P in keyof T]: PromiseResult<Awaited<T[P]>>}]>;
}
declare var String: StringConstructor;
//@ts-ignore
declare const arguments: IArguments;
declare var NaN: number;
declare var Infinity: number;
declare var setTimeout: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number;
declare var setInterval: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number;
declare var clearTimeout: (id: number) => void;
declare var clearInterval: (id: number) => void;
declare var parseInt: typeof Number.parseInt;
declare var parseFloat: typeof Number.parseFloat;
declare function log(...vals: any[]): void;
declare function assert(condition: () => unknown, message?: string): boolean;
declare var Array: ArrayConstructor;
declare var Boolean: BooleanConstructor;
declare var Promise: PromiseConstructor;
declare var Function: FunctionConstructor;
declare var Number: NumberConstructor;
declare var Object: ObjectConstructor;
declare var Symbol: SymbolConstructor;
declare var Promise: PromiseConstructor;
declare var Math: MathObject;
declare var Error: ErrorConstructor;
declare var RangeError: RangeErrorConstructor;
declare var TypeError: TypeErrorConstructor;
declare var SyntaxError: SyntaxErrorConstructor;
declare class Map<KeyT, ValueT> {
public [Symbol.iterator](): IterableIterator<[KeyT, ValueT]>;
public clear(): void;
public delete(key: KeyT): boolean;
public entries(): IterableIterator<[KeyT, ValueT]>;
public keys(): IterableIterator<KeyT>;
public values(): IterableIterator<ValueT>;
public get(key: KeyT): ValueT;
public set(key: KeyT, val: ValueT): this;
public has(key: KeyT): boolean;
public get size(): number;
public forEach(func: (key: KeyT, val: ValueT, map: Map<KeyT, ValueT>) => void, thisArg?: any): void;
public constructor();
}
declare class Set<T> {
public [Symbol.iterator](): IterableIterator<T>;
public entries(): IterableIterator<[T, T]>;
public keys(): IterableIterator<T>;
public values(): IterableIterator<T>;
public clear(): void;
public add(val: T): this;
public delete(val: T): boolean;
public has(key: T): boolean;
public get size(): number;
public forEach(func: (key: T, set: Set<T>) => void, thisArg?: any): void;
public constructor();
}
declare class RegExp implements Matcher, Splitter, Replacer, Searcher {
static escape(raw: any, flags?: string): RegExp;
prototype: RegExp;
exec(val: string): RegExpResult | null;
test(val: string): boolean;
toString(): string;
[Symbol.match](target: string): RegExpResult | string[] | null;
[Symbol.matchAll](target: string): IterableIterator<RegExpResult>;
[Symbol.split](target: string, limit?: number, sensible?: boolean): string[];
[Symbol.replace](target: string, replacement: string | ReplaceFunc): string;
[Symbol.search](target: string, reverse?: boolean, start?: number): number;
readonly dotAll: boolean;
readonly global: boolean;
readonly hasIndices: boolean;
readonly ignoreCase: boolean;
readonly multiline: boolean;
readonly sticky: boolean;
readonly unicode: boolean;
readonly source: string;
readonly flags: string;
lastIndex: number;
constructor(pattern?: string, flags?: string);
constructor(pattern?: RegExp, flags?: string);
}

View File

@@ -1,44 +1,29 @@
declare class Map<KeyT, ValueT> {
public [Symbol.iterator](): IterableIterator<[KeyT, ValueT]>;
define("map", () => {
var Map = env.global.Map = env.internals.Map;
public clear(): void;
public delete(key: KeyT): boolean;
Map.prototype[Symbol.iterator] = function() {
return this.entries();
};
public entries(): IterableIterator<[KeyT, ValueT]>;
public keys(): IterableIterator<KeyT>;
public values(): IterableIterator<ValueT>;
var entries = Map.prototype.entries;
var keys = Map.prototype.keys;
var values = Map.prototype.values;
public get(key: KeyT): ValueT;
public set(key: KeyT, val: ValueT): this;
public has(key: KeyT): boolean;
Map.prototype.entries = function() {
var it = entries.call(this);
it[Symbol.iterator] = () => it;
return it;
};
Map.prototype.keys = function() {
var it = keys.call(this);
it[Symbol.iterator] = () => it;
return it;
};
Map.prototype.values = function() {
var it = values.call(this);
it[Symbol.iterator] = () => it;
return it;
};
public get size(): number;
public forEach(func: (key: KeyT, val: ValueT, map: Map<KeyT, ValueT>) => void, thisArg?: any): void;
public constructor();
}
Map.prototype[Symbol.iterator] = function() {
return this.entries();
};
var entries = Map.prototype.entries;
var keys = Map.prototype.keys;
var values = Map.prototype.values;
Map.prototype.entries = function() {
var it = entries.call(this);
it[Symbol.iterator] = () => it;
return it;
};
Map.prototype.keys = function() {
var it = keys.call(this);
it[Symbol.iterator] = () => it;
return it;
};
Map.prototype.values = function() {
var it = values.call(this);
it[Symbol.iterator] = () => it;
return it;
};
env.global.Map = Map;
});

12
lib/modules.ts Normal file
View File

@@ -0,0 +1,12 @@
var { define, run } = (() => {
const modules: Record<string, Function> = {};
function define(name: string, func: Function) {
modules[name] = func;
}
function run(name: string) {
return modules[name]();
}
return { define, run };
})();

View File

@@ -1,43 +1,3 @@
type PromiseFulfillFunc<T> = (val: T) => void;
type PromiseThenFunc<T, NextT> = (val: T) => NextT;
type PromiseRejectFunc = (err: unknown) => void;
type PromiseFunc<T> = (resolve: PromiseFulfillFunc<T>, reject: PromiseRejectFunc) => void;
type PromiseResult<T> ={ type: 'fulfilled'; value: T; } | { type: 'rejected'; reason: any; }
interface Thenable<T> {
then<NextT>(this: Promise<T>, onFulfilled: PromiseThenFunc<T, NextT>, onRejected?: PromiseRejectFunc): Promise<Awaited<NextT>>;
then(this: Promise<T>, onFulfilled: undefined, onRejected?: PromiseRejectFunc): Promise<T>;
}
// wippidy-wine, this code is now mine :D
type Awaited<T> =
T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
F extends ((value: infer V, ...args: infer _) => any) ? // if the argument to `then` is callable, extracts the first argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T;
interface PromiseConstructor {
prototype: Promise<any>;
new <T>(func: PromiseFunc<T>): Promise<Awaited<T>>;
resolve<T>(val: T): Promise<Awaited<T>>;
reject(val: any): Promise<never>;
any<T>(promises: (Promise<T>|T)[]): Promise<T>;
race<T>(promises: (Promise<T>|T)[]): Promise<T>;
all<T extends any[]>(promises: T): Promise<{ [Key in keyof T]: Awaited<T[Key]> }>;
allSettled<T extends any[]>(...promises: T): Promise<[...{ [P in keyof T]: PromiseResult<Awaited<T[P]>>}]>;
}
interface Promise<T> extends Thenable<T> {
constructor: PromiseConstructor;
catch(func: PromiseRejectFunc): Promise<T>;
finally(func: () => void): Promise<T>;
}
declare var Promise: PromiseConstructor;
(Promise.prototype as any)[Symbol.typeName] = 'Promise';
define("promise", () => {
(env.global.Promise = env.internals.Promise).prototype[Symbol.typeName] = 'Promise';
});

View File

@@ -1,211 +1,143 @@
interface RegExpResultIndices extends Array<[number, number]> {
groups?: { [name: string]: [number, number]; };
}
interface RegExpResult extends Array<string> {
groups?: { [name: string]: string; };
index: number;
input: string;
indices?: RegExpResultIndices;
escape(raw: string, flags: string): RegExp;
}
interface SymbolConstructor {
readonly match: unique symbol;
readonly matchAll: unique symbol;
readonly split: unique symbol;
readonly replace: unique symbol;
readonly search: unique symbol;
}
define("regex", () => {
var RegExp = env.global.RegExp = env.internals.RegExp;
type ReplaceFunc = (match: string, ...args: any[]) => string;
interface Matcher {
[Symbol.match](target: string): RegExpResult | string[] | null;
[Symbol.matchAll](target: string): IterableIterator<RegExpResult>;
}
interface Splitter {
[Symbol.split](target: string, limit?: number, sensible?: boolean): string[];
}
interface Replacer {
[Symbol.replace](target: string, replacement: string): string;
}
interface Searcher {
[Symbol.search](target: string, reverse?: boolean, start?: number): number;
}
declare class RegExp implements Matcher, Splitter, Replacer, Searcher {
static escape(raw: any, flags?: string): RegExp;
prototype: RegExp;
exec(val: string): RegExpResult | null;
test(val: string): boolean;
toString(): string;
[Symbol.match](target: string): RegExpResult | string[] | null;
[Symbol.matchAll](target: string): IterableIterator<RegExpResult>;
[Symbol.split](target: string, limit?: number, sensible?: boolean): string[];
[Symbol.replace](target: string, replacement: string | ReplaceFunc): string;
[Symbol.search](target: string, reverse?: boolean, start?: number): number;
readonly dotAll: boolean;
readonly global: boolean;
readonly hasIndices: boolean;
readonly ignoreCase: boolean;
readonly multiline: boolean;
readonly sticky: boolean;
readonly unicode: boolean;
readonly source: string;
readonly flags: string;
lastIndex: number;
constructor(pattern?: string, flags?: string);
constructor(pattern?: RegExp, flags?: string);
}
(Symbol as any).replace = Symbol('Symbol.replace');
(Symbol as any).match = Symbol('Symbol.match');
(Symbol as any).matchAll = Symbol('Symbol.matchAll');
(Symbol as any).split = Symbol('Symbol.split');
(Symbol as any).search = Symbol('Symbol.search');
setProps(RegExp.prototype, {
[Symbol.typeName]: 'RegExp',
test(val) {
return !!this.exec(val);
},
toString() {
return '/' + this.source + '/' + this.flags;
},
[Symbol.match](target) {
if (this.global) {
setProps(RegExp.prototype as RegExp, env, {
[Symbol.typeName]: 'RegExp',
test(val) {
return !!this.exec(val);
},
toString() {
return '/' + this.source + '/' + this.flags;
},
[Symbol.match](target) {
if (this.global) {
const res: string[] = [];
let val;
while (val = this.exec(target)) {
res.push(val[0]);
}
this.lastIndex = 0;
return res;
}
else {
const res = this.exec(target);
if (!this.sticky) this.lastIndex = 0;
return res;
}
},
[Symbol.matchAll](target) {
let pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
return {
next: (): IteratorResult<RegExpResult, undefined> => {
const val = pattern?.exec(target);
if (val === null || val === undefined) {
pattern = undefined;
return { done: true };
}
else return { value: val };
},
[Symbol.iterator]() { return this; }
}
},
[Symbol.split](target, limit, sensible) {
const pattern = new this.constructor(this, this.flags + "g") as RegExp;
let match: RegExpResult | null;
let lastEnd = 0;
const res: string[] = [];
let val;
while (val = this.exec(target)) {
res.push(val[0]);
while ((match = pattern.exec(target)) !== null) {
let added: string[] = [];
if (match.index >= target.length) break;
if (match[0].length === 0) {
added = [ target.substring(lastEnd, pattern.lastIndex), ];
if (pattern.lastIndex < target.length) added.push(...match.slice(1));
}
else if (match.index - lastEnd > 0) {
added = [ target.substring(lastEnd, match.index), ...match.slice(1) ];
}
else {
for (let i = 1; i < match.length; i++) {
res[res.length - match.length + i] = match[i];
}
}
if (sensible) {
if (limit !== undefined && res.length + added.length >= limit) break;
else res.push(...added);
}
else {
for (let i = 0; i < added.length; i++) {
if (limit !== undefined && res.length >= limit) return res;
else res.push(added[i]);
}
}
lastEnd = pattern.lastIndex;
}
this.lastIndex = 0;
if (lastEnd < target.length) {
res.push(target.substring(lastEnd));
}
return res;
}
else {
const res = this.exec(target);
if (!this.sticky) this.lastIndex = 0;
return res;
}
},
[Symbol.matchAll](target) {
let pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
return {
next: (): IteratorResult<RegExpResult, undefined> => {
const val = pattern?.exec(target);
if (val === null || val === undefined) {
pattern = undefined;
return { done: true };
},
[Symbol.replace](target, replacement) {
const pattern = new this.constructor(this, this.flags + "d") as RegExp;
let match: RegExpResult | null;
let lastEnd = 0;
const res: string[] = [];
// log(pattern.toString());
while ((match = pattern.exec(target)) !== null) {
const indices = match.indices![0];
res.push(target.substring(lastEnd, indices[0]));
if (replacement instanceof Function) {
res.push(replacement(target.substring(indices[0], indices[1]), ...match.slice(1), indices[0], target));
}
else return { value: val };
},
[Symbol.iterator]() { return this; }
}
},
[Symbol.split](target, limit, sensible) {
const pattern = new this.constructor(this, this.flags + "g") as RegExp;
let match: RegExpResult | null;
let lastEnd = 0;
const res: string[] = [];
while ((match = pattern.exec(target)) !== null) {
let added: string[] = [];
if (match.index >= target.length) break;
if (match[0].length === 0) {
added = [ target.substring(lastEnd, pattern.lastIndex), ];
if (pattern.lastIndex < target.length) added.push(...match.slice(1));
else {
res.push(replacement);
}
lastEnd = indices[1];
if (!pattern.global) break;
}
else if (match.index - lastEnd > 0) {
added = [ target.substring(lastEnd, match.index), ...match.slice(1) ];
if (lastEnd < target.length) {
res.push(target.substring(lastEnd));
}
return res.join('');
},
[Symbol.search](target, reverse, start) {
const pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
if (!reverse) {
pattern.lastIndex = (start as any) | 0;
const res = pattern.exec(target);
if (res) return res.index;
else return -1;
}
else {
for (let i = 1; i < match.length; i++) {
res[res.length - match.length + i] = match[i];
start ??= target.length;
start |= 0;
let res: RegExpResult | null = null;
while (true) {
const tmp = pattern.exec(target);
if (tmp === null || tmp.index > start) break;
res = tmp;
}
if (res && res.index <= start) return res.index;
else return -1;
}
if (sensible) {
if (limit !== undefined && res.length + added.length >= limit) break;
else res.push(...added);
}
else {
for (let i = 0; i < added.length; i++) {
if (limit !== undefined && res.length >= limit) return res;
else res.push(added[i]);
}
}
lastEnd = pattern.lastIndex;
}
if (lastEnd < target.length) {
res.push(target.substring(lastEnd));
}
return res;
},
[Symbol.replace](target, replacement) {
const pattern = new this.constructor(this, this.flags + "d") as RegExp;
let match: RegExpResult | null;
let lastEnd = 0;
const res: string[] = [];
// log(pattern.toString());
while ((match = pattern.exec(target)) !== null) {
const indices = match.indices![0];
res.push(target.substring(lastEnd, indices[0]));
if (replacement instanceof Function) {
res.push(replacement(target.substring(indices[0], indices[1]), ...match.slice(1), indices[0], target));
}
else {
res.push(replacement);
}
lastEnd = indices[1];
if (!pattern.global) break;
}
if (lastEnd < target.length) {
res.push(target.substring(lastEnd));
}
return res.join('');
},
[Symbol.search](target, reverse, start) {
const pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
if (!reverse) {
pattern.lastIndex = (start as any) | 0;
const res = pattern.exec(target);
if (res) return res.index;
else return -1;
}
else {
start ??= target.length;
start |= 0;
let res: RegExpResult | null = null;
while (true) {
const tmp = pattern.exec(target);
if (tmp === null || tmp.index > start) break;
res = tmp;
}
if (res && res.index <= start) return res.index;
else return -1;
}
},
});
},
});
});

View File

@@ -1,15 +0,0 @@
type RequireFunc = (path: string) => any;
interface Module {
exports: any;
name: string;
}
declare var require: RequireFunc;
declare var exports: any;
declare var module: Module;
gt.require = function(path: string) {
if (typeof path !== 'string') path = path + '';
return internals.require(path);
};

View File

@@ -1,28 +1,9 @@
declare class Set<T> {
public [Symbol.iterator](): IterableIterator<T>;
define("set", () => {
var Set = env.global.Set = env.internals.Set;
Set.prototype[Symbol.iterator] = function() {
return this.values();
};
public entries(): IterableIterator<[T, T]>;
public keys(): IterableIterator<T>;
public values(): IterableIterator<T>;
public clear(): void;
public add(val: T): this;
public delete(val: T): boolean;
public has(key: T): boolean;
public get size(): number;
public forEach(func: (key: T, set: Set<T>) => void, thisArg?: any): void;
public constructor();
}
Set.prototype[Symbol.iterator] = function() {
return this.values();
};
(() => {
var entries = Set.prototype.entries;
var keys = Set.prototype.keys;
var values = Set.prototype.values;
@@ -42,4 +23,4 @@ Set.prototype[Symbol.iterator] = function() {
it[Symbol.iterator] = () => it;
return it;
};
})();
});

44
lib/utils.ts Normal file
View File

@@ -0,0 +1,44 @@
interface Environment {
global: typeof globalThis & Record<string, any>;
captureErr: boolean;
internals: any;
}
function setProps<
TargetT extends object,
DescT extends {
[x in Exclude<keyof TargetT, 'constructor'> ]?: TargetT[x] extends ((...args: infer ArgsT) => infer RetT) ?
((this: TargetT, ...args: ArgsT) => RetT) :
TargetT[x]
}
>(target: TargetT, env: Environment, desc: DescT) {
var props = env.internals.keys(desc, false);
for (var i = 0; i < props.length; i++) {
var key = props[i];
env.internals.defineField(
target, key, (desc as any)[key],
true, // writable
false, // enumerable
true // configurable
);
}
}
function setConstr<ConstrT, T extends { constructor: ConstrT }>(target: T, constr: ConstrT, env: Environment) {
env.internals.defineField(
target, 'constructor', constr,
true, // writable
false, // enumerable
true // configurable
);
}
function wrapI(max: number, i: number) {
i |= 0;
if (i < 0) i = max + i;
return i;
}
function clampI(max: number, i: number) {
if (i < 0) i = 0;
if (i > max) i = max;
return i;
}

View File

@@ -1,369 +1,335 @@
// god this is awful
type FlatArray<Arr, Depth extends number> = {
"done": Arr,
"recur": Arr extends Array<infer InnerArr>
? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>
: Arr
}[Depth extends -1 ? "done" : "recur"];
interface Array<T> {
[i: number]: T;
constructor: ArrayConstructor;
length: number;
toString(): string;
// toLocaleString(): string;
join(separator?: string): string;
fill(val: T, start?: number, end?: number): T[];
pop(): T | undefined;
push(...items: T[]): number;
concat(...items: (T | T[])[]): T[];
concat(...items: (T | T[])[]): T[];
join(separator?: string): string;
reverse(): T[];
shift(): T | undefined;
slice(start?: number, end?: number): T[];
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number | undefined, ...items: T[]): T[];
unshift(...items: T[]): number;
indexOf(searchElement: T, fromIndex?: number): number;
lastIndexOf(searchElement: T, fromIndex?: number): number;
every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
includes(el: any, start?: number): boolean;
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
find(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
findIndex(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): number;
findLast(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
findLastIndex(predicate: (value: T, index: number, array: T[]) => boolean, thisArg?: any): number;
flat<D extends number = 1>(depth?: D): FlatArray<T, D>;
flatMap(func: (val: T, i: number, arr: T[]) => T | T[], thisAarg?: any): FlatArray<T[], 1>;
sort(func?: (a: T, b: T) => number): this;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
}
interface ArrayConstructor {
new <T>(arrayLength?: number): T[];
new <T>(...items: T[]): T[];
<T>(arrayLength?: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): arg is any[];
prototype: Array<any>;
}
declare var Array: ArrayConstructor;
gt.Array = function(len?: number) {
var res = [];
if (typeof len === 'number' && arguments.length === 1) {
if (len < 0) throw 'Invalid array length.';
res.length = len;
}
else {
for (var i = 0; i < arguments.length; i++) {
res[i] = arguments[i];
}
}
return res;
} as ArrayConstructor;
Array.prototype = ([] as any).__proto__ as Array<any>;
setConstr(Array.prototype, Array);
function wrapI(max: number, i: number) {
i |= 0;
if (i < 0) i = max + i;
return i;
}
function clampI(max: number, i: number) {
if (i < 0) i = 0;
if (i > max) i = max;
return i;
}
lgt.wrapI = wrapI;
lgt.clampI = clampI;
(Array.prototype as any)[Symbol.typeName] = "Array";
setProps(Array.prototype, {
concat() {
var res = [] as any[];
res.push.apply(res, this);
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (arg instanceof Array) {
res.push.apply(res, arg);
}
else {
res.push(arg);
}
}
return res;
},
every(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument not a function.");
func = func.bind(thisArg);
for (var i = 0; i < this.length; i++) {
if (!func(this[i], i, this)) return false;
}
return true;
},
some(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument not a function.");
func = func.bind(thisArg);
for (var i = 0; i < this.length; i++) {
if (func(this[i], i, this)) return true;
}
return false;
},
fill(val, start, end) {
if (arguments.length < 3) end = this.length;
if (arguments.length < 2) start = 0;
start = clampI(this.length, wrapI(this.length + 1, start ?? 0));
end = clampI(this.length, wrapI(this.length + 1, end ?? this.length));
for (; start < end; start++) {
this[start] = val;
}
return this;
},
filter(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
define("values/array", () => {
var Array = env.global.Array = function(len?: number) {
var res = [];
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) res.push(this[i]);
if (typeof len === 'number' && arguments.length === 1) {
if (len < 0) throw 'Invalid array length.';
res.length = len;
}
else {
for (var i = 0; i < arguments.length; i++) {
res[i] = arguments[i];
}
}
return res;
},
find(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) return this[i];
}
return undefined;
},
findIndex(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) return i;
}
return -1;
},
findLast(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
} as ArrayConstructor;
for (var i = this.length - 1; i >= 0; i--) {
if (i in this && func.call(thisArg, this[i], i, this)) return this[i];
}
Array.prototype = ([] as any).__proto__ as Array<any>;
setConstr(Array.prototype, Array, env);
return undefined;
},
findLastIndex(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
(Array.prototype as any)[Symbol.typeName] = "Array";
for (var i = this.length - 1; i >= 0; i--) {
if (i in this && func.call(thisArg, this[i], i, this)) return i;
}
setProps(Array.prototype, env, {
[Symbol.iterator]: function() {
return this.values();
},
return -1;
},
flat(depth) {
var res = [] as any[];
var buff = [];
res.push(...this);
values() {
var i = 0;
for (var i = 0; i < (depth ?? 1); i++) {
var anyArrays = false;
for (var el of res) {
if (el instanceof Array) {
buff.push(...el);
anyArrays = true;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: this[i - 1] };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
keys() {
var i = 0;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: i - 1 };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
entries() {
var i = 0;
return {
next: () => {
while (i < this.length) {
if (i++ in this) return { done: false, value: [i - 1, this[i - 1]] };
}
return { done: true, value: undefined };
},
[Symbol.iterator]() { return this; }
};
},
concat() {
var res = [] as any[];
res.push.apply(res, this);
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (arg instanceof Array) {
res.push.apply(res, arg);
}
else {
res.push(arg);
}
else buff.push(el);
}
res = buff;
buff = [];
if (!anyArrays) break;
}
return res;
},
every(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument not a function.");
func = func.bind(thisArg);
return res;
},
flatMap(func, th) {
return this.map(func, th).flat();
},
forEach(func, thisArg) {
for (var i = 0; i < this.length; i++) {
if (i in this) func.call(thisArg, this[i], i, this);
}
},
map(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
var res = [];
for (var i = 0; i < this.length; i++) {
if (i in this) res[i] = func.call(thisArg, this[i], i, this);
}
return res;
},
pop() {
if (this.length === 0) return undefined;
var val = this[this.length - 1];
this.length--;
return val;
},
push() {
for (var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return arguments.length;
},
shift() {
if (this.length === 0) return undefined;
var res = this[0];
for (var i = 0; i < this.length - 1; i++) {
this[i] = this[i + 1];
}
this.length--;
return res;
},
unshift() {
for (var i = this.length - 1; i >= 0; i--) {
this[i + arguments.length] = this[i];
}
for (var i = 0; i < arguments.length; i++) {
this[i] = arguments[i];
}
return arguments.length;
},
slice(start, end) {
start = clampI(this.length, wrapI(this.length + 1, start ?? 0));
end = clampI(this.length, wrapI(this.length + 1, end ?? this.length));
var res: any[] = [];
var n = end - start;
if (n <= 0) return res;
for (var i = 0; i < n; i++) {
res[i] = this[start + i];
}
return res;
},
toString() {
let res = '';
for (let i = 0; i < this.length; i++) {
if (i > 0) res += ',';
if (i in this && this[i] !== undefined && this[i] !== null) res += this[i];
}
return res;
},
indexOf(el, start) {
start = start! | 0;
for (var i = Math.max(0, start); i < this.length; i++) {
if (i in this && this[i] == el) return i;
}
return -1;
},
lastIndexOf(el, start) {
start = start! | 0;
for (var i = this.length; i >= start; i--) {
if (i in this && this[i] == el) return i;
}
return -1;
},
includes(el, start) {
return this.indexOf(el, start) >= 0;
},
join(val = ',') {
let res = '', first = true;
for (let i = 0; i < this.length; i++) {
if (!(i in this)) continue;
if (!first) res += val;
first = false;
res += this[i];
}
return res;
},
sort(func) {
func ??= (a, b) => {
const _a = a + '';
const _b = b + '';
if (_a > _b) return 1;
if (_a < _b) return -1;
return 0;
};
if (typeof func !== 'function') throw new TypeError('Expected func to be undefined or a function.');
internals.sort(this, func);
return this;
},
splice(start, deleteCount, ...items) {
start = clampI(this.length, wrapI(this.length, start ?? 0));
deleteCount = (deleteCount ?? Infinity | 0);
if (start + deleteCount >= this.length) deleteCount = this.length - start;
const res = this.slice(start, start + deleteCount);
const moveN = items.length - deleteCount;
const len = this.length;
if (moveN < 0) {
for (let i = start - moveN; i < len; i++) {
this[i + moveN] = this[i];
for (var i = 0; i < this.length; i++) {
if (!func(this[i], i, this)) return false;
}
}
else if (moveN > 0) {
for (let i = len - 1; i >= start; i--) {
this[i + moveN] = this[i];
return true;
},
some(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument not a function.");
func = func.bind(thisArg);
for (var i = 0; i < this.length; i++) {
if (func(this[i], i, this)) return true;
}
return false;
},
fill(val, start, end) {
if (arguments.length < 3) end = this.length;
if (arguments.length < 2) start = 0;
start = clampI(this.length, wrapI(this.length + 1, start ?? 0));
end = clampI(this.length, wrapI(this.length + 1, end ?? this.length));
for (; start < end; start++) {
this[start] = val;
}
return this;
},
filter(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
var res = [];
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) res.push(this[i]);
}
return res;
},
find(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) return this[i];
}
return undefined;
},
findIndex(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = 0; i < this.length; i++) {
if (i in this && func.call(thisArg, this[i], i, this)) return i;
}
return -1;
},
findLast(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = this.length - 1; i >= 0; i--) {
if (i in this && func.call(thisArg, this[i], i, this)) return this[i];
}
return undefined;
},
findLastIndex(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
for (var i = this.length - 1; i >= 0; i--) {
if (i in this && func.call(thisArg, this[i], i, this)) return i;
}
return -1;
},
flat(depth) {
var res = [] as any[];
var buff = [];
res.push(...this);
for (var i = 0; i < (depth ?? 1); i++) {
var anyArrays = false;
for (var el of res) {
if (el instanceof Array) {
buff.push(...el);
anyArrays = true;
}
else buff.push(el);
}
res = buff;
buff = [];
if (!anyArrays) break;
}
return res;
},
flatMap(func, th) {
return this.map(func, th).flat();
},
forEach(func, thisArg) {
for (var i = 0; i < this.length; i++) {
if (i in this) func.call(thisArg, this[i], i, this);
}
},
map(func, thisArg) {
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
var res = [];
for (var i = 0; i < this.length; i++) {
if (i in this) res[i] = func.call(thisArg, this[i], i, this);
}
return res;
},
pop() {
if (this.length === 0) return undefined;
var val = this[this.length - 1];
this.length--;
return val;
},
push() {
for (var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return arguments.length;
},
shift() {
if (this.length === 0) return undefined;
var res = this[0];
for (var i = 0; i < this.length - 1; i++) {
this[i] = this[i + 1];
}
this.length--;
return res;
},
unshift() {
for (var i = this.length - 1; i >= 0; i--) {
this[i + arguments.length] = this[i];
}
for (var i = 0; i < arguments.length; i++) {
this[i] = arguments[i];
}
return arguments.length;
},
slice(start, end) {
start = clampI(this.length, wrapI(this.length + 1, start ?? 0));
end = clampI(this.length, wrapI(this.length + 1, end ?? this.length));
var res: any[] = [];
var n = end - start;
if (n <= 0) return res;
for (var i = 0; i < n; i++) {
res[i] = this[start + i];
}
return res;
},
toString() {
let res = '';
for (let i = 0; i < this.length; i++) {
if (i > 0) res += ',';
if (i in this && this[i] !== undefined && this[i] !== null) res += this[i];
}
return res;
},
indexOf(el, start) {
start = start! | 0;
for (var i = Math.max(0, start); i < this.length; i++) {
if (i in this && this[i] == el) return i;
}
return -1;
},
lastIndexOf(el, start) {
start = start! | 0;
for (var i = this.length; i >= start; i--) {
if (i in this && this[i] == el) return i;
}
return -1;
},
includes(el, start) {
return this.indexOf(el, start) >= 0;
},
join(val = ',') {
let res = '', first = true;
for (let i = 0; i < this.length; i++) {
if (!(i in this)) continue;
if (!first) res += val;
first = false;
res += this[i];
}
return res;
},
sort(func) {
func ??= (a, b) => {
const _a = a + '';
const _b = b + '';
if (_a > _b) return 1;
if (_a < _b) return -1;
return 0;
};
if (typeof func !== 'function') throw new TypeError('Expected func to be undefined or a function.');
env.internals.sort(this, func);
return this;
},
splice(start, deleteCount, ...items) {
start = clampI(this.length, wrapI(this.length, start ?? 0));
deleteCount = (deleteCount ?? Infinity | 0);
if (start + deleteCount >= this.length) deleteCount = this.length - start;
const res = this.slice(start, start + deleteCount);
const moveN = items.length - deleteCount;
const len = this.length;
if (moveN < 0) {
for (let i = start - moveN; i < len; i++) {
this[i + moveN] = this[i];
}
}
else if (moveN > 0) {
for (let i = len - 1; i >= start; i--) {
this[i + moveN] = this[i];
}
}
for (let i = 0; i < items.length; i++) {
this[i + start] = items[i];
}
this.length = len + moveN;
return res;
}
for (let i = 0; i < items.length; i++) {
this[i + start] = items[i];
}
this.length = len + moveN;
return res;
}
});
setProps(Array, {
isArray(val: any) { return internals.isArr(val); }
});
});
setProps(Array, env, {
isArray(val: any) { return env.internals.isArr(val); }
});
});

View File

@@ -1,22 +1,12 @@
interface Boolean {
valueOf(): boolean;
constructor: BooleanConstructor;
}
interface BooleanConstructor {
(val: any): boolean;
new (val: any): Boolean;
prototype: Boolean;
}
declare var Boolean: BooleanConstructor;
gt.Boolean = function (this: Boolean | undefined, arg) {
var val;
if (arguments.length === 0) val = false;
else val = !!arg;
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as BooleanConstructor;
Boolean.prototype = (false as any).__proto__ as Boolean;
setConstr(Boolean.prototype, Boolean);
define("values/boolean", () => {
var Boolean = env.global.Boolean = function (this: Boolean | undefined, arg) {
var val;
if (arguments.length === 0) val = false;
else val = !!arg;
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as BooleanConstructor;
Boolean.prototype = (false as any).__proto__ as Boolean;
setConstr(Boolean.prototype, Boolean, env);
});

View File

@@ -1,89 +1,43 @@
interface Error {
constructor: ErrorConstructor;
name: string;
message: string;
stack: string[];
}
interface ErrorConstructor {
(msg?: any): Error;
new (msg?: any): Error;
prototype: Error;
}
define("values/errors", () => {
var Error = env.global.Error = function Error(msg: string) {
if (msg === undefined) msg = '';
else msg += '';
return Object.setPrototypeOf({
message: msg,
stack: [] as string[],
}, Error.prototype);
} as ErrorConstructor;
Error.prototype = env.internals.err ?? {};
Error.prototype.name = 'Error';
setConstr(Error.prototype, Error, env);
interface TypeErrorConstructor extends ErrorConstructor {
(msg?: any): TypeError;
new (msg?: any): TypeError;
prototype: Error;
}
interface TypeError extends Error {
constructor: TypeErrorConstructor;
name: 'TypeError';
}
Error.prototype.toString = function() {
if (!(this instanceof Error)) return '';
if (this.message === '') return this.name;
else return this.name + ': ' + this.message;
};
interface RangeErrorConstructor extends ErrorConstructor {
(msg?: any): RangeError;
new (msg?: any): RangeError;
prototype: Error;
}
interface RangeError extends Error {
constructor: RangeErrorConstructor;
name: 'RangeError';
}
function makeError<T extends ErrorConstructor>(name: string, proto: any): T {
var err = function (msg: string) {
var res = new Error(msg);
(res as any).__proto__ = err.prototype;
return res;
} as T;
interface SyntaxErrorConstructor extends ErrorConstructor {
(msg?: any): RangeError;
new (msg?: any): RangeError;
prototype: Error;
}
interface SyntaxError extends Error {
constructor: SyntaxErrorConstructor;
name: 'SyntaxError';
}
err.prototype = proto;
err.prototype.name = name;
setConstr(err.prototype, err as ErrorConstructor, env);
(err.prototype as any).__proto__ = Error.prototype;
(err as any).__proto__ = Error;
env.internals.special(err);
return err;
}
declare var Error: ErrorConstructor;
declare var RangeError: RangeErrorConstructor;
declare var TypeError: TypeErrorConstructor;
declare var SyntaxError: SyntaxErrorConstructor;
gt.Error = function Error(msg: string) {
if (msg === undefined) msg = '';
else msg += '';
return Object.setPrototypeOf({
message: msg,
stack: [] as string[],
}, Error.prototype);
} as ErrorConstructor;
Error.prototype = internals.err ?? {};
Error.prototype.name = 'Error';
setConstr(Error.prototype, Error);
Error.prototype.toString = function() {
if (!(this instanceof Error)) return '';
if (this.message === '') return this.name;
else return this.name + ': ' + this.message;
};
function makeError<T extends ErrorConstructor>(name: string, proto: any): T {
var err = function (msg: string) {
var res = new Error(msg);
(res as any).__proto__ = err.prototype;
return res;
} as T;
err.prototype = proto;
err.prototype.name = name;
setConstr(err.prototype, err as ErrorConstructor);
(err.prototype as any).__proto__ = Error.prototype;
(err as any).__proto__ = Error;
internals.special(err);
return err;
}
gt.RangeError = makeError('RangeError', internals.range ?? {});
gt.TypeError = makeError('TypeError', internals.type ?? {});
gt.SyntaxError = makeError('SyntaxError', internals.syntax ?? {});
env.global.RangeError = makeError('RangeError', env.internals.range ?? {});
env.global.TypeError = makeError('TypeError', env.internals.type ?? {});
env.global.SyntaxError = makeError('SyntaxError', env.internals.syntax ?? {});
});

View File

@@ -1,181 +1,140 @@
interface Function {
apply(this: Function, thisArg: any, argArray?: any): any;
call(this: Function, thisArg: any, ...argArray: any[]): any;
bind(this: Function, thisArg: any, ...argArray: any[]): Function;
define("values/function", () => {
var Function = env.global.Function = function() {
throw 'Using the constructor Function() is forbidden.';
} as unknown as FunctionConstructor;
toString(): string;
Function.prototype = (Function as any).__proto__ as Function;
setConstr(Function.prototype, Function, env);
prototype: any;
constructor: FunctionConstructor;
readonly length: number;
name: string;
}
interface FunctionConstructor extends Function {
(...args: string[]): (...args: any[]) => any;
new (...args: string[]): (...args: any[]) => any;
prototype: Function;
async<ArgsT extends any[], RetT>(
func: (await: <T>(val: T) => Awaited<T>) => (...args: ArgsT) => RetT
): (...args: ArgsT) => Promise<RetT>;
asyncGenerator<ArgsT extends any[], RetT>(
func: (await: <T>(val: T) => Awaited<T>, _yield: <T>(val: T) => void) => (...args: ArgsT) => RetT
): (...args: ArgsT) => AsyncGenerator<RetT>;
generator<ArgsT extends any[], T = unknown, RetT = unknown, TNext = unknown>(
func: (_yield: <T>(val: T) => TNext) => (...args: ArgsT) => RetT
): (...args: ArgsT) => Generator<T, RetT, TNext>;
}
setProps(Function.prototype, env, {
apply(thisArg, args) {
if (typeof args !== 'object') throw 'Expected arguments to be an array-like object.';
var len = args.length - 0;
let newArgs: any[];
if (Array.isArray(args)) newArgs = args;
else {
newArgs = [];
interface CallableFunction extends Function {
(...args: any[]): any;
apply<ThisArg, Args extends any[], RetT>(this: (this: ThisArg, ...args: Args) => RetT, thisArg: ThisArg, argArray?: Args): RetT;
call<ThisArg, Args extends any[], RetT>(this: (this: ThisArg, ...args: Args) => RetT, thisArg: ThisArg, ...argArray: Args): RetT;
bind<ThisArg, Args extends any[], Rest extends any[], RetT>(this: (this: ThisArg, ...args: [ ...Args, ...Rest ]) => RetT, thisArg: ThisArg, ...argArray: Args): (this: void, ...args: Rest) => RetT;
}
interface NewableFunction extends Function {
new(...args: any[]): any;
apply<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, argArray?: Args): RetT;
call<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, ...argArray: Args): RetT;
bind<Args extends any[], RetT>(this: new (...args: Args) => RetT, thisArg: any, ...argArray: Args): new (...args: Args) => RetT;
}
declare var Function: FunctionConstructor;
gt.Function = function() {
throw 'Using the constructor Function() is forbidden.';
} as unknown as FunctionConstructor;
Function.prototype = (Function as any).__proto__ as Function;
setConstr(Function.prototype, Function);
setProps(Function.prototype, {
apply(thisArg, args) {
if (typeof args !== 'object') throw 'Expected arguments to be an array-like object.';
var len = args.length - 0;
let newArgs: any[];
if (Array.isArray(args)) newArgs = args;
else {
newArgs = [];
while (len >= 0) {
len--;
newArgs[len] = args[len];
}
}
return internals.apply(this, thisArg, newArgs);
},
call(thisArg, ...args) {
return this.apply(thisArg, args);
},
bind(thisArg, ...args) {
var func = this;
var res = function() {
var resArgs = [];
for (var i = 0; i < args.length; i++) {
resArgs[i] = args[i];
}
for (var i = 0; i < arguments.length; i++) {
resArgs[i + args.length] = arguments[i];
}
return func.apply(thisArg, resArgs);
};
res.name = "<bound> " + func.name;
return res;
},
toString() {
return 'function (...) { ... }';
},
});
setProps(Function, {
async(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
return function (this: any) {
const args = arguments;
return new Promise((res, rej) => {
const gen = Function.generator(func as any).apply(this, args as any);
(function next(type: 'none' | 'err' | 'ret', val?: any) {
try {
let result;
switch (type) {
case 'err': result = gen.throw(val); break;
case 'ret': result = gen.next(val); break;
case 'none': result = gen.next(); break;
}
if (result.done) res(result.value);
else Promise.resolve(result.value).then(
v => next('ret', v),
v => next('err', v)
)
}
catch (e) {
rej(e);
}
})('none');
});
};
},
asyncGenerator(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
return function(this: any) {
const gen = Function.generator<any[], ['await' | 'yield', any]>((_yield) => func(
val => _yield(['await', val]) as any,
val => _yield(['yield', val])
)).apply(this, arguments as any);
const next = (resolve: Function, reject: Function, type: 'none' | 'val' | 'ret' | 'err', val?: any) => {
let res;
try {
switch (type) {
case 'val': res = gen.next(val); break;
case 'ret': res = gen.return(val); break;
case 'err': res = gen.throw(val); break;
default: res = gen.next(); break;
}
while (len >= 0) {
len--;
newArgs[len] = args[len];
}
catch (e) { return reject(e); }
}
if (res.done) return { done: true, res: <any>res };
else if (res.value[0] === 'await') Promise.resolve(res.value[1]).then(
v => next(resolve, reject, 'val', v),
v => next(resolve, reject, 'err', v),
)
else resolve({ done: false, value: res.value[1] });
return env.internals.apply(this, thisArg, newArgs);
},
call(thisArg, ...args) {
return this.apply(thisArg, args);
},
bind(thisArg, ...args) {
var func = this;
var res = function() {
var resArgs = [];
for (var i = 0; i < args.length; i++) {
resArgs[i] = args[i];
}
for (var i = 0; i < arguments.length; i++) {
resArgs[i + args.length] = arguments[i];
}
return func.apply(thisArg, resArgs);
};
res.name = "<bound> " + func.name;
return res;
},
toString() {
return 'function (...) { ... }';
},
});
setProps(Function, env, {
async(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
return {
next() {
const args = arguments;
if (arguments.length === 0) return new Promise((res, rej) => next(res, rej, 'none'));
else return new Promise((res, rej) => next(res, rej, 'val', args[0]));
},
return: (value) => new Promise((res, rej) => next(res, rej, 'ret', value)),
throw: (value) => new Promise((res, rej) => next(res, rej, 'err', value)),
[Symbol.asyncIterator]() { return this; }
return function (this: any) {
const args = arguments;
return new Promise((res, rej) => {
const gen = Function.generator(func as any).apply(this, args as any);
(function next(type: 'none' | 'err' | 'ret', val?: any) {
try {
let result;
switch (type) {
case 'err': result = gen.throw(val); break;
case 'ret': result = gen.next(val); break;
case 'none': result = gen.next(); break;
}
if (result.done) res(result.value);
else Promise.resolve(result.value).then(
v => next('ret', v),
v => next('err', v)
)
}
catch (e) {
rej(e);
}
})('none');
});
};
},
asyncGenerator(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
return function(this: any) {
const gen = Function.generator<any[], ['await' | 'yield', any]>((_yield) => func(
val => _yield(['await', val]) as any,
val => _yield(['yield', val])
)).apply(this, arguments as any);
const next = (resolve: Function, reject: Function, type: 'none' | 'val' | 'ret' | 'err', val?: any) => {
let res;
try {
switch (type) {
case 'val': res = gen.next(val); break;
case 'ret': res = gen.return(val); break;
case 'err': res = gen.throw(val); break;
default: res = gen.next(); break;
}
}
catch (e) { return reject(e); }
if (res.done) return { done: true, res: <any>res };
else if (res.value[0] === 'await') Promise.resolve(res.value[1]).then(
v => next(resolve, reject, 'val', v),
v => next(resolve, reject, 'err', v),
)
else resolve({ done: false, value: res.value[1] });
};
return {
next() {
const args = arguments;
if (arguments.length === 0) return new Promise((res, rej) => next(res, rej, 'none'));
else return new Promise((res, rej) => next(res, rej, 'val', args[0]));
},
return: (value) => new Promise((res, rej) => next(res, rej, 'ret', value)),
throw: (value) => new Promise((res, rej) => next(res, rej, 'err', value)),
[Symbol.asyncIterator]() { return this; }
}
}
},
generator(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
const gen = env.internals.makeGenerator(func);
return (...args: any[]) => {
const it = gen(args);
return {
next: it.next,
return: it.return,
throw: it.throw,
[Symbol.iterator]() { return this; }
}
}
}
},
generator(func) {
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
const gen = internals.makeGenerator(func);
return (...args: any[]) => {
const it = gen(args);
return {
next: it.next,
return: it.return,
throw: it.throw,
[Symbol.iterator]() { return this; }
}
}
}
})
})
});

View File

@@ -1,50 +1,33 @@
interface Number {
toString(): string;
valueOf(): number;
constructor: NumberConstructor;
}
interface NumberConstructor {
(val: any): number;
new (val: any): Number;
prototype: Number;
parseInt(val: unknown): number;
parseFloat(val: unknown): number;
}
define("values/number", () => {
var Number = env.global.Number = function(this: Number | undefined, arg: any) {
var val;
if (arguments.length === 0) val = 0;
else val = arg - 0;
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as NumberConstructor;
declare var Number: NumberConstructor;
declare var parseInt: typeof Number.parseInt;
declare var parseFloat: typeof Number.parseFloat;
declare var NaN: number;
declare var Infinity: number;
Number.prototype = (0 as any).__proto__ as Number;
setConstr(Number.prototype, Number, env);
gt.Number = function(this: Number | undefined, arg: any) {
var val;
if (arguments.length === 0) val = 0;
else val = arg - 0;
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as NumberConstructor;
setProps(Number.prototype, env, {
valueOf() {
if (typeof this === 'number') return this;
else return (this as any).value;
},
toString() {
if (typeof this === 'number') return this + '';
else return (this as any).value + '';
}
});
Number.prototype = (0 as any).__proto__ as Number;
setConstr(Number.prototype, Number);
setProps(Number, env, {
parseInt(val) { return Math.trunc(Number.parseFloat(val)); },
parseFloat(val) { return env.internals.parseFloat(val); },
});
setProps(Number.prototype, {
valueOf() {
if (typeof this === 'number') return this;
else return (this as any).value;
},
toString() {
if (typeof this === 'number') return this + '';
else return (this as any).value + '';
}
});
setProps(Number, {
parseInt(val) { return Math.trunc(Number.parseFloat(val)); },
parseFloat(val) { return internals.parseFloat(val); },
});
Object.defineProperty(gt, 'parseInt', { value: Number.parseInt, writable: false });
Object.defineProperty(gt, 'parseFloat', { value: Number.parseFloat, writable: false });
Object.defineProperty(gt, 'NaN', { value: 0 / 0, writable: false });
Object.defineProperty(gt, 'Infinity', { value: 1 / 0, writable: false });
env.global.Object.defineProperty(env.global, 'parseInt', { value: Number.parseInt, writable: false });
env.global.Object.defineProperty(env.global, 'parseFloat', { value: Number.parseFloat, writable: false });
env.global.Object.defineProperty(env.global, 'NaN', { value: 0 / 0, writable: false });
env.global.Object.defineProperty(env.global, 'Infinity', { value: 1 / 0, writable: false });
});

View File

@@ -1,234 +1,178 @@
interface Object {
constructor: NewableFunction;
[Symbol.typeName]: string;
/** @internal */
define("values/object", () => {
var Object = env.global.Object = function(arg: any) {
if (arg === undefined || arg === null) return {};
else if (typeof arg === 'boolean') return new Boolean(arg);
else if (typeof arg === 'number') return new Number(arg);
else if (typeof arg === 'string') return new String(arg);
return arg;
} as ObjectConstructor;
valueOf(): this;
toString(): string;
hasOwnProperty(key: any): boolean;
}
interface ObjectConstructor extends Function {
(arg: string): String;
(arg: number): Number;
(arg: boolean): Boolean;
(arg?: undefined | null): {};
<T extends object>(arg: T): T;
Object.prototype = ({} as any).__proto__ as Object;
setConstr(Object.prototype, Object as any, env);
new (arg: string): String;
new (arg: number): Number;
new (arg: boolean): Boolean;
new (arg?: undefined | null): {};
new <T extends object>(arg: T): T;
prototype: Object;
assign<T extends object>(target: T, ...src: object[]): T;
create<T extends object>(proto: T, props?: { [key: string]: PropertyDescriptor<any, T> }): T;
keys<T extends object>(obj: T, onlyString?: true): (keyof T)[];
keys<T extends object>(obj: T, onlyString: false): any[];
entries<T extends object>(obj: T, onlyString?: true): [keyof T, T[keyof T]][];
entries<T extends object>(obj: T, onlyString: false): [any, any][];
values<T extends object>(obj: T, onlyString?: true): (T[keyof T])[];
values<T extends object>(obj: T, onlyString: false): any[];
fromEntries(entries: Iterable<[any, any]>): object;
defineProperty<T, ThisT extends object>(obj: ThisT, key: any, desc: PropertyDescriptor<T, ThisT>): ThisT;
defineProperties<ThisT extends object>(obj: ThisT, desc: { [key: string]: PropertyDescriptor<any, ThisT> }): ThisT;
getOwnPropertyNames<T extends object>(obj: T): (keyof T)[];
getOwnPropertySymbols<T extends object>(obj: T): (keyof T)[];
hasOwn<T extends object, KeyT>(obj: T, key: KeyT): boolean;
getOwnPropertyDescriptor<T extends object, KeyT extends keyof T>(obj: T, key: KeyT): PropertyDescriptor<T[KeyT], T>;
getOwnPropertyDescriptors<T extends object>(obj: T): { [x in keyof T]: PropertyDescriptor<T[x], T> };
getPrototypeOf(obj: any): object | null;
setPrototypeOf<T>(obj: T, proto: object | null): T;
preventExtensions<T extends object>(obj: T): T;
seal<T extends object>(obj: T): T;
freeze<T extends object>(obj: T): T;
isExtensible(obj: object): boolean;
isSealed(obj: object): boolean;
isFrozen(obj: object): boolean;
}
declare var Object: ObjectConstructor;
gt.Object = function(arg: any) {
if (arg === undefined || arg === null) return {};
else if (typeof arg === 'boolean') return new Boolean(arg);
else if (typeof arg === 'number') return new Number(arg);
else if (typeof arg === 'string') return new String(arg);
return arg;
} as ObjectConstructor;
Object.prototype = ({} as any).__proto__ as Object;
setConstr(Object.prototype, Object as any);
function throwNotObject(obj: any, name: string) {
if (obj === null || typeof obj !== 'object' && typeof obj !== 'function') {
throw new TypeError(`Object.${name} may only be used for objects.`);
function throwNotObject(obj: any, name: string) {
if (obj === null || typeof obj !== 'object' && typeof obj !== 'function') {
throw new TypeError(`Object.${name} may only be used for objects.`);
}
}
function check(obj: any) {
return typeof obj === 'object' && obj !== null || typeof obj === 'function';
}
}
function check(obj: any) {
return typeof obj === 'object' && obj !== null || typeof obj === 'function';
}
setProps(Object, {
assign: function(dst, ...src) {
throwNotObject(dst, 'assign');
for (let i = 0; i < src.length; i++) {
const obj = src[i];
throwNotObject(obj, 'assign');
for (const key of Object.keys(obj)) {
(dst as any)[key] = (obj as any)[key];
setProps(Object, env, {
assign: function(dst, ...src) {
throwNotObject(dst, 'assign');
for (let i = 0; i < src.length; i++) {
const obj = src[i];
throwNotObject(obj, 'assign');
for (const key of Object.keys(obj)) {
(dst as any)[key] = (obj as any)[key];
}
}
return dst;
},
create(obj, props) {
props ??= {};
return Object.defineProperties({ __proto__: obj }, props as any) as any;
},
defineProperty(obj, key, attrib) {
throwNotObject(obj, 'defineProperty');
if (typeof attrib !== 'object') throw new TypeError('Expected attributes to be an object.');
if ('value' in attrib) {
if ('get' in attrib || 'set' in attrib) throw new TypeError('Cannot specify a value and accessors for a property.');
if (!env.internals.defineField(
obj, key,
attrib.value,
!!attrib.writable,
!!attrib.enumerable,
!!attrib.configurable
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
}
else {
if (typeof attrib.get !== 'function' && attrib.get !== undefined) throw new TypeError('Get accessor must be a function.');
if (typeof attrib.set !== 'function' && attrib.set !== undefined) throw new TypeError('Set accessor must be a function.');
if (!env.internals.defineProp(
obj, key,
attrib.get,
attrib.set,
!!attrib.enumerable,
!!attrib.configurable
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
}
return obj;
},
defineProperties(obj, attrib) {
throwNotObject(obj, 'defineProperties');
if (typeof attrib !== 'object' && typeof attrib !== 'function') throw 'Expected second argument to be an object.';
for (var key in attrib) {
Object.defineProperty(obj, key, attrib[key]);
}
return obj;
},
keys(obj, onlyString) {
onlyString = !!(onlyString ?? true);
return env.internals.keys(obj, onlyString);
},
entries(obj, onlyString) {
return Object.keys(obj, onlyString).map(v => [ v, (obj as any)[v] ]);
},
values(obj, onlyString) {
return Object.keys(obj, onlyString).map(v => (obj as any)[v]);
},
getOwnPropertyDescriptor(obj, key) {
return env.internals.ownProp(obj, key);
},
getOwnPropertyDescriptors(obj) {
return Object.fromEntries([
...Object.getOwnPropertyNames(obj),
...Object.getOwnPropertySymbols(obj)
].map(v => [ v, Object.getOwnPropertyDescriptor(obj, v) ])) as any;
},
getOwnPropertyNames(obj) {
return env.internals.ownPropKeys(obj, false);
},
getOwnPropertySymbols(obj) {
return env.internals.ownPropKeys(obj, true);
},
hasOwn(obj, key) {
if (Object.getOwnPropertyNames(obj).includes(key)) return true;
if (Object.getOwnPropertySymbols(obj).includes(key)) return true;
return false;
},
getPrototypeOf(obj) {
return obj.__proto__;
},
setPrototypeOf(obj, proto) {
(obj as any).__proto__ = proto;
return obj;
},
fromEntries(iterable) {
const res = {} as any;
for (const el of iterable) {
res[el[0]] = el[1];
}
return res;
},
preventExtensions(obj) {
throwNotObject(obj, 'preventExtensions');
env.internals.preventExtensions(obj);
return obj;
},
seal(obj) {
throwNotObject(obj, 'seal');
env.internals.seal(obj);
return obj;
},
freeze(obj) {
throwNotObject(obj, 'freeze');
env.internals.freeze(obj);
return obj;
},
isExtensible(obj) {
if (!check(obj)) return false;
return env.internals.extensible(obj);
},
isSealed(obj) {
if (!check(obj)) return true;
if (Object.isExtensible(obj)) return false;
return Object.getOwnPropertyNames(obj).every(v => !Object.getOwnPropertyDescriptor(obj, v).configurable);
},
isFrozen(obj) {
if (!check(obj)) return true;
if (Object.isExtensible(obj)) return false;
return Object.getOwnPropertyNames(obj).every(v => {
var prop = Object.getOwnPropertyDescriptor(obj, v);
if ('writable' in prop && prop.writable) return false;
return !prop.configurable;
});
}
return dst;
},
create(obj, props) {
props ??= {};
return Object.defineProperties({ __proto__: obj }, props as any) as any;
},
});
defineProperty(obj, key, attrib) {
throwNotObject(obj, 'defineProperty');
if (typeof attrib !== 'object') throw new TypeError('Expected attributes to be an object.');
if ('value' in attrib) {
if ('get' in attrib || 'set' in attrib) throw new TypeError('Cannot specify a value and accessors for a property.');
if (!internals.defineField(
obj, key,
attrib.value,
!!attrib.writable,
!!attrib.enumerable,
!!attrib.configurable
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
}
else {
if (typeof attrib.get !== 'function' && attrib.get !== undefined) throw new TypeError('Get accessor must be a function.');
if (typeof attrib.set !== 'function' && attrib.set !== undefined) throw new TypeError('Set accessor must be a function.');
if (!internals.defineProp(
obj, key,
attrib.get,
attrib.set,
!!attrib.enumerable,
!!attrib.configurable
)) throw new TypeError('Can\'t define property \'' + key + '\'.');
}
return obj;
},
defineProperties(obj, attrib) {
throwNotObject(obj, 'defineProperties');
if (typeof attrib !== 'object' && typeof attrib !== 'function') throw 'Expected second argument to be an object.';
for (var key in attrib) {
Object.defineProperty(obj, key, attrib[key]);
}
return obj;
},
keys(obj, onlyString) {
onlyString = !!(onlyString ?? true);
return internals.keys(obj, onlyString);
},
entries(obj, onlyString) {
return Object.keys(obj, onlyString).map(v => [ v, (obj as any)[v] ]);
},
values(obj, onlyString) {
return Object.keys(obj, onlyString).map(v => (obj as any)[v]);
},
getOwnPropertyDescriptor(obj, key) {
return internals.ownProp(obj, key);
},
getOwnPropertyDescriptors(obj) {
return Object.fromEntries([
...Object.getOwnPropertyNames(obj),
...Object.getOwnPropertySymbols(obj)
].map(v => [ v, Object.getOwnPropertyDescriptor(obj, v) ])) as any;
},
getOwnPropertyNames(obj) {
return internals.ownPropKeys(obj, false);
},
getOwnPropertySymbols(obj) {
return internals.ownPropKeys(obj, true);
},
hasOwn(obj, key) {
if (Object.getOwnPropertyNames(obj).includes(key)) return true;
if (Object.getOwnPropertySymbols(obj).includes(key)) return true;
return false;
},
getPrototypeOf(obj) {
return obj.__proto__;
},
setPrototypeOf(obj, proto) {
(obj as any).__proto__ = proto;
return obj;
},
fromEntries(iterable) {
const res = {} as any;
for (const el of iterable) {
res[el[0]] = el[1];
}
return res;
},
preventExtensions(obj) {
throwNotObject(obj, 'preventExtensions');
internals.preventExtensions(obj);
return obj;
},
seal(obj) {
throwNotObject(obj, 'seal');
internals.seal(obj);
return obj;
},
freeze(obj) {
throwNotObject(obj, 'freeze');
internals.freeze(obj);
return obj;
},
isExtensible(obj) {
if (!check(obj)) return false;
return internals.extensible(obj);
},
isSealed(obj) {
if (!check(obj)) return true;
if (Object.isExtensible(obj)) return false;
return Object.getOwnPropertyNames(obj).every(v => !Object.getOwnPropertyDescriptor(obj, v).configurable);
},
isFrozen(obj) {
if (!check(obj)) return true;
if (Object.isExtensible(obj)) return false;
return Object.getOwnPropertyNames(obj).every(v => {
var prop = Object.getOwnPropertyDescriptor(obj, v);
if ('writable' in prop && prop.writable) return false;
return !prop.configurable;
});
}
});
setProps(Object.prototype, {
valueOf() {
return this;
},
toString() {
return '[object ' + (this[Symbol.typeName] ?? 'Unknown') + ']';
},
hasOwnProperty(key) {
return Object.hasOwn(this, key);
},
});
setProps(Object.prototype, env, {
valueOf() {
return this;
},
toString() {
return '[object ' + (this[Symbol.typeName] ?? 'Unknown') + ']';
},
hasOwnProperty(key) {
return Object.hasOwn(this, key);
},
});
});

View File

@@ -1,261 +1,210 @@
interface Replacer {
[Symbol.replace](target: string, val: string | ((match: string, ...args: any[]) => string)): string;
}
define("values/string", () => {
var String = env.global.String = function(this: String | undefined, arg: any) {
var val;
if (arguments.length === 0) val = '';
else val = arg + '';
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as StringConstructor;
interface String {
[i: number]: string;
String.prototype = ('' as any).__proto__ as String;
setConstr(String.prototype, String, env);
toString(): string;
valueOf(): string;
setProps(String.prototype, env, {
toString() {
if (typeof this === 'string') return this;
else return (this as any).value;
},
valueOf() {
if (typeof this === 'string') return this;
else return (this as any).value;
},
charAt(pos: number): string;
charCodeAt(pos: number): number;
substring(start?: number, end?: number): string;
slice(start?: number, end?: number): string;
substr(start?: number, length?: number): string;
substring(start, end) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.substring(start, end);
else throw new Error('This function may be used only with primitive or object strings.');
}
start = start ?? 0 | 0;
end = (end ?? this.length) | 0;
return env.internals.substring(this, start, end);
},
substr(start, length) {
start = start ?? 0 | 0;
startsWith(str: string, pos?: number): string;
endsWith(str: string, pos?: number): string;
if (start >= this.length) start = this.length - 1;
if (start < 0) start = 0;
replace(pattern: string | Replacer, val: string): string;
replaceAll(pattern: string | Replacer, val: string): string;
length = (length ?? this.length - start) | 0;
return this.substring(start, length + start);
},
match(pattern: string | Matcher): RegExpResult | string[] | null;
matchAll(pattern: string | Matcher): IterableIterator<RegExpResult>;
toLowerCase() {
return env.internals.toLower(this + '');
},
toUpperCase() {
return env.internals.toUpper(this + '');
},
split(pattern: string | Splitter, limit?: number, sensible?: boolean): string;
charAt(pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.charAt(pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
concat(...others: string[]): string;
indexOf(term: string | Searcher, start?: number): number;
lastIndexOf(term: string | Searcher, start?: number): number;
pos = pos | 0;
if (pos < 0 || pos >= this.length) return '';
return this[pos];
},
charCodeAt(pos) {
var res = this.charAt(pos);
if (res === '') return NaN;
else return env.internals.toCharCode(res);
},
toLowerCase(): string;
toUpperCase(): string;
startsWith(term, pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.startsWith(term, pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
pos = pos! | 0;
return env.internals.startsWith(this, term + '', pos);
},
endsWith(term, pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.endsWith(term, pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
pos = (pos ?? this.length) | 0;
return env.internals.endsWith(this, term + '', pos);
},
trim(): string;
indexOf(term: any, start) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.indexOf(term, start);
else throw new Error('This function may be used only with primitive or object strings.');
}
includes(term: string, start?: number): boolean;
if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term);
length: number;
return term[Symbol.search](this, false, start);
},
lastIndexOf(term: any, start) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.indexOf(term, start);
else throw new Error('This function may be used only with primitive or object strings.');
}
constructor: StringConstructor;
}
interface StringConstructor {
(val: any): string;
new (val: any): String;
if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term);
fromCharCode(val: number): string;
return term[Symbol.search](this, true, start);
},
includes(term, start) {
return this.indexOf(term, start) >= 0;
},
prototype: String;
}
replace(pattern: any, val) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.replace(pattern, val);
else throw new Error('This function may be used only with primitive or object strings.');
}
declare var String: StringConstructor;
if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern);
gt.String = function(this: String | undefined, arg: any) {
var val;
if (arguments.length === 0) val = '';
else val = arg + '';
if (this === undefined || this === null) return val;
else (this as any).value = val;
} as StringConstructor;
return pattern[Symbol.replace](this, val);
},
replaceAll(pattern: any, val) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.replace(pattern, val);
else throw new Error('This function may be used only with primitive or object strings.');
}
String.prototype = ('' as any).__proto__ as String;
setConstr(String.prototype, String);
if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern, "g");
if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g");
setProps(String.prototype, {
toString() {
if (typeof this === 'string') return this;
else return (this as any).value;
},
valueOf() {
if (typeof this === 'string') return this;
else return (this as any).value;
},
return pattern[Symbol.replace](this, val);
},
substring(start, end) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.substring(start, end);
else throw new Error('This function may be used only with primitive or object strings.');
match(pattern: any) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.match(pattern);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern);
return pattern[Symbol.match](this);
},
matchAll(pattern: any) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.matchAll(pattern);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern, "g");
if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g");
return pattern[Symbol.match](this);
},
split(pattern: any, lim, sensible) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.split(pattern, lim, sensible);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.split] !== 'function') pattern = RegExp.escape(pattern, "g");
return pattern[Symbol.split](this, lim, sensible);
},
slice(start, end) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.slice(start, end);
else throw new Error('This function may be used only with primitive or object strings.');
}
start = wrapI(this.length, start ?? 0 | 0);
end = wrapI(this.length, end ?? this.length | 0);
if (start > end) return '';
return this.substring(start, end);
},
concat(...args) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.concat(...args);
else throw new Error('This function may be used only with primitive or object strings.');
}
var res = this;
for (var arg of args) res += arg;
return res;
},
trim() {
return this
.replace(/^\s+/g, '')
.replace(/\s+$/g, '');
}
start = start ?? 0 | 0;
end = (end ?? this.length) | 0;
return internals.substring(this, start, end);
},
substr(start, length) {
start = start ?? 0 | 0;
});
if (start >= this.length) start = this.length - 1;
if (start < 0) start = 0;
setProps(String, env, {
fromCharCode(val) {
return env.internals.fromCharCode(val | 0);
},
})
length = (length ?? this.length - start) | 0;
return this.substring(start, length + start);
},
env.global.Object.defineProperty(String.prototype, 'length', {
get() {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.length;
else throw new Error('This function may be used only with primitive or object strings.');
}
toLowerCase() {
return internals.toLower(this + '');
},
toUpperCase() {
return internals.toUpper(this + '');
},
charAt(pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.charAt(pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
pos = pos | 0;
if (pos < 0 || pos >= this.length) return '';
return this[pos];
},
charCodeAt(pos) {
var res = this.charAt(pos);
if (res === '') return NaN;
else return internals.toCharCode(res);
},
startsWith(term, pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.startsWith(term, pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
pos = pos! | 0;
return internals.startsWith(this, term + '', pos);
},
endsWith(term, pos) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.endsWith(term, pos);
else throw new Error('This function may be used only with primitive or object strings.');
}
pos = (pos ?? this.length) | 0;
return internals.endsWith(this, term + '', pos);
},
indexOf(term: any, start) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.indexOf(term, start);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term);
return term[Symbol.search](this, false, start);
},
lastIndexOf(term: any, start) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.indexOf(term, start);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof term[Symbol.search] !== 'function') term = RegExp.escape(term);
return term[Symbol.search](this, true, start);
},
includes(term, start) {
return this.indexOf(term, start) >= 0;
},
replace(pattern: any, val) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.replace(pattern, val);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern);
return pattern[Symbol.replace](this, val);
},
replaceAll(pattern: any, val) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.replace(pattern, val);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.replace] !== 'function') pattern = RegExp.escape(pattern, "g");
if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g");
return pattern[Symbol.replace](this, val);
},
match(pattern: any) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.match(pattern);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern);
return pattern[Symbol.match](this);
},
matchAll(pattern: any) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.matchAll(pattern);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.match] !== 'function') pattern = RegExp.escape(pattern, "g");
if (pattern instanceof RegExp && !pattern.global) pattern = new pattern.constructor(pattern.source, pattern.flags + "g");
return pattern[Symbol.match](this);
},
split(pattern: any, lim, sensible) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.split(pattern, lim, sensible);
else throw new Error('This function may be used only with primitive or object strings.');
}
if (typeof pattern[Symbol.split] !== 'function') pattern = RegExp.escape(pattern, "g");
return pattern[Symbol.split](this, lim, sensible);
},
slice(start, end) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.slice(start, end);
else throw new Error('This function may be used only with primitive or object strings.');
}
start = wrapI(this.length, start ?? 0 | 0);
end = wrapI(this.length, end ?? this.length | 0);
if (start > end) return '';
return this.substring(start, end);
},
concat(...args) {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.concat(...args);
else throw new Error('This function may be used only with primitive or object strings.');
}
var res = this;
for (var arg of args) res += arg;
return res;
},
trim() {
return this
.replace(/^\s+/g, '')
.replace(/\s+$/g, '');
}
});
setProps(String, {
fromCharCode(val) {
return internals.fromCharCode(val | 0);
},
})
Object.defineProperty(String.prototype, 'length', {
get() {
if (typeof this !== 'string') {
if (this instanceof String) return (this as any).value.length;
else throw new Error('This function may be used only with primitive or object strings.');
}
return internals.strlen(this);
},
configurable: true,
enumerable: false,
});
return env.internals.strlen(this);
},
configurable: true,
enumerable: false,
});
});

View File

@@ -1,38 +1,33 @@
interface Symbol {
valueOf(): symbol;
constructor: SymbolConstructor;
}
interface SymbolConstructor {
(val?: any): symbol;
prototype: Symbol;
for(key: string): symbol;
keyFor(sym: symbol): string;
readonly typeName: unique symbol;
}
define("values/symbol", () => {
var Symbol = env.global.Symbol = function(this: any, val?: string) {
if (this !== undefined && this !== null) throw new TypeError("Symbol may not be called with 'new'.");
if (typeof val !== 'string' && val !== undefined) throw new TypeError('val must be a string or undefined.');
return env.internals.symbol(val, true);
} as SymbolConstructor;
declare var Symbol: SymbolConstructor;
Symbol.prototype = env.internals.symbolProto;
setConstr(Symbol.prototype, Symbol, env);
(Symbol as any).typeName = Symbol("Symbol.name");
(Symbol as any).replace = Symbol('Symbol.replace');
(Symbol as any).match = Symbol('Symbol.match');
(Symbol as any).matchAll = Symbol('Symbol.matchAll');
(Symbol as any).split = Symbol('Symbol.split');
(Symbol as any).search = Symbol('Symbol.search');
(Symbol as any).iterator = Symbol('Symbol.iterator');
(Symbol as any).asyncIterator = Symbol('Symbol.asyncIterator');
gt.Symbol = function(this: any, val?: string) {
if (this !== undefined && this !== null) throw new TypeError("Symbol may not be called with 'new'.");
if (typeof val !== 'string' && val !== undefined) throw new TypeError('val must be a string or undefined.');
return internals.symbol(val, true);
} as SymbolConstructor;
setProps(Symbol, env, {
for(key) {
if (typeof key !== 'string' && key !== undefined) throw new TypeError('key must be a string or undefined.');
return env.internals.symbol(key, false);
},
keyFor(sym) {
if (typeof sym !== 'symbol') throw new TypeError('sym must be a symbol.');
return env.internals.symStr(sym);
},
typeName: Symbol('Symbol.name') as any,
});
Symbol.prototype = internals.symbolProto;
setConstr(Symbol.prototype, Symbol);
(Symbol as any).typeName = Symbol("Symbol.name");
setProps(Symbol, {
for(key) {
if (typeof key !== 'string' && key !== undefined) throw new TypeError('key must be a string or undefined.');
return internals.symbol(key, false);
},
keyFor(sym) {
if (typeof sym !== 'symbol') throw new TypeError('sym must be a symbol.');
return internals.symStr(sym);
},
typeName: Symbol('Symbol.name') as any,
});
Object.defineProperty(Object.prototype, Symbol.typeName, { value: 'Object' });
Object.defineProperty(gt, Symbol.typeName, { value: 'Window' });
env.global.Object.defineProperty(Object.prototype, Symbol.typeName, { value: 'Object' });
env.global.Object.defineProperty(env.global, Symbol.typeName, { value: 'Window' });
});