1 // ♓️🪡 सूत्र ∷ xsd/functions.js
2 // ====================================================================
4 // Copyright © 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/>.
23 import { div
, mod
} from "./operators.js";
29 dayTimeDurationLexicalRep
,
32 digit as lexicalDigit
,
59 scientificNotationNumeral
,
64 unsignedDecimalPtNumeral
,
65 unsignedNoDecimalPtNumeral
,
67 yearMonthDurationLexicalRep
,
68 } from "./productions.js";
78 const stringToFloat
= parseFloat
;
81 * Ensures that the provided matcher matches the provided value and
84 * ☡ This function throws if the matcher does not match.
86 * ※ This function is not exposed.
88 const ensureMatches
= (matcher
, $) => {
93 `सूत्र: Expected a ${matcher.name}, but got: ${$}.`,
99 * Ensures that the provided value with the provided name is present or
102 * ☡ This function throws if the presence of the value is not correct.
104 * ※ This function is not exposed.
106 const ensurePresence
= (name
, value
, present
= true) => {
107 if ((value
!== absent
) === !present
) {
109 `सूत्र: Expected ${name} to be ${
110 present ? "present" : "absent"
111 }, but got: ${value}.`,
119 * Ensures that the provided value is a valid, complete duration and
120 * returns an object with its months and seconds.
122 * ☡ This function throws if the provided value is not a valid,
125 * ※ This function is not exposed.
127 const duration
= ($) => {
128 const { months
, seconds
} = $;
129 if (!isIntegralNumber(months
)) {
131 `सूत्र: Expected duration to have an integer for months, but got: ${months}.`,
133 } else if (!isFiniteNumber(seconds
)) {
135 `सूत्र: Expected duration to have a finite number for seconds, but got: ${seconds}.`,
137 } else if (months
> 0 && seconds
< 0 || months
< 0 && seconds
> 0) {
139 `सूत्र: Expected seconds in duration to match polarity of months, but got: ${seconds}.`,
142 return { months
, seconds
};
147 * Ensures that the provided value is a valid
148 * date/timeSevenPropertyModel value and returns an object with its
149 * year, month, day, hour, minute, second, and timezoneOffset.
151 * ☡ This function throws if the provided value is not a valid
152 * date/timeSevenPropertyModel value.
154 * ※ This function is not exposed.
156 const date
·timeSevenPropertyModel
= ($) => {
157 if (type($) !== "object") {
159 `सूत्र: Expected a date/timeSevenPropertyModel value, but got: ${$}.`,
162 const { year
, month
, day
, hour
, minute
, second
, timezoneOffset
} =
164 if (year
!== absent
&& !isIntegralNumber(year
)) {
166 `सूत्र: Expected year to be an optional integer, but got: ${year}.`,
170 !(isIntegralNumber(month
) && month
>= 1 && month
<= 12)
173 `सूत्र: Expected month to be an optional integer between 1 and 12 inclusive, but got: ${month}.`,
177 !(isIntegralNumber(day
) && day
>= 1 && day
<= 31)
180 `सूत्र: Expected day to be an optional integer between 1 and 31 inclusive, but got: ${day}.`,
184 !(isIntegralNumber(hour
) && hour
>= 0 && hour
<= 24)
187 `सूत्र: Expected hour to be an optional integer between 0 and 24 inclusive, but got: ${hour}.`,
191 !(isIntegralNumber(minute
) && minute
>= 0 && minute
<= 59)
194 `सूत्र: Expected minute to be an optional integer between 0 and 59 inclusive, but got: ${minute}.`,
198 !(isFiniteNumber(second
) && second
>= 0 && second
< 60)
201 `सूत्र: Expected second to be an optional finite number greater than or equal to 0 and less than 60, but got: ${second}.`,
204 timezoneOffset
!== absent
&&
205 !(isIntegralNumber(timezoneOffset
) && timezoneOffset
>= -840 &&
206 timezoneOffset
<= 840)
209 `सूत्र: Expected timezoneOffset to be an optional integer between -840 and 840 inclusive, but got: ${timezoneOffset}.`,
212 month
!== absent
&& day
!== absent
&& !(
213 month
=== 2 && day
=== 29
214 ) && day
> daysInMonth(year
, month
)
217 `सूत्र: The provided day violates the day‐of‐month constraint for month ${month}: ${day}.`,
234 * Ensures that the provided value is an integer and returns it.
236 * ☡ This function throws if the provided value is not an integer.
238 * ※ This function is not exposed.
240 const integer
= ($) => {
241 if (!isIntegralNumber($)) {
242 throw new TypeError(`सूत्र: Expected an integer, but got: ${$}.`);
249 * Ensures that the provided value is a nonnegative integer and returns
252 * ☡ This function throws if the provided value is not a nonnegative
255 * ※ This function is not exposed.
257 const nonnegativeInteger
= ($) => {
258 if (!(isIntegralNumber($) && $ >= 0)) {
260 `सूत्र: Expected a nonnegative integer, but got: ${$}.`,
268 * Ensures that the provided value is a finite number and returns it.
270 * ☡ This function throws if the provided value is not a finite number.
272 * ※ This function is not exposed.
274 const decimalNumber
= ($) => {
275 if (!(isFiniteNumber($))) {
277 `सूत्र: Expected a finite number, but got: ${$}.`,
285 * Ensures that the provided value is a nonnegative finite number and
288 * ☡ This function throws if the provided value is not a nonnegative
291 * ※ This function is not exposed.
293 const nonnegativeDecimalNumber
= ($) => {
294 if (!(isFiniteNumber($) && $ >= 0)) {
296 `सूत्र: Expected a nonnegative finite number, but got: ${$}.`,
304 * Ensures that the provided value is a 32‐bit float and returns it.
306 * ☡ This function throws if the provided value is not a 32‐bit float.
308 * ※ This function is not exposed.
310 const float = ($) => {
311 if (typeof $ !== "number" || !sameValue(toFloat32($), $)) {
313 `सूत्र: Expected a float value, but got: ${$}.`,
321 * Ensures that the provided value is a number and returns it.
323 * ☡ This function throws if the provided value is not a number.
325 * ※ This function is not exposed.
327 const double = ($) => {
328 if (typeof $ !== "number") {
330 `सूत्र: Expected a double value, but got: ${$}.`,
338 * Ensures that the provided value is a hexBinary value, i·e a sequence
341 * ☡ This function throws if the provided value is not an array buffer.
343 * ※ This function is not exposed.
345 const hexBinaryValue
= ($) => {
346 if (!isArrayBuffer($)) {
348 `सूत्र: Expected a hexBinary value, but got: ${$}.`,
357 * Converts a string of 0’s and 1’s into a sequence of binary digits.
359 * ※ This function is not exposed.
364 * Converts a generator iterator into a sequence of values.
366 * ※ This function is not exposed.
371 * Converts a string into a sequence of characters.
373 * ※ This function is not exposed.
378 next
: generatorIteratorNext
,
379 } = getPrototype(function* () {}.prototype);
380 const { [ITERATOR
]: stringIterator
} = String
.prototype;
382 next
: stringIteratorNext
,
383 } = getPrototype(""[ITERATOR
]());
384 const binaryDigitIterator
= function* () {
385 for (const digit
of literalSequence(this)) {
386 yield digit
=== "0" ? 0 : 1;
389 const binaryDigitSequenceIterablePrototype
= {
393 generatorIteratorNext
,
394 call(binaryDigitIterator
, this.binaryDigits
, []),
400 const generatorSequenceIterablePrototype
= {
404 generatorIteratorNext
,
411 const literalSequenceIterablePrototype
= {
416 call(stringIterator
, this.literal
, []),
424 binaryDigitSequence
: (digits
) =>
426 binaryDigitSequenceIterablePrototype
,
427 { binaryDigits
: { value
: digits
} },
429 generatorSequence
: (generator
) =>
431 generatorSequenceIterablePrototype
,
432 { generator
: { value
: generator
} },
434 literalSequence
: (literal
) =>
436 literalSequenceIterablePrototype
,
437 { literal
: { value
: literal
} },