Create environments #4
249
lib/core.ts
249
lib/core.ts
@ -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;
|
||||
}
|
||||
};
|
216
lib/iterators.ts
216
lib/iterators.ts
@ -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
634
lib/lib.d.ts
vendored
Normal 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);
|
||||
}
|
65
lib/map.ts
65
lib/map.ts
@ -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
12
lib/modules.ts
Normal 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 };
|
||||
})();
|
@ -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';
|
||||
});
|
||||
|
320
lib/regex.ts
320
lib/regex.ts
@ -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;
|
||||
setProps(RegExp.prototype as RegExp, env, {
|
||||
[Symbol.typeName]: '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): string;
|
||||
}
|
||||
interface Searcher {
|
||||
[Symbol.search](target: string, reverse?: boolean, start?: number): number;
|
||||
}
|
||||
test(val) {
|
||||
return !!this.exec(val);
|
||||
},
|
||||
toString() {
|
||||
return '/' + this.source + '/' + this.flags;
|
||||
},
|
||||
|
||||
declare class RegExp implements Matcher, Splitter, Replacer, Searcher {
|
||||
static escape(raw: any, flags?: string): RegExp;
|
||||
[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;
|
||||
|
||||
prototype: RegExp;
|
||||
return {
|
||||
next: (): IteratorResult<RegExpResult, undefined> => {
|
||||
const val = pattern?.exec(target);
|
||||
|
||||
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) {
|
||||
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;
|
||||
},
|
||||
[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[] = [];
|
||||
|
||||
return {
|
||||
next: (): IteratorResult<RegExpResult, undefined> => {
|
||||
const val = pattern?.exec(target);
|
||||
// log(pattern.toString());
|
||||
|
||||
if (val === null || val === undefined) {
|
||||
pattern = undefined;
|
||||
return { done: true };
|
||||
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;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
@ -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);
|
||||
};
|
31
lib/set.ts
31
lib/set.ts
@ -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
44
lib/utils.ts
Normal 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;
|
||||
}
|
@ -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.");
|
||||
} as ArrayConstructor;
|
||||
|
||||
for (var i = 0; i < this.length; 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;
|
||||
},
|
||||
findIndex(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 = 0; i < this.length; 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;
|
||||
},
|
||||
findLast(func, thisArg) {
|
||||
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
|
||||
values() {
|
||||
var i = 0;
|
||||
|
||||
for (var i = this.length - 1; i >= 0; i--) {
|
||||
if (i in this && func.call(thisArg, this[i], i, this)) return this[i];
|
||||
}
|
||||
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 undefined;
|
||||
},
|
||||
findLastIndex(func, thisArg) {
|
||||
if (typeof func !== 'function') throw new TypeError("Given argument is not a function.");
|
||||
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;
|
||||
|
||||
for (var i = this.length - 1; i >= 0; i--) {
|
||||
if (i in this && func.call(thisArg, this[i], i, this)) return i;
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
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); }
|
||||
});
|
||||
});
|
@ -1,22 +1,12 @@
|
||||
interface Boolean {
|
||||
valueOf(): boolean;
|
||||
constructor: BooleanConstructor;
|
||||
}
|
||||
interface BooleanConstructor {
|
||||
(val: any): boolean;
|
||||
new (val: any): 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;
|
||||
|
||||
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);
|
||||
Boolean.prototype = (false as any).__proto__ as Boolean;
|
||||
setConstr(Boolean.prototype, Boolean, env);
|
||||
});
|
||||
|
@ -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 += '';
|
||||
|
||||
interface TypeErrorConstructor extends ErrorConstructor {
|
||||
(msg?: any): TypeError;
|
||||
new (msg?: any): TypeError;
|
||||
prototype: Error;
|
||||
}
|
||||
interface TypeError extends Error {
|
||||
constructor: TypeErrorConstructor;
|
||||
name: 'TypeError';
|
||||
}
|
||||
return Object.setPrototypeOf({
|
||||
message: msg,
|
||||
stack: [] as string[],
|
||||
}, Error.prototype);
|
||||
} as ErrorConstructor;
|
||||
|
||||
interface RangeErrorConstructor extends ErrorConstructor {
|
||||
(msg?: any): RangeError;
|
||||
new (msg?: any): RangeError;
|
||||
prototype: Error;
|
||||
}
|
||||
interface RangeError extends Error {
|
||||
constructor: RangeErrorConstructor;
|
||||
name: 'RangeError';
|
||||
}
|
||||
Error.prototype = env.internals.err ?? {};
|
||||
Error.prototype.name = 'Error';
|
||||
setConstr(Error.prototype, Error, env);
|
||||
|
||||
interface SyntaxErrorConstructor extends ErrorConstructor {
|
||||
(msg?: any): RangeError;
|
||||
new (msg?: any): RangeError;
|
||||
prototype: Error;
|
||||
}
|
||||
interface SyntaxError extends Error {
|
||||
constructor: SyntaxErrorConstructor;
|
||||
name: 'SyntaxError';
|
||||
}
|
||||
Error.prototype.toString = function() {
|
||||
if (!(this instanceof Error)) return '';
|
||||
|
||||
if (this.message === '') return this.name;
|
||||
else return this.name + ': ' + this.message;
|
||||
};
|
||||
|
||||
declare var Error: ErrorConstructor;
|
||||
declare var RangeError: RangeErrorConstructor;
|
||||
declare var TypeError: TypeErrorConstructor;
|
||||
declare var SyntaxError: SyntaxErrorConstructor;
|
||||
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;
|
||||
|
||||
gt.Error = function Error(msg: string) {
|
||||
if (msg === undefined) msg = '';
|
||||
else msg += '';
|
||||
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 Object.setPrototypeOf({
|
||||
message: msg,
|
||||
stack: [] as string[],
|
||||
}, Error.prototype);
|
||||
} as ErrorConstructor;
|
||||
return err;
|
||||
}
|
||||
|
||||
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 ?? {});
|
||||
});
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
@ -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 + '';
|
||||
}
|
||||
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 });
|
||||
});
|
||||
|
||||
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 });
|
||||
|
@ -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);
|
||||
},
|
||||
});
|
||||
});
|
@ -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,
|
||||
});
|
||||
});
|
@ -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,
|
||||
env.global.Object.defineProperty(Object.prototype, Symbol.typeName, { value: 'Object' });
|
||||
env.global.Object.defineProperty(env.global, Symbol.typeName, { value: 'Window' });
|
||||
});
|
||||
|
||||
Object.defineProperty(Object.prototype, Symbol.typeName, { value: 'Object' });
|
||||
Object.defineProperty(gt, Symbol.typeName, { value: 'Window' });
|
||||
|
@ -1,7 +1,6 @@
|
||||
package me.topchetoeu.jscript;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
@ -13,8 +12,6 @@ import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.events.Observer;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||
import me.topchetoeu.jscript.polyfills.PolyfillEngine;
|
||||
import me.topchetoeu.jscript.polyfills.TypescriptEngine;
|
||||
|
||||
public class Main {
|
||||
static Thread task;
|
||||
@ -54,7 +51,7 @@ public class Main {
|
||||
|
||||
public static void main(String args[]) {
|
||||
var in = new BufferedReader(new InputStreamReader(System.in));
|
||||
engine = new TypescriptEngine(new File("."));
|
||||
engine = new Engine();
|
||||
var scope = engine.global().globalChild();
|
||||
var exited = new boolean[1];
|
||||
|
||||
|
@ -6,7 +6,6 @@ import me.topchetoeu.jscript.Location;
|
||||
import me.topchetoeu.jscript.compilation.Instruction;
|
||||
import me.topchetoeu.jscript.compilation.Statement;
|
||||
import me.topchetoeu.jscript.compilation.control.ThrowStatement;
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.Operation;
|
||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
@ -52,40 +51,7 @@ public class OperationStatement extends Statement {
|
||||
}
|
||||
|
||||
try {
|
||||
var ctx = new CallContext(null);
|
||||
|
||||
switch (operation) {
|
||||
case ADD: return new ConstantStatement(loc(), Values.add(ctx, vals[0], vals[1]));
|
||||
case SUBTRACT: return new ConstantStatement(loc(), Values.subtract(ctx, vals[0], vals[1]));
|
||||
case DIVIDE: return new ConstantStatement(loc(), Values.divide(ctx, vals[0], vals[1]));
|
||||
case MULTIPLY: return new ConstantStatement(loc(), Values.multiply(ctx, vals[0], vals[1]));
|
||||
case MODULO: return new ConstantStatement(loc(), Values.modulo(ctx, vals[0], vals[1]));
|
||||
|
||||
case AND: return new ConstantStatement(loc(), Values.and(ctx, vals[0], vals[1]));
|
||||
case OR: return new ConstantStatement(loc(), Values.or(ctx, vals[0], vals[1]));
|
||||
case XOR: return new ConstantStatement(loc(), Values.xor(ctx, vals[0], vals[1]));
|
||||
|
||||
case EQUALS: return new ConstantStatement(loc(), Values.strictEquals(vals[0], vals[1]));
|
||||
case NOT_EQUALS: return new ConstantStatement(loc(), !Values.strictEquals(vals[0], vals[1]));
|
||||
case LOOSE_EQUALS: return new ConstantStatement(loc(), Values.looseEqual(ctx, vals[0], vals[1]));
|
||||
case LOOSE_NOT_EQUALS: return new ConstantStatement(loc(), !Values.looseEqual(ctx, vals[0], vals[1]));
|
||||
|
||||
case GREATER: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) < 0);
|
||||
case GREATER_EQUALS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) <= 0);
|
||||
case LESS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) > 0);
|
||||
case LESS_EQUALS: return new ConstantStatement(loc(), Values.compare(ctx, vals[0], vals[1]) >= 0);
|
||||
|
||||
case INVERSE: return new ConstantStatement(loc(), Values.bitwiseNot(ctx, vals[0]));
|
||||
case NOT: return new ConstantStatement(loc(), Values.not(vals[0]));
|
||||
case POS: return new ConstantStatement(loc(), Values.toNumber(ctx, vals[0]));
|
||||
case NEG: return new ConstantStatement(loc(), Values.negative(ctx, vals[0]));
|
||||
|
||||
case SHIFT_LEFT: return new ConstantStatement(loc(), Values.shiftLeft(ctx, vals[0], vals[1]));
|
||||
case SHIFT_RIGHT: return new ConstantStatement(loc(), Values.shiftRight(ctx, vals[0], vals[1]));
|
||||
case USHIFT_RIGHT: return new ConstantStatement(loc(), Values.unsignedShiftRight(ctx, vals[0], vals[1]));
|
||||
|
||||
default: break;
|
||||
}
|
||||
return new ConstantStatement(loc(), Values.operation(null, operation, vals));
|
||||
}
|
||||
catch (EngineException e) {
|
||||
return new ThrowStatement(loc(), new ConstantStatement(loc(), e.value));
|
||||
|
@ -142,13 +142,6 @@ public class Engine {
|
||||
}
|
||||
}
|
||||
|
||||
public void exposeClass(String name, Class<?> clazz) {
|
||||
global.define(name, true, typeRegister.getConstr(clazz));
|
||||
}
|
||||
public void exposeNamespace(String name, Class<?> clazz) {
|
||||
global.define(name, true, NativeTypeRegister.makeNamespace(clazz));
|
||||
}
|
||||
|
||||
public Thread start() {
|
||||
if (this.thread == null) {
|
||||
this.thread = new Thread(this::run, "JavaScript Runner #" + id);
|
||||
@ -176,6 +169,9 @@ public class Engine {
|
||||
public ObjectValue getPrototype(Class<?> clazz) {
|
||||
return typeRegister.getProto(clazz);
|
||||
}
|
||||
public FunctionValue getConstructor(Class<?> clazz) {
|
||||
return typeRegister.getConstr(clazz);
|
||||
}
|
||||
public CallContext context() { return new CallContext(this).mergeData(callCtxVals); }
|
||||
|
||||
public Awaitable<Object> pushMsg(boolean micro, FunctionValue func, Map<DataKey<?>, Object> data, Object thisArg, Object... args) {
|
||||
|
@ -93,13 +93,13 @@ public class CodeFrame {
|
||||
|
||||
return res;
|
||||
}
|
||||
public void push(Object val) {
|
||||
public void push(CallContext ctx, Object val) {
|
||||
if (stack.length <= stackPtr) {
|
||||
var newStack = new Object[stack.length * 2];
|
||||
System.arraycopy(stack, 0, newStack, 0, stack.length);
|
||||
stack = newStack;
|
||||
}
|
||||
stack[stackPtr++] = Values.normalize(val);
|
||||
stack[stackPtr++] = Values.normalize(ctx, val);
|
||||
}
|
||||
|
||||
public void start(CallContext ctx) {
|
||||
@ -150,7 +150,7 @@ public class CodeFrame {
|
||||
|
||||
try {
|
||||
this.jumpFlag = false;
|
||||
return Runners.exec(debugCmd, instr, this, ctx);
|
||||
return Runners.exec(ctx, debugCmd, instr, this);
|
||||
}
|
||||
catch (EngineException e) {
|
||||
throw e.add(function.name, prevLoc);
|
||||
@ -307,13 +307,13 @@ public class CodeFrame {
|
||||
}
|
||||
}
|
||||
|
||||
public CodeFrame(Object thisArg, Object[] args, CodeFunction func) {
|
||||
public CodeFrame(CallContext ctx, Object thisArg, Object[] args, CodeFunction func) {
|
||||
this.args = args.clone();
|
||||
this.scope = new LocalScope(func.localsN, func.captures);
|
||||
this.scope.get(0).set(null, thisArg);
|
||||
var argsObj = new ArrayValue();
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
argsObj.set(i, args[i]);
|
||||
argsObj.set(ctx, i, args[i]);
|
||||
}
|
||||
this.scope.get(1).value = argsObj;
|
||||
|
||||
|
@ -18,62 +18,62 @@ import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
public class Runners {
|
||||
public static final Object NO_RETURN = new Object();
|
||||
|
||||
public static Object execReturn(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execReturn(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr++;
|
||||
return frame.pop();
|
||||
}
|
||||
public static Object execSignal(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execSignal(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr++;
|
||||
return new SignalValue(instr.get(0));
|
||||
}
|
||||
public static Object execThrow(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execThrow(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
throw new EngineException(frame.pop());
|
||||
}
|
||||
public static Object execThrowSyntax(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execThrowSyntax(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
throw EngineException.ofSyntax((String)instr.get(0));
|
||||
}
|
||||
|
||||
private static Object call(DebugCommand state, CallContext ctx, Object func, Object thisArg, Object... args) throws InterruptedException {
|
||||
private static Object call(CallContext ctx, DebugCommand state, Object func, Object thisArg, Object... args) throws InterruptedException {
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
return Values.call(ctx, func, thisArg, args);
|
||||
}
|
||||
|
||||
public static Object execCall(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execCall(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var callArgs = frame.take(instr.get(0));
|
||||
var func = frame.pop();
|
||||
var thisArg = frame.pop();
|
||||
|
||||
frame.push(call(state, ctx, func, thisArg, callArgs));
|
||||
frame.push(ctx, call(ctx, state, func, thisArg, callArgs));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execCallNew(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execCallNew(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var callArgs = frame.take(instr.get(0));
|
||||
var funcObj = frame.pop();
|
||||
|
||||
if (Values.isFunction(funcObj) && Values.function(funcObj).special) {
|
||||
frame.push(call(state, ctx, funcObj, null, callArgs));
|
||||
frame.push(ctx, call(ctx, state, funcObj, null, callArgs));
|
||||
}
|
||||
else {
|
||||
var proto = Values.getMember(ctx, funcObj, "prototype");
|
||||
var obj = new ObjectValue();
|
||||
obj.setPrototype(ctx, proto);
|
||||
call(state, ctx, funcObj, obj, callArgs);
|
||||
frame.push(obj);
|
||||
call(ctx, state, funcObj, obj, callArgs);
|
||||
frame.push(ctx, obj);
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execMakeVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execMakeVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var name = (String)instr.get(0);
|
||||
frame.function.globals.define(name);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execDefProp(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execDefProp(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var setter = frame.pop();
|
||||
var getter = frame.pop();
|
||||
var name = frame.pop();
|
||||
@ -82,28 +82,28 @@ public class Runners {
|
||||
if (getter != null && !Values.isFunction(getter)) throw EngineException.ofType("Getter must be a function or undefined.");
|
||||
if (setter != null && !Values.isFunction(setter)) throw EngineException.ofType("Setter must be a function or undefined.");
|
||||
if (!Values.isObject(obj)) throw EngineException.ofType("Property apply target must be an object.");
|
||||
Values.object(obj).defineProperty(name, Values.function(getter), Values.function(setter), false, false);
|
||||
Values.object(obj).defineProperty(ctx, name, Values.function(getter), Values.function(setter), false, false);
|
||||
|
||||
frame.push(obj);
|
||||
frame.push(ctx, obj);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execInstanceof(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execInstanceof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var type = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
if (!Values.isPrimitive(type)) {
|
||||
var proto = Values.getMember(ctx, type, "prototype");
|
||||
frame.push(Values.isInstanceOf(ctx, obj, proto));
|
||||
frame.push(ctx, Values.isInstanceOf(ctx, obj, proto));
|
||||
}
|
||||
else {
|
||||
frame.push(false);
|
||||
frame.push(ctx, false);
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execKeys(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execKeys(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = frame.pop();
|
||||
|
||||
var arr = new ObjectValue();
|
||||
@ -113,81 +113,81 @@ public class Runners {
|
||||
Collections.reverse(members);
|
||||
for (var el : members) {
|
||||
if (el instanceof Symbol) continue;
|
||||
arr.defineProperty(i++, el);
|
||||
arr.defineProperty(ctx, i++, el);
|
||||
}
|
||||
|
||||
arr.defineProperty("length", i);
|
||||
arr.defineProperty(ctx, "length", i);
|
||||
|
||||
frame.push(arr);
|
||||
frame.push(ctx, arr);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execTry(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execTry(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.addTry(instr.get(0), instr.get(1), instr.get(2));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDup(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execDup(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int offset = instr.get(0), count = instr.get(1);
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
frame.push(frame.peek(offset + count - 1));
|
||||
frame.push(ctx, frame.peek(offset + count - 1));
|
||||
}
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execMove(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execMove(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int offset = instr.get(0), count = instr.get(1);
|
||||
|
||||
var tmp = frame.take(offset);
|
||||
var res = frame.take(count);
|
||||
|
||||
for (var i = 0; i < offset; i++) frame.push(tmp[i]);
|
||||
for (var i = 0; i < count; i++) frame.push(res[i]);
|
||||
for (var i = 0; i < offset; i++) frame.push(ctx, tmp[i]);
|
||||
for (var i = 0; i < count; i++) frame.push(ctx, res[i]);
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadUndefined(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(null);
|
||||
public static Object execLoadUndefined(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, null);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadValue(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(instr.get(0));
|
||||
public static Object execLoadValue(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, instr.get(0));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execLoadVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var i = instr.get(0);
|
||||
|
||||
if (i instanceof String) frame.push(frame.function.globals.get(ctx, (String)i));
|
||||
else frame.push(frame.scope.get((int)i).get(ctx));
|
||||
if (i instanceof String) frame.push(ctx, frame.function.globals.get(ctx, (String)i));
|
||||
else frame.push(ctx, frame.scope.get((int)i).get(ctx));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadObj(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(new ObjectValue());
|
||||
public static Object execLoadObj(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, new ObjectValue());
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadGlob(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
frame.push(frame.function.globals.obj);
|
||||
public static Object execLoadGlob(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.push(ctx, frame.function.globals.obj);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadArr(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execLoadArr(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
var res = new ArrayValue();
|
||||
res.setSize(instr.get(0));
|
||||
frame.push(res);
|
||||
frame.push(ctx, res);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadFunc(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execLoadFunc(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
int n = (Integer)instr.get(0);
|
||||
int localsN = (Integer)instr.get(1);
|
||||
int len = (Integer)instr.get(2);
|
||||
@ -203,18 +203,18 @@ public class Runners {
|
||||
System.arraycopy(frame.function.body, start, body, 0, end - start);
|
||||
|
||||
var func = new CodeFunction("", localsN, len, frame.function.globals, captures, body);
|
||||
frame.push(func);
|
||||
frame.push(ctx, func);
|
||||
|
||||
frame.codePtr += n;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execLoadMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
try {
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
frame.push(Values.getMember(ctx, obj, key));
|
||||
frame.push(ctx, Values.getMember(ctx, obj, key));
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw EngineException.ofType(e.getMessage());
|
||||
@ -222,33 +222,33 @@ public class Runners {
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execLoadKeyMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
frame.push(instr.get(0));
|
||||
return execLoadMember(state, instr, frame, ctx);
|
||||
public static Object execLoadKeyMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.push(ctx, instr.get(0));
|
||||
return execLoadMember(ctx, state, instr, frame);
|
||||
}
|
||||
public static Object execLoadRegEx(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
frame.push(ctx.engine().makeRegex(instr.get(0), instr.get(1)));
|
||||
public static Object execLoadRegEx(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
frame.push(ctx, ctx.engine().makeRegex(instr.get(0), instr.get(1)));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDiscard(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execDiscard(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.pop();
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreMember(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execStoreMember(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = frame.pop();
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
ctx.setData(CodeFrame.STOP_AT_START_KEY, state == DebugCommand.STEP_INTO);
|
||||
if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax("Can't set member '" + key + "'.");
|
||||
if ((boolean)instr.get(0)) frame.push(val);
|
||||
if ((boolean)instr.get(0)) frame.push(ctx, val);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreVar(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execStoreVar(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
|
||||
var i = instr.get(0);
|
||||
|
||||
@ -258,18 +258,18 @@ public class Runners {
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execStoreSelfFunc(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execStoreSelfFunc(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.scope.locals[(int)instr.get(0)].set(ctx, frame.function);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execJmp(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execJmp(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execJmpIf(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execJmpIf(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
if (Values.toBoolean(frame.pop())) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
@ -277,7 +277,7 @@ public class Runners {
|
||||
else frame.codePtr ++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execJmpIfNot(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execJmpIfNot(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
if (Values.not(frame.pop())) {
|
||||
frame.codePtr += (int)instr.get(0);
|
||||
frame.jumpFlag = true;
|
||||
@ -286,15 +286,15 @@ public class Runners {
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execIn(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execIn(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var obj = frame.pop();
|
||||
var index = frame.pop();
|
||||
|
||||
frame.push(Values.hasMember(ctx, obj, index, false));
|
||||
frame.push(ctx, Values.hasMember(ctx, obj, index, false));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execTypeof(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execTypeof(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
String name = instr.get(0);
|
||||
Object obj;
|
||||
|
||||
@ -306,12 +306,12 @@ public class Runners {
|
||||
}
|
||||
else obj = frame.pop();
|
||||
|
||||
frame.push(Values.type(obj));
|
||||
frame.push(ctx, Values.type(obj));
|
||||
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
public static Object execNop(Instruction instr, CodeFrame frame, CallContext ctx) {
|
||||
public static Object execNop(CallContext ctx, Instruction instr, CodeFrame frame) {
|
||||
if (instr.is(0, "dbg_names")) {
|
||||
var names = new String[instr.params.length - 1];
|
||||
for (var i = 0; i < instr.params.length - 1; i++) {
|
||||
@ -325,67 +325,67 @@ public class Runners {
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execDelete(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execDelete(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
var key = frame.pop();
|
||||
var val = frame.pop();
|
||||
|
||||
if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax("Can't delete member '" + key + "'.");
|
||||
frame.push(true);
|
||||
frame.push(ctx, true);
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object execOperation(Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object execOperation(CallContext ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
Operation op = instr.get(0);
|
||||
var args = new Object[op.operands];
|
||||
|
||||
for (var i = op.operands - 1; i >= 0; i--) args[i] = frame.pop();
|
||||
|
||||
frame.push(Values.operation(ctx, op, args));
|
||||
frame.push(ctx, Values.operation(ctx, op, args));
|
||||
frame.codePtr++;
|
||||
return NO_RETURN;
|
||||
}
|
||||
|
||||
public static Object exec(DebugCommand state, Instruction instr, CodeFrame frame, CallContext ctx) throws InterruptedException {
|
||||
public static Object exec(CallContext ctx, DebugCommand state, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||
// System.out.println(instr + "@" + instr.location);
|
||||
switch (instr.type) {
|
||||
case NOP: return execNop(instr, frame, ctx);
|
||||
case RETURN: return execReturn(instr, frame, ctx);
|
||||
case SIGNAL: return execSignal(instr, frame, ctx);
|
||||
case THROW: return execThrow(instr, frame, ctx);
|
||||
case THROW_SYNTAX: return execThrowSyntax(instr, frame, ctx);
|
||||
case CALL: return execCall(state, instr, frame, ctx);
|
||||
case CALL_NEW: return execCallNew(state, instr, frame, ctx);
|
||||
case TRY: return execTry(state, instr, frame, ctx);
|
||||
case NOP: return execNop(ctx, instr, frame);
|
||||
case RETURN: return execReturn(ctx, instr, frame);
|
||||
case SIGNAL: return execSignal(ctx, instr, frame);
|
||||
case THROW: return execThrow(ctx, instr, frame);
|
||||
case THROW_SYNTAX: return execThrowSyntax(ctx, instr, frame);
|
||||
case CALL: return execCall(ctx, state, instr, frame);
|
||||
case CALL_NEW: return execCallNew(ctx, state, instr, frame);
|
||||
case TRY: return execTry(ctx, instr, frame);
|
||||
|
||||
case DUP: return execDup(instr, frame, ctx);
|
||||
case MOVE: return execMove(instr, frame, ctx);
|
||||
case LOAD_VALUE: return execLoadValue(instr, frame, ctx);
|
||||
case LOAD_VAR: return execLoadVar(instr, frame, ctx);
|
||||
case LOAD_OBJ: return execLoadObj(instr, frame, ctx);
|
||||
case LOAD_ARR: return execLoadArr(instr, frame, ctx);
|
||||
case LOAD_FUNC: return execLoadFunc(instr, frame, ctx);
|
||||
case LOAD_MEMBER: return execLoadMember(state, instr, frame, ctx);
|
||||
case LOAD_VAL_MEMBER: return execLoadKeyMember(state, instr, frame, ctx);
|
||||
case LOAD_REGEX: return execLoadRegEx(instr, frame, ctx);
|
||||
case LOAD_GLOB: return execLoadGlob(instr, frame, ctx);
|
||||
case DUP: return execDup(ctx, instr, frame);
|
||||
case MOVE: return execMove(ctx, instr, frame);
|
||||
case LOAD_VALUE: return execLoadValue(ctx, instr, frame);
|
||||
case LOAD_VAR: return execLoadVar(ctx, instr, frame);
|
||||
case LOAD_OBJ: return execLoadObj(ctx, instr, frame);
|
||||
case LOAD_ARR: return execLoadArr(ctx, instr, frame);
|
||||
case LOAD_FUNC: return execLoadFunc(ctx, instr, frame);
|
||||
case LOAD_MEMBER: return execLoadMember(ctx, state, instr, frame);
|
||||
case LOAD_VAL_MEMBER: return execLoadKeyMember(ctx, state, instr, frame);
|
||||
case LOAD_REGEX: return execLoadRegEx(ctx, instr, frame);
|
||||
case LOAD_GLOB: return execLoadGlob(ctx, instr, frame);
|
||||
|
||||
case DISCARD: return execDiscard(instr, frame, ctx);
|
||||
case STORE_MEMBER: return execStoreMember(state, instr, frame, ctx);
|
||||
case STORE_VAR: return execStoreVar(instr, frame, ctx);
|
||||
case STORE_SELF_FUNC: return execStoreSelfFunc(instr, frame, ctx);
|
||||
case MAKE_VAR: return execMakeVar(instr, frame, ctx);
|
||||
case DISCARD: return execDiscard(ctx, instr, frame);
|
||||
case STORE_MEMBER: return execStoreMember(ctx, state, instr, frame);
|
||||
case STORE_VAR: return execStoreVar(ctx, instr, frame);
|
||||
case STORE_SELF_FUNC: return execStoreSelfFunc(ctx, instr, frame);
|
||||
case MAKE_VAR: return execMakeVar(ctx, instr, frame);
|
||||
|
||||
case KEYS: return execKeys(instr, frame, ctx);
|
||||
case DEF_PROP: return execDefProp(instr, frame, ctx);
|
||||
case TYPEOF: return execTypeof(instr, frame, ctx);
|
||||
case DELETE: return execDelete(instr, frame, ctx);
|
||||
case KEYS: return execKeys(ctx, instr, frame);
|
||||
case DEF_PROP: return execDefProp(ctx, instr, frame);
|
||||
case TYPEOF: return execTypeof(ctx, instr, frame);
|
||||
case DELETE: return execDelete(ctx, instr, frame);
|
||||
|
||||
case JMP: return execJmp(instr, frame, ctx);
|
||||
case JMP_IF: return execJmpIf(instr, frame, ctx);
|
||||
case JMP_IFN: return execJmpIfNot(instr, frame, ctx);
|
||||
case JMP: return execJmp(ctx, instr, frame);
|
||||
case JMP_IF: return execJmpIf(ctx, instr, frame);
|
||||
case JMP_IFN: return execJmpIfNot(ctx, instr, frame);
|
||||
|
||||
case OPERATION: return execOperation(instr, frame, ctx);
|
||||
case OPERATION: return execOperation(ctx, instr, frame);
|
||||
|
||||
default: throw EngineException.ofSyntax("Invalid instruction " + instr.type.name() + ".");
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class Module {
|
||||
|
||||
executing = true;
|
||||
var scope = ctx.engine().global().globalChild();
|
||||
scope.define("module", true, this);
|
||||
scope.define(null, "module", true, this);
|
||||
scope.define("exports", new ExportsVariable());
|
||||
|
||||
var parent = new File(filename).getParentFile();
|
||||
|
@ -38,24 +38,24 @@ public class GlobalScope implements ScopeRecord {
|
||||
Thread.currentThread().interrupt();
|
||||
return name;
|
||||
}
|
||||
obj.defineProperty(name, null);
|
||||
obj.defineProperty(null, name, null);
|
||||
return name;
|
||||
}
|
||||
public void define(String name, Variable val) {
|
||||
obj.defineProperty(name,
|
||||
obj.defineProperty(null, name,
|
||||
new NativeFunction("get " + name, (ctx, th, a) -> val.get(ctx)),
|
||||
new NativeFunction("set " + name, (ctx, th, args) -> { val.set(ctx, args.length > 0 ? args[0] : null); return null; }),
|
||||
true, true
|
||||
);
|
||||
}
|
||||
public void define(String name, boolean readonly, Object val) {
|
||||
obj.defineProperty(name, val, readonly, true, true);
|
||||
public void define(CallContext ctx, String name, boolean readonly, Object val) {
|
||||
obj.defineProperty(ctx, name, val, readonly, true, true);
|
||||
}
|
||||
public void define(String... names) {
|
||||
for (var n : names) define(n);
|
||||
}
|
||||
public void define(boolean readonly, FunctionValue val) {
|
||||
define(val.name, readonly, val);
|
||||
define(null, val.name, readonly, val);
|
||||
}
|
||||
|
||||
public Object get(CallContext ctx, String name) throws InterruptedException {
|
||||
|
@ -18,7 +18,7 @@ public class ValueVariable implements Variable {
|
||||
@Override
|
||||
public void set(CallContext ctx, Object val) {
|
||||
if (readonly) return;
|
||||
this.value = Values.normalize(val);
|
||||
this.value = Values.normalize(ctx, val);
|
||||
}
|
||||
|
||||
public ValueVariable(boolean readonly, Object val) {
|
||||
|
@ -29,14 +29,14 @@ public class ArrayValue extends ObjectValue {
|
||||
if (res == EMPTY) return null;
|
||||
else return res;
|
||||
}
|
||||
public void set(int i, Object val) {
|
||||
public void set(CallContext ctx, int i, Object val) {
|
||||
if (i < 0) return;
|
||||
|
||||
while (values.size() <= i) {
|
||||
values.add(EMPTY);
|
||||
}
|
||||
|
||||
values.set(i, Values.normalize(val));
|
||||
values.set(i, Values.normalize(ctx, val));
|
||||
}
|
||||
public boolean has(int i) {
|
||||
return i >= 0 && i < values.size() && values.get(i) != EMPTY;
|
||||
@ -102,7 +102,7 @@ public class ArrayValue extends ObjectValue {
|
||||
if (key instanceof Number) {
|
||||
var i = Values.number(key);
|
||||
if (i >= 0 && i - Math.floor(i) == 0) {
|
||||
set((int)i, val);
|
||||
set(ctx, (int)i, val);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -149,12 +149,12 @@ public class ArrayValue extends ObjectValue {
|
||||
nonEnumerableSet.add("length");
|
||||
nonConfigurableSet.add("length");
|
||||
}
|
||||
public ArrayValue(Object ...values) {
|
||||
public ArrayValue(CallContext ctx, Object ...values) {
|
||||
this();
|
||||
for (var i = 0; i < values.length; i++) this.values.add(values[i]);
|
||||
for (var i = 0; i < values.length; i++) this.values.add(Values.normalize(ctx, values[i]));
|
||||
}
|
||||
|
||||
public static ArrayValue of(Collection<Object> values) {
|
||||
return new ArrayValue(values.toArray(Object[]::new));
|
||||
public static ArrayValue of(CallContext ctx, Collection<Object> values) {
|
||||
return new ArrayValue(ctx, values.toArray(Object[]::new));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class CodeFunction extends FunctionValue {
|
||||
|
||||
@Override
|
||||
public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
return new CodeFrame(thisArg, args, this).run(ctx);
|
||||
return new CodeFrame(ctx, thisArg, args, this).run(ctx);
|
||||
}
|
||||
|
||||
public CodeFunction(String name, int localsN, int length, GlobalScope globals, ValueVariable[] captures, Instruction[] body) {
|
||||
|
@ -63,8 +63,8 @@ public abstract class FunctionValue extends ObjectValue {
|
||||
nonEnumerableSet.add("length");
|
||||
|
||||
var proto = new ObjectValue();
|
||||
proto.defineProperty("constructor", this, true, false, false);
|
||||
this.defineProperty("prototype", proto, true, false, false);
|
||||
proto.defineProperty(null, "constructor", this, true, false, false);
|
||||
this.defineProperty(null, "prototype", proto, true, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,8 @@ public class ObjectValue {
|
||||
state = State.FROZEN;
|
||||
}
|
||||
|
||||
public final boolean defineProperty(Object key, Object val, boolean writable, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(key); val = Values.normalize(val);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, Object val, boolean writable, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
boolean reconfigured =
|
||||
writable != memberWritable(key) ||
|
||||
configurable != memberConfigurable(key) ||
|
||||
@ -118,11 +118,11 @@ public class ObjectValue {
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
public final boolean defineProperty(Object key, Object val) {
|
||||
return defineProperty(Values.normalize(key), Values.normalize(val), true, true, true);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, Object val) {
|
||||
return defineProperty(ctx, key, val, true, true, true);
|
||||
}
|
||||
public final boolean defineProperty(Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(key);
|
||||
public final boolean defineProperty(CallContext ctx, Object key, FunctionValue getter, FunctionValue setter, boolean configurable, boolean enumerable) {
|
||||
key = Values.normalize(ctx, key);
|
||||
if (
|
||||
properties.containsKey(key) &&
|
||||
properties.get(key).getter == getter &&
|
||||
@ -162,7 +162,7 @@ public class ObjectValue {
|
||||
return (ObjectValue)prototype;
|
||||
}
|
||||
public final boolean setPrototype(CallContext ctx, Object val) {
|
||||
val = Values.normalize(val);
|
||||
val = Values.normalize(ctx, val);
|
||||
|
||||
if (!extensible()) return false;
|
||||
if (val == null || val == Values.NULL) prototype = null;
|
||||
@ -228,7 +228,7 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final Object getMember(CallContext ctx, Object key, Object thisArg) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key.equals("__proto__")) {
|
||||
var res = getPrototype(ctx);
|
||||
@ -239,7 +239,7 @@ public class ObjectValue {
|
||||
|
||||
if (prop != null) {
|
||||
if (prop.getter == null) return null;
|
||||
else return prop.getter.call(ctx, Values.normalize(thisArg));
|
||||
else return prop.getter.call(ctx, Values.normalize(ctx, thisArg));
|
||||
}
|
||||
else return getField(ctx, key);
|
||||
}
|
||||
@ -248,12 +248,12 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final boolean setMember(CallContext ctx, Object key, Object val, Object thisArg, boolean onlyProps) throws InterruptedException {
|
||||
key = Values.normalize(key); val = Values.normalize(val);
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
if (prop != null) {
|
||||
if (prop.setter == null) return false;
|
||||
prop.setter.call(ctx, Values.normalize(thisArg), val);
|
||||
prop.setter.call(ctx, Values.normalize(ctx, thisArg), val);
|
||||
return true;
|
||||
}
|
||||
else if (onlyProps) return false;
|
||||
@ -267,11 +267,11 @@ public class ObjectValue {
|
||||
else return setField(ctx, key, val);
|
||||
}
|
||||
public final boolean setMember(CallContext ctx, Object key, Object val, boolean onlyProps) throws InterruptedException {
|
||||
return setMember(ctx, Values.normalize(key), Values.normalize(val), this, onlyProps);
|
||||
return setMember(ctx, Values.normalize(ctx, key), Values.normalize(ctx, val), this, onlyProps);
|
||||
}
|
||||
|
||||
public final boolean hasMember(CallContext ctx, Object key, boolean own) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key != null && key.equals("__proto__")) return true;
|
||||
if (hasField(ctx, key)) return true;
|
||||
@ -280,7 +280,7 @@ public class ObjectValue {
|
||||
return prototype != null && getPrototype(ctx).hasMember(ctx, key, own);
|
||||
}
|
||||
public final boolean deleteMember(CallContext ctx, Object key) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (!memberConfigurable(key)) return false;
|
||||
properties.remove(key);
|
||||
@ -291,21 +291,21 @@ public class ObjectValue {
|
||||
}
|
||||
|
||||
public final ObjectValue getMemberDescriptor(CallContext ctx, Object key) throws InterruptedException {
|
||||
key = Values.normalize(key);
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
var prop = properties.get(key);
|
||||
var res = new ObjectValue();
|
||||
|
||||
res.defineProperty("configurable", memberConfigurable(key));
|
||||
res.defineProperty("enumerable", memberEnumerable(key));
|
||||
res.defineProperty(ctx, "configurable", memberConfigurable(key));
|
||||
res.defineProperty(ctx, "enumerable", memberEnumerable(key));
|
||||
|
||||
if (prop != null) {
|
||||
res.defineProperty("get", prop.getter);
|
||||
res.defineProperty("set", prop.setter);
|
||||
res.defineProperty(ctx, "get", prop.getter);
|
||||
res.defineProperty(ctx, "set", prop.setter);
|
||||
}
|
||||
else if (hasField(ctx, key)) {
|
||||
res.defineProperty("value", values.get(key));
|
||||
res.defineProperty("writable", memberWritable(key));
|
||||
res.defineProperty(ctx, "value", values.get(key));
|
||||
res.defineProperty(ctx, "writable", memberWritable(key));
|
||||
}
|
||||
else return null;
|
||||
return res;
|
||||
@ -326,10 +326,10 @@ public class ObjectValue {
|
||||
return res;
|
||||
}
|
||||
|
||||
public ObjectValue(Map<?, ?> values) {
|
||||
public ObjectValue(CallContext ctx, Map<?, ?> values) {
|
||||
this(PlaceholderProto.OBJECT);
|
||||
for (var el : values.entrySet()) {
|
||||
defineProperty(el.getKey(), el.getValue());
|
||||
defineProperty(ctx, el.getKey(), el.getValue());
|
||||
}
|
||||
}
|
||||
public ObjectValue(PlaceholderProto proto) {
|
||||
|
@ -88,7 +88,7 @@ public class Values {
|
||||
}
|
||||
|
||||
public static Object toPrimitive(CallContext ctx, Object obj, ConvertHint hint) throws InterruptedException {
|
||||
obj = normalize(obj);
|
||||
obj = normalize(ctx, obj);
|
||||
if (isPrimitive(obj)) return obj;
|
||||
|
||||
var first = hint == ConvertHint.VALUEOF ? "valueOf" : "toString";
|
||||
@ -231,8 +231,8 @@ public class Values {
|
||||
case OR: return or(ctx, args[0], args[1]);
|
||||
case XOR: return xor(ctx, args[0], args[1]);
|
||||
|
||||
case EQUALS: return strictEquals(args[0], args[1]);
|
||||
case NOT_EQUALS: return !strictEquals(args[0], args[1]);
|
||||
case EQUALS: return strictEquals(ctx, args[0], args[1]);
|
||||
case NOT_EQUALS: return !strictEquals(ctx, args[0], args[1]);
|
||||
case LOOSE_EQUALS: return looseEqual(ctx, args[0], args[1]);
|
||||
case LOOSE_NOT_EQUALS: return !looseEqual(ctx, args[0], args[1]);
|
||||
|
||||
@ -261,7 +261,7 @@ public class Values {
|
||||
}
|
||||
|
||||
public static Object getMember(CallContext ctx, Object obj, Object key) throws InterruptedException {
|
||||
obj = normalize(obj); key = normalize(key);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined.");
|
||||
if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null.");
|
||||
if (isObject(obj)) return object(obj).getMember(ctx, key);
|
||||
@ -281,7 +281,7 @@ public class Values {
|
||||
else return proto.getMember(ctx, key, obj);
|
||||
}
|
||||
public static boolean setMember(CallContext ctx, Object obj, Object key, Object val) throws InterruptedException {
|
||||
obj = normalize(obj); key = normalize(key); val = normalize(val);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key); val = normalize(ctx, val);
|
||||
if (obj == null) throw EngineException.ofType("Tried to access member of undefined.");
|
||||
if (obj == NULL) throw EngineException.ofType("Tried to access member of null.");
|
||||
if (key.equals("__proto__")) return setPrototype(ctx, obj, val);
|
||||
@ -292,7 +292,7 @@ public class Values {
|
||||
}
|
||||
public static boolean hasMember(CallContext ctx, Object obj, Object key, boolean own) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return false;
|
||||
obj = normalize(obj); key = normalize(key);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
|
||||
if (key.equals("__proto__")) return true;
|
||||
if (isObject(obj)) return object(obj).hasMember(ctx, key, own);
|
||||
@ -310,14 +310,14 @@ public class Values {
|
||||
}
|
||||
public static boolean deleteMember(CallContext ctx, Object obj, Object key) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return false;
|
||||
obj = normalize(obj); key = normalize(key);
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
|
||||
if (isObject(obj)) return object(obj).deleteMember(ctx, key);
|
||||
else return false;
|
||||
}
|
||||
public static ObjectValue getPrototype(CallContext ctx, Object obj) throws InterruptedException {
|
||||
if (obj == null || obj == NULL) return null;
|
||||
obj = normalize(obj);
|
||||
obj = normalize(ctx, obj);
|
||||
if (isObject(obj)) return object(obj).getPrototype(ctx);
|
||||
if (ctx == null) return null;
|
||||
|
||||
@ -329,7 +329,7 @@ public class Values {
|
||||
return null;
|
||||
}
|
||||
public static boolean setPrototype(CallContext ctx, Object obj, Object proto) throws InterruptedException {
|
||||
obj = normalize(obj); proto = normalize(proto);
|
||||
obj = normalize(ctx, obj); proto = normalize(ctx, proto);
|
||||
return isObject(obj) && object(obj).setPrototype(ctx, proto);
|
||||
}
|
||||
public static List<Object> getMembers(CallContext ctx, Object obj, boolean own, boolean includeNonEnumerable) throws InterruptedException {
|
||||
@ -359,8 +359,8 @@ public class Values {
|
||||
return function(func).call(ctx, thisArg, args);
|
||||
}
|
||||
|
||||
public static boolean strictEquals(Object a, Object b) {
|
||||
a = normalize(a); b = normalize(b);
|
||||
public static boolean strictEquals(CallContext ctx, Object a, Object b) {
|
||||
a = normalize(ctx, a); b = normalize(ctx, b);
|
||||
|
||||
if (a == null || b == null) return a == null && b == null;
|
||||
if (isNan(a) || isNan(b)) return false;
|
||||
@ -370,7 +370,7 @@ public class Values {
|
||||
return a == b || a.equals(b);
|
||||
}
|
||||
public static boolean looseEqual(CallContext ctx, Object a, Object b) throws InterruptedException {
|
||||
a = normalize(a); b = normalize(b);
|
||||
a = normalize(ctx, a); b = normalize(ctx, b);
|
||||
|
||||
// In loose equality, null is equivalent to undefined
|
||||
if (a == NULL) a = null;
|
||||
@ -387,13 +387,13 @@ public class Values {
|
||||
// Compare symbols by reference
|
||||
if (a instanceof Symbol || b instanceof Symbol) return a == b;
|
||||
if (a instanceof Boolean || b instanceof Boolean) return toBoolean(a) == toBoolean(b);
|
||||
if (a instanceof Number || b instanceof Number) return strictEquals(toNumber(ctx, a), toNumber(ctx, b));
|
||||
if (a instanceof Number || b instanceof Number) return strictEquals(ctx, toNumber(ctx, a), toNumber(ctx, b));
|
||||
|
||||
// Default to strings
|
||||
return toString(ctx, a).equals(toString(ctx, b));
|
||||
}
|
||||
|
||||
public static Object normalize(Object val) {
|
||||
public static Object normalize(CallContext ctx, Object val) {
|
||||
if (val instanceof Number) return number(val);
|
||||
if (isPrimitive(val) || val instanceof ObjectValue) return val;
|
||||
if (val instanceof Character) return val + "";
|
||||
@ -402,7 +402,7 @@ public class Values {
|
||||
var res = new ObjectValue();
|
||||
|
||||
for (var entry : ((Map<?, ?>)val).entrySet()) {
|
||||
res.defineProperty(entry.getKey(), entry.getValue());
|
||||
res.defineProperty(ctx, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -412,12 +412,17 @@ public class Values {
|
||||
var res = new ArrayValue();
|
||||
|
||||
for (var entry : ((Iterable<?>)val)) {
|
||||
res.set(res.size(), entry);
|
||||
res.set(ctx, res.size(), entry);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (val instanceof Class) {
|
||||
if (ctx == null) return null;
|
||||
else return ctx.engine.getConstructor((Class<?>)val);
|
||||
}
|
||||
|
||||
return new NativeWrapper(val);
|
||||
}
|
||||
|
||||
@ -562,14 +567,14 @@ public class Values {
|
||||
var it = iterable.iterator();
|
||||
|
||||
try {
|
||||
var key = getMember(ctx, getMember(ctx, ctx.engine().symbolProto(), "constructor"), "iterable");
|
||||
res.defineProperty(key, new NativeFunction("", (_ctx, thisArg, args) -> fromJavaIterable(ctx, iterable)));
|
||||
var key = getMember(ctx, getMember(ctx, ctx.engine().symbolProto(), "constructor"), "iterator");
|
||||
res.defineProperty(ctx, key, new NativeFunction("", (_ctx, thisArg, args) -> thisArg));
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException e) { }
|
||||
|
||||
res.defineProperty("next", new NativeFunction("", (_ctx, _th, _args) -> {
|
||||
if (!it.hasNext()) return new ObjectValue(Map.of("done", true));
|
||||
else return new ObjectValue(Map.of("value", it.next()));
|
||||
res.defineProperty(ctx, "next", new NativeFunction("", (_ctx, _th, _args) -> {
|
||||
if (!it.hasNext()) return new ObjectValue(ctx, Map.of("done", true));
|
||||
else return new ObjectValue(ctx, Map.of("value", it.next()));
|
||||
}));
|
||||
|
||||
return res;
|
||||
|
@ -41,7 +41,7 @@ public class EngineException extends RuntimeException {
|
||||
|
||||
private static Object err(String msg, PlaceholderProto proto) {
|
||||
var res = new ObjectValue(proto);
|
||||
res.defineProperty("message", msg);
|
||||
res.defineProperty(null, "message", msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class NativeTypeRegister {
|
||||
var val = target.values.get(name);
|
||||
|
||||
if (name.equals("")) name = method.getName();
|
||||
if (!(val instanceof OverloadFunction)) target.defineProperty(name, val = new OverloadFunction(name));
|
||||
if (!(val instanceof OverloadFunction)) target.defineProperty(null, name, val = new OverloadFunction(name));
|
||||
|
||||
((OverloadFunction)val).overloads.add(Overload.fromMethod(method));
|
||||
}
|
||||
@ -40,7 +40,7 @@ public class NativeTypeRegister {
|
||||
else getter = new OverloadFunction("get " + name);
|
||||
|
||||
getter.overloads.add(Overload.fromMethod(method));
|
||||
target.defineProperty(name, getter, setter, true, true);
|
||||
target.defineProperty(null, name, getter, setter, true, true);
|
||||
}
|
||||
if (set != null) {
|
||||
var name = set.value();
|
||||
@ -52,7 +52,7 @@ public class NativeTypeRegister {
|
||||
else setter = new OverloadFunction("set " + name);
|
||||
|
||||
setter.overloads.add(Overload.fromMethod(method));
|
||||
target.defineProperty(name, getter, setter, true, true);
|
||||
target.defineProperty(null, name, getter, setter, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,7 +67,7 @@ public class NativeTypeRegister {
|
||||
if (name.equals("")) name = field.getName();
|
||||
var getter = new OverloadFunction("get " + name).add(Overload.getterFromField(field));
|
||||
var setter = new OverloadFunction("set " + name).add(Overload.setterFromField(field));
|
||||
target.defineProperty(name, getter, setter, true, false);
|
||||
target.defineProperty(null, name, getter, setter, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,7 +84,7 @@ public class NativeTypeRegister {
|
||||
return ctx.engine().typeRegister().getConstr(cl);
|
||||
}));
|
||||
|
||||
target.defineProperty(name, getter, null, true, false);
|
||||
target.defineProperty(null, name, getter, null, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class OverloadFunction extends FunctionValue {
|
||||
Object _this = overload.thisArg == null ? null : Values.convert(ctx, thisArg, overload.thisArg);
|
||||
|
||||
try {
|
||||
return Values.normalize(overload.runner.run(ctx, _this, newArgs));
|
||||
return Values.normalize(ctx, overload.runner.run(ctx, _this, newArgs));
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw EngineException.ofError("The class may not be instantiated.");
|
||||
|
@ -22,13 +22,13 @@ public class GeneratorFunction extends FunctionValue {
|
||||
if (done) {
|
||||
if (inducedError != Runners.NO_RETURN) throw new EngineException(inducedError);
|
||||
var res = new ObjectValue();
|
||||
res.defineProperty("done", true);
|
||||
res.defineProperty("value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn);
|
||||
res.defineProperty(ctx, "done", true);
|
||||
res.defineProperty(ctx, "value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn);
|
||||
return res;
|
||||
}
|
||||
|
||||
Object res = null;
|
||||
if (inducedValue != Runners.NO_RETURN) frame.push(inducedValue);
|
||||
if (inducedValue != Runners.NO_RETURN) frame.push(ctx, inducedValue);
|
||||
frame.start(ctx);
|
||||
yielding = false;
|
||||
while (!yielding) {
|
||||
@ -51,8 +51,8 @@ public class GeneratorFunction extends FunctionValue {
|
||||
else res = frame.pop();
|
||||
|
||||
var obj = new ObjectValue();
|
||||
obj.defineProperty("done", done);
|
||||
obj.defineProperty("value", res);
|
||||
obj.defineProperty(ctx, "done", done);
|
||||
obj.defineProperty(ctx, "value", res);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -84,11 +84,11 @@ public class GeneratorFunction extends FunctionValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(CallContext _ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
public Object call(CallContext ctx, Object thisArg, Object... args) throws InterruptedException {
|
||||
var handler = new Generator();
|
||||
var func = factory.call(_ctx, thisArg, new NativeFunction("yield", handler::yield));
|
||||
var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield));
|
||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||
handler.frame = new CodeFrame(thisArg, args, (CodeFunction)func);
|
||||
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,12 @@ public class Internals {
|
||||
return func.call(ctx, th, args.toArray());
|
||||
}
|
||||
@Native
|
||||
public boolean defineProp(ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(key, getter, setter, configurable, enumerable);
|
||||
public boolean defineProp(CallContext ctx, ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(ctx, key, getter, setter, configurable, enumerable);
|
||||
}
|
||||
@Native
|
||||
public boolean defineField(ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(key, val, writable, configurable, enumerable);
|
||||
public boolean defineField(CallContext ctx, ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) {
|
||||
return obj.defineProperty(ctx, key, val, writable, configurable, enumerable);
|
||||
}
|
||||
|
||||
@Native
|
||||
@ -209,7 +209,7 @@ public class Internals {
|
||||
|
||||
for (var el : list) {
|
||||
if (el instanceof Symbol && onlyString) continue;
|
||||
res.set(i++, el);
|
||||
res.set(ctx, i++, el);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -223,7 +223,7 @@ public class Internals {
|
||||
var list = Values.object(obj).keys(true);
|
||||
|
||||
for (var el : list) {
|
||||
if (el instanceof Symbol == symbols) res.set(i++, el);
|
||||
if (el instanceof Symbol == symbols) res.set(ctx, i++, el);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,11 @@ public class JSON {
|
||||
if (val.isBoolean()) return val.bool();
|
||||
if (val.isString()) return val.string();
|
||||
if (val.isNumber()) return val.number();
|
||||
if (val.isList()) return ArrayValue.of(val.list().stream().map(JSON::toJS).collect(Collectors.toList()));
|
||||
if (val.isList()) return ArrayValue.of(null, val.list().stream().map(JSON::toJS).collect(Collectors.toList()));
|
||||
if (val.isMap()) {
|
||||
var res = new ObjectValue();
|
||||
for (var el : val.map().entrySet()) {
|
||||
res.defineProperty(el.getKey(), toJS(el.getValue()));
|
||||
res.defineProperty(null, el.getKey(), toJS(el.getValue()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class Map {
|
||||
return Values.fromJavaIterable(ctx, objs
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(v -> new ArrayValue(v.getKey(), v.getValue()))
|
||||
.map(v -> new ArrayValue(ctx, v.getKey(), v.getValue()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
@ -8,10 +8,6 @@ import java.io.InputStreamReader;
|
||||
|
||||
import me.topchetoeu.jscript.engine.Engine;
|
||||
import me.topchetoeu.jscript.engine.modules.ModuleManager;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.parsing.Parsing;
|
||||
|
||||
public class PolyfillEngine extends Engine {
|
||||
public static String streamToString(InputStream in) {
|
||||
@ -52,59 +48,58 @@ public class PolyfillEngine extends Engine {
|
||||
|
||||
this.modules = new ModuleManager(root);
|
||||
|
||||
exposeNamespace("Math", Math.class);
|
||||
exposeNamespace("JSON", JSON.class);
|
||||
exposeClass("Promise", Promise.class);
|
||||
exposeClass("RegExp", RegExp.class);
|
||||
exposeClass("Date", Date.class);
|
||||
exposeClass("Map", Map.class);
|
||||
exposeClass("Set", Set.class);
|
||||
// exposeNamespace("Math", Math.class);
|
||||
// exposeNamespace("JSON", JSON.class);
|
||||
// exposeClass("Promise", Promise.class);
|
||||
// exposeClass("RegExp", RegExp.class);
|
||||
// exposeClass("Date", Date.class);
|
||||
// exposeClass("Map", Map.class);
|
||||
// exposeClass("Set", Set.class);
|
||||
|
||||
global().define("Object", "Function", "String", "Number", "Boolean", "Symbol");
|
||||
global().define("Array", "require");
|
||||
global().define("Error", "SyntaxError", "TypeError", "RangeError");
|
||||
global().define("setTimeout", "setInterval", "clearTimeout", "clearInterval");
|
||||
// global().define("process", true, "trololo");
|
||||
global().define("debugger");
|
||||
// global().define("Object", "Function", "String", "Number", "Boolean", "Symbol");
|
||||
// global().define("Array", "require");
|
||||
// global().define("Error", "SyntaxError", "TypeError", "RangeError");
|
||||
// global().define("setTimeout", "setInterval", "clearTimeout", "clearInterval");
|
||||
// global().define("debugger");
|
||||
|
||||
global().define(true, new NativeFunction("measure", (ctx, thisArg, values) -> {
|
||||
var start = System.nanoTime();
|
||||
try {
|
||||
return Values.call(ctx, values[0], ctx);
|
||||
}
|
||||
finally {
|
||||
System.out.println(String.format("Function took %s ms", (System.nanoTime() - start) / 1000000.));
|
||||
}
|
||||
}));
|
||||
global().define(true, new NativeFunction("isNaN", (ctx, thisArg, args) -> {
|
||||
if (args.length == 0) return true;
|
||||
else return Double.isNaN(Values.toNumber(ctx, args[0]));
|
||||
}));
|
||||
global().define(true, new NativeFunction("log", (el, t, args) -> {
|
||||
for (var obj : args) Values.printValue(el, obj);
|
||||
System.out.println();
|
||||
return null;
|
||||
}));
|
||||
// global().define(true, new NativeFunction("measure", (ctx, thisArg, values) -> {
|
||||
// var start = System.nanoTime();
|
||||
// try {
|
||||
// return Values.call(ctx, values[0], ctx);
|
||||
// }
|
||||
// finally {
|
||||
// System.out.println(String.format("Function took %s ms", (System.nanoTime() - start) / 1000000.));
|
||||
// }
|
||||
// }));
|
||||
// global().define(true, new NativeFunction("isNaN", (ctx, thisArg, args) -> {
|
||||
// if (args.length == 0) return true;
|
||||
// else return Double.isNaN(Values.toNumber(ctx, args[0]));
|
||||
// }));
|
||||
// global().define(true, new NativeFunction("log", (el, t, args) -> {
|
||||
// for (var obj : args) Values.printValue(el, obj);
|
||||
// System.out.println();
|
||||
// return null;
|
||||
// }));
|
||||
|
||||
var scope = global().globalChild();
|
||||
scope.define("gt", true, global().obj);
|
||||
scope.define("lgt", true, scope.obj);
|
||||
scope.define("setProps", "setConstr");
|
||||
scope.define("internals", true, new Internals());
|
||||
scope.define(true, new NativeFunction("run", (ctx, thisArg, args) -> {
|
||||
var filename = (String)args[0];
|
||||
boolean pollute = args.length > 1 && args[1].equals(true);
|
||||
FunctionValue func;
|
||||
var src = resourceToString("js/" + filename);
|
||||
if (src == null) throw new RuntimeException("The source '" + filename + "' doesn't exist.");
|
||||
// var scope = global().globalChild();
|
||||
// scope.define("gt", true, global().obj);
|
||||
// scope.define("lgt", true, scope.obj);
|
||||
// scope.define("setProps", "setConstr");
|
||||
// scope.define("internals", true, new Internals());
|
||||
// scope.define(true, new NativeFunction("run", (ctx, thisArg, args) -> {
|
||||
// var filename = (String)args[0];
|
||||
// boolean pollute = args.length > 1 && args[1].equals(true);
|
||||
// FunctionValue func;
|
||||
// var src = resourceToString("js/" + filename);
|
||||
// if (src == null) throw new RuntimeException("The source '" + filename + "' doesn't exist.");
|
||||
|
||||
if (pollute) func = Parsing.compile(global(), filename, src);
|
||||
else func = Parsing.compile(scope.globalChild(), filename, src);
|
||||
// if (pollute) func = Parsing.compile(global(), filename, src);
|
||||
// else func = Parsing.compile(scope.globalChild(), filename, src);
|
||||
|
||||
func.call(ctx);
|
||||
return null;
|
||||
}));
|
||||
// func.call(ctx);
|
||||
// return null;
|
||||
// }));
|
||||
|
||||
pushMsg(false, scope.globalChild(), java.util.Map.of(), "core.js", resourceToString("js/core.js"), null);
|
||||
// pushMsg(false, scope.globalChild(), java.util.Map.of(), "core.js", resourceToString("js/core.js"), null);
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native("resolve")
|
||||
public static Promise ofResolved(CallContext engine, Object val) {
|
||||
public static Promise ofResolved(CallContext ctx, Object val) {
|
||||
if (Values.isWrapper(val, Promise.class)) return Values.wrapper(val, Promise.class);
|
||||
var res = new Promise();
|
||||
res.fulfill(engine, val);
|
||||
res.fulfill(ctx, val);
|
||||
return res;
|
||||
}
|
||||
public static Promise ofResolved(Object val) {
|
||||
@ -41,9 +41,9 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native("reject")
|
||||
public static Promise ofRejected(CallContext engine, Object val) {
|
||||
public static Promise ofRejected(CallContext ctx, Object val) {
|
||||
var res = new Promise();
|
||||
res.reject(engine, val);
|
||||
res.reject(ctx, val);
|
||||
return res;
|
||||
}
|
||||
public static Promise ofRejected(Object val) {
|
||||
@ -53,7 +53,7 @@ public class Promise {
|
||||
}
|
||||
|
||||
@Native
|
||||
public static Promise any(CallContext engine, Object _promises) {
|
||||
public static Promise any(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@ -66,17 +66,17 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
errors.set(index, args[0]);
|
||||
errors.set(ctx, index, args[0]);
|
||||
n[0]--;
|
||||
if (n[0] <= 0) res.reject(e, errors);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
else {
|
||||
res.fulfill(engine, val);
|
||||
res.fulfill(ctx, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -84,7 +84,7 @@ public class Promise {
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise race(CallContext engine, Object _promises) {
|
||||
public static Promise race(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@ -93,7 +93,7 @@ public class Promise {
|
||||
for (var i = 0; i < promises.size(); i++) {
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
|
||||
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
|
||||
);
|
||||
@ -106,7 +106,7 @@ public class Promise {
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise all(CallContext engine, Object _promises) {
|
||||
public static Promise all(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@ -119,9 +119,9 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, args[0]);
|
||||
result.set(ctx, index, args[0]);
|
||||
n[0]--;
|
||||
if (n[0] <= 0) res.fulfill(e, result);
|
||||
return null;
|
||||
@ -129,17 +129,17 @@ public class Promise {
|
||||
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
|
||||
);
|
||||
else {
|
||||
result.set(i, val);
|
||||
result.set(ctx, i, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n[0] <= 0) res.fulfill(engine, result);
|
||||
if (n[0] <= 0) res.fulfill(ctx, result);
|
||||
|
||||
return res;
|
||||
}
|
||||
@Native
|
||||
public static Promise allSettled(CallContext engine, Object _promises) {
|
||||
public static Promise allSettled(CallContext ctx, Object _promises) {
|
||||
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
|
||||
var promises = Values.array(_promises);
|
||||
if (promises.size() == 0) return ofResolved(new ArrayValue());
|
||||
@ -152,9 +152,9 @@ public class Promise {
|
||||
var index = i;
|
||||
var val = promises.get(i);
|
||||
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
|
||||
engine,
|
||||
ctx,
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, new ObjectValue(Map.of(
|
||||
result.set(ctx, index, new ObjectValue(ctx, Map.of(
|
||||
"status", "fulfilled",
|
||||
"value", args[0]
|
||||
)));
|
||||
@ -163,7 +163,7 @@ public class Promise {
|
||||
return null;
|
||||
}),
|
||||
new NativeFunction(null, (e, th, args) -> {
|
||||
result.set(index, new ObjectValue(Map.of(
|
||||
result.set(ctx, index, new ObjectValue(ctx, Map.of(
|
||||
"status", "rejected",
|
||||
"reason", args[0]
|
||||
)));
|
||||
@ -173,7 +173,7 @@ public class Promise {
|
||||
})
|
||||
);
|
||||
else {
|
||||
result.set(i, new ObjectValue(Map.of(
|
||||
result.set(ctx, i, new ObjectValue(ctx, Map.of(
|
||||
"status", "fulfilled",
|
||||
"value", val
|
||||
)));
|
||||
@ -181,7 +181,7 @@ public class Promise {
|
||||
}
|
||||
}
|
||||
|
||||
if (n[0] <= 0) res.fulfill(engine, result);
|
||||
if (n[0] <= 0) res.fulfill(ctx, result);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ public class RegExp {
|
||||
|
||||
for (var el : namedGroups) {
|
||||
try {
|
||||
groups.defineProperty(el, matcher.group(el));
|
||||
groups.defineProperty(null, el, matcher.group(el));
|
||||
}
|
||||
catch (IllegalArgumentException e) { }
|
||||
}
|
||||
@ -127,23 +127,23 @@ public class RegExp {
|
||||
|
||||
|
||||
for (int i = 0; i < matcher.groupCount() + 1; i++) {
|
||||
obj.set(i, matcher.group(i));
|
||||
obj.set(null, i, matcher.group(i));
|
||||
}
|
||||
obj.defineProperty("groups", groups);
|
||||
obj.defineProperty("index", matcher.start());
|
||||
obj.defineProperty("input", str);
|
||||
obj.defineProperty(null, "groups", groups);
|
||||
obj.defineProperty(null, "index", matcher.start());
|
||||
obj.defineProperty(null, "input", str);
|
||||
|
||||
if (hasIndices) {
|
||||
var indices = new ArrayValue();
|
||||
for (int i = 0; i < matcher.groupCount() + 1; i++) {
|
||||
indices.set(i, new ArrayValue(matcher.start(i), matcher.end(i)));
|
||||
indices.set(null, i, new ArrayValue(null, matcher.start(i), matcher.end(i)));
|
||||
}
|
||||
var groupIndices = new ObjectValue();
|
||||
for (var el : namedGroups) {
|
||||
groupIndices.defineProperty(el, new ArrayValue(matcher.start(el), matcher.end(el)));
|
||||
groupIndices.defineProperty(null, el, new ArrayValue(null, matcher.start(el), matcher.end(el)));
|
||||
}
|
||||
indices.defineProperty("groups", groupIndices);
|
||||
obj.defineProperty("indices", indices);
|
||||
indices.defineProperty(null, "groups", groupIndices);
|
||||
obj.defineProperty(null, "indices", indices);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -6,7 +6,6 @@ import java.util.stream.Collectors;
|
||||
import me.topchetoeu.jscript.engine.CallContext;
|
||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
@ -44,55 +43,20 @@ public class Set {
|
||||
}
|
||||
|
||||
@Native
|
||||
public ObjectValue entries() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", new ArrayValue(val, val),
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue entries(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs
|
||||
.stream()
|
||||
.map(v -> new ArrayValue(ctx, v, v))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
@Native
|
||||
public ObjectValue keys() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", val,
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue keys(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs);
|
||||
}
|
||||
@Native
|
||||
public ObjectValue values() {
|
||||
var it = objs.stream().collect(Collectors.toList()).iterator();
|
||||
|
||||
var next = new NativeFunction("next", (ctx, thisArg, args) -> {
|
||||
if (it.hasNext()) {
|
||||
var val = it.next();
|
||||
return new ObjectValue(java.util.Map.of(
|
||||
"value", val,
|
||||
"done", false
|
||||
));
|
||||
}
|
||||
else return new ObjectValue(java.util.Map.of("done", true));
|
||||
});
|
||||
|
||||
return new ObjectValue(java.util.Map.of("next", next));
|
||||
public ObjectValue values(CallContext ctx) throws InterruptedException {
|
||||
return Values.fromJavaIterable(ctx, objs);
|
||||
}
|
||||
|
||||
@NativeGetter("size")
|
||||
|
@ -1,12 +1,29 @@
|
||||
{
|
||||
"include": [ "lib/**/*.ts" ],
|
||||
"files": [
|
||||
"lib/lib.d.ts",
|
||||
"lib/modules.ts",
|
||||
"lib/utils.ts",
|
||||
"lib/values/object.ts",
|
||||
"lib/values/symbol.ts",
|
||||
"lib/values/function.ts",
|
||||
"lib/values/errors.ts",
|
||||
"lib/values/string.ts",
|
||||
"lib/values/number.ts",
|
||||
"lib/values/boolean.ts",
|
||||
"lib/values/array.ts",
|
||||
"lib/promise.ts",
|
||||
"lib/map.ts",
|
||||
"lib/set.ts",
|
||||
"lib/regex.ts",
|
||||
"lib/core.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"outDir": "bin/me/topchetoeu/jscript/js",
|
||||
"declarationDir": "bin/me/topchetoeu/jscript/dts",
|
||||
"outFile": "bin/me/topchetoeu/jscript/js/core.js",
|
||||
// "declarationDir": "",
|
||||
// "declarationDir": "bin/me/topchetoeu/jscript/dts",
|
||||
"target": "ES5",
|
||||
"lib": [],
|
||||
"module": "CommonJS",
|
||||
"declaration": true,
|
||||
"module": "None",
|
||||
"stripInternal": true,
|
||||
"downlevelIteration": true,
|
||||
"esModuleInterop": true,
|
||||
|
Loading…
Reference in New Issue
Block a user