add more functions in stdlib, fix some issues
This commit is contained in:
parent
f80266618c
commit
398d88c0a5
@ -1,10 +1,11 @@
|
||||
import { Error } from "./errors.ts";
|
||||
import { func, object, string } from "./primordials.ts";
|
||||
import { String } from "./string.ts";
|
||||
import { limitI, symbols, wrapI } from "./utils.ts";
|
||||
|
||||
export const Array = (() => {
|
||||
class Array {
|
||||
public forEach(this: any[], cb: (val: any, i: number, self: this[]) => void, self?: any) {
|
||||
public forEach(this: any[], cb: (val: any, i: number, self: this) => void, self?: any) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (i in this) func.invoke(cb, self, [this[i], i, this]);
|
||||
}
|
||||
@ -98,7 +99,7 @@ export const Array = (() => {
|
||||
const res: any[] = [];
|
||||
res.length = end - start;
|
||||
|
||||
for (let i = start; i < end; i++) {
|
||||
for (let i = 0; i < end - start; i++) {
|
||||
res[i] = this[start + i];
|
||||
}
|
||||
|
||||
@ -163,6 +164,13 @@ export const Array = (() => {
|
||||
|
||||
return false;
|
||||
}
|
||||
public every(this: any[], cb: Function, self?: any) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (i in this && !func.invoke(cb, self, [this[i], i, this])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public find(this: any[], cb: Function, self?: any) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (i in this && func.invoke(cb, self, [this[i], i, this])) return this[i];
|
||||
@ -170,6 +178,25 @@ export const Array = (() => {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
public indexOf(this: any[], val: any, start = 0) {
|
||||
start |= 0;
|
||||
if (start < 0) start = 0;
|
||||
for (let i = start; i < this.length; i++) {
|
||||
if (i in this && this[i] === val) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
public lastIndexOf(this: any[], val: any, start = 0) {
|
||||
start |= 0;
|
||||
if (start < 0) start = 0;
|
||||
|
||||
for (let i = this.length - 1; i >= start; i--) {
|
||||
if (i in this && this[i] === val) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public sort(this: any[], cb?: Function) {
|
||||
cb ||= (a: any, b: any) => {
|
||||
|
@ -42,7 +42,7 @@ export const Function = (() => {
|
||||
};
|
||||
}
|
||||
|
||||
public constructor (...args: string[]) {
|
||||
public constructor () {
|
||||
const parts = ["(function anonymous("];
|
||||
for (let i = 0; i < arguments.length - 1; i++) {
|
||||
if (i > 0) parts[parts.length] = ",";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Array } from "./array.ts";
|
||||
import { func, map, object, symbol } from "./primordials.ts";
|
||||
import { func, map, symbol } from "./primordials.ts";
|
||||
import { symbols } from "./utils.ts";
|
||||
|
||||
const mapKey: unique symbol = symbol.makeSymbol("Map.impl") as any;
|
||||
|
@ -41,6 +41,16 @@ method("floor", function floor(val: number) {
|
||||
|
||||
return val - rem;
|
||||
});
|
||||
method("ceil", function floor(val: number) {
|
||||
val = val - 0;
|
||||
if (number.isNaN(val)) return number.NaN;
|
||||
|
||||
let rem = val % 1;
|
||||
if (rem === 0) return val;
|
||||
if (rem < 0) rem += 1;
|
||||
|
||||
return val + (1 - rem);
|
||||
});
|
||||
|
||||
method("pow", function pow(a: number, b: number) {
|
||||
return number.pow(a, b);
|
||||
|
@ -23,7 +23,7 @@ export const Number = (() => {
|
||||
public static isFinite(value: number) {
|
||||
value = unwrapThis(value, "number", Number, "Number.isFinite", "value");
|
||||
if (value === undefined || value !== value) return false;
|
||||
if (value === Infinity || value === -Infinity) return false;
|
||||
if (value === number.Infinity || value === -number.Infinity) return false;
|
||||
return true;
|
||||
}
|
||||
public static isInteger(value: number) {
|
||||
@ -51,14 +51,14 @@ export const Number = (() => {
|
||||
else return number.parseInt(value + "", radix);
|
||||
}
|
||||
|
||||
public static readonly EPSILON: number;
|
||||
public static readonly MIN_SAFE_INTEGER: number;
|
||||
public static readonly MAX_SAFE_INTEGER: number;
|
||||
public static readonly POSITIVE_INFINITY: number;
|
||||
public static readonly NEGATIVE_INFINITY: number;
|
||||
public static readonly NaN: number;
|
||||
public static readonly MAX_VALUE: number;
|
||||
public static readonly MIN_VALUE: number;
|
||||
declare public static readonly EPSILON: number;
|
||||
declare public static readonly MIN_SAFE_INTEGER: number;
|
||||
declare public static readonly MAX_SAFE_INTEGER: number;
|
||||
declare public static readonly POSITIVE_INFINITY: number;
|
||||
declare public static readonly NEGATIVE_INFINITY: number;
|
||||
declare public static readonly NaN: number;
|
||||
declare public static readonly MAX_VALUE: number;
|
||||
declare public static readonly MIN_VALUE: number;
|
||||
}
|
||||
|
||||
object.defineField(Number, "EPSILON", { c: false, e: false, w: false, v: 2.220446049250313e-16 });
|
||||
|
@ -12,7 +12,7 @@ export const Object = (() => {
|
||||
if (this === undefined) return "[object Undefined]";
|
||||
else if (this === null) return "[object Null]";
|
||||
else if (typeof this === "object") {
|
||||
if (symbols.toStringTag in this) return "[object " + this[symbols.toStringTag] + "]";
|
||||
if (symbols.toStringTag in this) return "[object " + (this as any)[symbols.toStringTag] + "]";
|
||||
else return "[object Object]";
|
||||
}
|
||||
else if (typeof this === "number" || this instanceof Object) return "[object Object]";
|
||||
@ -84,8 +84,8 @@ export const Object = (() => {
|
||||
return obj;
|
||||
}
|
||||
public static defineProperties(obj: object, desc: PropertyDescriptorMap) {
|
||||
const keys = object.getOwnMembers(desc, false);
|
||||
const symbols = object.getOwnSymbolMembers(desc, false);
|
||||
const keys = object.getOwnMembers(desc, false) as ((keyof typeof obj) & string)[];
|
||||
const symbols = object.getOwnSymbolMembers(desc, false) as ((keyof typeof obj) & symbol)[];
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
Object.defineProperty(obj, keys[i], desc[keys[i]]);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { func, regex, symbol } from "./primordials.ts";
|
||||
import { String } from "./string.ts";
|
||||
import { ReplaceRange } from "./utils.ts";
|
||||
import { type ReplaceRange } from "./utils.ts";
|
||||
import { applyReplaces } from "./utils.ts";
|
||||
import { applySplits } from "./utils.ts";
|
||||
import { symbols } from "./utils.ts";
|
||||
@ -8,22 +8,24 @@ import { symbols } from "./utils.ts";
|
||||
const regexKey: unique symbol = symbol.makeSymbol("RegExp.impl") as any;
|
||||
|
||||
export class RegExp {
|
||||
private [regexKey]: InstanceType<typeof regex>;
|
||||
private [regexKey]!: InstanceType<typeof regex>;
|
||||
|
||||
public readonly source: string;
|
||||
public readonly flags: string;
|
||||
public readonly source!: string;
|
||||
public readonly flags!: string;
|
||||
public lastIndex = 0;
|
||||
|
||||
public readonly indices: boolean;
|
||||
public readonly global: boolean;
|
||||
public readonly ignoreCase: boolean;
|
||||
public readonly multiline: boolean;
|
||||
public readonly dotall: boolean;
|
||||
public readonly unicode: boolean;
|
||||
public readonly unicodeSets: boolean;
|
||||
public readonly sticky: boolean;
|
||||
public readonly indices!: boolean;
|
||||
public readonly global!: boolean;
|
||||
public readonly ignoreCase!: boolean;
|
||||
public readonly multiline!: boolean;
|
||||
public readonly dotall!: boolean;
|
||||
public readonly unicode!: boolean;
|
||||
public readonly unicodeSets!: boolean;
|
||||
public readonly sticky!: boolean;
|
||||
|
||||
public constructor(source: any, flags = "") {
|
||||
if (func.invokeType(arguments, this) === "call") return new RegExp(source, flags);
|
||||
|
||||
public constructor(source: any, flags: string) {
|
||||
source = this.source = String(typeof source === "object" && "source" in source ? source.source : source);
|
||||
flags = String(flags);
|
||||
|
||||
@ -134,4 +136,3 @@ export class RegExp {
|
||||
return applyReplaces(target, matches, replacer, regex.groupCount() + 1);
|
||||
}
|
||||
}
|
||||
func.setCallable(RegExp, false);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { TypeError } from "./errors.ts";
|
||||
import { func, number, regex, string } from "./primordials.ts";
|
||||
import { RegExp } from "./regex.ts";
|
||||
import { applyReplaces, applySplits, limitI, ReplaceRange, symbols, unwrapThis, valueKey, wrapI } from "./utils.ts";
|
||||
import { applyReplaces, applySplits, limitI, type ReplaceRange, symbols, unwrapThis, valueKey, wrapI } from "./utils.ts";
|
||||
|
||||
const trimStartRegex = new regex("^\\s+", false, false, false, false, false);
|
||||
const trimEndRegex = new regex("\\s+$", false, false, false, false, false);
|
||||
@ -12,7 +13,7 @@ export const String = (() => {
|
||||
public at(index: number) {
|
||||
throw "Not implemented :/";
|
||||
return unwrapThis(this, "string", String, "String.prototype.at")[index];
|
||||
};
|
||||
}
|
||||
public toString() {
|
||||
return unwrapThis(this, "string", String, "String.prototype.toString");
|
||||
}
|
||||
@ -24,6 +25,16 @@ export const String = (() => {
|
||||
const self = unwrapThis(this, "string", String, "String.prototype.indexOf");
|
||||
return string.indexOf(self, (String as any)(search), +offset, false) >= 0;
|
||||
}
|
||||
public startsWith(search: string) {
|
||||
const self = unwrapThis(this, "string", String, "String.prototype.indexOf");
|
||||
if (self.length < search.length) return false;
|
||||
return string.substring(self, 0, search.length) === search;
|
||||
}
|
||||
public endsWith(search: string) {
|
||||
const self = unwrapThis(this, "string", String, "String.prototype.indexOf");
|
||||
if (self.length < search.length) return false;
|
||||
return string.substring(self, self.length - search.length, self.length) === search;
|
||||
}
|
||||
|
||||
public indexOf(search: string, offset = 0) {
|
||||
const self = unwrapThis(this, "string", String, "String.prototype.indexOf");
|
||||
@ -123,10 +134,11 @@ export const String = (() => {
|
||||
return applyReplaces(self, matches, replacer, false);
|
||||
}
|
||||
|
||||
public slice(this: string, start = 0, end = this.length) {
|
||||
public slice(start = 0, end?: number) {
|
||||
const self = unwrapThis(this, "string", String, "String.prototype.slice");
|
||||
start = limitI(wrapI(start, this.length), this.length);
|
||||
end = limitI(wrapI(end, this.length), this.length);
|
||||
if (end === undefined) end = self.length;
|
||||
start = limitI(wrapI(start, self.length), self.length);
|
||||
end = limitI(wrapI(end, self.length), self.length);
|
||||
|
||||
if (end <= start) return "";
|
||||
return string.substring(self, start, end);
|
||||
|
@ -195,12 +195,12 @@ export function applySplits(text: string, limit: number | undefined, next: (offs
|
||||
const res: string[] = [];
|
||||
|
||||
while (true) {
|
||||
if (limit != null && res.length >= limit) break;
|
||||
if (limit != null && limit >= 0 && res.length >= limit) break;
|
||||
|
||||
const curr = next(offset);
|
||||
|
||||
if (curr == null) {
|
||||
if (!lastEmpty) res[res.length] = string.substring(text, lastEnd, text.length);
|
||||
if (!lastEmpty || !res.length) res[res.length] = string.substring(text, lastEnd, text.length);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user