unscopables: UNSCOPABLES,
} = Symbol;
+export const {
+ /**
+ * ln(10).
+ *
+ * ※ This is an alias for `Math.LN10`.
+ */
+ LN10,
+
+ /**
+ * ln(2).
+ *
+ * ※ This is an alias for `Math.LN2`.
+ */
+ LN2,
+
+ /**
+ * log10(ℇ).
+ *
+ * ※ This is an alias for `Math.LOG10E`.
+ */
+ LOG10E: LOG10ℇ,
+
+ /**
+ * log2(ℇ).
+ *
+ * ※ This is an alias for `Math.LOG2E`.
+ */
+ LOG2E: LOG2ℇ,
+
+ /**
+ * sqrt(½).
+ *
+ * ※ This is an alias for `Math.SQRT1_2`.
+ */
+ SQRT1_2: RECIPROCAL_SQRT2,
+
+ /**
+ * sqrt(2).
+ *
+ * ※ This is an alias for `Math.SQRT2`.
+ */
+ SQRT2,
+
+ /**
+ * The mathematical constant π.
+ *
+ * ※ This is an alias for `Math.PI`.
+ */
+ PI: Π,
+
+ /**
+ * The Euler number.
+ *
+ * ※ This is an alias for `Math.E`.
+ */
+ E: ℇ,
+} = Math;
+
+export const {
+ /**
+ * The largest number value less than infinity.
+ *
+ * ※ This is an alias for `Number.MAX_VALUE`.
+ */
+ MAX_VALUE: MAXIMUM_NUMBER,
+
+ /**
+ * 2**53 - 1.
+ *
+ * ※ This is an alias for `Number.MAX_SAFE_INTEGER`.
+ */
+ MAX_SAFE_INTEGER: MAXIMUM_SAFE_INTEGRAL_NUMBER,
+
+ /**
+ * The smallest number value greater than negative infinity.
+ *
+ * ※ This is an alias for `Number.MIN_VALUE`.
+ */
+ MIN_VALUE: MINIMUM_NUMBER,
+
+ /**
+ * -(2**53 - 1).
+ *
+ * ※ This is an alias for `Number.MIN_SAFE_INTEGER`.
+ */
+ MIN_SAFE_INTEGER: MINIMUM_SAFE_INTEGRAL_NUMBER,
+
+ /**
+ * Negative infinity.
+ *
+ * ※ This is an alias for `Number.NEGATIVE_INFINITY`.
+ */
+ NEGATIVE_INFINITY,
+
+ /**
+ * Nan.
+ *
+ * ※ This is an alias for `Number.NaN`.
+ */
+ NaN: NAN,
+
+ /**
+ * Positive infinity.
+ *
+ * ※ This is an alias for `Number.POSITIVE_INFINITY`.
+ */
+ POSITIVE_INFINITY,
+
+ /**
+ * The difference between 1 and the smallest number greater than 1.
+ *
+ * ※ This is an alias for `Number.EPSILON`.
+ */
+ EPSILON: Ε,
+} = Number;
+
+/** Negative zero. */
+export const NEGATIVE_ZERO = -0;
+
/** The null primitive. */
export const NULL = null;
+/** Positive zero. */
+export const POSITIVE_ZERO = 0;
+
/** The undefined primitive. */
export const UNDEFINED = undefined;
+/**
+ * Completes the provided property descriptor by setting missing values
+ * to their defaults.
+ *
+ * ※ This method modifies the provided object and returns undefined.
+ */
+export const completePropertyDescriptor = (Desc) => {
+ if (Desc === UNDEFINED) {
+ throw new TypeError(
+ "Piscēs: Cannot complete undefined property descriptor.",
+ );
+ } else if (!("get" in Desc || "set" in Desc)) {
+ // This is a generic or data descriptor.
+ if (!("value" in Desc)) {
+ // `value` is not defined on this.
+ Desc.value = UNDEFINED;
+ } else {
+ // `value` is already defined on this.
+ /* do nothing */
+ }
+ if (!("writable" in Desc)) {
+ // `writable` is not defined on this.
+ Desc.writable = false;
+ } else {
+ // `writable` is already defined on this.
+ /* do nothing */
+ }
+ } else {
+ // This is not a generic or data descriptor.
+ if (!("get" in Desc)) {
+ // `get` is not defined on this.
+ Desc.get = UNDEFINED;
+ } else {
+ // `get` is already defined on this.
+ /* do nothing */
+ }
+ if (!("set" in Desc)) {
+ // `set` is not defined on this.
+ Desc.set = UNDEFINED;
+ } else {
+ // `set` is already defined on this.
+ /* do nothing */
+ }
+ }
+ if (!("enumerable" in Desc)) {
+ // `enumerable` is not defined on this.
+ Desc.enumerable = false;
+ } else {
+ // `enumerable` is already defined on this.
+ /* do nothing */
+ }
+ if (!("configurable" in Desc)) {
+ // `configurable` is not defined on this.
+ Desc.configurable = false;
+ } else {
+ // `configurable` is already defined on this.
+ /* do nothing */
+ }
+};
+
+/** Gets whether the provided value is an accessor descrtiptor. */
+export const isAccessorDescriptor = (Desc) =>
+ Desc !== UNDEFINED && ("get" in Desc || "set" in Desc);
+
+/** Gets whether the provided value is a data descrtiptor. */
+export const isDataDescriptor = (Desc) =>
+ Desc !== UNDEFINED && ("value" in Desc || "writable" in Desc);
+
+/**
+ * Gets whether the provided value is a fully‐populated property
+ * descriptor.
+ */
+export const isFullyPopulatedDescriptor = (Desc) =>
+ Desc !== UNDEFINED &&
+ ("value" in Desc && "writable" in Desc ||
+ "get" in Desc && "set" in Desc) &&
+ "enumerable" in Desc && "configurable" in Desc;
+
+/**
+ * Gets whether the provided value is a generic (not accessor or data)
+ * descrtiptor.
+ */
+export const isGenericDescriptor = (Desc) =>
+ Desc !== UNDEFINED &&
+ !("get" in Desc || "set" in Desc || "value" in Desc ||
+ "writable" in Desc);
+
export const {
/**
* Returns the primitive value of the provided object per its
*/
ordinaryToPrimitive,
+ /**
+ * Returns a string function name generated from the provided value
+ * and optional prefix.
+ */
+ toFunctionName,
+
/**
* Returns the provided value converted to a primitive, or throws if
* no such conversion is possible.
toPrimitive,
} = (() => {
const { apply: call } = Reflect;
+ const getSymbolDescription = Object.getOwnPropertyDescriptor(
+ Symbol.prototype,
+ "description",
+ ).get;
return {
ordinaryToPrimitive: (O, hint) => {
"Piscēs: Unable to convert object to primitive",
);
},
+ toFunctionName: ($, prefix = UNDEFINED) => {
+ const key = toPrimitive($, "string");
+ const name = (() => {
+ if (typeof key === "symbol") {
+ // The provided value is a symbol; format its description.
+ const description = call(getSymbolDescription, key, []);
+ return description === UNDEFINED ? "" : `[${description}]`;
+ } else {
+ // The provided value not a symbol; convert it to a string
+ // property key.
+ return `${key}`;
+ }
+ })();
+ return prefix !== UNDEFINED ? `${prefix} ${name}` : name;
+ },
toPrimitive: ($, preferredType = "default") => {
const hint = `${preferredType}`;
if (
);
} else if (type($) === "object") {
// The provided value is an object.
- const exoticToPrim = $[TO_PRIMITIVE] ?? undefined;
- if (exoticToPrim !== undefined) {
+ const exoticToPrim = $[TO_PRIMITIVE] ?? UNDEFINED;
+ if (exoticToPrim !== UNDEFINED) {
// The provided value has an exotic primitive conversion
// method.
if (typeof exoticToPrim !== "function") {
};
})();
-/**
- * Returns whether the provided values are the same value.
- *
- * ※ This differs from `===` in the cases of nan and zero.
- */
-export const sameValue = Object.is;
-
export const {
+ /**
+ * Returns whether the provided values are the same value.
+ *
+ * ※ This differs from `===` in the cases of nan and zero.
+ */
+ sameValue,
+
/**
* Returns whether the provided values are either the same value or
* both zero (either positive or negative).
* ※ This differs from `===` in the case of nan.
*/
sameValueZero,
+
+ /**
+ * Returns the result of converting the provided value to an index,
+ * or throws an error if it is out of range.
+ */
+ toIndex,
+
+ /**
+ * Returns the result of converting the provided value to a length.
+ */
+ toLength,
} = (() => {
+ const { floor, max, min } = Math;
const { isNaN: isNan } = Number;
+ const { is } = Object;
return {
+ sameValue: (a, b) => is(a, b),
sameValueZero: ($1, $2) => {
const type1 = type($1);
const type2 = type($2);
return $1 === $2;
}
},
+ toIndex: ($) => {
+ const integer = floor($);
+ if (isNan(integer) || integer == 0) {
+ // The value is zero·like.
+ return 0;
+ } else {
+ // The value is not zero·like.
+ const clamped = toLength(integer);
+ if (clamped !== integer) {
+ // Clamping the value changes it.
+ throw new RangeError(`Piscēs: Index out of range: ${$}.`);
+ } else {
+ // The value is within appropriate bounds.
+ return integer;
+ }
+ }
+ },
+ toLength: ($) => {
+ const len = floor($);
+ return isNan(len) || len == 0
+ ? 0
+ : max(min(len, MAXIMUM_SAFE_INTEGRAL_NUMBER), 0);
+ },
};
})();
+/**
+ * Returns the property key (symbol or string) corresponding to the
+ * provided value.
+ */
+export const toPropertyKey = ($) => {
+ const key = toPrimitive($, "string");
+ return typeof key === "symbol" ? key : `${key}`;
+};
+
/**
* Returns a lowercase string identifying the type of the provided
* value.