functionalscript 0.1.608 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/Cargo.lock +4 -0
- package/Cargo.toml +4 -2
- package/README.md +1 -1
- package/com/cpp/module.f.d.mts +4 -8
- package/com/cpp/module.f.mjs +20 -25
- package/com/cpp/testlib.f.mjs +3 -4
- package/com/cs/module.f.d.mts +4 -8
- package/com/cs/module.f.mjs +18 -23
- package/com/cs/testlib.f.mjs +3 -5
- package/com/rust/module.f.d.mts +3 -7
- package/com/rust/module.f.mjs +25 -30
- package/com/rust/nanocom/src/cobject.rs +1 -1
- package/com/rust/testlib.f.mjs +3 -5
- package/com/test/build.f.d.mts +2 -2
- package/com/test/build.f.mjs +2 -2
- package/com/test/build.mjs +4 -4
- package/com/test/rust/src/lib.rs +4 -4
- package/com/types/module.f.d.mts +5 -10
- package/com/types/module.f.mjs +5 -12
- package/commonjs/build/module.f.d.mts +13 -17
- package/commonjs/build/module.f.mjs +23 -28
- package/commonjs/build/test.f.mjs +4 -4
- package/commonjs/module/function/module.f.d.mts +0 -2
- package/commonjs/module/function/module.f.mjs +0 -2
- package/commonjs/module/module.f.d.mts +16 -21
- package/commonjs/module/module.f.mjs +2 -9
- package/commonjs/module.d.mts +1 -5
- package/commonjs/module.f.d.mts +0 -2
- package/commonjs/module.f.mjs +0 -2
- package/commonjs/module.mjs +2 -7
- package/commonjs/package/dependencies/module.f.d.mts +3 -7
- package/commonjs/package/dependencies/module.f.mjs +5 -10
- package/commonjs/package/dependencies/test.f.mjs +1 -1
- package/commonjs/package/module.f.d.mts +12 -18
- package/commonjs/package/module.f.mjs +6 -13
- package/commonjs/package/test.f.mjs +1 -1
- package/commonjs/path/module.f.d.mts +25 -32
- package/commonjs/path/module.f.mjs +12 -23
- package/commonjs/path/test.f.mjs +11 -11
- package/commonjs/test.mjs +1 -1
- package/dev/module.f.d.mts +1 -4
- package/dev/module.f.mjs +1 -4
- package/dev/module.mjs +1 -1
- package/dev/test/module.f.d.mts +2 -3
- package/dev/test/module.f.mjs +5 -7
- package/djs/module.f.d.mts +13 -18
- package/djs/module.f.mjs +12 -19
- package/djs/parser/module.f.d.mts +53 -37
- package/djs/parser/module.f.mjs +278 -131
- package/djs/parser/test.f.d.mts +4 -0
- package/djs/parser/test.f.mjs +186 -70
- package/djs/test.f.mjs +4 -4
- package/djs/tokenizer/module.f.d.mts +6 -10
- package/djs/tokenizer/module.f.mjs +19 -22
- package/djs/tokenizer/test.f.mjs +7 -7
- package/doc/LANGUAGE.md +17 -16
- package/doc/README.md +14 -50
- package/fsc/README.md +0 -3
- package/fsc/module.f.d.mts +4 -9
- package/fsc/module.f.mjs +17 -24
- package/fsc/test.f.mjs +3 -3
- package/fsm/README.md +1 -1
- package/fsm/module.f.d.mts +13 -20
- package/fsm/module.f.mjs +27 -38
- package/fsm/test.f.mjs +8 -8
- package/html/README.md +24 -0
- package/html/module.f.d.mts +7 -12
- package/html/module.f.mjs +14 -23
- package/html/test.f.mjs +4 -4
- package/issues/01-test-debug.md +3 -0
- package/issues/{publish.md → 05-publish.md} +8 -8
- package/issues/17-djs-extension.md +6 -0
- package/issues/README.md +20 -13
- package/issues/lang/1000-json.md +38 -0
- package/issues/lang/2110-default-export.md +2 -2
- package/issues/lang/2310-undefined.md +1 -1
- package/issues/lang/2330-property-accessor.md +225 -0
- package/issues/lang/2360-built-in.md +54 -47
- package/issues/lang/3240-export.md +44 -0
- package/issues/lang/README.md +64 -22
- package/issues/test.f.d.mts +16 -0
- package/issues/test.f.mjs +57 -0
- package/js/tokenizer/module.f.d.mts +18 -17
- package/js/tokenizer/module.f.mjs +80 -61
- package/js/tokenizer/test.f.mjs +15 -12
- package/json/module.f.d.mts +18 -26
- package/json/module.f.mjs +18 -31
- package/json/parser/module.f.d.mts +9 -13
- package/json/parser/module.f.mjs +9 -14
- package/json/parser/test.f.mjs +7 -7
- package/json/serializer/module.f.d.mts +11 -20
- package/json/serializer/module.f.mjs +14 -29
- package/json/serializer/test.f.mjs +2 -2
- package/json/test.f.mjs +3 -3
- package/json/tokenizer/module.f.d.mts +6 -10
- package/json/tokenizer/module.f.mjs +16 -20
- package/json/tokenizer/test.f.mjs +6 -6
- package/jsr.json +1 -1
- package/nanvm-lib/Cargo.toml +6 -0
- package/nanvm-lib/src/extension.rs +119 -0
- package/nanvm-lib/src/interface.rs +136 -0
- package/nanvm-lib/src/lib.rs +7 -0
- package/nanvm-lib/src/naive.rs +229 -0
- package/nanvm-lib/src/nanenum.rs +230 -0
- package/nanvm-lib/src/nullish.rs +7 -0
- package/nanvm-lib/src/sign.rs +5 -0
- package/nanvm-lib/src/simple.rs +32 -0
- package/nanvm-lib/tests/test.f.d.mts +36 -0
- package/nanvm-lib/tests/test.f.mjs +79 -0
- package/nanvm-lib/tests/test.rs +108 -0
- package/nodejs/version/main.mjs +1 -1
- package/nodejs/version/module.f.d.mts +4 -9
- package/nodejs/version/module.f.mjs +2 -7
- package/nodejs/version/test.f.mjs +3 -3
- package/package.json +1 -1
- package/prime_field/module.f.d.mts +20 -23
- package/prime_field/module.f.mjs +9 -12
- package/prime_field/test.f.mjs +1 -1
- package/secp/module.f.d.mts +27 -28
- package/secp/module.f.mjs +38 -39
- package/secp/test.f.mjs +4 -4
- package/sha2/module.f.d.mts +8 -16
- package/sha2/module.f.mjs +7 -20
- package/sha2/test.f.mjs +4 -4
- package/text/README.md +2 -2
- package/text/ascii/module.f.d.mts +69 -72
- package/text/ascii/module.f.mjs +5 -10
- package/text/ascii/test.f.mjs +3 -3
- package/text/module.f.d.mts +9 -14
- package/text/module.f.mjs +7 -14
- package/text/sgr/module.f.d.mts +7 -9
- package/text/sgr/module.f.mjs +2 -4
- package/text/test.f.mjs +3 -3
- package/text/utf16/module.f.d.mts +8 -15
- package/text/utf16/module.f.mjs +17 -28
- package/text/utf16/test.f.mjs +5 -5
- package/text/utf8/module.f.d.mts +4 -9
- package/text/utf8/module.f.mjs +9 -16
- package/text/utf8/test.f.mjs +4 -4
- package/types/array/module.f.d.mts +14 -24
- package/types/array/module.f.mjs +8 -25
- package/types/array/test.f.mjs +3 -3
- package/types/bigfloat/module.f.d.mts +4 -9
- package/types/bigfloat/module.f.mjs +3 -10
- package/types/bigfloat/test.f.mjs +1 -1
- package/types/bigint/module.f.d.mts +16 -64
- package/types/bigint/module.f.mjs +11 -30
- package/types/bigint/test.f.mjs +1 -1
- package/types/btree/find/module.f.d.mts +20 -26
- package/types/btree/find/module.f.mjs +8 -17
- package/types/btree/find/test.f.mjs +7 -7
- package/types/btree/module.f.d.mts +4 -8
- package/types/btree/module.f.mjs +6 -11
- package/types/btree/remove/module.f.d.mts +7 -12
- package/types/btree/remove/module.f.mjs +10 -17
- package/types/btree/remove/test.f.mjs +5 -5
- package/types/btree/set/module.f.d.mts +3 -7
- package/types/btree/set/module.f.mjs +4 -9
- package/types/btree/set/test.f.mjs +4 -4
- package/types/btree/test.f.mjs +9 -9
- package/types/btree/types/module.f.d.mts +0 -2
- package/types/btree/types/module.f.mjs +0 -2
- package/types/byte_set/module.f.d.mts +16 -29
- package/types/byte_set/module.f.mjs +14 -39
- package/types/byte_set/test.f.mjs +5 -5
- package/types/function/compare/module.f.d.mts +9 -15
- package/types/function/compare/module.f.mjs +3 -12
- package/types/function/compare/test.f.mjs +1 -1
- package/types/function/module.f.d.mts +20 -27
- package/types/function/module.f.mjs +4 -15
- package/types/function/operator/module.f.d.mts +28 -43
- package/types/function/operator/module.f.mjs +14 -41
- package/types/function/test.f.mjs +1 -1
- package/types/list/module.f.d.mts +56 -91
- package/types/list/module.f.mjs +45 -114
- package/types/list/test.f.mjs +10 -10
- package/types/map/module.f.d.mts +15 -24
- package/types/map/module.f.mjs +15 -30
- package/types/map/test.f.mjs +2 -2
- package/types/nibble_set/module.f.d.mts +10 -20
- package/types/nibble_set/module.f.mjs +7 -24
- package/types/nibble_set/test.f.mjs +2 -2
- package/types/nullable/module.f.d.mts +3 -8
- package/types/nullable/module.f.mjs +2 -9
- package/types/nullable/test.f.mjs +1 -1
- package/types/number/module.f.d.mts +7 -13
- package/types/number/module.f.mjs +8 -19
- package/types/number/test.f.mjs +1 -1
- package/types/object/module.f.d.mts +11 -18
- package/types/object/module.f.mjs +9 -20
- package/types/object/test.f.mjs +1 -1
- package/types/range/module.f.d.mts +3 -8
- package/types/range/module.f.mjs +2 -9
- package/types/range/test.f.mjs +1 -1
- package/types/range_map/module.f.d.mts +9 -15
- package/types/range_map/module.f.mjs +9 -18
- package/types/range_map/test.f.mjs +32 -32
- package/types/result/module.d.mts +3 -3
- package/types/result/module.f.d.mts +6 -12
- package/types/result/module.f.mjs +3 -12
- package/types/result/module.mjs +2 -2
- package/types/sorted_list/module.f.d.mts +22 -28
- package/types/sorted_list/module.f.mjs +10 -19
- package/types/sorted_list/test.f.mjs +7 -7
- package/types/sorted_set/module.f.d.mts +6 -12
- package/types/sorted_set/module.f.mjs +7 -16
- package/types/sorted_set/test.f.mjs +7 -7
- package/types/string/module.f.d.mts +8 -14
- package/types/string/module.f.mjs +10 -21
- package/types/string/test.f.mjs +2 -2
- package/types/string_set/module.f.d.mts +8 -16
- package/types/string_set/module.f.mjs +12 -27
- package/types/string_set/test.f.mjs +1 -1
- package/issues/lang/2351-property-accessor.md +0 -44
- package/issues/lang/2352-property-call.md +0 -43
- package/issues/lang/2353-property-at.md +0 -19
- package/issues/test-debug.md +0 -12
- /package/issues/{esm.md → 02-esm.md} +0 -0
- /package/issues/{djs.md → 03-djs.md} +0 -0
- /package/issues/{fs-load.md → 11-fs-load.md} +0 -0
- /package/issues/lang/{2330-grouping.md → 2350-grouping.md} +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
// @ts-self-types="./module.f.d.mts"
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import * as operator from '../../types/function/operator/module.f.mjs'
|
|
3
|
+
import * as range_map from '../../types/range_map/module.f.mjs'
|
|
4
4
|
const { merge, fromRange, get } = range_map
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import * as list from '../../types/list/module.f.mjs'
|
|
6
|
+
import * as map from '../../types/map/module.f.mjs'
|
|
7
7
|
const { at } = map
|
|
8
|
-
import
|
|
8
|
+
import * as _range from '../../types/range/module.f.mjs'
|
|
9
9
|
const { one } = _range
|
|
10
10
|
const { empty, stateScan, flat, toArray, reduce: listReduce, scan } = list
|
|
11
11
|
import * as bigfloatT from '../../types/bigfloat/module.f.mjs'
|
|
12
12
|
const { fromCharCode } = String
|
|
13
|
-
import ascii from '../../text/ascii/module.f.mjs'
|
|
13
|
+
import * as ascii from '../../text/ascii/module.f.mjs'
|
|
14
|
+
const { range } = ascii
|
|
14
15
|
const {
|
|
15
|
-
range,
|
|
16
16
|
//
|
|
17
17
|
backspace,
|
|
18
18
|
ht,
|
|
@@ -68,7 +68,7 @@ const {
|
|
|
68
68
|
leftCurlyBracket,
|
|
69
69
|
rightCurlyBracket,
|
|
70
70
|
dollarSign
|
|
71
|
-
} = ascii
|
|
71
|
+
} = ascii.ascii
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* @typedef {{
|
|
@@ -96,6 +96,8 @@ const {
|
|
|
96
96
|
|
|
97
97
|
/** @typedef {{readonly kind: 'ws'}} WhitespaceToken */
|
|
98
98
|
|
|
99
|
+
/** @typedef {{readonly kind: 'nl'}} NewLineToken */
|
|
100
|
+
|
|
99
101
|
/** @typedef {{readonly kind: 'true'}} TrueToken */
|
|
100
102
|
|
|
101
103
|
/** @typedef {{readonly kind: 'false'}} FalseToken */
|
|
@@ -143,6 +145,7 @@ const {
|
|
|
143
145
|
* FalseToken |
|
|
144
146
|
* NullToken |
|
|
145
147
|
* WhitespaceToken |
|
|
148
|
+
* NewLineToken |
|
|
146
149
|
* StringToken |
|
|
147
150
|
* NumberToken |
|
|
148
151
|
* ErrorToken |
|
|
@@ -154,15 +157,19 @@ const {
|
|
|
154
157
|
|
|
155
158
|
const rangeOneNine = range('19')
|
|
156
159
|
|
|
160
|
+
const rangeSetNewLine = [
|
|
161
|
+
one(lf),
|
|
162
|
+
one(cr)
|
|
163
|
+
]
|
|
164
|
+
|
|
157
165
|
const rangeSetWhiteSpace = [
|
|
158
166
|
one(ht),
|
|
159
|
-
one(lf),
|
|
160
|
-
one(cr),
|
|
161
167
|
one(space)
|
|
162
168
|
]
|
|
163
169
|
|
|
164
170
|
const rangeSetTerminalForNumber = [
|
|
165
171
|
...rangeSetWhiteSpace,
|
|
172
|
+
...rangeSetNewLine,
|
|
166
173
|
one(exclamationMark),
|
|
167
174
|
one(percentSign),
|
|
168
175
|
one(ampersand),
|
|
@@ -235,6 +242,7 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
235
242
|
* ParseOperatorState |
|
|
236
243
|
* ParseMinusState |
|
|
237
244
|
* ParseWhitespaceState |
|
|
245
|
+
* ParseNewLineState |
|
|
238
246
|
* EofState
|
|
239
247
|
* } TokenizerState
|
|
240
248
|
*/
|
|
@@ -257,6 +265,8 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
257
265
|
|
|
258
266
|
/** @typedef {{ readonly kind: 'ws'}} ParseWhitespaceState */
|
|
259
267
|
|
|
268
|
+
/** @typedef {{ readonly kind: 'nl'}} ParseNewLineState */
|
|
269
|
+
|
|
260
270
|
/** @typedef {{ readonly kind: 'string', readonly value: string}} ParseStringState */
|
|
261
271
|
|
|
262
272
|
/** @typedef {{ readonly kind: 'escapeChar', readonly value: string}} ParseEscapeCharState */
|
|
@@ -299,14 +309,14 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
299
309
|
|
|
300
310
|
/** @typedef {number|null} CharCodeOrEof */
|
|
301
311
|
|
|
302
|
-
/** @typedef {(input: number) => readonly[
|
|
312
|
+
/** @typedef {(input: number) => readonly[list.List<JsToken>, TokenizerState]} ToToken */
|
|
303
313
|
|
|
304
314
|
/**
|
|
305
315
|
* @template T
|
|
306
316
|
* @typedef {(state: T) => ToToken} CreateToToken<T>
|
|
307
317
|
*/
|
|
308
318
|
|
|
309
|
-
/** @typedef {
|
|
319
|
+
/** @typedef {list.List<_range.Range>} RangeSet */
|
|
310
320
|
|
|
311
321
|
/**
|
|
312
322
|
* @template T
|
|
@@ -315,7 +325,7 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
315
325
|
|
|
316
326
|
/**
|
|
317
327
|
* @template T
|
|
318
|
-
* @typedef {
|
|
328
|
+
* @typedef {range_map.RangeMapArray<CreateToToken<T>>} RangeMapToToken<T>
|
|
319
329
|
*/
|
|
320
330
|
|
|
321
331
|
/** @type {(old: string) => (input: number) => string} */
|
|
@@ -328,34 +338,34 @@ const union = def => a => b => {
|
|
|
328
338
|
throw [a, b]
|
|
329
339
|
}
|
|
330
340
|
|
|
331
|
-
/** @type {<T>(def: CreateToToken<T>) =>
|
|
341
|
+
/** @type {<T>(def: CreateToToken<T>) => range_map.RangeMerge<CreateToToken<T>>} */
|
|
332
342
|
const rangeMapMerge = def => merge({
|
|
333
343
|
union: union(def),
|
|
334
344
|
equal: operator.strictEqual,
|
|
335
345
|
})
|
|
336
346
|
|
|
337
|
-
/** @type {<T>(r:
|
|
347
|
+
/** @type {<T>(r: _range.Range) => (f: CreateToToken<T>) => RangeFunc<T>} */
|
|
338
348
|
const rangeFunc = r => f => def => fromRange(def)(r)(f)
|
|
339
349
|
|
|
340
|
-
/** @type {<T>(def: CreateToToken<T>) => (
|
|
350
|
+
/** @type {<T>(def: CreateToToken<T>) => (operator.Scan<RangeFunc<T>, RangeMapToToken<T>>)} */
|
|
341
351
|
const scanRangeOp = def => f => [f(def), scanRangeOp(def)]
|
|
342
352
|
|
|
343
|
-
/** @type {<T>(def: CreateToToken<T>) => (a:
|
|
353
|
+
/** @type {<T>(def: CreateToToken<T>) => (a: list.List<RangeFunc<T>>) => RangeMapToToken<T>} */
|
|
344
354
|
const reduceRangeMap = def => a => {
|
|
345
355
|
const rm = scan(scanRangeOp(def))(a)
|
|
346
356
|
return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
|
|
347
357
|
}
|
|
348
358
|
|
|
349
|
-
/** @type {<T>(def: CreateToToken<T>) => (f: CreateToToken<T>) => (
|
|
359
|
+
/** @type {<T>(def: CreateToToken<T>) => (f: CreateToToken<T>) => (operator.Scan<_range.Range, RangeMapToToken<T>>)} */
|
|
350
360
|
const scanRangeSetOp = def => f => r => [fromRange(def)(r)(f), scanRangeSetOp(def)(f)]
|
|
351
361
|
|
|
352
|
-
/** @type {<T>(rs:
|
|
362
|
+
/** @type {<T>(rs: list.List<_range.Range>) => (f: CreateToToken<T>) => RangeFunc<T>} */
|
|
353
363
|
const rangeSetFunc = rs => f => def => {
|
|
354
364
|
const rm = scan(scanRangeSetOp(def)(f))(rs)
|
|
355
365
|
return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
|
|
356
366
|
}
|
|
357
367
|
|
|
358
|
-
/** @type {<T>(def: CreateToToken<T>) => (a:
|
|
368
|
+
/** @type {<T>(def: CreateToToken<T>) => (a: list.List<RangeFunc<T>>) => CreateToToken<T>} */
|
|
359
369
|
const create = def => a => {
|
|
360
370
|
/** @typedef {typeof def extends CreateToToken<infer T> ? T : never} T */
|
|
361
371
|
const i = reduceRangeMap(def)(a)
|
|
@@ -392,7 +402,7 @@ const bufferToNumberToken = ({numberKind, value, b}) =>
|
|
|
392
402
|
|
|
393
403
|
/**
|
|
394
404
|
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords
|
|
395
|
-
* @type {
|
|
405
|
+
* @type {list.List<map.Entry<JsToken>>}
|
|
396
406
|
*/
|
|
397
407
|
const keywordEntries = [
|
|
398
408
|
['arguments', { kind: 'arguments'}],
|
|
@@ -448,11 +458,11 @@ const keywordEntries = [
|
|
|
448
458
|
const keywordMap = map.fromEntries(keywordEntries)
|
|
449
459
|
|
|
450
460
|
/** @type {(token: JsToken) => Boolean} */
|
|
451
|
-
const isKeywordToken = token => at(token.kind)(keywordMap) !== null
|
|
461
|
+
export const isKeywordToken = token => at(token.kind)(keywordMap) !== null
|
|
452
462
|
|
|
453
463
|
/**
|
|
454
464
|
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators
|
|
455
|
-
* @type {
|
|
465
|
+
* @type {list.List<map.Entry<JsToken>>}
|
|
456
466
|
*/
|
|
457
467
|
const operatorEntries = [
|
|
458
468
|
['!', { kind: '!'}],
|
|
@@ -520,24 +530,25 @@ const getOperatorToken = op => at(op)(operatorMap) ?? { kind: 'error', message:
|
|
|
520
530
|
/** @type {(op: string) => Boolean} */
|
|
521
531
|
const hasOperatorToken = op => at(op)(operatorMap) !== null
|
|
522
532
|
|
|
523
|
-
/** @type {(state: InitialState) => (input: number) => readonly[
|
|
533
|
+
/** @type {(state: InitialState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
524
534
|
const initialStateOp = create(state => () => [[{ kind: 'error', message: 'unexpected character' }], state])([
|
|
525
535
|
rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: 'int' }]),
|
|
526
536
|
rangeSetFunc(rangeIdStart)(() => input => [empty, { kind: 'id', value: fromCharCode(input) }]),
|
|
527
537
|
rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, { kind: 'ws' }]),
|
|
538
|
+
rangeSetFunc(rangeSetNewLine)(state => () => [empty, { kind: 'nl' }]),
|
|
528
539
|
rangeFunc(one(quotationMark))(() => () => [empty, { kind: 'string', value: '' }]),
|
|
529
540
|
rangeFunc(one(digit0))(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: '0' }]),
|
|
530
541
|
rangeSetFunc(rangeOpStart)(() => input => [empty, { kind: 'op', value: fromCharCode(input) }])
|
|
531
542
|
])
|
|
532
543
|
|
|
533
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
544
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
534
545
|
const invalidNumberToToken = () => input =>
|
|
535
546
|
{
|
|
536
547
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
537
548
|
return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
|
|
538
549
|
}
|
|
539
550
|
|
|
540
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
551
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
541
552
|
const fullStopToToken = state => input => {
|
|
542
553
|
switch (state.numberKind) {
|
|
543
554
|
case '0':
|
|
@@ -546,7 +557,7 @@ const fullStopToToken = state => input => {
|
|
|
546
557
|
}
|
|
547
558
|
}
|
|
548
559
|
|
|
549
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
560
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
550
561
|
const digit0ToToken = state => input => {
|
|
551
562
|
switch (state.numberKind) {
|
|
552
563
|
case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
|
|
@@ -560,7 +571,7 @@ const digit0ToToken = state => input => {
|
|
|
560
571
|
}
|
|
561
572
|
}
|
|
562
573
|
|
|
563
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
574
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
564
575
|
const digit19ToToken = state => input => {
|
|
565
576
|
switch (state.numberKind) {
|
|
566
577
|
case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
|
|
@@ -574,7 +585,7 @@ const digit19ToToken = state => input => {
|
|
|
574
585
|
}
|
|
575
586
|
}
|
|
576
587
|
|
|
577
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
588
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
578
589
|
const expToToken = state => input => {
|
|
579
590
|
switch (state.numberKind) {
|
|
580
591
|
case '0':
|
|
@@ -584,7 +595,7 @@ const expToToken = state => input => {
|
|
|
584
595
|
}
|
|
585
596
|
}
|
|
586
597
|
|
|
587
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
598
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
588
599
|
const hyphenMinusToToken = state => input => {
|
|
589
600
|
switch (state.numberKind) {
|
|
590
601
|
case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: { ... state.b, es: -1}, numberKind: 'e-' }]
|
|
@@ -592,7 +603,7 @@ const hyphenMinusToToken = state => input => {
|
|
|
592
603
|
}
|
|
593
604
|
}
|
|
594
605
|
|
|
595
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
606
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
596
607
|
const plusSignToToken = state => input => {
|
|
597
608
|
switch (state.numberKind) {
|
|
598
609
|
case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e+' }]
|
|
@@ -600,7 +611,7 @@ const plusSignToToken = state => input => {
|
|
|
600
611
|
}
|
|
601
612
|
}
|
|
602
613
|
|
|
603
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
614
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
604
615
|
const terminalToToken = state => input => {
|
|
605
616
|
switch (state.numberKind) {
|
|
606
617
|
case '.':
|
|
@@ -619,7 +630,7 @@ const terminalToToken = state => input => {
|
|
|
619
630
|
}
|
|
620
631
|
}
|
|
621
632
|
|
|
622
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
633
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
623
634
|
const bigintToToken = state => input => {
|
|
624
635
|
switch (state.numberKind) {
|
|
625
636
|
case '0':
|
|
@@ -635,7 +646,7 @@ const bigintToToken = state => input => {
|
|
|
635
646
|
}
|
|
636
647
|
}
|
|
637
648
|
|
|
638
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
649
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
639
650
|
const parseNumberStateOp = create(invalidNumberToToken)([
|
|
640
651
|
rangeFunc(one(fullStop))(fullStopToToken),
|
|
641
652
|
rangeFunc(one(digit0))(digit0ToToken),
|
|
@@ -647,7 +658,7 @@ const parseNumberStateOp = create(invalidNumberToToken)([
|
|
|
647
658
|
rangeFunc(one(latinSmallLetterN))(bigintToToken),
|
|
648
659
|
])
|
|
649
660
|
|
|
650
|
-
/** @type {(state: InvalidNumberState) => (input: number) => readonly[
|
|
661
|
+
/** @type {(state: InvalidNumberState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
651
662
|
const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber' }])([
|
|
652
663
|
rangeSetFunc(rangeSetTerminalForNumber)(() => input => {
|
|
653
664
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
@@ -655,26 +666,26 @@ const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber'
|
|
|
655
666
|
})
|
|
656
667
|
])
|
|
657
668
|
|
|
658
|
-
/** @type {(state: ParseMinusState) => (input: number) => readonly[
|
|
669
|
+
/** @type {(state: ParseMinusState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
659
670
|
const parseMinusStateOp = create(() => input => tokenizeOp({ kind: 'op', value: '-' })(input))([
|
|
660
671
|
rangeFunc(one(fullStop))(() => input => tokenizeOp({ kind: 'invalidNumber' })(input)),
|
|
661
672
|
rangeFunc(one(digit0))(() => () => [empty, { kind: 'number', value: '-0', b: startNegativeNumber, numberKind: '0' }]),
|
|
662
673
|
rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: appendChar('-')(input), b: addIntDigit(input)(startNegativeNumber), numberKind: 'int' }]),
|
|
663
674
|
])
|
|
664
675
|
|
|
665
|
-
/** @type {(state: ParseStringState) => (input: number) => readonly[
|
|
676
|
+
/** @type {(state: ParseStringState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
666
677
|
const parseStringStateOp = create(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }])([
|
|
667
678
|
rangeFunc(one(quotationMark))(state => () => [[{ kind: 'string', value: state.value }], { kind: 'initial' }]),
|
|
668
679
|
rangeFunc(one(reverseSolidus))(state => () => [empty, { kind: 'escapeChar', value: state.value }])
|
|
669
680
|
])
|
|
670
681
|
|
|
671
|
-
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[
|
|
682
|
+
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
672
683
|
const parseEscapeDefault = state => input => {
|
|
673
684
|
const next = tokenizeOp({ kind: 'string', value: state.value })(input)
|
|
674
685
|
return [{ first: { kind: 'error', message: 'unescaped character' }, tail: next[0] }, next[1]]
|
|
675
686
|
}
|
|
676
687
|
|
|
677
|
-
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[
|
|
688
|
+
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
678
689
|
const parseEscapeCharStateOp = create(parseEscapeDefault)([
|
|
679
690
|
rangeSetFunc([one(quotationMark), one(reverseSolidus), one(solidus)])(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }]),
|
|
680
691
|
rangeFunc(one(latinSmallLetterB))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(backspace) }]),
|
|
@@ -685,13 +696,13 @@ const parseEscapeCharStateOp = create(parseEscapeDefault)([
|
|
|
685
696
|
rangeFunc(one(latinSmallLetterU))(state => () => [empty, { kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0 }]),
|
|
686
697
|
])
|
|
687
698
|
|
|
688
|
-
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
699
|
+
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
689
700
|
const parseUnicodeCharDefault = state => input => {
|
|
690
701
|
const next = tokenizeOp({ kind: 'string', value: state.value })(input)
|
|
691
702
|
return [{ first: { kind: 'error', message: 'invalid hex value' }, tail: next[0] }, next[1]]
|
|
692
703
|
}
|
|
693
704
|
|
|
694
|
-
/** @type {(offser: number) => (state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
705
|
+
/** @type {(offser: number) => (state: ParseUnicodeCharState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
695
706
|
const parseUnicodeCharHex = offset => state => input => {
|
|
696
707
|
const hexValue = input - offset
|
|
697
708
|
const newUnicode = state.unicode | (hexValue << (3 - state.hexIndex) * 4)
|
|
@@ -700,7 +711,7 @@ const parseUnicodeCharHex = offset => state => input => {
|
|
|
700
711
|
{ kind: 'unicodeChar', value: state.value, unicode: newUnicode, hexIndex: state.hexIndex + 1 }]
|
|
701
712
|
}
|
|
702
713
|
|
|
703
|
-
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
714
|
+
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
704
715
|
const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
|
|
705
716
|
rangeFunc(digitRange)(parseUnicodeCharHex(digit0)),
|
|
706
717
|
rangeFunc(rangeSmallAF)(parseUnicodeCharHex(latinSmallLetterA - 10)),
|
|
@@ -710,19 +721,19 @@ const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
|
|
|
710
721
|
/** @type {(s: string) => JsToken} */
|
|
711
722
|
const idToToken = s => at(s)(keywordMap) ?? { kind: 'id', value: s }
|
|
712
723
|
|
|
713
|
-
/** @type {(state: ParseIdState) => (input: number) => readonly[
|
|
724
|
+
/** @type {(state: ParseIdState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
714
725
|
const parseIdDefault = state => input => {
|
|
715
726
|
const keyWordToken = idToToken(state.value)
|
|
716
727
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
717
728
|
return [{ first: keyWordToken, tail: next[0] }, next[1]]
|
|
718
729
|
}
|
|
719
730
|
|
|
720
|
-
/** @type {(state: ParseIdState) => (input: number) => readonly[
|
|
731
|
+
/** @type {(state: ParseIdState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
721
732
|
const parseIdStateOp = create(parseIdDefault)([
|
|
722
733
|
rangeSetFunc(rangeId)(state => input => [empty, { kind: 'id', value: appendChar(state.value)(input) }])
|
|
723
734
|
])
|
|
724
735
|
|
|
725
|
-
/** @type {(state: ParseOperatorState) => (input: number) => readonly[
|
|
736
|
+
/** @type {(state: ParseOperatorState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
726
737
|
const parseOperatorStateOp = state => input => {
|
|
727
738
|
const nextStateValue = appendChar(state.value)(input)
|
|
728
739
|
if (hasOperatorToken(nextStateValue))
|
|
@@ -731,21 +742,34 @@ const parseOperatorStateOp = state => input => {
|
|
|
731
742
|
return [{ first: getOperatorToken(state.value), tail: next[0] }, next[1]]
|
|
732
743
|
}
|
|
733
744
|
|
|
734
|
-
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[
|
|
745
|
+
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
735
746
|
const parseWhitespaceDefault = state => input => {
|
|
736
747
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
737
748
|
return [{ first: { kind: 'ws' }, tail: next[0] }, next[1]]
|
|
738
749
|
}
|
|
739
750
|
|
|
740
|
-
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[
|
|
751
|
+
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
741
752
|
const parseWhitespaceStateOp = create(parseWhitespaceDefault)([
|
|
742
|
-
rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, state])
|
|
753
|
+
rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, state]),
|
|
754
|
+
rangeSetFunc(rangeSetNewLine)(state => () => [empty, { kind: 'nl' }])
|
|
743
755
|
])
|
|
744
756
|
|
|
745
|
-
/** @type {(state:
|
|
757
|
+
/** @type {(state: ParseNewLineState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
758
|
+
const parseNewLineDefault = state => input => {
|
|
759
|
+
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
760
|
+
return [{ first: { kind: 'nl' }, tail: next[0] }, next[1]]
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/** @type {(state: ParseNewLineState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
764
|
+
const parseNewLineStateOp = create(parseNewLineDefault)([
|
|
765
|
+
rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, state]),
|
|
766
|
+
rangeSetFunc(rangeSetNewLine)(state => () => [empty, state])
|
|
767
|
+
])
|
|
768
|
+
|
|
769
|
+
/** @type {(state: EofState) => (input: number) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
746
770
|
const eofStateOp = create(state => () => [[{ kind: 'error', message: 'eof' }], state])([])
|
|
747
771
|
|
|
748
|
-
/** @type {
|
|
772
|
+
/** @type {operator.StateScan<number, TokenizerState, list.List<JsToken>>} */
|
|
749
773
|
const tokenizeCharCodeOp = state => {
|
|
750
774
|
switch (state.kind) {
|
|
751
775
|
case 'initial': return initialStateOp(state)
|
|
@@ -758,11 +782,12 @@ const tokenizeCharCodeOp = state => {
|
|
|
758
782
|
case 'op': return parseOperatorStateOp(state)
|
|
759
783
|
case '-': return parseMinusStateOp(state)
|
|
760
784
|
case 'ws': return parseWhitespaceStateOp(state)
|
|
785
|
+
case 'nl': return parseNewLineStateOp(state)
|
|
761
786
|
case 'eof': return eofStateOp(state)
|
|
762
787
|
}
|
|
763
788
|
}
|
|
764
789
|
|
|
765
|
-
/** @type {(state: TokenizerState) => readonly[
|
|
790
|
+
/** @type {(state: TokenizerState) => readonly[list.List<JsToken>, TokenizerState]} */
|
|
766
791
|
const tokenizeEofOp = state => {
|
|
767
792
|
switch (state.kind) {
|
|
768
793
|
case 'initial': return [empty, { kind: 'eof' }]
|
|
@@ -782,23 +807,17 @@ const tokenizeEofOp = state => {
|
|
|
782
807
|
case 'op': return [[getOperatorToken(state.value)], { kind: 'eof' }]
|
|
783
808
|
case '-': return [[{kind: '-'}], { kind: 'eof' }]
|
|
784
809
|
case 'ws': return [[{kind: 'ws'}], { kind: 'eof' }]
|
|
810
|
+
case 'nl': return [[{kind: 'nl'}], { kind: 'eof' }]
|
|
785
811
|
case 'eof': return [[{ kind: 'error', message: 'eof' }], state]
|
|
786
812
|
}
|
|
787
813
|
}
|
|
788
814
|
|
|
789
|
-
/** @type {
|
|
815
|
+
/** @type {operator.StateScan<CharCodeOrEof, TokenizerState, list.List<JsToken>>} */
|
|
790
816
|
const tokenizeOp = state => input => input === null ? tokenizeEofOp(state) : tokenizeCharCodeOp(state)(input)
|
|
791
817
|
|
|
792
818
|
const scanTokenize = stateScan(tokenizeOp)
|
|
793
819
|
|
|
794
820
|
const initial = scanTokenize({ kind: 'initial' })
|
|
795
821
|
|
|
796
|
-
/** @type {(input:
|
|
797
|
-
const tokenize = input => flat(initial(flat([/** @type {
|
|
798
|
-
|
|
799
|
-
export default {
|
|
800
|
-
/** @readonly */
|
|
801
|
-
tokenize,
|
|
802
|
-
/** @readonly */
|
|
803
|
-
isKeywordToken
|
|
804
|
-
}
|
|
822
|
+
/** @type {(input: list.List<number>) => list.List<JsToken>} */
|
|
823
|
+
export const tokenize = input => flat(initial(flat([/** @type {list.List<CharCodeOrEof>} */(input), [null]])))
|
package/js/tokenizer/test.f.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import list from '../../types/list/module.f.mjs'
|
|
1
|
+
import * as tokenizer from './module.f.mjs'
|
|
2
|
+
import * as list from '../../types/list/module.f.mjs'
|
|
3
3
|
const { toArray } = list
|
|
4
|
-
import djs from '../../djs/module.f.mjs'
|
|
5
|
-
import o from '../../types/object/module.f.mjs'
|
|
4
|
+
import * as djs from '../../djs/module.f.mjs'
|
|
5
|
+
import * as o from '../../types/object/module.f.mjs'
|
|
6
6
|
const { sort } = o
|
|
7
|
-
import encoding from '../../text/utf16/module.f.mjs'
|
|
7
|
+
import * as encoding from '../../text/utf16/module.f.mjs'
|
|
8
8
|
|
|
9
|
-
/** @type {(s: string) => readonly
|
|
9
|
+
/** @type {(s: string) => readonly tokenizer.JsToken[]} */
|
|
10
10
|
const tokenizeString = s => toArray(tokenizer.tokenize(encoding.stringToList(s)))
|
|
11
11
|
|
|
12
12
|
const stringify = djs.stringify(sort)
|
|
@@ -47,9 +47,8 @@ export default {
|
|
|
47
47
|
},
|
|
48
48
|
() => {
|
|
49
49
|
const result = stringify(tokenizeString('{ \t\n\r}'))
|
|
50
|
-
if (result !== '[{"kind":"{"},{"kind":"
|
|
50
|
+
if (result !== '[{"kind":"{"},{"kind":"nl"},{"kind":"}"}]') { throw result }
|
|
51
51
|
},
|
|
52
|
-
|
|
53
52
|
() => {
|
|
54
53
|
const result = stringify(tokenizeString('""'))
|
|
55
54
|
if (result !== '[{"kind":"string","value":""}]') { throw result }
|
|
@@ -344,16 +343,20 @@ export default {
|
|
|
344
343
|
if (result !== '[{"kind":"ws"}]') { throw result }
|
|
345
344
|
},
|
|
346
345
|
() => {
|
|
347
|
-
const result = stringify(tokenizeString('\
|
|
346
|
+
const result = stringify(tokenizeString(' \t'))
|
|
348
347
|
if (result !== '[{"kind":"ws"}]') { throw result }
|
|
349
348
|
},
|
|
349
|
+
() => {
|
|
350
|
+
const result = stringify(tokenizeString('\n'))
|
|
351
|
+
if (result !== '[{"kind":"nl"}]') { throw result }
|
|
352
|
+
},
|
|
350
353
|
() => {
|
|
351
354
|
const result = stringify(tokenizeString('\r'))
|
|
352
|
-
if (result !== '[{"kind":"
|
|
355
|
+
if (result !== '[{"kind":"nl"}]') { throw result }
|
|
353
356
|
},
|
|
354
357
|
() => {
|
|
355
|
-
const result = stringify(tokenizeString(' \t\n\r'))
|
|
356
|
-
if (result !== '[{"kind":"
|
|
358
|
+
const result = stringify(tokenizeString(' \t\n\r '))
|
|
359
|
+
if (result !== '[{"kind":"nl"}]') { throw result }
|
|
357
360
|
},
|
|
358
361
|
],
|
|
359
362
|
id: [
|
package/json/module.f.d.mts
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
declare namespace _default {
|
|
2
|
-
export { setProperty };
|
|
3
|
-
export { stringify };
|
|
4
|
-
export { serialize };
|
|
5
|
-
export { parse };
|
|
6
|
-
export { isObject };
|
|
7
|
-
}
|
|
8
|
-
export default _default;
|
|
9
|
-
export type Object = { readonly [k in string]: Unknown; };
|
|
10
|
-
export type Array = readonly Unknown[];
|
|
11
|
-
export type Unknown = Object | boolean | string | number | null | Array;
|
|
12
|
-
export type Entry = O.Entry<Unknown>;
|
|
13
|
-
export type Entries = (List.List<Entry>);
|
|
14
|
-
export type MapEntries = (entries: Entries) => Entries;
|
|
15
1
|
/**
|
|
16
2
|
* @typedef {{
|
|
17
3
|
* readonly [k in string]: Unknown
|
|
@@ -19,23 +5,29 @@ export type MapEntries = (entries: Entries) => Entries;
|
|
|
19
5
|
*/
|
|
20
6
|
/** @typedef {readonly Unknown[]} Array */
|
|
21
7
|
/** @typedef {Object|boolean|string|number|null|Array} Unknown */
|
|
22
|
-
/** @type {(value: Unknown) => (path:
|
|
23
|
-
|
|
8
|
+
/** @type {(value: Unknown) => (path: list.List<string>) => (src: Unknown) => Unknown} */
|
|
9
|
+
export const setProperty: (value: Unknown) => (path: list.List<string>) => (src: Unknown) => Unknown;
|
|
10
|
+
/** @typedef {object.Entry<Unknown>} Entry*/
|
|
11
|
+
/** @typedef {(list.List<Entry>)} Entries */
|
|
12
|
+
/** @typedef {(entries: Entries) => Entries} MapEntries */
|
|
13
|
+
/** @type {(mapEntries: MapEntries) => (value: Unknown) => list.List<string>} */
|
|
14
|
+
export const serialize: (mapEntries: MapEntries) => (value: Unknown) => list.List<string>;
|
|
24
15
|
/**
|
|
25
16
|
* The standard `JSON.stringify` rules determined by
|
|
26
17
|
* https://262.ecma-international.org/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys
|
|
27
18
|
*
|
|
28
19
|
* @type {(mapEntries: MapEntries) => (value: Unknown) => string}
|
|
29
20
|
*/
|
|
30
|
-
|
|
31
|
-
/** @typedef {O.Entry<Unknown>} Entry*/
|
|
32
|
-
/** @typedef {(List.List<Entry>)} Entries */
|
|
33
|
-
/** @typedef {(entries: Entries) => Entries} MapEntries */
|
|
34
|
-
/** @type {(mapEntries: MapEntries) => (value: Unknown) => List.List<string>} */
|
|
35
|
-
declare const serialize: (mapEntries: MapEntries) => (value: Unknown) => List.List<string>;
|
|
21
|
+
export const stringify: (mapEntries: MapEntries) => (value: Unknown) => string;
|
|
36
22
|
/** @type {(value: string) => Unknown} */
|
|
37
|
-
|
|
23
|
+
export const parse: (value: string) => Unknown;
|
|
38
24
|
/** @type {(value: Unknown) => value is Object} */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
export const isObject: (value: Unknown) => value is Object;
|
|
26
|
+
export type Object = { readonly [k in string]: Unknown; };
|
|
27
|
+
export type Array = readonly Unknown[];
|
|
28
|
+
export type Unknown = Object | boolean | string | number | null | Array;
|
|
29
|
+
export type Entry = object.Entry<Unknown>;
|
|
30
|
+
export type Entries = (list.List<Entry>);
|
|
31
|
+
export type MapEntries = (entries: Entries) => Entries;
|
|
32
|
+
import * as list from '../types/list/module.f.mjs';
|
|
33
|
+
import * as object from '../types/object/module.f.mjs';
|
package/json/module.f.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// @ts-self-types="./module.f.d.mts"
|
|
2
|
-
import
|
|
2
|
+
import * as list from '../types/list/module.f.mjs'
|
|
3
3
|
const { next, flat, map } = list
|
|
4
|
-
import string from '../types/string/module.f.mjs'
|
|
4
|
+
import * as string from '../types/string/module.f.mjs'
|
|
5
5
|
const { concat } = string
|
|
6
|
-
import
|
|
6
|
+
import * as object from '../types/object/module.f.mjs'
|
|
7
7
|
const { at } = object
|
|
8
|
-
import f from '../types/function/module.f.mjs'
|
|
8
|
+
import * as f from '../types/function/module.f.mjs'
|
|
9
9
|
const { compose, fn } = f
|
|
10
10
|
const { entries } = Object
|
|
11
|
-
import s from './serializer/module.f.mjs'
|
|
11
|
+
import * as s from './serializer/module.f.mjs'
|
|
12
12
|
const { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } = s
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -21,9 +21,9 @@ const { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize,
|
|
|
21
21
|
|
|
22
22
|
/** @typedef {Object|boolean|string|number|null|Array} Unknown */
|
|
23
23
|
|
|
24
|
-
/** @type {(value: Unknown) => (path:
|
|
25
|
-
const setProperty = value => {
|
|
26
|
-
/** @type {(path:
|
|
24
|
+
/** @type {(value: Unknown) => (path: list.List<string>) => (src: Unknown) => Unknown} */
|
|
25
|
+
export const setProperty = value => {
|
|
26
|
+
/** @type {(path: list.List<string>) => (src: Unknown) => Unknown} */
|
|
27
27
|
const f = path => src => {
|
|
28
28
|
const result = next(path)
|
|
29
29
|
if (result === null) { return value }
|
|
@@ -36,28 +36,28 @@ const setProperty = value => {
|
|
|
36
36
|
|
|
37
37
|
const colon = [':']
|
|
38
38
|
|
|
39
|
-
/** @typedef {
|
|
39
|
+
/** @typedef {object.Entry<Unknown>} Entry*/
|
|
40
40
|
|
|
41
|
-
/** @typedef {(
|
|
41
|
+
/** @typedef {(list.List<Entry>)} Entries */
|
|
42
42
|
|
|
43
43
|
/** @typedef {(entries: Entries) => Entries} MapEntries */
|
|
44
44
|
|
|
45
|
-
/** @type {(mapEntries: MapEntries) => (value: Unknown) =>
|
|
46
|
-
const serialize = sort => {
|
|
47
|
-
/** @type {(kv: readonly[string, Unknown]) =>
|
|
45
|
+
/** @type {(mapEntries: MapEntries) => (value: Unknown) => list.List<string>} */
|
|
46
|
+
export const serialize = sort => {
|
|
47
|
+
/** @type {(kv: readonly[string, Unknown]) => list.List<string>} */
|
|
48
48
|
const propertySerialize = ([k, v]) => flat([
|
|
49
49
|
stringSerialize(k),
|
|
50
50
|
colon,
|
|
51
51
|
f(v)
|
|
52
52
|
])
|
|
53
53
|
const mapPropertySerialize = map(propertySerialize)
|
|
54
|
-
/** @type {(object: Object) =>
|
|
54
|
+
/** @type {(object: Object) => list.List<string>} */
|
|
55
55
|
const objectSerialize = fn(entries)
|
|
56
56
|
.then(sort)
|
|
57
57
|
.then(mapPropertySerialize)
|
|
58
58
|
.then(objectWrap)
|
|
59
59
|
.result
|
|
60
|
-
/** @type {(value: Unknown) =>
|
|
60
|
+
/** @type {(value: Unknown) => list.List<string>} */
|
|
61
61
|
const f = value => {
|
|
62
62
|
switch (typeof value) {
|
|
63
63
|
case 'boolean': { return boolSerialize(value) }
|
|
@@ -80,23 +80,10 @@ const serialize = sort => {
|
|
|
80
80
|
*
|
|
81
81
|
* @type {(mapEntries: MapEntries) => (value: Unknown) => string}
|
|
82
82
|
*/
|
|
83
|
-
const stringify = sort => compose(serialize(sort))(concat)
|
|
83
|
+
export const stringify = sort => compose(serialize(sort))(concat)
|
|
84
84
|
|
|
85
85
|
/** @type {(value: string) => Unknown} */
|
|
86
|
-
const parse = JSON.parse
|
|
86
|
+
export const parse = JSON.parse
|
|
87
87
|
|
|
88
88
|
/** @type {(value: Unknown) => value is Object} */
|
|
89
|
-
const isObject = value => typeof value === 'object' && value !== null && !(value instanceof Array)
|
|
90
|
-
|
|
91
|
-
export default {
|
|
92
|
-
/** @readonly */
|
|
93
|
-
setProperty,
|
|
94
|
-
/** @readonly */
|
|
95
|
-
stringify,
|
|
96
|
-
/** @readonly */
|
|
97
|
-
serialize,
|
|
98
|
-
/** @readonly */
|
|
99
|
-
parse,
|
|
100
|
-
/** @readonly */
|
|
101
|
-
isObject,
|
|
102
|
-
}
|
|
89
|
+
export const isObject = value => typeof value === 'object' && value !== null && !(value instanceof Array)
|