functionalscript 0.0.592 → 0.1.594
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/.github/workflows/ci.yml +3 -3
- package/README.md +1 -0
- package/com/cpp/{module.f.cjs → module.f.mjs} +22 -21
- package/com/cpp/{test.f.cjs → test.f.mjs} +2 -2
- package/com/cpp/testlib.f.mjs +9 -0
- package/com/cs/{module.f.cjs → module.f.mjs} +20 -19
- package/com/cs/{test.f.cjs → test.f.mjs} +2 -2
- package/com/cs/testlib.f.mjs +10 -0
- package/com/rust/{module.f.cjs → module.f.mjs} +37 -35
- package/com/rust/{test.f.cjs → test.f.mjs} +2 -2
- package/com/rust/testlib.f.mjs +10 -0
- package/com/test/{build.f.cjs → build.f.mjs} +6 -6
- package/com/test/{build.cjs → build.mjs} +16 -8
- package/com/types/{module.f.cjs → module.f.mjs} +9 -8
- package/com/types/{testlib.f.cjs → testlib.f.mjs} +2 -2
- package/commonjs/build/{module.f.cjs → module.f.mjs} +23 -23
- package/commonjs/build/{test.f.cjs → test.f.mjs} +13 -12
- package/commonjs/module/function/{module.f.cjs → module.f.mjs} +4 -4
- package/commonjs/module/{module.f.cjs → module.f.mjs} +3 -5
- package/commonjs/module.f.mjs +11 -0
- package/commonjs/{module.cjs → module.mjs} +8 -6
- package/commonjs/package/dependencies/{module.f.cjs → module.f.mjs} +5 -5
- package/commonjs/package/dependencies/{test.f.cjs → test.f.mjs} +2 -2
- package/commonjs/package/{module.f.cjs → module.f.mjs} +7 -6
- package/commonjs/package/{test.f.cjs → test.f.mjs} +2 -2
- package/commonjs/path/{module.f.cjs → module.f.mjs} +15 -14
- package/commonjs/path/{test.f.cjs → test.f.mjs} +16 -14
- package/commonjs/{test.cjs → test.mjs} +4 -4
- package/dev/{module.f.cjs → module.f.mjs} +1 -1
- package/dev/module.mjs +5 -3
- package/dev/test/{module.f.cjs → module.f.mjs} +21 -9
- package/dev/{test.f.cjs → test.f.mjs} +1 -1
- package/dev/test.mjs +1 -1
- package/djs/{module.f.cjs → module.f.mjs} +18 -15
- package/djs/parser/{module.f.cjs → module.f.mjs} +29 -28
- package/djs/parser/{test.f.cjs → test.f.mjs} +10 -8
- package/djs/{test.f.cjs → test.f.mjs} +7 -5
- package/djs/tokenizer/{module.f.cjs → module.f.mjs} +19 -18
- package/djs/tokenizer/{test.f.cjs → test.f.mjs} +9 -7
- package/fsc/{module.f.cjs → module.f.mjs} +17 -16
- package/fsc/{test.f.cjs → test.f.mjs} +6 -4
- package/fsm/{module.f.cjs → module.f.mjs} +28 -24
- package/fsm/{test.f.cjs → test.f.mjs} +13 -9
- package/html/{module.f.cjs → module.f.mjs} +16 -13
- package/html/{test.f.cjs → test.f.mjs} +5 -5
- package/index.f.mjs +45 -35
- package/issues/README.md +15 -0
- package/js/tokenizer/{module.f.cjs → module.f.mjs} +52 -51
- package/js/tokenizer/{test.f.cjs → test.f.mjs} +9 -7
- package/json/{module.f.cjs → module.f.mjs} +18 -17
- package/json/parser/{module.f.cjs → module.f.mjs} +27 -26
- package/json/parser/{test.f.cjs → test.f.mjs} +10 -8
- package/json/serializer/{module.f.cjs → module.f.mjs} +12 -12
- package/json/serializer/{test.f.cjs → test.f.mjs} +4 -3
- package/json/{test.f.cjs → test.f.mjs} +6 -4
- package/json/tokenizer/{module.f.cjs → module.f.mjs} +16 -15
- package/json/tokenizer/{test.f.cjs → test.f.mjs} +9 -7
- package/jsr.json +1 -1
- package/nodejs/version/main.mjs +5 -0
- package/nodejs/version/{module.f.cjs → module.f.mjs} +2 -2
- package/nodejs/version/{test.f.cjs → test.f.mjs} +5 -5
- package/package.json +3 -3
- package/prime_field/{module.f.cjs → module.f.mjs} +6 -5
- package/prime_field/{test.f.cjs → test.f.mjs} +3 -2
- package/secp/{module.f.cjs → module.f.mjs} +7 -6
- package/secp/{test.f.cjs → test.f.mjs} +6 -6
- package/sha2/{module.f.cjs → module.f.mjs} +5 -5
- package/sha2/{test.f.cjs → test.f.mjs} +7 -6
- package/text/ascii/{module.f.cjs → module.f.mjs} +3 -3
- package/text/ascii/test.f.mjs +14 -0
- package/text/{module.f.cjs → module.f.mjs} +6 -6
- package/text/sgr/{module.f.cjs → module.f.mjs} +1 -1
- package/text/{test.f.cjs → test.f.mjs} +5 -4
- package/text/utf16/{module.f.cjs → module.f.mjs} +16 -14
- package/text/utf16/{test.f.cjs → test.f.mjs} +7 -6
- package/text/utf8/{module.f.cjs → module.f.mjs} +11 -11
- package/text/utf8/{test.f.cjs → test.f.mjs} +6 -5
- package/tsconfig.json +2 -2
- package/types/array/{module.f.cjs → module.f.mjs} +2 -2
- package/types/array/{test.f.cjs → test.f.mjs} +5 -4
- package/types/bigfloat/{module.f.cjs → module.f.mjs} +3 -3
- package/types/bigfloat/{test.f.cjs → test.f.mjs} +3 -2
- package/types/bigint/{module.f.cjs → module.f.mjs} +8 -7
- package/types/bigint/{test.f.cjs → test.f.mjs} +3 -2
- package/types/btree/find/{module.f.cjs → module.f.mjs} +12 -12
- package/types/btree/find/{test.f.cjs → test.f.mjs} +11 -9
- package/types/btree/{module.f.cjs → module.f.mjs} +7 -12
- package/types/btree/remove/{module.f.cjs → module.f.mjs} +17 -16
- package/types/btree/remove/{test.f.cjs → test.f.mjs} +9 -7
- package/types/btree/set/{module.f.cjs → module.f.mjs} +9 -9
- package/types/btree/set/{test.f.cjs → test.f.mjs} +8 -6
- package/types/btree/{test.f.cjs → test.f.mjs} +23 -20
- package/types/btree/types/{module.f.cjs → module.f.mjs} +1 -1
- package/types/byte_set/{module.f.cjs → module.f.mjs} +8 -7
- package/types/byte_set/{test.f.cjs → test.f.mjs} +8 -7
- package/types/function/compare/{module.f.cjs → module.f.mjs} +2 -2
- package/types/function/compare/{test.f.cjs → test.f.mjs} +3 -2
- package/types/function/{module.f.cjs → module.f.mjs} +1 -5
- package/types/function/operator/{module.f.cjs → module.f.mjs} +1 -1
- package/types/function/{test.f.cjs → test.f.mjs} +4 -2
- package/types/list/{module.f.cjs → module.f.mjs} +12 -12
- package/types/list/{test.f.cjs → test.f.mjs} +13 -11
- package/types/map/{module.f.cjs → module.f.mjs} +21 -18
- package/types/map/{test.f.cjs → test.f.mjs} +5 -4
- package/types/nibble_set/{module.f.cjs → module.f.mjs} +1 -1
- package/types/nibble_set/{test.f.cjs → test.f.mjs} +4 -3
- package/types/nullable/{module.f.cjs → module.f.mjs} +1 -1
- package/types/nullable/{test.f.cjs → test.f.mjs} +2 -2
- package/types/number/module.f.mjs +26 -0
- package/types/number/{test.f.cjs → test.f.mjs} +3 -2
- package/types/object/{module.f.cjs → module.f.mjs} +6 -6
- package/types/object/{test.f.cjs → test.f.mjs} +2 -2
- package/types/range/{module.f.cjs → module.f.mjs} +1 -1
- package/types/range/{test.f.cjs → test.f.mjs} +2 -2
- package/types/range_map/{module.f.cjs → module.f.mjs} +16 -15
- package/types/range_map/{test.f.cjs → test.f.mjs} +35 -33
- package/types/result/{module.f.cjs → module.f.mjs} +1 -1
- package/types/result/{module.cjs → module.mjs} +3 -3
- package/types/sorted_list/{module.f.cjs → module.f.mjs} +11 -10
- package/types/sorted_list/{test.f.cjs → test.f.mjs} +14 -10
- package/types/sorted_set/{module.f.cjs → module.f.mjs} +8 -7
- package/types/sorted_set/{test.f.cjs → test.f.mjs} +14 -10
- package/types/string/{module.f.cjs → module.f.mjs} +8 -7
- package/types/string/{test.f.cjs → test.f.mjs} +5 -3
- package/types/string_set/{module.f.cjs → module.f.mjs} +15 -10
- package/types/string_set/{test.f.cjs → test.f.mjs} +2 -2
- package/com/cpp/testlib.f.cjs +0 -6
- package/com/cs/testlib.f.cjs +0 -6
- package/com/module.f.cjs +0 -6
- package/com/rust/testlib.f.cjs +0 -6
- package/commonjs/module.f.cjs +0 -20
- package/nodejs/module.f.cjs +0 -4
- package/nodejs/version/main.cjs +0 -6
- package/text/ascii/test.f.cjs +0 -12
- package/types/number/module.f.cjs +0 -24
- package/types/object/test.html +0 -9
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import operator, * as Operator from '../../types/function/operator/module.f.mjs'
|
|
2
|
+
import range_map, * as RangeMap from '../../types/range_map/module.f.mjs'
|
|
3
3
|
const { merge, fromRange, get } = range_map
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import list, * as List from '../../types/list/module.f.mjs'
|
|
5
|
+
import map, * as Map from '../../types/map/module.f.mjs'
|
|
6
6
|
const { at } = map
|
|
7
|
-
|
|
7
|
+
import _range, * as Range from '../../types/range/module.f.mjs'
|
|
8
8
|
const { one } = _range
|
|
9
9
|
const { empty, stateScan, flat, toArray, reduce: listReduce, scan } = list
|
|
10
|
-
|
|
10
|
+
import * as bigfloatT from '../../types/bigfloat/module.f.mjs'
|
|
11
11
|
const { fromCharCode } = String
|
|
12
|
+
import ascii from '../../text/ascii/module.f.mjs'
|
|
12
13
|
const {
|
|
13
14
|
range,
|
|
14
15
|
//
|
|
@@ -66,7 +67,7 @@ const {
|
|
|
66
67
|
leftCurlyBracket,
|
|
67
68
|
rightCurlyBracket,
|
|
68
69
|
dollarSign
|
|
69
|
-
} =
|
|
70
|
+
} = ascii
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
* @typedef {{
|
|
@@ -79,7 +80,7 @@ const {
|
|
|
79
80
|
* @typedef {{
|
|
80
81
|
* readonly kind: 'number'
|
|
81
82
|
* readonly value: string
|
|
82
|
-
* readonly bf:
|
|
83
|
+
* readonly bf: bigfloatT.BigFloat
|
|
83
84
|
* }} NumberToken
|
|
84
85
|
* */
|
|
85
86
|
|
|
@@ -297,14 +298,14 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
297
298
|
|
|
298
299
|
/** @typedef {number|null} CharCodeOrEof */
|
|
299
300
|
|
|
300
|
-
/** @typedef {(input: number) => readonly[
|
|
301
|
+
/** @typedef {(input: number) => readonly[List.List<JsToken>, TokenizerState]} ToToken */
|
|
301
302
|
|
|
302
303
|
/**
|
|
303
304
|
* @template T
|
|
304
305
|
* @typedef {(state: T) => ToToken} CreateToToken<T>
|
|
305
306
|
*/
|
|
306
307
|
|
|
307
|
-
/** @typedef {
|
|
308
|
+
/** @typedef {List.List<Range.Range>} RangeSet */
|
|
308
309
|
|
|
309
310
|
/**
|
|
310
311
|
* @template T
|
|
@@ -313,7 +314,7 @@ const rangeId = [digitRange, ...rangeIdStart]
|
|
|
313
314
|
|
|
314
315
|
/**
|
|
315
316
|
* @template T
|
|
316
|
-
* @typedef {
|
|
317
|
+
* @typedef {RangeMap.RangeMapArray<CreateToToken<T>>} RangeMapToToken<T>
|
|
317
318
|
*/
|
|
318
319
|
|
|
319
320
|
/** @type {(old: string) => (input: number) => string} */
|
|
@@ -326,34 +327,34 @@ const union = def => a => b => {
|
|
|
326
327
|
throw [a, b]
|
|
327
328
|
}
|
|
328
329
|
|
|
329
|
-
/** @type {<T>(def: CreateToToken<T>) =>
|
|
330
|
+
/** @type {<T>(def: CreateToToken<T>) => RangeMap.RangeMerge<CreateToToken<T>>} */
|
|
330
331
|
const rangeMapMerge = def => merge({
|
|
331
332
|
union: union(def),
|
|
332
333
|
equal: operator.strictEqual,
|
|
333
334
|
})
|
|
334
335
|
|
|
335
|
-
/** @type {<T>(r:
|
|
336
|
+
/** @type {<T>(r: Range.Range) => (f: CreateToToken<T>) => RangeFunc<T>} */
|
|
336
337
|
const rangeFunc = r => f => def => fromRange(def)(r)(f)
|
|
337
338
|
|
|
338
|
-
/** @type {<T>(def: CreateToToken<T>) => (
|
|
339
|
+
/** @type {<T>(def: CreateToToken<T>) => (Operator.Scan<RangeFunc<T>, RangeMapToToken<T>>)} */
|
|
339
340
|
const scanRangeOp = def => f => [f(def), scanRangeOp(def)]
|
|
340
341
|
|
|
341
|
-
/** @type {<T>(def: CreateToToken<T>) => (a:
|
|
342
|
+
/** @type {<T>(def: CreateToToken<T>) => (a: List.List<RangeFunc<T>>) => RangeMapToToken<T>} */
|
|
342
343
|
const reduceRangeMap = def => a => {
|
|
343
344
|
const rm = scan(scanRangeOp(def))(a)
|
|
344
345
|
return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
|
|
345
346
|
}
|
|
346
347
|
|
|
347
|
-
/** @type {<T>(def: CreateToToken<T>) => (f: CreateToToken<T>) => (
|
|
348
|
+
/** @type {<T>(def: CreateToToken<T>) => (f: CreateToToken<T>) => (Operator.Scan<Range.Range, RangeMapToToken<T>>)} */
|
|
348
349
|
const scanRangeSetOp = def => f => r => [fromRange(def)(r)(f), scanRangeSetOp(def)(f)]
|
|
349
350
|
|
|
350
|
-
/** @type {<T>(rs:
|
|
351
|
+
/** @type {<T>(rs: List.List<Range.Range>) => (f: CreateToToken<T>) => RangeFunc<T>} */
|
|
351
352
|
const rangeSetFunc = rs => f => def => {
|
|
352
353
|
const rm = scan(scanRangeSetOp(def)(f))(rs)
|
|
353
354
|
return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
|
|
354
355
|
}
|
|
355
356
|
|
|
356
|
-
/** @type {<T>(def: CreateToToken<T>) => (a:
|
|
357
|
+
/** @type {<T>(def: CreateToToken<T>) => (a: List.List<RangeFunc<T>>) => CreateToToken<T>} */
|
|
357
358
|
const create = def => a => {
|
|
358
359
|
/** @typedef {typeof def extends CreateToToken<infer T> ? T : never} T */
|
|
359
360
|
const i = reduceRangeMap(def)(a)
|
|
@@ -390,7 +391,7 @@ const bufferToNumberToken = ({numberKind, value, b}) =>
|
|
|
390
391
|
|
|
391
392
|
/**
|
|
392
393
|
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords
|
|
393
|
-
* @type {
|
|
394
|
+
* @type {List.List<Map.Entry<JsToken>>}
|
|
394
395
|
*/
|
|
395
396
|
const keywordEntries = [
|
|
396
397
|
['arguments', { kind: 'arguments'}],
|
|
@@ -450,7 +451,7 @@ const isKeywordToken = token => at(token.kind)(keywordMap) !== null
|
|
|
450
451
|
|
|
451
452
|
/**
|
|
452
453
|
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators
|
|
453
|
-
* @type {
|
|
454
|
+
* @type {List.List<Map.Entry<JsToken>>}
|
|
454
455
|
*/
|
|
455
456
|
const operatorEntries = [
|
|
456
457
|
['!', { kind: '!'}],
|
|
@@ -518,7 +519,7 @@ const getOperatorToken = op => at(op)(operatorMap) ?? { kind: 'error', message:
|
|
|
518
519
|
/** @type {(op: string) => Boolean} */
|
|
519
520
|
const hasOperatorToken = op => at(op)(operatorMap) !== null
|
|
520
521
|
|
|
521
|
-
/** @type {(state: InitialState) => (input: number) => readonly[
|
|
522
|
+
/** @type {(state: InitialState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
522
523
|
const initialStateOp = create(state => () => [[{ kind: 'error', message: 'unexpected character' }], state])([
|
|
523
524
|
rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: 'int' }]),
|
|
524
525
|
rangeSetFunc(rangeIdStart)(() => input => [empty, { kind: 'id', value: fromCharCode(input) }]),
|
|
@@ -528,14 +529,14 @@ const initialStateOp = create(state => () => [[{ kind: 'error', message: 'unexpe
|
|
|
528
529
|
rangeSetFunc(rangeOpStart)(() => input => [empty, { kind: 'op', value: fromCharCode(input) }])
|
|
529
530
|
])
|
|
530
531
|
|
|
531
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
532
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
532
533
|
const invalidNumberToToken = () => input =>
|
|
533
534
|
{
|
|
534
535
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
535
536
|
return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
|
|
536
537
|
}
|
|
537
538
|
|
|
538
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
539
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
539
540
|
const fullStopToToken = state => input => {
|
|
540
541
|
switch (state.numberKind) {
|
|
541
542
|
case '0':
|
|
@@ -544,7 +545,7 @@ const fullStopToToken = state => input => {
|
|
|
544
545
|
}
|
|
545
546
|
}
|
|
546
547
|
|
|
547
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
548
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
548
549
|
const digit0ToToken = state => input => {
|
|
549
550
|
switch (state.numberKind) {
|
|
550
551
|
case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
|
|
@@ -558,7 +559,7 @@ const digit0ToToken = state => input => {
|
|
|
558
559
|
}
|
|
559
560
|
}
|
|
560
561
|
|
|
561
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
562
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
562
563
|
const digit19ToToken = state => input => {
|
|
563
564
|
switch (state.numberKind) {
|
|
564
565
|
case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
|
|
@@ -572,7 +573,7 @@ const digit19ToToken = state => input => {
|
|
|
572
573
|
}
|
|
573
574
|
}
|
|
574
575
|
|
|
575
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
576
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
576
577
|
const expToToken = state => input => {
|
|
577
578
|
switch (state.numberKind) {
|
|
578
579
|
case '0':
|
|
@@ -582,7 +583,7 @@ const expToToken = state => input => {
|
|
|
582
583
|
}
|
|
583
584
|
}
|
|
584
585
|
|
|
585
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
586
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
586
587
|
const hyphenMinusToToken = state => input => {
|
|
587
588
|
switch (state.numberKind) {
|
|
588
589
|
case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: { ... state.b, es: -1}, numberKind: 'e-' }]
|
|
@@ -590,7 +591,7 @@ const hyphenMinusToToken = state => input => {
|
|
|
590
591
|
}
|
|
591
592
|
}
|
|
592
593
|
|
|
593
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
594
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
594
595
|
const plusSignToToken = state => input => {
|
|
595
596
|
switch (state.numberKind) {
|
|
596
597
|
case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e+' }]
|
|
@@ -598,7 +599,7 @@ const plusSignToToken = state => input => {
|
|
|
598
599
|
}
|
|
599
600
|
}
|
|
600
601
|
|
|
601
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
602
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
602
603
|
const terminalToToken = state => input => {
|
|
603
604
|
switch (state.numberKind) {
|
|
604
605
|
case '.':
|
|
@@ -617,7 +618,7 @@ const terminalToToken = state => input => {
|
|
|
617
618
|
}
|
|
618
619
|
}
|
|
619
620
|
|
|
620
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
621
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
621
622
|
const bigintToToken = state => input => {
|
|
622
623
|
switch (state.numberKind) {
|
|
623
624
|
case '0':
|
|
@@ -633,7 +634,7 @@ const bigintToToken = state => input => {
|
|
|
633
634
|
}
|
|
634
635
|
}
|
|
635
636
|
|
|
636
|
-
/** @type {(state: ParseNumberState) => (input: number) => readonly[
|
|
637
|
+
/** @type {(state: ParseNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
637
638
|
const parseNumberStateOp = create(invalidNumberToToken)([
|
|
638
639
|
rangeFunc(one(fullStop))(fullStopToToken),
|
|
639
640
|
rangeFunc(one(digit0))(digit0ToToken),
|
|
@@ -645,7 +646,7 @@ const parseNumberStateOp = create(invalidNumberToToken)([
|
|
|
645
646
|
rangeFunc(one(latinSmallLetterN))(bigintToToken),
|
|
646
647
|
])
|
|
647
648
|
|
|
648
|
-
/** @type {(state: InvalidNumberState) => (input: number) => readonly[
|
|
649
|
+
/** @type {(state: InvalidNumberState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
649
650
|
const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber' }])([
|
|
650
651
|
rangeSetFunc(rangeSetTerminalForNumber)(() => input => {
|
|
651
652
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
@@ -653,26 +654,26 @@ const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber'
|
|
|
653
654
|
})
|
|
654
655
|
])
|
|
655
656
|
|
|
656
|
-
/** @type {(state: ParseMinusState) => (input: number) => readonly[
|
|
657
|
+
/** @type {(state: ParseMinusState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
657
658
|
const parseMinusStateOp = create(() => input => tokenizeOp({ kind: 'op', value: '-' })(input))([
|
|
658
659
|
rangeFunc(one(fullStop))(() => input => tokenizeOp({ kind: 'invalidNumber' })(input)),
|
|
659
660
|
rangeFunc(one(digit0))(() => () => [empty, { kind: 'number', value: '-0', b: startNegativeNumber, numberKind: '0' }]),
|
|
660
661
|
rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: appendChar('-')(input), b: addIntDigit(input)(startNegativeNumber), numberKind: 'int' }]),
|
|
661
662
|
])
|
|
662
663
|
|
|
663
|
-
/** @type {(state: ParseStringState) => (input: number) => readonly[
|
|
664
|
+
/** @type {(state: ParseStringState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
664
665
|
const parseStringStateOp = create(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }])([
|
|
665
666
|
rangeFunc(one(quotationMark))(state => () => [[{ kind: 'string', value: state.value }], { kind: 'initial' }]),
|
|
666
667
|
rangeFunc(one(reverseSolidus))(state => () => [empty, { kind: 'escapeChar', value: state.value }])
|
|
667
668
|
])
|
|
668
669
|
|
|
669
|
-
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[
|
|
670
|
+
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
670
671
|
const parseEscapeDefault = state => input => {
|
|
671
672
|
const next = tokenizeOp({ kind: 'string', value: state.value })(input)
|
|
672
673
|
return [{ first: { kind: 'error', message: 'unescaped character' }, tail: next[0] }, next[1]]
|
|
673
674
|
}
|
|
674
675
|
|
|
675
|
-
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[
|
|
676
|
+
/** @type {(state: ParseEscapeCharState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
676
677
|
const parseEscapeCharStateOp = create(parseEscapeDefault)([
|
|
677
678
|
rangeSetFunc([one(quotationMark), one(reverseSolidus), one(solidus)])(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }]),
|
|
678
679
|
rangeFunc(one(latinSmallLetterB))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(backspace) }]),
|
|
@@ -683,13 +684,13 @@ const parseEscapeCharStateOp = create(parseEscapeDefault)([
|
|
|
683
684
|
rangeFunc(one(latinSmallLetterU))(state => () => [empty, { kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0 }]),
|
|
684
685
|
])
|
|
685
686
|
|
|
686
|
-
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
687
|
+
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
687
688
|
const parseUnicodeCharDefault = state => input => {
|
|
688
689
|
const next = tokenizeOp({ kind: 'string', value: state.value })(input)
|
|
689
690
|
return [{ first: { kind: 'error', message: 'invalid hex value' }, tail: next[0] }, next[1]]
|
|
690
691
|
}
|
|
691
692
|
|
|
692
|
-
/** @type {(offser: number) => (state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
693
|
+
/** @type {(offser: number) => (state: ParseUnicodeCharState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
693
694
|
const parseUnicodeCharHex = offset => state => input => {
|
|
694
695
|
const hexValue = input - offset
|
|
695
696
|
const newUnicode = state.unicode | (hexValue << (3 - state.hexIndex) * 4)
|
|
@@ -698,7 +699,7 @@ const parseUnicodeCharHex = offset => state => input => {
|
|
|
698
699
|
{ kind: 'unicodeChar', value: state.value, unicode: newUnicode, hexIndex: state.hexIndex + 1 }]
|
|
699
700
|
}
|
|
700
701
|
|
|
701
|
-
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[
|
|
702
|
+
/** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
702
703
|
const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
|
|
703
704
|
rangeFunc(digitRange)(parseUnicodeCharHex(digit0)),
|
|
704
705
|
rangeFunc(rangeSmallAF)(parseUnicodeCharHex(latinSmallLetterA - 10)),
|
|
@@ -708,19 +709,19 @@ const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
|
|
|
708
709
|
/** @type {(s: string) => JsToken} */
|
|
709
710
|
const idToToken = s => at(s)(keywordMap) ?? { kind: 'id', value: s }
|
|
710
711
|
|
|
711
|
-
/** @type {(state: ParseIdState) => (input: number) => readonly[
|
|
712
|
+
/** @type {(state: ParseIdState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
712
713
|
const parseIdDefault = state => input => {
|
|
713
714
|
const keyWordToken = idToToken(state.value)
|
|
714
715
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
715
716
|
return [{ first: keyWordToken, tail: next[0] }, next[1]]
|
|
716
717
|
}
|
|
717
718
|
|
|
718
|
-
/** @type {(state: ParseIdState) => (input: number) => readonly[
|
|
719
|
+
/** @type {(state: ParseIdState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
719
720
|
const parseIdStateOp = create(parseIdDefault)([
|
|
720
721
|
rangeSetFunc(rangeId)(state => input => [empty, { kind: 'id', value: appendChar(state.value)(input) }])
|
|
721
722
|
])
|
|
722
723
|
|
|
723
|
-
/** @type {(state: ParseOperatorState) => (input: number) => readonly[
|
|
724
|
+
/** @type {(state: ParseOperatorState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
724
725
|
const parseOperatorStateOp = state => input => {
|
|
725
726
|
const nextStateValue = appendChar(state.value)(input)
|
|
726
727
|
if (hasOperatorToken(nextStateValue))
|
|
@@ -729,21 +730,21 @@ const parseOperatorStateOp = state => input => {
|
|
|
729
730
|
return [{ first: getOperatorToken(state.value), tail: next[0] }, next[1]]
|
|
730
731
|
}
|
|
731
732
|
|
|
732
|
-
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[
|
|
733
|
+
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
733
734
|
const parseWhitespaceDefault = state => input => {
|
|
734
735
|
const next = tokenizeOp({ kind: 'initial' })(input)
|
|
735
736
|
return [{ first: { kind: 'ws' }, tail: next[0] }, next[1]]
|
|
736
737
|
}
|
|
737
738
|
|
|
738
|
-
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[
|
|
739
|
+
/** @type {(state: ParseWhitespaceState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
739
740
|
const parseWhitespaceStateOp = create(parseWhitespaceDefault)([
|
|
740
741
|
rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, state])
|
|
741
742
|
])
|
|
742
743
|
|
|
743
|
-
/** @type {(state: EofState) => (input: number) => readonly[
|
|
744
|
+
/** @type {(state: EofState) => (input: number) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
744
745
|
const eofStateOp = create(state => () => [[{ kind: 'error', message: 'eof' }], state])([])
|
|
745
746
|
|
|
746
|
-
/** @type {
|
|
747
|
+
/** @type {Operator.StateScan<number, TokenizerState, List.List<JsToken>>} */
|
|
747
748
|
const tokenizeCharCodeOp = state => {
|
|
748
749
|
switch (state.kind) {
|
|
749
750
|
case 'initial': return initialStateOp(state)
|
|
@@ -760,7 +761,7 @@ const tokenizeCharCodeOp = state => {
|
|
|
760
761
|
}
|
|
761
762
|
}
|
|
762
763
|
|
|
763
|
-
/** @type {(state: TokenizerState) => readonly[
|
|
764
|
+
/** @type {(state: TokenizerState) => readonly[List.List<JsToken>, TokenizerState]} */
|
|
764
765
|
const tokenizeEofOp = state => {
|
|
765
766
|
switch (state.kind) {
|
|
766
767
|
case 'initial': return [empty, { kind: 'eof' }]
|
|
@@ -784,17 +785,17 @@ const tokenizeEofOp = state => {
|
|
|
784
785
|
}
|
|
785
786
|
}
|
|
786
787
|
|
|
787
|
-
/** @type {
|
|
788
|
+
/** @type {Operator.StateScan<CharCodeOrEof, TokenizerState, List.List<JsToken>>} */
|
|
788
789
|
const tokenizeOp = state => input => input === null ? tokenizeEofOp(state) : tokenizeCharCodeOp(state)(input)
|
|
789
790
|
|
|
790
791
|
const scanTokenize = stateScan(tokenizeOp)
|
|
791
792
|
|
|
792
793
|
const initial = scanTokenize({ kind: 'initial' })
|
|
793
794
|
|
|
794
|
-
/** @type {(input:
|
|
795
|
-
const tokenize = input => flat(initial(flat([/** @type {
|
|
795
|
+
/** @type {(input: List.List<number>) => List.List<JsToken>} */
|
|
796
|
+
const tokenize = input => flat(initial(flat([/** @type {List.List<CharCodeOrEof>} */(input), [null]])))
|
|
796
797
|
|
|
797
|
-
|
|
798
|
+
export default {
|
|
798
799
|
/** @readonly */
|
|
799
800
|
tokenize,
|
|
800
801
|
/** @readonly */
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import tokenizer, * as tokenizerT from './module.f.mjs'
|
|
2
|
+
import list from '../../types/list/module.f.mjs'
|
|
3
|
+
const { toArray, countdown } = list
|
|
4
|
+
import djs from '../../djs/module.f.mjs'
|
|
5
|
+
import o from '../../types/object/module.f.mjs'
|
|
6
|
+
const { sort } = o
|
|
7
|
+
import encoding from '../../text/utf16/module.f.mjs'
|
|
6
8
|
|
|
7
|
-
/** @type {(s: string) => readonly
|
|
9
|
+
/** @type {(s: string) => readonly tokenizerT.JsToken[]} */
|
|
8
10
|
const tokenizeString = s => toArray(tokenizer.tokenize(encoding.stringToList(s)))
|
|
9
11
|
|
|
10
12
|
const stringify = djs.stringify(sort)
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
export default {
|
|
13
15
|
djs: [
|
|
14
16
|
() => {
|
|
15
17
|
const result = tokenizeString('')
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
const { next, flat, map
|
|
3
|
-
|
|
4
|
-
const
|
|
1
|
+
import list, * as List from '../types/list/module.f.mjs'
|
|
2
|
+
const { next, flat, map } = list
|
|
3
|
+
import string from '../types/string/module.f.mjs'
|
|
4
|
+
const { concat } = string
|
|
5
|
+
import object, * as O from '../types/object/module.f.mjs'
|
|
5
6
|
const { at } = object
|
|
6
|
-
|
|
7
|
+
import f from '../types/function/module.f.mjs'
|
|
8
|
+
const { compose, fn } = f
|
|
7
9
|
const { entries } = Object
|
|
8
|
-
|
|
10
|
+
import s from './serializer/module.f.mjs'
|
|
11
|
+
const { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } = s
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* @typedef {{
|
|
@@ -17,9 +20,9 @@ const { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize,
|
|
|
17
20
|
|
|
18
21
|
/** @typedef {Object|boolean|string|number|null|Array} Unknown */
|
|
19
22
|
|
|
20
|
-
/** @type {(value: Unknown) => (path:
|
|
23
|
+
/** @type {(value: Unknown) => (path: List.List<string>) => (src: Unknown) => Unknown} */
|
|
21
24
|
const setProperty = value => {
|
|
22
|
-
/** @type {(path:
|
|
25
|
+
/** @type {(path: List.List<string>) => (src: Unknown) => Unknown} */
|
|
23
26
|
const f = path => src => {
|
|
24
27
|
const result = next(path)
|
|
25
28
|
if (result === null) { return value }
|
|
@@ -32,28 +35,28 @@ const setProperty = value => {
|
|
|
32
35
|
|
|
33
36
|
const colon = [':']
|
|
34
37
|
|
|
35
|
-
/** @typedef {
|
|
38
|
+
/** @typedef {O.Entry<Unknown>} Entry*/
|
|
36
39
|
|
|
37
|
-
/** @typedef {(
|
|
40
|
+
/** @typedef {(List.List<Entry>)} Entries */
|
|
38
41
|
|
|
39
42
|
/** @typedef {(entries: Entries) => Entries} MapEntries */
|
|
40
43
|
|
|
41
|
-
/** @type {(mapEntries: MapEntries) => (value: Unknown) =>
|
|
44
|
+
/** @type {(mapEntries: MapEntries) => (value: Unknown) => List.List<string>} */
|
|
42
45
|
const serialize = sort => {
|
|
43
|
-
/** @type {(kv: readonly[string, Unknown]) =>
|
|
46
|
+
/** @type {(kv: readonly[string, Unknown]) => List.List<string>} */
|
|
44
47
|
const propertySerialize = ([k, v]) => flat([
|
|
45
48
|
stringSerialize(k),
|
|
46
49
|
colon,
|
|
47
50
|
f(v)
|
|
48
51
|
])
|
|
49
52
|
const mapPropertySerialize = map(propertySerialize)
|
|
50
|
-
/** @type {(object: Object) =>
|
|
53
|
+
/** @type {(object: Object) => List.List<string>} */
|
|
51
54
|
const objectSerialize = fn(entries)
|
|
52
55
|
.then(sort)
|
|
53
56
|
.then(mapPropertySerialize)
|
|
54
57
|
.then(objectWrap)
|
|
55
58
|
.result
|
|
56
|
-
/** @type {(value: Unknown) =>
|
|
59
|
+
/** @type {(value: Unknown) => List.List<string>} */
|
|
57
60
|
const f = value => {
|
|
58
61
|
switch (typeof value) {
|
|
59
62
|
case 'boolean': { return boolSerialize(value) }
|
|
@@ -84,9 +87,7 @@ const parse = JSON.parse
|
|
|
84
87
|
/** @type {(value: Unknown) => value is Object} */
|
|
85
88
|
const isObject = value => typeof value === 'object' && value !== null && !(value instanceof Array)
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
/** @readonly */
|
|
89
|
-
tokenizer: require('./tokenizer/module.f.cjs'),
|
|
90
|
+
export default {
|
|
90
91
|
/** @readonly */
|
|
91
92
|
setProperty,
|
|
92
93
|
/** @readonly */
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import result, * as Result from '../../types/result/module.f.mjs'
|
|
2
|
+
import list, * as List from '../../types/list/module.f.mjs'
|
|
3
3
|
const { fold, first, drop, toArray } = list
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import * as Operator from '../../types/function/operator/module.f.mjs'
|
|
5
|
+
import * as tokenizerT from '../tokenizer/module.f.mjs'
|
|
6
|
+
import map, * as Map from '../../types/map/module.f.mjs'
|
|
7
7
|
const { setReplace } = map
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import * as Json from '../module.f.mjs'
|
|
9
|
+
import o from '../../types/object/module.f.mjs'
|
|
10
|
+
const { fromMap } = o
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* @typedef {{
|
|
14
15
|
* readonly kind: 'object'
|
|
15
|
-
* readonly values:
|
|
16
|
+
* readonly values: Map.Map<Json.Unknown>
|
|
16
17
|
* readonly key: string
|
|
17
18
|
* }} JsonObject
|
|
18
19
|
* */
|
|
@@ -20,7 +21,7 @@ const { fromMap } = require('../../types/object/module.f.cjs')
|
|
|
20
21
|
/**
|
|
21
22
|
* @typedef {{
|
|
22
23
|
* readonly kind: 'array'
|
|
23
|
-
* readonly values:
|
|
24
|
+
* readonly values: List.List<Json.Unknown>
|
|
24
25
|
* }} JsonArray
|
|
25
26
|
* */
|
|
26
27
|
|
|
@@ -31,7 +32,7 @@ const { fromMap } = require('../../types/object/module.f.cjs')
|
|
|
31
32
|
* } JsonStackElement
|
|
32
33
|
*/
|
|
33
34
|
|
|
34
|
-
/** @typedef {
|
|
35
|
+
/** @typedef {List.List<JsonStackElement>} JsonStack */
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* @typedef {{
|
|
@@ -44,7 +45,7 @@ const { fromMap } = require('../../types/object/module.f.cjs')
|
|
|
44
45
|
/**
|
|
45
46
|
* @typedef {{
|
|
46
47
|
* readonly status: 'result'
|
|
47
|
-
* readonly value:
|
|
48
|
+
* readonly value: Json.Unknown
|
|
48
49
|
* }} StateResult
|
|
49
50
|
*/
|
|
50
51
|
|
|
@@ -66,10 +67,10 @@ const { fromMap } = require('../../types/object/module.f.cjs')
|
|
|
66
67
|
/** @type {(obj: JsonObject) => (key: string) => JsonObject} */
|
|
67
68
|
const addKeyToObject = obj => key => ({ kind: 'object', values: obj.values, key: key })
|
|
68
69
|
|
|
69
|
-
/** @type {(obj: JsonObject) => (value:
|
|
70
|
+
/** @type {(obj: JsonObject) => (value: Json.Unknown) => JsonObject} */
|
|
70
71
|
const addValueToObject = obj => value => ({ kind: 'object', values: setReplace(obj.key)(value)(obj.values), key: '' })
|
|
71
72
|
|
|
72
|
-
/** @type {(array: JsonArray) => (value:
|
|
73
|
+
/** @type {(array: JsonArray) => (value: Json.Unknown) => JsonArray} */
|
|
73
74
|
const addToArray = array => value => ({ kind: 'array', values: list.concat(array.values)([value]) })
|
|
74
75
|
|
|
75
76
|
/** @type {(state: StateParse) => (key: string) => JsonState} */
|
|
@@ -78,7 +79,7 @@ const pushKey = state => value => {
|
|
|
78
79
|
return { status: 'error', message: 'error' }
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
/** @type {(state: StateParse) => (value:
|
|
82
|
+
/** @type {(state: StateParse) => (value: Json.Unknown) => JsonState} */
|
|
82
83
|
const pushValue = state => value => {
|
|
83
84
|
if (state.top === null) { return { status: 'result', value: value } }
|
|
84
85
|
if (state.top.kind === 'array') { return { status: '[v', top: addToArray(state.top)(value), stack: state.stack } }
|
|
@@ -113,7 +114,7 @@ const endObject = state => {
|
|
|
113
114
|
return pushValue(newState)(obj)
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
/** @type {(token:
|
|
117
|
+
/** @type {(token: tokenizerT.JsonToken) => Json.Unknown} */
|
|
117
118
|
const tokenToValue = token => {
|
|
118
119
|
switch (token.kind) {
|
|
119
120
|
case 'null': return null
|
|
@@ -125,7 +126,7 @@ const tokenToValue = token => {
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
/** @type {(token:
|
|
129
|
+
/** @type {(token: tokenizerT.JsonToken) => boolean} */
|
|
129
130
|
const isValueToken = token => {
|
|
130
131
|
switch (token.kind) {
|
|
131
132
|
case 'null':
|
|
@@ -137,7 +138,7 @@ const isValueToken = token => {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
/** @type {(token:
|
|
141
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
141
142
|
const parseValueOp = token => state => {
|
|
142
143
|
if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
|
|
143
144
|
if (token.kind === '[') { return startArray(state) }
|
|
@@ -145,7 +146,7 @@ const parseValueOp = token => state => {
|
|
|
145
146
|
return { status: 'error', message: 'unexpected token' }
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
/** @type {(token:
|
|
149
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
149
150
|
const parseArrayStartOp = token => state => {
|
|
150
151
|
if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
|
|
151
152
|
if (token.kind === '[') { return startArray(state) }
|
|
@@ -154,40 +155,40 @@ const parseArrayStartOp = token => state => {
|
|
|
154
155
|
return { status: 'error', message: 'unexpected token' }
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
/** @type {(token:
|
|
158
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
158
159
|
const parseArrayValueOp = token => state => {
|
|
159
160
|
if (token.kind === ']') { return endArray(state) }
|
|
160
161
|
if (token.kind === ',') { return { status: '[,', top: state.top, stack: state.stack } }
|
|
161
162
|
return { status: 'error', message: 'unexpected token' }
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
/** @type {(token:
|
|
165
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
165
166
|
const parseObjectStartOp = token => state => {
|
|
166
167
|
if (token.kind === 'string') { return pushKey(state)(token.value) }
|
|
167
168
|
if (token.kind === '}') { return endObject(state) }
|
|
168
169
|
return { status: 'error', message: 'unexpected token' }
|
|
169
170
|
}
|
|
170
171
|
|
|
171
|
-
/** @type {(token:
|
|
172
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
172
173
|
const parseObjectKeyOp = token => state => {
|
|
173
174
|
if (token.kind === ':') { return { status: '{:', top: state.top, stack: state.stack } }
|
|
174
175
|
return { status: 'error', message: 'unexpected token' }
|
|
175
176
|
}
|
|
176
177
|
|
|
177
|
-
/** @type {(token:
|
|
178
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
178
179
|
const parseObjectNextOp = token => state => {
|
|
179
180
|
if (token.kind === '}') { return endObject(state) }
|
|
180
181
|
if (token.kind === ',') { return { status: '{,', top: state.top, stack: state.stack } }
|
|
181
182
|
return { status: 'error', message: 'unexpected token' }
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
/** @type {(token:
|
|
185
|
+
/** @type {(token: tokenizerT.JsonToken) => (state: StateParse) => JsonState}} */
|
|
185
186
|
const parseObjectCommaOp = token => state => {
|
|
186
187
|
if (token.kind === 'string') { return pushKey(state)(token.value) }
|
|
187
188
|
return { status: 'error', message: 'unexpected token' }
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
/** @type {
|
|
191
|
+
/** @type {Operator.Fold<tokenizerT.JsonToken, JsonState>} */
|
|
191
192
|
const foldOp = token => state => {
|
|
192
193
|
switch (state.status) {
|
|
193
194
|
case 'result': return { status: 'error', message: 'unexpected token' }
|
|
@@ -204,7 +205,7 @@ const foldOp = token => state => {
|
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
|
|
207
|
-
/** @type {(tokenList:
|
|
208
|
+
/** @type {(tokenList: List.List<tokenizerT.JsonToken>) => Result.Result<Json.Unknown, string>} */
|
|
208
209
|
const parse = tokenList => {
|
|
209
210
|
const state = fold(foldOp)({ status: '', top: null, stack: null })(tokenList)
|
|
210
211
|
switch (state.status) {
|
|
@@ -214,7 +215,7 @@ const parse = tokenList => {
|
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
|
|
217
|
-
|
|
218
|
+
export default {
|
|
218
219
|
/** @readonly */
|
|
219
220
|
parse
|
|
220
221
|
}
|