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