1 // ♓🌟 Piscēs ∷ value.js
2 // ====================================================================
4 // Copyright © 2022‐2023 Lady [@ Lady’s Computer].
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
11 /** The welknown `@@asyncIterator` symbol. */
12 asyncIterator
: ASYNC_ITERATOR
,
14 /** The welknown `@@hasInstance` symbol. */
15 hasInstance
: HAS_INSTANCE
,
17 /** The welknown `@@isConcatSpreadable` symbol. */
18 isConcatSpreadable
: IS_CONCAT_SPREADABLE
,
20 /** The welknown `@@iterator` symbol. */
23 /** The welknown `@@match` symbol. */
26 /** The welknown `@@matchAll` symbol. */
29 /** The welknown `@@replace` symbol. */
32 /** The welknown `@@species` symbol. */
35 /** The welknown `@@split` symbol. */
38 /** The welknown `@@toPrimitive` symbol. */
39 toPrimitive
: TO_PRIMITIVE
,
41 /** The welknown `@@toStringTag` symbol. */
42 toStringTag
: TO_STRING_TAG
,
44 /** The welknown `@@unscopables` symbol. */
45 unscopables
: UNSCOPABLES
,
52 * ※ This is an alias for `Math.LN10`.
59 * ※ This is an alias for `Math.LN2`.
66 * ※ This is an alias for `Math.LOG10E`.
73 * ※ This is an alias for `Math.LOG2E`.
80 * ※ This is an alias for `Math.SQRT1_2`.
82 SQRT1_2
: RECIPROCAL_SQRT2
,
87 * ※ This is an alias for `Math.SQRT2`.
92 * The mathematical constant π.
94 * ※ This is an alias for `Math.PI`.
101 * ※ This is an alias for `Math.E`.
108 * The largest number value less than infinity.
110 * ※ This is an alias for `Number.MAX_VALUE`.
112 MAX_VALUE
: MAXIMUM_NUMBER
,
117 * ※ This is an alias for `Number.MAX_SAFE_INTEGER`.
119 MAX_SAFE_INTEGER
: MAXIMUM_SAFE_INTEGRAL_NUMBER
,
122 * The smallest number value greater than negative infinity.
124 * ※ This is an alias for `Number.MIN_VALUE`.
126 MIN_VALUE
: MINIMUM_NUMBER
,
131 * ※ This is an alias for `Number.MIN_SAFE_INTEGER`.
133 MIN_SAFE_INTEGER
: MINIMUM_SAFE_INTEGRAL_NUMBER
,
138 * ※ This is an alias for `Number.NEGATIVE_INFINITY`.
145 * ※ This is an alias for `Number.NaN`.
152 * ※ This is an alias for `Number.POSITIVE_INFINITY`.
157 * The difference between 1 and the smallest number greater than 1.
159 * ※ This is an alias for `Number.EPSILON`.
164 /** Negative zero. */
165 export const NEGATIVE_ZERO
= -0;
167 /** The null primitive. */
168 export const NULL
= null;
170 /** Positive zero. */
171 export const POSITIVE_ZERO
= 0;
173 /** The undefined primitive. */
174 export const UNDEFINED
= undefined;
178 * Returns the primitive value of the provided object per its
179 * `.toString` and `.valueOf` methods.
181 * If the provided hint is "string", then `.toString` takes
182 * precedence; otherwise, `.valueOf` does.
184 * Throws an error if both of these methods are not callable or do
185 * not return a primitive.
190 * Returns the provided value converted to a primitive, or throws if
191 * no such conversion is possible.
193 * The provided preferred type, if specified, should be "string",
194 * "number", or "default". If the provided input has a
195 * `.[Symbol.toPrimitive]` method, this function will throw rather
196 * than calling that method with a preferred type other than one of
201 const { apply
: call
} = Reflect
;
204 ordinaryToPrimitive
: (O
, hint
) => {
205 const methodNames
= hint
== "string"
206 ? ["toString", "valueOf"]
207 : ["valueOf", "toString"];
208 for (let index
= 0; index
< methodNames
.length
; ++index
) {
209 const method
= O
[methodNames
[index
]];
210 if (typeof method
=== "function") {
211 // Method is callable.
212 const result
= call(method
, O
, []);
213 if (type(result
) !== "object") {
214 // Method returns a primitive.
217 // Method returns an object.
221 // Method is not callable.
226 "Piscēs: Unable to convert object to primitive",
229 toPrimitive
: ($, preferredType
= "default") => {
230 const hint
= `${preferredType}`;
232 "default" !== hint
&& "string" !== hint
&&
235 // An invalid preferred type was specified.
237 `Piscēs: Invalid preferred type: ${preferredType}.`,
239 } else if (type($) === "object") {
240 // The provided value is an object.
241 const exoticToPrim
= $[TO_PRIMITIVE
] ?? undefined;
242 if (exoticToPrim
!== undefined) {
243 // The provided value has an exotic primitive conversion
245 if (typeof exoticToPrim
!== "function") {
246 // The method is not callable.
248 "Piscēs: `.[Symbol.toPrimitive]` was neither nullish nor callable.",
251 // The method is callable.
252 return call(exoticToPrim
, $, [hint
]);
255 // Use the ordinary primitive conversion function.
256 return ordinaryToPrimitive($, hint
);
259 // The provided value is already a primitive.
268 * Returns whether the provided values are the same value.
270 * ※ This differs from `===` in the cases of nan and zero.
275 * Returns whether the provided values are either the same value or
276 * both zero (either positive or negative).
278 * ※ This differs from `===` in the case of nan.
283 * Returns the result of converting the provided value to an index,
284 * or throws an error if it is out of range.
289 * Returns the result of converting the provided value to a length.
293 const { floor
, max
, min
} = Math
;
294 const { isNaN
: isNan
} = Number
;
295 const { is
} = Object
;
297 sameValue
: (a
, b
) => is(a
, b
),
298 sameValueZero
: ($1, $2) => {
299 const type1
= type($1);
300 const type2
= type($2);
301 if (type1
!== type2
) {
302 // The provided values are not of the same type.
304 } else if (type1
=== "number") {
305 // The provided values are numbers; check if they are nan and
306 // use strict equality otherwise.
307 return isNan($1) && isNan($2) || $1 === $2;
309 // The provided values are not numbers; use strict equality.
314 const integer
= floor($);
315 if (isNan(integer
) || integer
== 0) {
316 // The value is zero·like.
319 // The value is not zero·like.
320 const clamped
= toLength(integer
);
321 if (clamped
!== integer
) {
322 // Clamping the value changes it.
323 throw new RangeError(`Piscēs: Index out of range: ${$}.`);
325 // The value is within appropriate bounds.
331 const len
= floor($);
332 return isNan(len
) || len
== 0
334 : max(min(len
, MAXIMUM_SAFE_INTEGRAL_NUMBER
), 0);
340 * Returns a lowercase string identifying the type of the provided
343 * This differs from the value of the `typeof` operator only in the
344 * cases of objects and null.
346 export const type
= ($) => {
348 // The provided value is null.
351 // The provided value is not null.
352 const type
·of = typeof $;
353 return type
·of === "function" ? "object" : type
·of;