functionalscript 0.0.523 → 0.0.524

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.
@@ -1,554 +1,44 @@
1
- const operator = require('../../types/function/operator/module.f.cjs')
2
- const range_map = require('../../types/range_map/module.f.cjs')
3
- const { merge, fromRange, get } = range_map
4
1
  const list = require('../../types/list/module.f.cjs')
5
- const _range = require('../../types/range/module.f.cjs')
6
- const { one } = _range
7
- const { empty, stateScan, flat, toArray, reduce: listReduce, scan } = list
8
- const bigfloat = require('../../types/bigfloat/module.f.cjs')
9
- const { fromCharCode } = String
10
- const {
11
- range,
12
- //
13
- backspace,
14
- ht,
15
- lf,
16
- ff,
17
- cr,
18
- //
19
- space,
20
- quotationMark,
21
- plusSign,
22
- comma,
23
- hyphenMinus,
24
- fullStop,
25
- solidus,
26
- //
27
- digitRange,
28
- digit0,
29
- colon,
30
- //
31
- latinCapitalLetterRange,
32
- latinCapitalLetterA,
33
- latinCapitalLetterE,
34
- //
35
- leftSquareBracket,
36
- reverseSolidus,
37
- rightSquareBracket,
38
- lowLine,
39
- //
40
- latinSmallLetterRange,
41
- latinSmallLetterA,
42
- latinSmallLetterB,
43
- latinSmallLetterE,
44
- latinSmallLetterF,
45
- latinSmallLetterN,
46
- latinSmallLetterR,
47
- latinSmallLetterT,
48
- latinSmallLetterU,
49
- //
50
- leftCurlyBracket,
51
- rightCurlyBracket,
52
- dollarSign
53
- } = require('../../text/ascii/module.f.cjs')
54
-
55
- /**
56
- * @typedef {{
57
- * readonly kind: 'string'
58
- * readonly value: string
59
- * }} StringToken
60
- * */
61
-
62
- /**
63
- * @typedef {{
64
- * readonly kind: 'number'
65
- * readonly value: string
66
- * readonly bf: bigfloat.BigFloat
67
- * }} NumberToken
68
- * */
69
-
70
- /**
71
- * @typedef {{
72
- * readonly kind: 'bigint'
73
- * readonly value: bigint
74
- * }} BigIntToken
75
- * */
76
-
77
- /** @typedef {{readonly kind: 'error', message: ErrorMessage}} ErrorToken */
78
-
79
- /** @typedef {{readonly kind: '{' | '}' | ':' | ',' | '[' | ']' | 'true' | 'false' | 'null'}} SimpleToken */
80
-
81
- /**
82
- * @typedef {{
83
- * readonly kind: 'id'
84
- * readonly value: string
85
- * }} IdToken
86
- * */
2
+ const jsTokenizer = require('../../js/tokenizer/module.f.cjs')
87
3
 
88
4
  /**
89
5
  * @typedef {|
90
- * SimpleToken |
91
- * StringToken |
92
- * NumberToken |
93
- * ErrorToken |
94
- * IdToken |
95
- * BigIntToken
6
+ * jsTokenizer.SimpleToken |
7
+ * jsTokenizer.StringToken |
8
+ * jsTokenizer.NumberToken |
9
+ * jsTokenizer.ErrorToken |
10
+ * jsTokenizer.IdToken |
11
+ * jsTokenizer.BigIntToken
96
12
  * } FjsonToken
97
13
  */
98
14
 
99
- const rangeOneNine = range('19')
100
-
101
- const rangeSetWhiteSpace = [
102
- one(ht),
103
- one(lf),
104
- one(cr),
105
- one(space)
106
- ]
107
-
108
- const rangeSetTerminalForNumber = [
109
- one(ht),
110
- one(lf),
111
- one(cr),
112
- one(space),
113
- one(quotationMark),
114
- one(comma),
115
- one(leftCurlyBracket),
116
- one(rightCurlyBracket),
117
- one(leftSquareBracket),
118
- one(rightSquareBracket),
119
- one(colon)
120
- ]
121
-
122
- const rangeSmallAF = range('af')
123
- const rangeCapitalAF = range('AF')
124
-
125
- const rangeIdStart = [
126
- latinSmallLetterRange,
127
- latinCapitalLetterRange,
128
- one(lowLine),
129
- one(dollarSign)
130
- ]
131
-
132
- const rangeId = [digitRange, ...rangeIdStart]
133
-
134
- /**
135
- * @typedef {|
136
- * InitialState |
137
- * ParseIdState |
138
- * ParseStringState |
139
- * ParseEscapeCharState |
140
- * ParseUnicodeCharState |
141
- * ParseNumberState |
142
- * InvalidNumberState |
143
- * EofState
144
- * } TokenizerState
145
- */
146
-
147
- /**
148
- * @typedef {|
149
- * '" are missing' |
150
- * 'unescaped character' |
151
- * 'invalid hex value' |
152
- * 'unexpected character' |
153
- * 'invalid number' |
154
- * 'invalid token' |
155
- * 'eof'
156
- * } ErrorMessage
157
- */
158
-
159
- /** @typedef {{ readonly kind: 'initial'}} InitialState */
160
-
161
- /** @typedef {{ readonly kind: 'id', readonly value: string}} ParseIdState */
162
-
163
- /** @typedef {{ readonly kind: 'string', readonly value: string}} ParseStringState */
164
-
165
- /** @typedef {{ readonly kind: 'escapeChar', readonly value: string}} ParseEscapeCharState */
166
-
167
- /**
168
- * @typedef {{
169
- * readonly kind: 'unicodeChar'
170
- * readonly value: string
171
- * readonly unicode: number
172
- * readonly hexIndex: number
173
- * }} ParseUnicodeCharState
174
- */
175
-
176
- /**
177
- * @typedef {{
178
- * readonly kind: 'number',
179
- * readonly numberKind: '0' | '-' | 'int' | '.' | 'fractional' | 'e' | 'e+' | 'e-' | 'expDigits' | 'bigint'
180
- * readonly value: string
181
- * readonly b: ParseNumberBuffer
182
- * }} ParseNumberState
183
- */
184
-
185
- /**
186
- * @typedef {{
187
- * readonly s: -1n | 1n
188
- * readonly m: bigint
189
- * readonly f: number
190
- * readonly es: -1 | 1
191
- * readonly e: number
192
- * }} ParseNumberBuffer
193
- */
194
-
195
- /** @typedef {{ readonly kind: 'invalidNumber'}} InvalidNumberState */
196
-
197
- /** @typedef {{ readonly kind: 'eof'}} EofState */
198
-
199
- /** @typedef {number|null} CharCodeOrEof */
200
-
201
- /** @typedef {(input: number) => readonly[list.List<FjsonToken>, TokenizerState]} ToToken */
202
-
203
- /**
204
- * @template T
205
- * @typedef {(state: T) => ToToken} CreateToToken<T>
206
- */
207
-
208
- /** @typedef {list.List<_range.Range>} RangeSet */
209
-
210
- /**
211
- * @template T
212
- * @typedef {(def: CreateToToken<T>) => (RangeMapToToken<T>)} RangeFunc<T>
213
- */
214
-
215
- /**
216
- * @template T
217
- * @typedef {range_map.RangeMapArray<CreateToToken<T>>} RangeMapToToken<T>
218
- */
219
-
220
- /** @type {(old: string) => (input: number) => string} */
221
- const appendChar = old => input => `${old}${fromCharCode(input)}`
222
-
223
- /** @type {<T>(def: CreateToToken<T>) => (a: CreateToToken<T>) => (b: CreateToToken<T>) => CreateToToken<T>} */
224
- const union = def => a => b => {
225
- if (a === def || a === b) { return b }
226
- if (b === def) { return a }
227
- throw [a, b]
228
- }
229
-
230
- /** @type {<T>(def: CreateToToken<T>) => range_map.RangeMerge<CreateToToken<T>>} */
231
- const rangeMapMerge = def => merge({
232
- union: union(def),
233
- equal: operator.strictEqual,
234
- })
235
-
236
- /** @type {<T>(r: _range.Range) => (f: CreateToToken<T>) => RangeFunc<T>} */
237
- const rangeFunc = r => f => def => fromRange(def)(r)(f)
238
-
239
- /** @type {<T>(def: CreateToToken<T>) => (operator.Scan<RangeFunc<T>, RangeMapToToken<T>>)} */
240
- const scanRangeOp = def => f => [f(def), scanRangeOp(def)]
241
-
242
- /** @type {<T>(def: CreateToToken<T>) => (a: list.List<RangeFunc<T>>) => RangeMapToToken<T>} */
243
- const reduceRangeMap = def => a => {
244
- const rm = scan(scanRangeOp(def))(a)
245
- return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
246
- }
247
-
248
- /** @type {<T>(def: CreateToToken<T>) => (f: CreateToToken<T>) => (operator.Scan<_range.Range, RangeMapToToken<T>>)} */
249
- const scanRangeSetOp = def => f => r => [fromRange(def)(r)(f), scanRangeSetOp(def)(f)]
250
-
251
- /** @type {<T>(rs: list.List<_range.Range>) => (f: CreateToToken<T>) => RangeFunc<T>} */
252
- const rangeSetFunc = rs => f => def => {
253
- const rm = scan(scanRangeSetOp(def)(f))(rs)
254
- return toArray(listReduce(rangeMapMerge(def))(empty)(rm))
255
- }
256
-
257
- /** @type {<T>(def: CreateToToken<T>) => (a: list.List<RangeFunc<T>>) => CreateToToken<T>} */
258
- const create = def => a => {
259
- /** @typedef {typeof def extends CreateToToken<infer T> ? T : never} T */
260
- const i = reduceRangeMap(def)(a)
261
- /** @type {(v: number) => (i: RangeMapToToken<T>) => (v: T) => ToToken} */
262
- const x = get(def)
263
- return v => c => x(c)(i)(v)(c)
264
- }
265
-
266
- /** @type {(digit: number) => bigint} */
267
- const digitToBigInt = d => BigInt(d - digit0)
268
-
269
- /** @type {(digit: number) => ParseNumberBuffer} */
270
- const startNumber = digit => ({ s: 1n, m: digitToBigInt(digit), f: 0, es: 1, e: 0 })
271
-
272
- /** @type {ParseNumberBuffer} */
273
- const startNegativeNumber = { s: -1n, m: 0n, f: 0, es: 1, e: 0 }
274
-
275
- /** @type {(digit: number) => (b: ParseNumberBuffer) => ParseNumberBuffer} */
276
- const addIntDigit = digit => b => ({ ... b, m: b.m * 10n + digitToBigInt(digit)})
277
-
278
- /** @type {(digit: number) => (b: ParseNumberBuffer) => ParseNumberBuffer} */
279
- const addFracDigit = digit => b => ({ ... b, m: b.m * 10n + digitToBigInt(digit), f: b.f - 1})
280
-
281
- /** @type {(digit: number) => (b: ParseNumberBuffer) => ParseNumberBuffer} */
282
- const addExpDigit = digit => b => ({ ... b, e: b.e * 10 + digit - digit0})
283
-
284
- /** @type {(s: ParseNumberState) => FjsonToken} */
285
- const bufferToNumberToken = ({numberKind, value, b}) =>
286
- {
287
- if (numberKind === 'bigint')
288
- return { kind: 'bigint', value: b.s * b.m }
289
- return { kind: 'number', value: value, bf: [b.s * b.m, b.f + b.es * b.e] }
290
- }
291
-
292
- /** @type {(state: InitialState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
293
- const initialStateOp = create(state => () => [[{ kind: 'error', message: 'unexpected character' }], state])([
294
- rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: 'int' }]),
295
- rangeSetFunc(rangeIdStart)(() => input => [empty, { kind: 'id', value: fromCharCode(input) }]),
296
- rangeSetFunc(rangeSetWhiteSpace)(state => () => [empty, state]),
297
- rangeFunc(one(leftCurlyBracket))(state => () => [[{ kind: '{' }], state]),
298
- rangeFunc(one(rightCurlyBracket))(state => () => [[{ kind: '}' }], state]),
299
- rangeFunc(one(colon))(state => () => [[{ kind: ':' }], state]),
300
- rangeFunc(one(comma))(state => () => [[{ kind: ',' }], state]),
301
- rangeFunc(one(leftSquareBracket))(state => () => [[{ kind: '[' }], state]),
302
- rangeFunc(one(rightSquareBracket))(state => () => [[{ kind: ']' }], state]),
303
- rangeFunc(one(quotationMark))(() => () => [empty, { kind: 'string', value: '' }]),
304
- rangeFunc(one(digit0))(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: '0' }]),
305
- rangeFunc(one(hyphenMinus))(() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNegativeNumber, numberKind: '-' }])
306
- ])
307
-
308
- /** @type {() => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
309
- const invalidNumberToToken = () => input =>
15
+ /** @type {(input: jsTokenizer.JsToken) => FjsonToken} */
16
+ const mapToken = input =>
310
17
  {
311
- const next = tokenizeOp({ kind: 'initial' })(input)
312
- return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
313
- }
314
-
315
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
316
- const fullStopToToken = state => input => {
317
- switch (state.numberKind) {
318
- case '0':
319
- case 'int': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: '.' }]
320
- default: return tokenizeOp({ kind: 'invalidNumber' })(input)
321
- }
322
- }
323
-
324
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
325
- const digit0ToToken = state => input => {
326
- switch (state.numberKind) {
327
- case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
328
- case '-': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: '0' }]
329
- case '.':
330
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addFracDigit(input)(state.b), numberKind: 'fractional' }]
331
- case 'e':
332
- case 'e+':
333
- case 'e-':
334
- case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addExpDigit(input)(state.b), numberKind: 'expDigits' }]
335
- default: return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addIntDigit(input)(state.b), numberKind: state.numberKind }]
336
- }
337
- }
338
-
339
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
340
- const digit19ToToken = state => input => {
341
- switch (state.numberKind) {
342
- case '0': return tokenizeOp({ kind: 'invalidNumber' })(input)
343
- case '.':
344
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addFracDigit(input)(state.b), numberKind: 'fractional' }]
345
- case 'e':
346
- case 'e+':
347
- case 'e-':
348
- case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addExpDigit(input)(state.b), numberKind: 'expDigits' }]
349
- default: return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addIntDigit(input)(state.b), numberKind: 'int' }]
350
- }
351
- }
352
-
353
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
354
- const expToToken = state => input => {
355
- switch (state.numberKind) {
356
- case '0':
357
- case 'int':
358
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e' }]
359
- default: return tokenizeOp({ kind: 'invalidNumber' })(input)
18
+ switch(input.kind)
19
+ {
20
+ case "id":
21
+ case "bigint":
22
+ case "{":
23
+ case "}":
24
+ case ":":
25
+ case ",":
26
+ case "[":
27
+ case "]":
28
+ case "true":
29
+ case "false":
30
+ case "null":
31
+ case "string":
32
+ case "number":
33
+ case "error": return input
34
+ default: return { kind: "error", message: "invalid token" }
360
35
  }
361
36
  }
362
37
 
363
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
364
- const hyphenMinusToToken = state => input => {
365
- switch (state.numberKind) {
366
- case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: { ... state.b, es: -1}, numberKind: 'e-' }]
367
- default: return tokenizeOp({ kind: 'invalidNumber' })(input)
368
- }
369
- }
370
-
371
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
372
- const plusSignToToken = state => input => {
373
- switch (state.numberKind) {
374
- case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e+' }]
375
- default: return tokenizeOp({ kind: 'invalidNumber' })(input)
376
- }
377
- }
378
-
379
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
380
- const terminalToToken = state => input => {
381
- switch (state.numberKind) {
382
- case '-':
383
- case '.':
384
- case 'e':
385
- case 'e+':
386
- case 'e-':
387
- {
388
- const next = tokenizeOp({ kind: 'initial' })(input)
389
- return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
390
- }
391
- default:
392
- {
393
- const next = tokenizeOp({ kind: 'initial' })(input)
394
- return [{ first: bufferToNumberToken(state), tail: next[0] }, next[1]]
395
- }
396
- }
397
- }
398
-
399
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
400
- const bigintToToken = state => input => {
401
- switch (state.numberKind) {
402
- case '0':
403
- case 'int':
404
- {
405
- return [empty, { kind: 'number', value: state.value, b: state.b, numberKind: 'bigint' }]
406
- }
407
- default:
408
- {
409
- const next = tokenizeOp({ kind: 'initial' })(input)
410
- return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
411
- }
412
- }
413
- }
414
-
415
- /** @type {(state: ParseNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
416
- const parseNumberStateOp = create(invalidNumberToToken)([
417
- rangeFunc(one(fullStop))(fullStopToToken),
418
- rangeFunc(one(digit0))(digit0ToToken),
419
- rangeFunc(rangeOneNine)(digit19ToToken),
420
- rangeSetFunc([one(latinSmallLetterE), one(latinCapitalLetterE)])(expToToken),
421
- rangeFunc(one(hyphenMinus))(hyphenMinusToToken),
422
- rangeFunc(one(plusSign))(plusSignToToken),
423
- rangeSetFunc(rangeSetTerminalForNumber)(terminalToToken),
424
- rangeFunc(one(latinSmallLetterN))(bigintToToken),
425
- ])
426
-
427
- /** @type {(state: InvalidNumberState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
428
- const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber' }])([
429
- rangeSetFunc(rangeSetTerminalForNumber)(() => input => {
430
- const next = tokenizeOp({ kind: 'initial' })(input)
431
- return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
432
- })
433
- ])
434
-
435
- /** @type {(state: ParseStringState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
436
- const parseStringStateOp = create(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }])([
437
- rangeFunc(one(quotationMark))(state => () => [[{ kind: 'string', value: state.value }], { kind: 'initial' }]),
438
- rangeFunc(one(reverseSolidus))(state => () => [empty, { kind: 'escapeChar', value: state.value }])
439
- ])
440
-
441
- /** @type {(state: ParseEscapeCharState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
442
- const parseEscapeDefault = state => input => {
443
- const next = tokenizeOp({ kind: 'string', value: state.value })(input)
444
- return [{ first: { kind: 'error', message: 'unescaped character' }, tail: next[0] }, next[1]]
445
- }
446
-
447
- /** @type {(state: ParseEscapeCharState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
448
- const parseEscapeCharStateOp = create(parseEscapeDefault)([
449
- rangeSetFunc([one(quotationMark), one(reverseSolidus), one(solidus)])(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }]),
450
- rangeFunc(one(latinSmallLetterB))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(backspace) }]),
451
- rangeFunc(one(latinSmallLetterF))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(ff) }]),
452
- rangeFunc(one(latinSmallLetterN))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(lf) }]),
453
- rangeFunc(one(latinSmallLetterR))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(cr) }]),
454
- rangeFunc(one(latinSmallLetterT))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(ht) }]),
455
- rangeFunc(one(latinSmallLetterU))(state => () => [empty, { kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0 }]),
456
- ])
457
-
458
- /** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
459
- const parseUnicodeCharDefault = state => input => {
460
- const next = tokenizeOp({ kind: 'string', value: state.value })(input)
461
- return [{ first: { kind: 'error', message: 'invalid hex value' }, tail: next[0] }, next[1]]
462
- }
463
-
464
- /** @type {(offser: number) => (state: ParseUnicodeCharState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
465
- const parseUnicodeCharHex = offset => state => input => {
466
- const hexValue = input - offset
467
- const newUnicode = state.unicode | (hexValue << (3 - state.hexIndex) * 4)
468
- return [empty, state.hexIndex === 3 ?
469
- { kind: 'string', value: appendChar(state.value)(newUnicode) } :
470
- { kind: 'unicodeChar', value: state.value, unicode: newUnicode, hexIndex: state.hexIndex + 1 }]
471
- }
472
-
473
- /** @type {(state: ParseUnicodeCharState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
474
- const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
475
- rangeFunc(digitRange)(parseUnicodeCharHex(digit0)),
476
- rangeFunc(rangeSmallAF)(parseUnicodeCharHex(latinSmallLetterA - 10)),
477
- rangeFunc(rangeCapitalAF)(parseUnicodeCharHex(latinCapitalLetterA - 10))
478
- ])
479
-
480
- /** @type {(s: string) => FjsonToken} */
481
- const idToToken = s => {
482
- switch (s) {
483
- case 'true': return { kind: 'true' }
484
- case 'false': return { kind: 'false' }
485
- case 'null': return { kind: 'null' }
486
- default: return { kind: 'id', value: s }
487
- }
488
- }
489
-
490
- /** @type {(state: ParseIdState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
491
- const parseIdDefault = state => input => {
492
- const keyWordToken = idToToken(state.value)
493
- const next = tokenizeOp({ kind: 'initial' })(input)
494
- return [{ first: keyWordToken, tail: next[0] }, next[1]]
495
- }
496
-
497
- /** @type {(state: ParseIdState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
498
- const parseIdStateOp = create(parseIdDefault)([
499
- rangeSetFunc(rangeId)(state => input => [empty, { kind: 'id', value: appendChar(state.value)(input) }])
500
- ])
501
-
502
- /** @type {(state: EofState) => (input: number) => readonly[list.List<FjsonToken>, TokenizerState]} */
503
- const eofStateOp = create(state => () => [[{ kind: 'error', message: 'eof' }], state])([])
504
-
505
- /** @type {operator.StateScan<number, TokenizerState, list.List<FjsonToken>>} */
506
- const tokenizeCharCodeOp = state => {
507
- switch (state.kind) {
508
- case 'initial': return initialStateOp(state)
509
- case 'id': return parseIdStateOp(state)
510
- case 'string': return parseStringStateOp(state)
511
- case 'escapeChar': return parseEscapeCharStateOp(state)
512
- case 'unicodeChar': return parseUnicodeCharStateOp(state)
513
- case 'invalidNumber': return invalidNumberStateOp(state)
514
- case 'number': return parseNumberStateOp(state)
515
- case 'eof': return eofStateOp(state)
516
- }
517
- }
518
-
519
- /** @type {(state: TokenizerState) => readonly[list.List<FjsonToken>, TokenizerState]} */
520
- const tokenizeEofOp = state => {
521
- switch (state.kind) {
522
- case 'initial': return [empty, { kind: 'eof' }]
523
- case 'id': return [[idToToken(state.value)], { kind: 'eof' }]
524
- case 'string':
525
- case 'escapeChar':
526
- case 'unicodeChar': return [[{ kind: 'error', message: '" are missing' }], { kind: 'eof' }]
527
- case 'invalidNumber': return [[{ kind: 'error', message: 'invalid number' }], { kind: 'eof' }]
528
- case 'number':
529
- switch (state.numberKind) {
530
- case '-':
531
- case '.':
532
- case 'e':
533
- case 'e+':
534
- case 'e-': return [[{ kind: 'error', message: 'invalid number' }], { kind: 'invalidNumber', }]
535
- default: return [[bufferToNumberToken(state)], { kind: 'eof' }]
536
- }
537
- case 'eof': return [[{ kind: 'error', message: 'eof' }], state]
538
- }
539
- }
540
-
541
- /** @type {operator.StateScan<CharCodeOrEof, TokenizerState, list.List<FjsonToken>>} */
542
- const tokenizeOp = state => input => input === null ? tokenizeEofOp(state) : tokenizeCharCodeOp(state)(input)
543
-
544
- const scanTokenize = stateScan(tokenizeOp)
545
-
546
- const initial = scanTokenize({ kind: 'initial' })
547
-
548
38
  /** @type {(input: list.List<number>) => list.List<FjsonToken>} */
549
- const tokenize = input => flat(initial(flat([/** @type {list.List<CharCodeOrEof>} */(input), [null]])))
39
+ const tokenize = input => list.map(mapToken)(jsTokenizer.tokenize(input))
550
40
 
551
41
  module.exports = {
552
42
  /** @readonly */
553
43
  tokenize
554
- }
44
+ }
@@ -10,7 +10,7 @@ const tokenizeString = s => toArray(tokenizer.tokenize(encoding.stringToList(s))
10
10
  const stringify = fjson.stringify(sort)
11
11
 
12
12
  module.exports = {
13
- testing: [
13
+ fjson: [
14
14
  () => {
15
15
  const result = tokenizeString('')
16
16
  if (result.length !== 0) { throw result }